Вопрос

От: http://ejohn.org/apps/learn/#2.

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
};

Кто-нибудь может сказать мне, почему необходимо второе возвращение (до fn.apply)?

Кроме того, кто-нибудь может объяснить, почему args.concat нужен? Почему бы не повторно написано как:

fn.apply(object, args)

вместо

return fn.apply(object,
          args.concat(Array.prototype.slice.call(arguments)));
Это было полезно?

Решение

Второй доход необходим, потому что в противном случае мы потеряем любое возвращаемое значение из связанной функции.

Вы можете знать это, но не повредит, чтобы упомянуть. Если мы не обертываем fn.apply внутри другой функции, то мы напрямую призываем функцию fn который является подактивным, как bind должен только установить контекст выполнения (что должно this См. Внутри функции), и не вызывают его.

Методы JavaScript могут быть вызваны, вызывая call или apply Метод на них. Вот небольшой пример:

function example() {
    alert("useless example");
}

example.apply() // or example.call(), alerts "useless example";

Внешняя функция в Prototype Bind () должна работать как невидимая обертка вокруг связанной функции. Таким образом, любые аргументы, которые передаются на обертку, также должны быть переданы в связанную функцию, и он должен вернуть любое значение, которое связано, что возвращает функции, именно поэтому отчет о возвращении.

Причина выполнения Args.Concat внутри Fn.apply отличается и не является необязательной. bind В прототипе позволяет представлять аргументы к связанной функции.

args представляет аргументы, которые были переданы, когда мы позвонили bind на функцию. arguments Представляет аргументы, которые были переданы, когда мы назвали связанную функцию. Мы в основном объединяем две массивы там.

Из приведенного выше примера:

var obj = { x: 'prop x' };
var boundExample = example.bind(obj, 12, 23); // args => 12, 23
boundExample(36, 49); // arguments => 36, 49

// arguments that our example() function receives => 12, 23, 36, 49

Другие советы

Старый пост, но новый подход;)

Function.prototype.bind = function(){
    var fn = this, 
    context = arguments[0], 
    args = Array.prototype.slice.call(arguments, 1);
    return function(){
        return fn.apply(context, args.concat([].slice.call(arguments)));
    }
}

obj = {'abc':'x'};
var func = function() {
  console.log(arguments);
  alert(this.abc);
}
var x = func.bind(obj);

console.log(x(1,2,3));

Это очень хороший пример, чтобы объяснить. Запустите его и проверьте журнал консоли. Затем измените код, чтобы оставить

[].slice.call(arguments)

Вы увидите, что Console.log выполнения X (1,2,3) больше не отображает аргументы. Это связано с тем, что аргументы объекты являются локальной переменной во всех функциях. Это может звучать немного запутанным, но что это значит в основном:

var x = func.bind(obj,1,2,3);

Возвращает эту функцию внутренне:

function() {
    return fn.apply(obj, [1,2,3].concat([].slice.call(arguments)));
}

Так что это скорее шаблон для функции.

Когда вы сейчас запускаете:

x(4,5,6)

Это будет RAN:

fn.apply(obj, [1,2,3].concat([].slice.call(arguments)))

С помощью специальных аргументов объектом = {0: 4,1: 5,2: 6}, которые могут быть преобразованы в массив с использованием [] .SLICE.call, где аргументы представляют собой локальный объект, который автоматически назначается в течение привлечения во время привода функция.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top