在Javascript中窗口真的是全局的吗?

在Javascript中窗口真的是全局的吗?,javascript,scope,closures,theory,Javascript,Scope,Closures,Theory,以浏览器中的这段Javascript为例: <script> console.log(window.someThing); var x = 12; function foo() { window.otherThing = x; } </script> 在Javascript中窗口真的是全局的吗 对。除非在更窄的范围内创建名为window的新变量 function foo() { var window; } 在foo内部,我们可以访问窗口,我们都知道

以浏览器中的这段Javascript为例:

<script>

console.log(window.someThing);
var x = 12;

function foo() {
   window.otherThing = x;
}

</script>
在Javascript中窗口真的是全局的吗

对。除非在更窄的范围内创建名为window的新变量

function foo() {
    var window;
}
在foo内部,我们可以访问窗口,我们都知道这一点,但确切的原因是什么

任何函数都可以访问在更大范围内声明的变量。窗口没有什么特别之处。

它与范围链有关


请看以下内容。(大约从第5分钟开始)

据我所知,Douglas Crockford在书中解释了
window
是包含所有全局变量的web浏览器的全局对象。它就像一个环…

您可以访问ECMAscript中的“范围外”或“自由”变量的原因就是所谓的范围链。范围链是每个执行上下文的一个特殊属性。正如前面多次提到的,上下文对象至少看起来像:

  • [[范围]]
  • 变量/激活对象
  • “此”上下文值
每次访问上下文(例如函数)中的变量(-name)时,查找过程总是在它自己的
激活对象中启动。所有形式参数、函数声明和局部定义变量(var)都存储在该特殊对象中。如果在该对象中未找到variablename,则搜索将进入
[[Scope]]
-链。每次初始化函数(-context)时,它都会将所有父上下文变量/激活对象复制到其内部
[[Scope]]
属性中。这就是我们所说的词汇范围。这就是为什么闭包在ECMAscript中工作的原因。由于
全局上下文
也有一个
变量对象
(更准确地说,**全局对象的变量对象是全局对象本身),因此它也会被复制到函数[[Scope]]属性中

这就是您可以从任何函数中访问
窗口的原因:-)


上面的解释有一个重要的概念性结论:ECMAscript中的任何函数都是闭包,这是正确的。因为每个函数都将至少复制其[[Scope]]属性中的全局上下文VO。

所有这些都是在ECMAScript中定义的

全局是一个没有外部词汇环境的词汇环境。所有其他环境都嵌套在其中,并绑定到具有规范指定特性的全局对象

这会将全局对象的属性放置在范围链的开头,所有其他环境都从中继承

:

全局环境是在执行任何ECMAScript代码之前创建的唯一词汇环境。全局环境的环境记录是一个对象环境记录,其绑定对象是全局对象(15.1)。全局环境的外部环境引用为空

在执行ECMAScript代码时,可以向全局对象添加其他属性,并修改初始属性

唯一的全局对象是在控件进入任何执行上下文之前创建的

除非另有指定,否则全局对象的标准内置属性具有属性{[[Writable]]:true、[[Enumerable]]:false、[[Configurable]]:true}

全局对象没有[[Construction]]内部属性;不能将全局对象用作新运算符的构造函数

全局对象没有[[Call]]内部属性;无法将全局对象作为函数调用

全局对象的[[Prototype]]和[[Class]]内部属性的值取决于实现

除了本规范中定义的属性外,全局对象还可能具有其他主机定义的属性。这可能包括其值为全局对象本身的属性;例如,在HTML文档对象模型中,全局对象的窗口属性是全局对象本身


窗口是所有javascript对象的基本作用域,它自动“附加”到您定义的每个变量,除非在声明之前使用“var”,在本例中,变量的作用域是局部的(这意味着它包含在父函数内,或者如果在函数块外声明变量,则它也是全局的)。此外,窗口被定义为常量,也就是说,您不能重新定义窗口对象。(您将得到一个错误,称为“类型错误:重新声明常量窗口”)

因此:

这与:

var foo = 5;
或:

但是:


在这种情况下,“foo”是本地的(window.foo==未定义)

全局范围
窗口只适用于主线程。在web workers中没有
窗口
全局变量。取而代之的是和

此辅助全局作用域存储在名为
self
的变量中,如MDN所述:

此范围包含通常由对象传递的信息

当您在web worker中使用的第三方代码正在使用window对象时,这可能会成为一个问题。通过声明@FelipeMicaroniLalli在中建议的
window
变量,可以轻松解决此问题,如下所示:

var window = self;

但是window所在的作用域是作用域链中最宽的作用域,还是一个特殊的全局作用域?Javascript引擎在运行时如何在内部解析它?正如我所说的“没什么特别的”(嗯,这不是很正确,因为它是默认变量,但在作用域方面没有什么特别的)@Bart van Heukelom:它会检查本地作用域中是否有同名变量,如果没有找到,它会一直向上直到
Object
@Shef-until-Object?当然窗口不是Object的静态属性……或者是吗?@Bart van Heukelom:对不起,是要写
window
Object.Interestin
var foo = 5;
function() {
foo = 5;
}
function() {
var foo = 5;
}
var window = self;