【问题标题】:How come JavaScript {this} doesn't reference the parent object?为什么 JavaScript {this} 不引用父对象?
【发布时间】:2011-09-07 01:05:19
【问题描述】:

在制作对象时,我假设this 会返回对象的实例——相反,它似乎是别的东西。这是为什么呢?

var Obj = { 
    foo : 'value',
    bar : function() { return this.foo; } // Error
    bar : function() { return Obj.foo; }  // Works
}

更新:我一定遗漏了一些东西,因为在某些情况下,在对象内部使用 this 不起作用。为什么这有时只引用对象实例?

【问题讨论】:

  • 您的代码产生语法错误...您不能在此处放置分号。
  • 对不起大家,我在发布之前忘记验证示例。我不是在谈论实际的代码 sn-p - 那只是为了显示我要询问的代码。
  • 一个函数的 this 值由函数的调用方式设置,而不是由它的声明或初始化方式设置(除了 ES5 bind i> 使用方法)。
  • 再次,生成一个适合您的 sometimes 案例的代码示例......然后您可能会得到一个有意义的答案。

标签: javascript oop this


【解决方案1】:

确实如此。您有语法问题。

使用逗号分隔对象成员

var Obj = { 
    foo : 'value',
    bar : function() { return this.foo; },
}

在成员函数内this 指的是对调用该函数的对象的引用。

jsFiddle Example

【讨论】:

  • 抱歉语法错误,这只是示例代码。我一定遗漏了一些东西,因为this 仍然无法处理某些对象。
  • 好吧,编程是一种二进制(双关语),要么有效,要么无效,如果您有另一个无效的示例,我很乐意给你看,把它添加到问题中。
  • -1 因为它只是答案的一部分。函数的 this 关键字由调用以多种方式设置:作为对象方法,使用 callapply,使用 new,使用ES5 bind,根本不使用任何东西(所以 this 可能是全局对象或未定义)。
  • 我通过说 "within member functions ... " 来限定我的解释,不,你是对的我没有写一篇关于this在javascript中含义的研究论文,简单地回答了与手头的问题相关,有很多资源可以挖掘this的更深层次的含义。
  • 尽管 JavaScript 并没有真正的成员函数:对象可以具有引用函数的属性,但即使这些函数直接在创建对象 A 的对象文字中定义(如问题中所示),您也可以仍然以将 this 设置为对象 B 的方式调用它们。
【解决方案2】:

在 JavaScript 函数中,this 的设置取决于函数的调用方式。

使用您的示例Obj,假设您更正了语法错误并在属性之间使用逗号:

var Obj = {
  foo : 'value', // needs comma, not semicolon
  bar : function() { return this.foo; }
}

如果您在Obj 上使用“点”语法来调用bar 函数,那么this 将自动设置为Obj

Obj.bar(); // this will be Obj

这是确保this 最终设置为您想要的方式的简单方法。但是,如果您以其他方式调用该函数,this 可以设置为其他值:

var nonObjBar = Obj.bar; // get a reference to the function
nonObjBar(); // this will (probably) be `window`, but depends if
             // in strict mode or inside some other function, etc

var Obj2 = { foo: "other foo" };
Obj.bar.call(Obj2); // the .call() method sets this to Obj2
                    // so bar will return Obj2's foo, "other foo"

最后一个示例使用Obj.bar 上的.call() 方法调用函数,允许您将this 设置为您喜欢的任何值(在某些情况下,严格与非严格模式会影响其工作方式)。

如果您来自 Java 等语言,这可能看起来很奇怪,但 JavaScript 函数不属于任何给定对象。这种行为是非常明确的并且是故意的。

【讨论】:

    【解决方案3】:

    在“值”之后修复分号后,这似乎有效:

    var Obj = { 
        foo : 'value',
        bar : function() { return this.foo; } // Error
    };
    
    alert(Obj.bar());   // alerts 'value'
    

    在此处查看工作的 jsFiddle:http://jsfiddle.net/jfriend00/UFPFf/

    当您在对象上调用方法时,javascript 引擎会设置 this 指针以在方法调用期间指向该对象。

    【讨论】:

      【解决方案4】:

      foo 后面不应该有分号。

      实际上,当您致电Obj.bar 时,您this指的是Obj

      http://jsfiddle.net/AAkbR/

      var Obj = { 
          foo : 'value',
          bar : function () { return this.foo; }
      };
      
      alert(Obj.bar() === Obj.foo);
      

      警报为真。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        • 1970-01-01
        • 2020-08-19
        • 2011-06-02
        • 1970-01-01
        • 2015-06-18
        相关资源
        最近更新 更多