Offer 驾到,掘友接招!我正在参与2022春招系列活动-Debug实录任务,点击查看活动详情
问题描述:
一个注册事件处理程序的构造函数
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', function () {
alert(this.data);
});
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor('foo', transport);
但是,无法data在回调中访问已创建对象的属性。它看起来this不是指的是创建的对象,而是另一个对象。
尝试使用对象方法而不是匿名函数
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', this.alert);
}
MyConstructor.prototype.alert = function() {
alert(this.name);
};
但它表现出同样的问题。 如何访问正确的对象?
解决方法:
- 使用
bind()功能
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', ( function () {
alert(this.data);
}).bind(this) );
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor('foo', transport);
如果使用的是 Underscore.js - underscorejs.org/#bind
transport.on('data', _.bind(function () {
alert(this.data);
}, this));
- 在另一个变量中存储对 context/this 的引用
function MyConstructor(data, transport) {
var self = this;
this.data = data;
transport.on('data', function() {
alert(self.data);
});
}
- 使用箭头函数
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => {
alert(this.data);
});
}
总结:
与其他语言相比,函数的this关键字在 JavaScript 中的行为略有不同。
严格模式和非严格模式也有一些区别。
在大多数情况下, this 的值取决于函数的调用方式。
执行时不能通过赋值来设置,每次调用函数时可能都不一样。
ES5 引入了 bind() 方法来设置函数的值,this而不管它是如何被调用的,
并且 ES2015 引入了不提供this绑定的箭头函数(它保留了封闭词法上下文的这个值)。