2016-04-18 3 views
1

Я учусь о Bind, вызов, и применить, и у меня есть вопрос о Bind, что я не был в состоянии найти хороший ответ на него:Сразу вызывают методы с Javascript Bind

сказать, что я следующего код

var Jim = { 
    firstName: 'Jim', 
    lastName: 'Bob', 
    fullName: function() { 
     return this.firstName + ' ' + this.lastName; 
    } 
}; 

var fName = Jim.fullName; //now fName's context is window 

//If I invoke fName here, I will get the expected 'undefined undefined' 
console.log(fName()); 

Я могу, однако, сделать следующее и получить мой связанный метод для вызова сразу после прохождения нового контекста:

fName.bind(Jim)(); //this returns 'Jim Bob' 

Я чувствую, что это просто имитируя то, что может (ш ould?) быть сделано с call или apply. Если я снова вызываю fName() после предыдущей строки, он все еще привязан к объекту окна (fName не был изменен с помощью использования bind). Это плохая практика?

Как об этом, хотя:

var Jim = { 
    //same object definition as above 
}; 

var Chris = { 
    firstName: 'Chris', 
    lastName: 'Smith' 
}; 

var fName = Jim.fullName.bind(Jim); //now fName's context is the Jim object 
console.log(fName()); //this will log 'Jim Bob' as expected 

и теперь, если я пытаюсь связать связанный метод в другом контексте в месте, он не работает:

fName.bind(Chris)(); //this still logs 'Jim Bob' from the original context 

Я считаю, что во втором случае это потому, что я в основном создаю «связанную функцию», поэтому он имеет два контекста и просто подходит для первого.

Любые мысли по любому из этих случаев?

+1

Непонятно, что именно вы спрашиваете. – zerkms

+1

Если второе 'bind' может изменить значение' this', это означает, что первый 'bind' не связал его. – Oriol

+0

* "Теперь контекст fName - это окно" * - Нет, это не так.Контекст устанавливается каждый раз, когда функция * называется *, а не каждый раз, когда вы создаете ссылку на нее. fName и Jim.fullName - ссылки на одну и ту же функцию. Что касается .bind(), им просто не нужно называть его только для немедленного вызова возвращаемой функции - поскольку вы, как говорят, можете использовать для этого .call() или .apply(). Точка .bind() - это создать функцию, которую вы можете вызвать в какой-то другой точке, поэтому, чтобы использовать ее разумно, вы должны назначить возвращаемую функцию переменной или передать ее как аргумент какой-либо другой функции. – nnnnnn

ответ

0

Вы по существу правы по всей доске. Ведение

var fName = Jim.fullName; 
fName.bind(Jim)(); 

Есть точно такая же вещь, как

var fName = Jim.fullName; 
fName.call(Jim); 

Я не уверен, что я бы назвал первый пример «плохой практики», но это определенно не «хорошая практика.» call делает именно то, что вы хотите, не генерируя новое значение функции и, по моему мнению, лучше описывает ваши намерения.

Что касается того, почему вы не можете восстановить функцию, вы очень близки к правому. Вместо того, чтобы иметь два контекста для fName, он все еще имеет только один. Но bind явно заявляет: «Это контекст этой функции, не вопрос об этом».

0

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

В соответствии с MDN docs,

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

+0

Я не видел эту часть документации! Не может быть переопределенная часть довольно ясна :) Спасибо за ваш ответ. –

Смежные вопросы