Javascript &引用;这";在全局函数中

Javascript &引用;这";在全局函数中,javascript,this,Javascript,This,我的印象是“this”关键字代表范围内的当前所有者。显然,这是错误的。让我谈谈代码: alert(this); // alerts as [object Window] -- Okay function p1() { alert(this); } var p2 = function() { alert(this); } p1(); // alerts as undefined -- ??? p2(); // alerts a

我的印象是“this”关键字代表范围内的当前所有者。显然,这是错误的。让我谈谈代码:

alert(this);     // alerts as [object Window] -- Okay

function p1() {
    alert(this);
}

var p2 = function() {
    alert(this);
}

p1();           // alerts as undefined  -- ???
p2();           // alerts as undefined  -- ??
window.p1();    // alerts as [object Window] -- Okay
window.p2();    // alerts as [object Window] -- Okay
正如我所料,上面的代码首先警告[object Window],但随后对p1()和p2()的两个调用将“this”警告为“undefined”。对p1()和p2()的最后两个调用将“this”作为[对象窗口]发出警报

p1()和p2()是否存在于全局(即窗口)范围内?我认为调用window.p1()与调用p1()同义,就像调用alert()与window.alert()同义一样


按照我的(C#)思维方式,p1()和p2()是全局范围。这些函数是全局窗口对象的成员,因此当它们引用“this”时,它们应该引用[对象窗口]。显然,我在这里是错的。

因为您使用的是
严格模式
,并且按照规范:

如果在严格模式代码中对此进行求值,则不会将此值强制为对象

您拥有的代码在所有警报实例中都会发出警报,但由于您处于严格模式,因此它是未定义的

更新:chrome开发工具提醒
窗口
未定义
,但是如果您将其包装在一个自动执行函数中,您会得到预期的
未定义

(function(){
   'use strict';
   alert(this);
}());

当您调用像
foo()
这样的函数时,this的值取决于代码是否运行(默认值)

在严格模式下,
将是
未定义的
(正如您已经发现的)

在“松散模式”
中,此
确实将引用
窗口
,但这不是因为函数是全局的,即全局范围“拥有”。对于本地函数,您可以获得相同的行为:

(函数(){
函数foo(){
console.log(this);//记录窗口对象,但'foo'不是全局的
}
foo();

}());
表示您所指的对象。在面向对象编程中,它主要用于区分对象的自身变量和输入变量

示例(伪代码):

var1//对象的实例变量
无效构造函数(var1){
this.var1=var1
}

这描述的是构造函数接受一个名为
var1
的变量,并将自己的变量
var1
设置为它

在您的情况下,我假设在函数中:

函数p1(){
警惕(这个);
}


被称为
p1(),它不是严格地在对象上下文中,因此
没有任何意义。通过从窗口的上下文
window.p1()调用它
,您正在使窗口对象调用函数,因此给
这个
一个值。

看起来您在Chrome控制台上以严格的Moderns fine运行脚本。。我得到所有警报的
[object Window]
!问题是严格的模式。运行您在此处输入的代码会按照您预期的方式运行,并为所有警报设置警报窗口&刚刚更新了我的答案:chrome giving window而不是undefined,它似乎可以在sef中找到,而不是输入控制台。这只是一个重复:)@Kitler:哪个问题?而且,即使它是重复的,也不会使我的答案无效。到目前为止,每个范围问题的答案是什么?你甚至有一个关于它们的详细的规范…@Kitler:如果你提到的问题目前被认为是重复的,那么,好吧,它不是。链接的问题是关于这个
,是的,但它是关于一个不同的问题。@Kitler不是真的。。他们主要解释的是
call/apply/bind
而不是严格模式抱歉,但这是不正确的。该问题是由严格模式引起的。在示例p1()和window.p1()中,严格模式是影响
this
值的因素,感谢您的澄清。我同意chrome控制台(开发工具)不提示“未定义”。把我弄糊涂了!这让我感到困惑,奇怪的是firefox在控制台中使用了“use strict”,而chome需要一个包装器