使用函数内的“this”关键字访问全局属性

时间:2011-08-07 07:49:30

标签: javascript this

我知道在javascript中,当您在函数中使用"this"关键字时,"this"会根据Quirksmode website引用该函数的“所有者”。因此,当我们有一个函数并且在其中使用"this"时,"this"引用全局(窗口)对象。

我对"this"的工作方式感到有些困惑,例如在下面的代码中,"this"然后应该能够解析x,因为x几乎是全局对象的属性(在本例中为窗口)。但在这种情况下,this.x会提醒"undefined"而不是x值。

var x = "Global";

function foo(){
    alert(this.x);   //undefined     
};
foo();

我接着尝试了其他一些事情:

function bar(){
    function foo(){
        alert(this); //[Object DOMWindow]
    };
    foo();
};

bar();

如果我的理解是正确的,那么'this'应该在第二种情况下引用bar(),因为它是foo()的所有者,但为什么它仍然指的是全球对象

有人可以解释关于“this”关键字的正确理论是什么吗?

4 个答案:

答案 0 :(得分:6)

你得到了错误的结局。 this的值取决于函数如何调用,而不是如何定义。

  • 如果您致电window.foo(),那么(foo内部)this将为window
  • 如果您致电bar.foo(),则this将为bar(虽然您需要复制foo,因此它首先属于bar的财产
  • 如果您致电baz.bar.foo(),则this将为bar(您只能通过this获取父对象)
  • 如果您致电foo.call(bar),那么this也将barcall允许您覆盖this
  • 如果您致电new foo(),则this将成为正在创建的新对象

默认对象为window,因此,如果您只是致电foo(),那么这与window.foo()相同。

定义函数的范围无关紧要。

答案 1 :(得分:2)

总结您的问题,您在第一个代码段中问及为什么this.xundefined

var x = "Global";
function foo(){
    alert(this.x);   //undefined     
}
foo();

根本没有意义,this值应引用全局对象 - 如果您的代码处于严格模式,那么您将获得TypeError,因为this本身就是undefined - 。

我认为this.x可能是undefined的唯一方法是x的变量声明是在函数中进行的。

检查以下两个示例:12,它们的代码完全相同,区别在于第二个,代码包含在onload事件处理程序中,所以x变量在全局范围内不存在(window.xundefined)...

答案 2 :(得分:0)

是的,this 总是正在执行的函数的所有者,关于此主题的最佳答案是more than you ever wanted to know about this

var x = "Global";

function foo(){
    alert(this.x); // alerts "Global" for me    
};

对于bar(),它是一个独立的函数,this将绑定到“全局”对象,如上面链接的答案中所述,您的情况是{{1} }

答案 3 :(得分:0)

如果您真的希望了解this的工作原理,请阅读10.3 Execution Context部分及之后的 ECMAscript 262 specs

以下是第10.4.3节中的内容:

  

10.4.3输入功能代码

     

当控制进入执行时,执行以下步骤   函数对象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的结果   传递F的[[Scope]]内部属性的值作为   参数。

  10.   
  11. 将LexicalEnvironment设置为localEnv。

  12.   
  13. 将VariableEnvironment设置为localEnv。

  14.   
  15. 让代码为F的[[Code]]内部属性的值。

  16.   
  17. 使用功能代码执行声明绑定实例化   代码和argumentsList,如10.5。

  18. 中所述