理解'this'对象上下文

时间:2013-05-29 19:36:48

标签: javascript prototype

我不理解在不使用this关键字时BigObject构造函数中的undefined如何new - 请参阅下面的示例。给出Firebug中的以下代码片段:

( function( global ){  
  "use strict";   
  var fromunderbutter = "fun"; 
  global.BigObject = function( options ){      
       console.log( this );      
       console.log( this instanceof BigObject );  
  };    
})( this );

以下代码有意义:

>>> var x = new BigObject();
>>> Object { }  // new constructor creates blank object context that is assigned to BigObject 
>>> true  // BigObject was the object context ( this ) that invoked BigObject()

据我所知,this指的是当前的对象上下文。在上面的示例中,由于new关键字,this将引用一个空白对象,该对象将被新创建并应用于函数调用。

但是下一部分对我来说没有意义:

>>> BigObject()
>>> undefined  
>>> false

为什么this未定义?我假设this会引用某些东西 - 可能是全局对象窗口。不确定如何考虑这个结果。

由于

4 个答案:

答案 0 :(得分:4)

在严格模式下,在没有上下文的情况下调用函数时,thisundefined

  

10.4.3 Entering Function Code # Ⓣ

     

当控件进入函数对象F中包含的函数代码的执行上下文,提供的调用者thisArg以及调用者提供的argumentsList时,执行以下步骤:

     
      
  1. 如果功能代码是严格代码,请将ThisBinding设置为thisArg
  2.   
  3. 如果thisArg null 未定义,请将ThisBinding设置为全局对象。
  4.   
  5. 如果Type(thisArg)不是Object,请将ThisBinding设置为ToObject(thisArg)
  6.   
  7. 否则将ThisBinding设置为thisArg
  8.   
  9. localEnv成为调用NewDeclarativeEnvironment的结果,将[{Scope]] [{1}}的内部属性的值作为参数传递。
  10.   
  11. 将LexicalEnvironment设置为F
  12.   
  13. 将VariableEnvironment设置为localEnv
  14.   
  15. 让代码为localEnv的[[代码]]内部属性的值。
  16.   
  17. 使用功能代码Fcode执行声明绑定实例化,如10.5中所述。
  18.   

提供的代码是严格的代码,调用的argumentListthisArg(没有为调用提供上下文)。

答案 1 :(得分:0)

如果没有元素事件,则无法定义。

答案 2 :(得分:0)

因为这就是语言规范所说的应该做的事情。

听起来像是一个翻转的答案,但事实并非如此。严格来说,这是任意的:你可以编写一个编译器来做任何事情,但是大多数可能想象的事情都是个坏主意。这些事情通常都有充分的理由。

在这种情况下,原因是当使用和不使用new时,相同的函数会执行完全不同的操作。这绝不是一个好主意。你可能会想出一个奇怪的案例,它可以做一些有用的事情,但是总会有更可读和可维护的方法来做同样的事情。

语言功能与法律相反:你不要仅仅因为需要超过三秒的时间来考虑任何理由,因为它们总是对绝对的每个人都是完全无法忍受的。只有当你有一个引人注目的,经过深思熟虑,经过充分研究和测试的理由,才能相信它们对很多人来说非常有用,并且几乎从不具有破坏性。或者,如果您正在设计Visual Basic或tcl,当然。

答案 3 :(得分:0)

如果您想解决此问题,请使用:

(function(global){  
  "use strict";   
  var fromunderbutter = "fun"; 
  global.BigObject = function (options) {
    if (!(this instanceof BigObject)) return new BigObject(options);     
    console.log(this);      
    console.log(this instanceof BigObject);  
  };    
})(this);

正如zzzzBov所提到的,您需要绑定this来模仿BigObject this才能使用您当前的代码。这需要做:BigObject.bind(new BigObject())({ /* options */ })。这显然不是调用代码的理想方式。