关于';这';Javascript中的关键字
我可以说,对于那些来自C#等语言的人来说,“this”关键字是Javascript中最令人困惑的部分 我在网上和StackOverflow上读到了很多关于这方面的文章。喜欢和 我知道“this”关键字将绑定到上下文。在构造函数中,它将绑定到正在创建的对象,当没有即时上下文时,它将绑定到全局对象(即窗口) 我知道这一切,但困惑仍未完全消除;因此,最好的理解方法是测试代码关于';这';Javascript中的关键字,javascript,this,Javascript,This,我可以说,对于那些来自C#等语言的人来说,“this”关键字是Javascript中最令人困惑的部分 我在网上和StackOverflow上读到了很多关于这方面的文章。喜欢和 我知道“this”关键字将绑定到上下文。在构造函数中,它将绑定到正在创建的对象,当没有即时上下文时,它将绑定到全局对象(即窗口) 我知道这一切,但困惑仍未完全消除;因此,最好的理解方法是测试代码 所以我决定写一些小代码,我对这个关键字的复杂程度感到惊讶 以下是我测试的代码: function sayHi(name){
所以我决定写一些小代码,我对
这个
关键字的复杂程度感到惊讶
以下是我测试的代码:
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”)代码>完全无效
现在,当我只更改一件事情时,就会出现混乱(change var tt=>this.tt):
结果让我惊讶,当警报方法发出(Hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
所以我有了一个想法,对这句话sayHi(“John”)
但这导致整个代码无法正常工作
我知道这可能是个新手问题。但这里真的很混乱,我也试着读了很多文章和问题,但我忽略了这一点
为什么这句话sayHi(“John”)代码>将hi2.ss设置为John??为什么我们删除它时它会破坏代码;尽管我们在后面使用new
关键字调用sayHi
方法,因为您将参数“name”分配给this
引用的对象的属性(在本例中为window
),但在该对象文本中对“tt”的后续引用将是“tt”属性,因为这是下一个封闭范围
您第一次调用“sayHi”时没有使用new
操作符,因此在该调用中,此
将引用全局对象(窗口
)。第二个版本中的第一行
this.tt = name;
因此将window.tt
设置为“John”
下一个呼叫由新的操作员进行。因此,函数中的此
引用新实例化的对象。线路
this.tt = name;
因此对任何事情都没有净影响,因为函数在所有情况下都返回不同的对象。测试的最后一行:
alert(hi2.ss);
说“John”是因为这是window.tt
中的内容。这有什么关系?因为“sayHi”返回一个对象,其属性(“ss”)由符号“tt”的值设置。作用域中唯一的“tt”将是window.tt
,它是在第一次调用函数时设置的。调用构造函数时,如果函数中不存在return语句,则隐式返回此
,否则返回值,并且只忽略此
在第二个示例中,您将name参数保存为this.tt
,但返回一个不同的对象。这就是事情不起作用的原因。基本上使用这个
或返回一个自定义对象,但不要两者都做。当您第一次调用sayHi(“John”)代码>,此
将指向全局对象窗口
。这意味着this.tt=name
实际上创建了一个全局tt
变量
然后当你调用newsayhi(“华莱士”)
,此
正确地指向了sayHi
的一个新实例,但您正在返回另一个对象,而不是让new
自然返回该实例
如果仔细查看对象文字,您可以像ss:tt,
那样定义ss
。由于您没有使用this.tt
,并且在构造函数的作用域中找不到tt
符号,因此该值将被解析为全局变量(以前设置为John
)。在“严格”模式下,当在没有任何上下文的情况下调用函数时,this
是未定义的
。ss:tt,
是基于本地变量而不是此变量的属性进行赋值的,因为该变量不存在,所以应该是未定义的。@scragar在向下阅读答案并理解所有答案之后。现在你的评论有意义了。谢谢你的回答。。但我还是很困惑。所以你说当我调用sayHi(“john”)时,“this”是(window),然后它是window.tt=john。。。但是为什么当我用新创建的对象(hi2)再次调用该方法时,hi2.tt仍然是john而不是wallace??我还是很困惑。。进一步感谢Instrumentonit的“John”,因为在第二次调用中,这个
不是窗口
——您用新的
来调用它。非常清楚。感谢您的耐心,但现在我的问题如下:第一次致电sayHi(“john”)给了我一个变量(window.tt=“john”);但是第二个调用(hi2=newsayhi(“wallace”)应该给我另一个变量(hi2.tt=“wallace”)…你是说tt是不允许在本地使用的,因为它是全局设置的吗?不,它不是hi2.tt
-它是由于你通过new
调用函数而创建的全新对象。函数的第一行将成功地将该对象的“tt”属性设置为“wallace”,但随后你将“ss”设置为纯“tt”而不是“this.tt”.我爱你,伙计..虽然这里的所有答案都很有用;但是你提醒我我犯了一个对象文字错误。当我将ss:tt
定义为ss:this.tt
时,代码的行为与预期的一样…现在我明白了。我是否可以编辑你的答案,以便以正确的格式添加代码?@stackunderflow我是glad I可以提供帮助。附加到this
的实例变量和用var
声明的函数范围变量是两个非常不同的东西。Acc
alert(hi2.ss);