Функциональный контекст


Функции в 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.