简体   繁体   English

全局 Object 与变量 Object

[英]Global Object vs. Variable Object

So I've learned about hoisting, scope chains and execution context.所以我了解了提升、scope 链和执行上下文。 However, I'm not able to grasp one particular thing.但是,我无法掌握一件事。 Are the variable object and the global object different objects?变量 object 和全局 object 是不同的对象吗? And, is the "Execution Context Object" the same as the global object?而且,“执行上下文对象”是否与全局 object 相同?

Here's some code that I experimented with to get an answer.这是我尝试得到答案的一些代码。

let variable = 0;

function updateVar(value) {
  this.variable = value;  
}

updateVar(1);

console.log(variable);
// 0

/* 
If I remove the 'this' keyword in the updateVar() function, 
the console logs 1.
Why?   

Thank you for your help in advance!提前谢谢你的帮助! Julian朱利安

It sounds like you might be reading some outdated material.听起来您可能正在阅读一些过时的材料。 The term "variable object" hasn't been used in the specification since the 3rd edition in 1999. :-) The term from ES5 onward is environment record .自 1999 年第 3 版以来,规范中没有使用术语“变量对象”。:-) 从 ES5 开始的术语是环境记录

Are the [environment record] and the global object different objects? [环境记录]和全局object是不同的对象吗?

Yes.是的。 But the global environment is a nested pair of environments: The outer one uses the global object as its binding object (which is roughly what "variable object" meant in ES3).但是全局环境是一对嵌套的环境:外部环境使用全局 object作为其绑定 object (大致就是 ES3 中“变量对象”的意思)。 Then there's an inner one for let , const , and class globals, which do not become properties of the global object.然后是letconstclass全局变量的内部变量,它们不会成为全局 object 的属性。 You can see that if you start with SetRealmGlobalObject in the spec, and follow where it does NewGlobalEnvironment , which creates a new object environment record using the global object for binding.您可以看到,如果您从规范中的SetRealmGlobalObject开始,并按照它在NewGlobalEnvironment的位置进行操作,它将使用全局 object 进行绑定创建一个新的 object 环境记录

And, is the "Execution Context Object" the same as the global object?而且,“执行上下文对象”是否与全局 object 相同?

An execution context has an environment record.执行上下文具有环境记录。

If I remove the 'this' keyword in the updateVar() function,如果我删除 updateVar() function 中的“this”关键字,
the console logs 1.控制台记录 1。
Why?为什么?

Because of the two nested global environments:由于两个嵌套的全局环境:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|         environment record for global object bindings         |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   |  environment record for global declarative bindings  |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   |                                                      |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|                                                               |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

So when you do this at global scope:因此,当您在全局 scope 执行此操作时:

let variable = 0;

it creates a binding in this inner global environment record:它在这个内部全局环境记录中创建一个绑定:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|         environment record for global object bindings         |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   |  environment record for global declarative bindings  |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   | variable: 0                                          |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|                                                               |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

When you do this:当你这样做时:

function updateVar(value) {
  this.variable = value;  
}
updateVar(1);

during the call to updateVar , this refers to the global object.在调用updateVar期间, this指的是全局 object。 So this.variable = 1 creates a property on that object (which, because that object is the outermost binding object, is a global):所以this.variable = 1在 object 上创建一个属性(因为 object 是最外层的绑定 object,是一个全局属性):

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|         environment record for global object bindings         |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| variable: 1                                                   |
|                                                               |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   |  environment record for global declarative bindings  |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   | variable: 0                                          |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|                                                               |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

When you do console.log(variable) at global scope, variable resolves to the declarative environment binding, and you get the value 0 .当您在全局 scope 处执行console.log(variable)时, variable解析为声明性环境绑定,您将获得值0

If you do this instead:如果您改为这样做:

When you do this:当你这样做时:

function updateVar(value) {
  variable = value;   // <=== No `this`
}
updateVar(1);

instead of creating a property on the global object, since variable resolves to the declarative environment binding, you're updating that binding:而不是在全局 object 上创建属性,因为variable解析为声明性环境绑定,您正在更新该绑定:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|         environment record for global object bindings         |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   |  environment record for global declarative bindings  |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|   | variable: 1                                          |    |
|   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+    |
|                                                               |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

With this in updateVar , you can see that it creates a property on the global object by using the variable on window (which is a proxy for the global object in browsers):this中,您可以看到它使用updateVar上的变量(它是浏览器中全局window的代理)在全局 object 上创建了一个属性:

 let variable = 0; function updateVar(value) { this.variable = value; } updateVar(1); console.log(variable); console.log(window.variable);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM