0

Почему метод bind() в JavaScript необходим?

3

Проблема в примере 1 заключается в том, что 'this' ссылается на глобальный объект, а не на объект myName.

Я понимаю, как использовать метод bind() для привязки значения this к определенному объекту, и это решает проблему в примере 1. Но почему эта проблема возникает изначально? Это просто особенность JavaScript?

Кроме того, меня интересует, почему пример 3 решает эту проблему, и в чем разница между примером 2 и примером 3.

Вот код для наглядности:

this.name = "John";

var myName = {
  name: "Tom",
  getName: function() {
    return this.name;
  }
}

var storeMyName = myName.getName; // пример 1
var storeMyName2 = myName.getName.bind(myName); // пример 2
var storeMyName3 = myName.getName(); // пример 3

console.log("пример 1: " + storeMyName()); // не работает
console.log("пример 2: " + storeMyName2()); // работает
console.log("пример 3: " + storeMyName3); // работает

Почему в первом примере возникает проблема с 'this', и как именно примеры 2 и 3 по-разному решают эту проблему?

2 ответ(ов)

0

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

Когда вы определяете объект a с методом bar, этот метод, по сути, относится к объекту a, и в нем this ссылается на a. Однако, когда вы присваиваете a.bar переменной bound, вы фактически создаете ссылку на функцию bar без ее окружения. В результате, при вызове bound(), this становится глобальным объектом (или undefined в строгом режиме), что и приводит к получению "global foo".

Вот ваш пример:

var foo = "global foo"; // foo определен в глобальном контексте
var a = {
  foo: "object foo",
  bar: function() {
    return this.foo; // Здесь `this` ссылается на объект `a`
  }
};

var bound = a.bar; // Мы просто ссылаемся на функцию без контекста
console.log(bound()); // Вернет "global foo", а не "object foo"

Чтобы сохранить правильный контекст this, вы можете использовать метод bind, который создает новую функцию с заданным значением this. Например:

var boundWithContext = a.bar.bind(a);
console.log(boundWithContext()); // Теперь вернет "object foo"

Таким образом, использование bind, а также такие методы, как call или apply, позволяет контролировать контекст выполнения функции, что часто бывает необходимо при работе с колбэками или передаче функций в качестве аргументов.

0

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

Основываясь на вашем примере:

var storeMyName = myName.getName;

В этой строке вы вызываете функцию storeMyName в глобальном контексте, поэтому в этом случае this.name будет ссылаться на верхний уровень (т.е. глобальный контекст / "John").

var storeMyName2 = myName.getName.bind(myName);

В этой строке вы явно изменяете контекст выполнения функции storeMyName2 (говоря, что не хотите выполнять эту функцию в глобальном контексте, а хотите использовать контекст объекта myName, так что в этом случае this.name будет равно "Tom").

var storeMyName3 = myName.getName(); // пример 3

А в этой строке вы просто вызываете функцию в контексте объекта myName, более того, вы не выполняете storeMyName3, и именно поэтому её контекст не является глобальным.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь