Внедрение Javascript Bind?
Так как bind
не является функцией перекрестного браузера (старый), для него есть polyfill: (из книги Джона Ресига)
/*1*/ Function.prototype.bind = function ()
/*2*/ {
/*3*/ var fn = this,
/*4*/ args = Array.prototype.slice.call(arguments),
/*5*/ object = args.shift();
/*6*/ return function ()
/*7*/ {
/*8*/ return fn.apply(object,
/*9*/ args.concat(Array.prototype.slice.call(arguments)));
/*10*/ };
/*11*/ };
Но я не понимаю, зачем нам arguments
в строке #9
.
Я имею в виду:
Если у меня есть этот объект:
var foo = {
x: 3
}
И у меня есть эта функция:
var bar = function(p,b){
console.log(this.x+' '+p+' '+b);
}
Итак, если я хочу, чтобы bar
выполнялся в контексте foo
, с параметрами - все, что мне нужно сделать, это:
var boundFunc = bar.bind(foo,1,2)
boundFunc ()...
Итак, когда я запускаю var.bind(foo,1,2)
, arguments
есть [object Object],1,2
.
Эти аргументы сохраняются в строке # 4.
Великий.
Теперь функция bind
возвращает свою закрытую функцию:
function ()
{
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
}
Вопрос
Зачем нам arguments
здесь? кажется, что они для чего-то вроде:
var boundFunc = bar.bind(foo,1,2)
boundFunc (more1,more2....) //<----- ??
Я что-то упустил?
Oonce Я установил первый var boundFunc = bar.bind(foo,1,2)
, я уже объявил параметры. почему мы нуждаемся в них дважды?
Ответы
Ответ 1
Есть два места, которые вы можете передать в аргументах связанной функции:
1) Когда вы вызываете bind (первый arguments
). Они всегда применяются к связанной функции, когда она вызывается.
2) Когда вы вызываете связанную функцию (вторая arguments
). Это "больше1, больше2", о которых вы упоминаете. Они изменяются в зависимости от того, что предусмотрено при вызове связанного аргумента.
Строка 9 объединяет исходные связанные аргументы с дополнительными аргументами.
Я предполагаю, что концепция, которую вы можете смутить, состоит в том, что вам не нужно сначала привязывать ВСЕ аргументы - вы можете привязать только объект контекста, или вы можете связать и первый аргумент, но иметь вызывающих функции поставьте все остальное. Например:
function sum() {
var _sum = 0
for (var i = 0; i < arguments.length ; i++) {
_sum += arguments[i];
}
return _sum;
}
var sum_plus_two = sum.bind({},2);
sum_plus_two(5,7) == 14;
Ответ 2
.bind
также служит частное приложение. Лучшим примером могут служить обработчики событий:
var handler = function(data, event) { };
element.addEventListener('click', handler.bind(null, someData));
Если аргументы из фактического вызова функции не будут переданы, вы не сможете получить доступ к объекту события.