当你向 setTimeout()
(或者其他函数)传递一个函数时,该函数中的this
指向跟你的期望可能不同。
由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字会指向 window (严格模式和非严格模式都会指向window)。
举例:
let myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
执行的输出结果与设想不同
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
myArray.myMethod
函数传递给 setTimeout
,到了定时时间,this
没有指向,默认指向window
对象。并且没有方法把 thisArg
传递给setTimeout
,正如Array方法的forEach
,reduce
等。下面的例子表示使用call
方法设置this
也没用。
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
可能的解决方案:
用包装函数来设置this:
setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
或者箭头函数也可以:
setTimeout(() => {myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(() => {myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
文章借鉴于 MDN文档