Skip to content

46 Pollyfills

Biswajit Sundara edited this page Aug 23, 2023 · 3 revisions

Pollyfill is a piece of code that provides additional functionality that is not natively supported by a browser.

  • It allows developers to use features of the latest ECMAScript (JavaScript) specifications in older browsers that do not support these features.
  • Polyfills are often used to bridge the gap between the JavaScript code developers want to write (using modern language features) and the JavaScript that older browsers can understand.

1. Example

  • We check if String.prototype.startsWith is already defined. If it's not, we define it using a polyfill function.
  • The polyfill function emulates the behavior of startsWith() by using the indexOf() method to check if the string starts with the specified substring, considering an optional starting position.
  • After defining the polyfill, you can use str.startsWith() as if it were a built-in method, even in browsers that don't support it natively.
  • This way, you can ensure consistent behavior for your code across different browsers, even when some of them do not support the latest JavaScript features.
// Check if String.prototype.startsWith() is not available (older browsers)
if (!String.prototype.startsWith) {
  // Define the polyfill
  String.prototype.startsWith = function (searchString, position) {
    position = position || 0;

    return this.indexOf(searchString, position) === position;
  };
}
<body>
    <script>
      var str = "Hello, World!";
      console.log(str.startsWith1("Hello")); // true
      console.log(str.startsWith1("World", 7)); // true
      console.log(str.startsWith1("Goodbye")); // false
    </script>
</body>
  • Similarly we can implement for Array.prototype.includes also

2. Polyfill the bind method

Before creating polyfill, let's see how a traditional bind method works.

Default bind method

const name = {
  firstname: "Biswajit",
  lastName: "Sundara",
};

const printName = function () {
  console.log(this.firstname + " " + this.lastName);
};

const printMyname = printName.bind(name);
printMyname();   //prints Biswajit Sundara

Polyfill

  • Every function in JS has access to bind method, so our function mybind also should be available.(add to prototype)
  • bind returns a function so lets return a function
const name = {
  firstname: "Biswajit",
  lastName: "Sundara",
};

Function.prototype.mybind = function (...args) {
  let obj = this;
  const params = args.slice(1);
  return function (...args2) {
    obj.apply(args[0], [...params, ...args2]);
  };
};

const printName = function (hometown, state) {
  console.log(
    this.firstname + " " + this.lastName + " " + hometown + " " + state
  );
};

const printMyname = printName.mybind(name, "Bhubaneswar");
printMyname("Odisha");

3. Refined Code

Same example like before however little refined code.

  • Here we are checking for custom mybind as bind is already available
  • First check if Function.prototype.mybind() is not available (older browsers)
if (!Function.prototype.mybind) {
  Function.prototype.mybind = function (context) {
    var fn = this;

    // Get additional arguments
    // arguments is a global object we can access inside function
    // arguments is an array like object, so we can't apply slice on it directly
    // We are starting the slicing from the second elements, so starts with 1
    var args = Array.prototype.slice.call(arguments, 1);

    return function () {
      //get the arguments for this inner function
      params = Array.prototype.slice.call(arguments);

      // Combine bind and call-time arguments
      var bindArgs = args.concat(params);

      // Invoke the original function with the desired context and arguments
      return fn.apply(context, bindArgs);
    };
  };
}

// Example usage
function greet(name, greet) {
  console.log(`${greet}, ${name}! I'm ${this.message} age ${this.age}`);
}

var person = {
  message: "a friendly person",
  age: 21,
};

var greetPerson = greet.mybind(person, "Biswajit");
greetPerson("Hello"); // Output: Hello, Biswajit! I'm a friendly person

Clone this wiki locally