Javascript 中的 window 真的是全局的吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6679635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:29:39  来源:igfitidea点击:

Is window really global in Javascript?

javascriptscopeclosurestheory

提问by Bart van Heukelom

Take this piece of Javascript in a browser:

在浏览器中获取这段 Javascript:

<script>

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

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

</script>

Inside foowe can access window, we all know that, but why exactly?

在里面foo我们可以访问window,我们都知道,但究竟是为什么呢?

  • Is it some kind of special global variable?
  • Or does the "root scope" (inside the scripttag) have it as an implicit local variable and is it simply "closure-inherited" as any other local variable (like xabove) can be?
  • 它是某种特殊的全局变量吗?
  • 或者“根范围”(在script标签内)是否将其作为隐式局部变量,它是否像任何其他局部变量(x如上)一样简单地“继承自闭包” ?

And how does that concur with variables declared directly inside the scripttag being set as properties of window? (Or is that not so?)

这与直接在script标记内声明的变量被设置为 的属性window有何一致?(或者不是这样?)

<script>
var x = 12;
function() {
   console.log(window.x);
}
</script>

采纳答案by jAndy

The reason why you can access "out of scope"or "free"variables in ECMAscript is the such called Scope chain. The scope chain is a special property from each Execution context. As mentioned several times before, a context object looks at least like:

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

  • [[scope]]
  • Variable / Activation Object
  • "this" context value
  • [[范围]]
  • 变量/激活对象
  • “这个”上下文值

each time you access a variable(-name) within a context (a function for instance), the lookup process always starts in it's own Activation Object. All formal parameters, function declarations and locally defined variables (var) are stored in that special object. If the variablename was not found in that object, the search goes into the [[Scope]]-chain. Each time a function(-context) is initialized, it'll copy all parent context variable/activation objectsinto its internal [[Scope]]property. That is what we call, a lexical scope. That is the reason why Closureswork in ECMAscript. Since the Global contextalso has an Variable Object(more precisely, **the variable object for the global object is the global object itself) it also gets copied into the functions [[Scope]]property.

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

That is the reason why you can access windowfrom within any function :-)

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

The above explanation has one important conceptional conclusion: Any function in ECMAscript is a Closure, which is true. Since every function will at least copy the global context VOin its [[Scope]]property.

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

回答by Quentin

Is window really global in Javascript?

Javascript 中的 window 真的是全局的吗?

Yes. Unless you create a new variable called window in a narrower scope

是的。除非您在更窄的范围内创建一个名为 window 的新变量

function foo() {
    var window;
}

Inside foo we can access window, we all know that, but why exactly?

在 foo 中我们可以访问 window,我们都知道,但究竟是为什么呢?

Any function can access variables declared in a wider scope. There is nothing special about window there.

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

回答by user113716

It's all defined in ECMAScript.

这一切都在 ECMAScript 中定义。

The global is a Lexical environment that doesn't have an outer lexical environment. All other environments are nested within it, and is bound to a global object with properties specified by the spec.

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

This places the properties of the global object at the start of the scope chain, from which all other environments inherit.

这将全局对象的属性置于作用域链的开头,所有其他环境都从该作用域链继承。

ES 10.2.3 The Global Environment:

ES 10.2.3 全球环境

The global environment is a unique Lexical Environment which is created before any ECMAScript code is executed. The global environment's Environment Record is an object environment record whose binding object is the global object (15.1). The global environment's outer environment reference is null.

As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.

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

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

ES 15.1 The Global Object

ES 15.1 全局对象

The unique global object is created before control enters any execution context.

Unless otherwise specified, the standard built-in properties of the global object have attributes {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.

The global object does not have a [[Construct]] internal property; it is not possible to use the global object as a constructor with the new operator.

The global object does not have a [[Call]] internal property; it is not possible to invoke the global object as a function.

The values of the [[Prototype]] and [[Class]] internal properties of the global object are implementation-dependent.

In addition to the properties defined in this specification the global object may have additional host defined properties. This may include a property whose value is the global object itself; for example, in the HTML document object model the window property of the global object is the global object itself.

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

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

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

全局对象没有 [[Call]] 内部属性;不可能将全局对象作为函数调用。

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

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

回答by Saxoier

It has to do with the scope chain.

它与作用域链有关

Have a look at the following presentation of Nicholas C. Zakas. (starting around min 5)

看看Nicholas C. Zakas的以下介绍。(大约从 5 分钟开始)

回答by daveoncode

window is the base scope of all javascript objects, and it's automatically "attached" to each variables you define, unless you use "var" before the declaration, in this case the scope of the variable it's local (that means that it's contained inside the parent function, or is otherwise global too, if you are declaring your variable outside a function block). Moreover window is defined as a constant, that is you can't redefine the window object(you will get an error saying "type error: redeclaration of const window").

window 是所有 javascript 对象的基本范围,它会自动“附加”到您定义的每个变量,除非您在声明之前使用“var”,在这种情况下,变量的范围是它的局部范围(这意味着它包含在父函数,或者也是全局的,如果你在函数块之外声明你的变量)。而且window 被定义为一个 constant,也就是说你不能重新定义 window 对象(你会得到一个错误消息“type error: redeclaration of const window”)。

so:

所以:

window.foo = 5;

it's the same as:

它与以下相同:

var foo = 5;

or:

或者:

function() {
foo = 5;
}

but:

但:

function() {
var foo = 5;
}

in this case "foo" is local (window.foo === undefined)

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

回答by Wilt

The windowglobal scope applies only to the main thread. In web workers there is no windowglobal variable. Instead you have WorkerGlobalScopeinside a WebWorkerand in a SharedWorkerGlobalScopeinside a SharedWorker.

window全球范围仅适用于主线程。在网络工作者中没有window全局变量。相反,你有WorkerGlobalScopeinside aWebWorker和 in a SharedWorkerGlobalScopeinside aSharedWorker

This worker global scope is stored in a variable called selfand as MDN describes it:

这个 worker 全局作用域存储在一个名为的变量中self,正如 MDN 描述的那样:

this scope contains the information usually conveyed by Windowobjects.

此范围包含通常由Window对象传达的信息。

This can become a problem when 3rd party code you are using in your web worker is using the window object. This can be easily solved by declaring a windowvariable as suggested by @FelipeMicaroniLalli in his answer herelike this:

当您在 Web Worker 中使用的第 3 方代码使用 window 对象时,这可能会成为一个问题。这可以通过声明一个window变量来轻松解决,如@FelipeMicaroniLalli 在他的回答中所建议的,如下所示:

var window = self;

回答by Vithozor

In the book Javascript: The Good Parts, as I understand, Douglas Crockford explains that windowis the global object of the web browser that contains all the global variables. It is like the One Ring...

Javascript: The Good Parts一书中,据我所知,Douglas Crockford 解释说这window是包含所有全局变量的 Web 浏览器的全局对象。这就像一环...