【问题标题】:Why does the value of "this" changes.?为什么“this”的值会发生变化。?
【发布时间】:2013-10-09 16:17:56
【问题描述】:

我正在学习 javascript,但遇到了疑问。为什么“this”的值在第一个示例中未定义,但在第二个示例中正确打印出来。

示例 1:

var myNamespace = {
    myObject: {
        sayHello: function() {
            console.log( "name is " + this.myName );
        },
        myName: "john"
    }
};

var hello = myNamespace.myObject.sayHello;

hello(); // "name is undefined"

示例 2:

var myNamespace = {
    myObject: {
        sayHello: function() {
            console.log( "Hi! My name is " + this.myName );
        },
        myName: "Rebecca"
    }
};

var obj = myNamespace.myObject;

obj.sayHello();//"Hi! My name is Rebecca"

为什么“this”的值在函数中会发生变化。我错过了什么概念?

【问题讨论】:

  • 你的期望很好,JavaScript 的this 语义被破坏了。 :-)
  • 它是javascript而不是“java script”..非常非常大的区别..:)
  • 基本上,问题在于,在 Javascript 中,this 在您访问对象中的方法时没有绑定(例如在 Python 中),但只有在您调用它时才绑定。所以它实际上是“实际方法调用表达式中. 左侧的对象”。在您的第二个示例中,即obj,在您的第一个示例中,您没有使用点语法调用该方法,所以它什么都不是。 (您还可以通过使用Function.bind() 或使用Function.call()Function.apply() 来选择this 的值,只是为了让事情变得更复杂。jQuery 普遍这样做。)
  • 1个例子,hello是函数,2个例子hello是对象myObject;函数 sayHello 没有定义 myName,而 myObject 有

标签: javascript this


【解决方案1】:

第一种情况,您只是获取函数对可变 hello 的引用,并从全局上下文(浏览器中的窗口,节点中的全局)调用它,所以 this 成为调用函数的对象,除了(绑定职能)。您始终可以使用 function.call 显式设置上下文或使用 Ecma5 function.bind 将上下文显式设置为函数

hello.call(myNamespace.myObject); //now you are setting the context explicitly during the function call.

或者只是在获取函数引用时绑定它。

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); //Now no matter where you call it from `this` will point to the context of myObject

第二种情况,您是从对象本身调用它,因此this 指向该对象。

【讨论】:

    【解决方案2】:

    在第一种情况下,隐含的this 对象是全局范围。因为在全局范围内没有myName,所以你得到了未定义的。

    如果您想要一个具有正确this 的免费功能,请使用bind

    var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 2020-01-16
      • 1970-01-01
      相关资源
      最近更新 更多