Что такое полифилл?
MDN определяет его как «Полифилл - это фрагмент кода (обычно JavaScript в Интернете), используемый для обеспечения современных функций в старых браузерах, которые изначально не поддерживают его».
Проще говоря, это способ добавить обратную совместимость.
О чем следует помнить при написании полифилла:
1. Какой полифилл мы пишем? Это метод или класс и т. Д.
2. Каковы ожидаемые аргументы моего полифилла и их порядок?
3. Каков тип возвращаемого значения моего полифилла?
Давайте посмотрим на полифил Bind.
В) Какие полифилы мы пишем?
А) Метод
В) Каковы ожидаемые аргументы моего полифилла и их порядок?
А) Первым аргументом должен быть контекст, за которым следует любой аргумент, переданный пользователем
В) Каков тип возвращаемого значения моего полифилла?
А) Bind возвращает новый метод с определенным контекстом
Поскольку привязка вызывается с обозначением точки (.) Для объекта функции, мы определим наш полифилл в прототипе функции.
Привязать полифил с использованием метода «Применить»
Function.prototype.newBindWithApply = function (ctx, ...args) { // Preserving the current function let fn = this; // Preserving the default arguments passed with context let allArguments = args; // returning the new method with context return function (args1) { allArguments = [...allArguments, ...args1] return fn.apply(ctx, allArguments) } }
Привязать полифил без использования метода «Применить»
Function.prototype.newBindWithoutApply = function (ctx, ...args) { // Preserving the default arguments passed with context let allArguments = args; /* Since we are not using call/apply, I'll create a reference of binding method within the context, and method will be invoked as context.methodcall() */ ctx.fnToCall = this; // returning the new method with context return function (...args1) { allArguments = [...allArguments, ...args1] return ctx.fnToCall(...args) } }
Быстрая реализация:
function printNameAge (argumentPassed) { console.log(this.name, this.age, argumentPassed) } let p1 = printNameAge.newBindWithoutApply({name:'foo', age: 20}, 'Without Apply Default Argument')(); Output: 'foo' 20 'Without Apply Default Argument' let p2 = printNameAge.newBindWithoutApply({name:'bar', age: 40})('Without Apply Calling Argument'); Output: 'bar' 40 'Without Apply Calling Argument' let p3 = printNameAge.newBindWithApply({name:'foo', age: 20}, 'With Apply Default Argument')(); Output: 'foo' 20 'With Apply Default Argument' let p4 = printNameAge.newBindWithApply({name:'bar', age: 40})('With Apply Calling Argument'); Output: 'bar' 40 'Without Apply Calling Argument'
Точно так же Quick Polyfill для Apply может быть:
Function.prototype.myApply = function(ctx, ...args) { ctx.fnToCall = this; return ctx.fnToCall(...args) }
Это всего лишь быстрый способ написания полифиллов. В реальном сценарии может потребоваться сделать полифилы более безопасными с помощью Object.seal () или Object.freeze ().