我可以说“this”关键字对于那些使用 C# 等语言的人来说是 Javascript 中最令人困惑的部分。
我也在互联网和 StackOverflow 上阅读了很多关于此的内容。喜欢here和 here .
我知道“this”关键字将绑定(bind)到上下文。在构造函数中它将绑定(bind)到正在创建的对象,当没有直接上下文时它将绑定(bind)到全局对象(即窗口)
这些我都知道了,但是困惑还没有完全消除;因此,最好的理解方式是通过测试代码。
所以我决定编写小代码,令我惊讶的是 this
关键字如此复杂。
这是我测试的代码:
function sayHi(name){
var tt = name;
return {
ss: tt,
work: function(anotherName){
alert ("hiiiii " + anotherName);
}
};
}
//this method invocation has no effect at all right now
sayHi("John");
var hi2 = new sayHi("wallace");
hi2.work("May");
alert(hi2.ss);
正如预期的那样,警报窗口将显示 (Hiiiiii May) 然后 (wallace)。现在请注意 sayHi("John");
行根本没有任何效果。
现在,当我只改变一件事(改变 var tt => this.tt)时,困惑就会开始:
function sayHi(name){
//this is the ONLY change I did.
this.tt = name;
return {
ss: tt,
work: function(anotherName){
alert ("hiiiii " + anotherName);
}
};
}
// Now this line invocation will be problematic
sayHi("John");
var hi2 = new sayHi("wallace");
hi2.work("May");
alert(hi2.ss);
当警报方法给出 (Hiiiiiii May) 然后 (John) 而不是 (wallace) 时,结果让我感到惊讶;
所以我有了注释行 sayHi("John");
的想法,但这导致整个代码无法正常工作。
我知道这可能是新手问题。但这里真的很困惑,我确实尝试阅读了很多文章和 SO 问题,但我错过了这一点。
为什么行 sayHi("John");
将 hi2.ss 设置为 John?以及为什么当我们删除它时它会破坏代码;尽管我们随后使用 new
关键字调用了 sayHi
方法 ??
最佳答案
因为您将参数“name”分配给 this
引用的对象的属性(在本例中为 window
),您随后对“tt”的引用"在该对象文字中将指向全局对象的 "tt"属性,因为这是下一个封闭范围。
您第一次调用“sayHi”时没有使用 new
运算符,因此在该调用中 this
将引用全局对象(window
).第二版第一行
this.tt = name;
因此会将 window.tt
设置为“John”。
下一次调用是用 new
运算符进行的。因此,函数中的 this
指的是新实例化的对象。线路
this.tt = name;
因此实际上对任何事情都没有实际影响,因为该函数在所有情况下都会返回一个不同对象。测试的最后一行:
alert(hi2.ss);
说“John”是因为那是 window.tt
中的内容。为什么这很重要?因为“sayHi”返回一个对象,其属性(“ss”)由符号“tt”的值设置。作用域中唯一的“tt”将是 window.tt
,它在 第一次 函数调用中被设置回来。
关于javascript - 关于 Javascript 中 'this' 关键字的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23955489/