Функции в JavaScript выполняются в определенном контексте, и, используя this
переменную, мы имеем к нему доступ.
Все стандартные функции браузера выполняются в контексте окна. Функции, определенные в объекте или классе (другой функции), будут использовать контекст объекта, в котором они были созданы. Однако мы также можем изменить контекст функции во время выполнения, либо до, либо во время выполнения функции.
Чтобы привязать функцию к объекту и сделать ее методом объекта, мы можем использовать bind
функцию. Вот простой пример:
var person = {
name : "John"
};
function printName()
{
console.log(this.name);
}
Очевидно, что мы не можем вызвать, не связав функцию с объектом . Для этого мы должны создать связанный метод функции printName с человеком, используя следующий код:printName()
person
var boundPrintName = printName.bind(person);
boundPrintName(); // prints out "John"
Мы можем использовать call
и apply
функцию для вызова функции , как если бы она была привязана к объекту. Разница между call
и apply
функциями только тем , как они получают свои аргументы - call
функция принимает this
аргумент первой, а затем аргументы функции, в то время как apply
функция принимает this
аргумент первой, и массив аргументов , чтобы перейти к функции как второй аргумент функции.
Например, давайте назовем printName
с person
в зависимости от контекста , используя call
метод:
printName.call(person); // prints out "John"
Разница между call
/ apply
и bind
заключается в том, что bind
возвращает новую функцию, идентичную старой, за исключением того, что значение this
в новой функции теперь является объектом , к которому она была привязана. call
/ apply
вызывает функцию с this
привязанным объектом, но она не возвращает возврат новой функции или не изменяет оригинал, а вызывает ее с другим значением для this
.
Например:
var boundPrintName = printName.call(person); //boundPrintName gets printName's return value (null)
boundPrintName(); //doesn't work because it's not a function, it's null
printName.bind(person); //returns a new function, but nothing is using it so it's useless
printName(); //throws error because this.name is not defined
Думайте об этом call
как о выполнении возвращаемого значения bind
.
Например:
printName.call(person); //is the same as
printName.bind(person)(); //executes the function returned by bind
Или подумайте о том, чтобы bind
вернуться к ярлыку call
.
Например:
var boundPrintName = printName.bind(person); //is the same as
var boundPrintName = function()
{
printName.call(person);
}
Создайте связанные копии printFullName и printDetails для человека с именем boundPrintFullName и boundPrintDetails.