在Javascript中窗口真的是全局的吗?
以浏览器中的这段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内部,我们可以访问窗口,我们都知道
<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中的“范围外”或“自由”变量的原因就是所谓的范围链。范围链是每个执行上下文的一个特殊属性。正如前面多次提到的,上下文对象至少看起来像:
- [[范围]]
- 变量/激活对象
- “此”上下文值
激活对象中启动。所有形式参数、函数声明和局部定义变量(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;