javascript - 关于 Javascript 中 'this' 关键字的困惑

标签 javascript this

我可以说“this”关键字对于那些使用 C# 等语言的人来说是 Javascript 中最令人困惑的部分。

我也在互联网和 StackOverflow 上阅读了很多关于此的内容。喜欢herehere .

我知道“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"); 的想法,但这导致整个代码无法正常工作。

demo is here

我知道这可能是新手问题。但这里真的很困惑,我确实尝试阅读了很多文章和 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/

相关文章:

c++ - 函数调用的 "this"的评估是否以相对于参数的未指定顺序进行?

javascript - 'this' 可以在 Javascript 中为空吗

javascript - 如何使用传递给乐趣的对象作为内部函数的上下文?

javascript - TypeScript 类和 JS 范围混淆(再次)

javascript - 使固定的第三列与中间容器齐平

javascript - 如何使用 onstart 和 oncomplete 创建 jquery 函数

Javascript函数定义

javascript - 一次只允许显示一个幻灯片切换 div

javascript - 检测打印机是否已成功打印页面

javascript - 为什么 javascript 方法在与 setTimeout 一起使用时会失去与对象的连接