为新手问题道歉,但请考虑此代码
function Greeter( name) { this.name = name; }
Greeter.prototype.delayed_greet = function() {
setTimeout( function cb() {
console.log(' Hello ' + this.name);
}, 500);
};
Greeter.prototype.greet = function() {
console.log(' Hello ' + this.name);
}
const greeter = new Greeter(' World');
greeter.delayed_greet(); // will print "Hello undefined"
greeter.greet(); // will print "Hello World"
所以在delayed_greet
方法中,this
在setTimeout
内嵌套时会引用什么?它显然不是指greeter
对象,否则它会起作用。
答案 0 :(得分:3)
setTimeout
通常在浏览器中定义为window.setTimeout
,并且可以仅作为setTimeout
调用,因为它在全局范围内可用。
这也意味着上下文和this
值始终为window
,除非明确设置了另一个this
值。
MDN说
setTimeout()
执行的代码从执行上下文调用 与调用setTimeout的函数分开。为被调用函数设置
this
关键字的常用规则 如果您未在呼叫中设置this
或使用绑定,则应用它 将以非严格模式默认为全局(或窗口)对象,或 在严格模式下未定义。它与函数的
this
值不同 叫做setTimeout。
MDN还概述了解决这个问题的多种方法"在setTimeout
。
我个人认为我会采取简单的方法,并使用变量
Greeter.prototype.delayed_greet = function() {
var that = this;
setTimeout( function cb() {
console.log(' Hello ' + that.name);
}, 500);
};
另一种选择是箭头功能,因为它们保留了周围环境,并且不会创建自己的上下文。
var o = {
fn () {
setTimeout( () => { console.log(this) }, 500)
}
}
var o2 = {
fn () {
setTimeout( function() {
console.log(this === window)
}, 1000)
}
}
o.fn(); // fn() --- arrow function
o2.fn(); // true, is window --- regular function