Одной из распространенных проблем, с которой могут столкнуться начинающие разработчики в JavaScript, является доступ к правильному объекту this
внутри обратного вызова. Для рассмотрения этой проблемы рассмотрим следующий пример кода:
function MyConstructor(data, transport) { this.data = data; transport.on('data', function () { console.log(this.data); }); } var transport = { on: function(event, callback) { setTimeout(callback, 1000); } }; var obj = new MyConstructor('foo', transport);
В этом примере ожидается, что обратный вызов, переданный в функцию transport.on
, будет иметь доступ к свойству data
объекта, созданного с помощью MyConstructor
. Однако в действительности this
внутри обратного вызова не ссылается на этот объект, и this.data
будет undefined
.
Проблема заключается в том, что this
в JavaScript определяется в момент вызова функции, а не в момент ее определения. Когда функция обратного вызова вызывается внутри transport.on
, this
будет ссылаться на контекст, в котором выполняется эта функция, а не на объект, созданный с помощью MyConstructor
.
Решить эту проблему можно несколькими способами. Во-первых, можно сохранить ссылку на правильный объект this
в переменной и затем использовать эту переменную в обратном вызове:
function MyConstructor(data, transport) { var self = this; this.data = data; transport.on('data', function () { console.log(self.data); }); }
Во-вторых, можно использовать метод bind
для привязки контекста к функции обратного вызова:
function MyConstructor(data, transport) { this.data = data; transport.on('data', function () { console.log(this.data); }.bind(this)); }
Оба этих подхода позволяют сохранить правильный контекст для this
и обеспечить доступ к свойству data
объекта внутри обратного вызова.
Добавить комментарий