我创建了这些函数来检查每个函数中的“this”是什么,并且想知道当使用call函数时,为什么“this”不是“test”对象?
function foo() {
console.log("call foo:", this);
bar();
}
function bar() {
//why the "this" is not the "test" object
console.log("call bar:", this);
}
function Test() {
}
var test = new Test();
foo.call(test);
答案 0 :(得分:5)
如果您执行foo.call(test)
,则在foo()
内,this
将为test
。
但是,在foo()
内,当您再调用bar()
时,this
值将在bar()
内重置为其默认值。
Javascript中的每个函数调用都根据函数的调用方式设置this
的新值。
普通函数调用(如bar()
)将this
的值设置为全局对象(如果未在严格模式下运行)或undefined
如果运行严格模式。
要查看,将this
值设置为特定值的方法是:
foo.call(test, ...); // sets this to test
foo.apply(test, ...); // sets this to test
obj.method(); // sets this to obj
var x = foo.bind(test);
x(); // sets this to test
var x = new foo(); // create a new object and sets this to the new object
foo(); // this set to global object or undefined (in strict mode)
请记住,根据上述规则,Javascript中的每个函数调用都会重置this
的值。它永远不会从之前的值“继承”。根据函数调用的方式,它总是在每个函数调用中设置为新的。对于Javascript新手来说,这是一个常见的误解(很多时候,我被同样的事情绊倒了)。
还值得注意的是,当调用回调函数时,回调函数可能将this
的值设置为特定的值(在内部使用。apply()
或.call()
)。例如:
function submitHandler(e) {
// value of this is in this function is set
// by addEventListener to the DOM object that handled the event
}
document.getElementById("submit").addEventListener("click", submitHandler);
关于该主题的其他参考文献:
When you pass 'this' as an argument