Javascript 为什么变量会成为窗口对象上的键?

Javascript 为什么变量会成为窗口对象上的键?,javascript,Javascript,我注意到,当我在window对象上写入时,变量变成键,它们的值变成所述键的值。例如: var variable = "value"; console.log(window.variable);//logs "value" 但如果我创建了一个自己的新对象,比如: var o = { key: "value", var key2 = "value2" }; // result: "syntax error" 我必须使用冒号来设置键/值对。即使使用构造函数,虽然没有语法错误,但我似

我注意到,当我在window对象上写入时,变量变成键,它们的值变成所述键的值。例如:

var variable = "value";
console.log(window.variable);//logs "value"
但如果我创建了一个自己的新对象,比如:

var o = {
    key: "value",
    var key2 = "value2"
}; // result: "syntax error"
我必须使用冒号来设置键/值对。即使使用构造函数,虽然没有语法错误,但我似乎无法在构造函数内部、对象实例化期间或之后执行此操作:

function Blueprint(){
    this.key = "value";
    var key2 = "value2";
}

var o = new Blueprint;
console.log(o.key); //result: "value"
console.log(o.key2); //result: "undefined"
现在,我明白了为什么,在前一种情况下,我生成了一个语法错误,在后一种情况下,我无法将key2附加到Blueprint构造函数,但我不明白的是,为什么在全局窗口对象上,我可以自由地使用变量添加属性,它们会立即成为窗口对象上的键。除了在windows对象上,变量的行为似乎与对象和属性创建无关

我还注意到,在使用节点进行实验时,全局对象上也有类似的行为。全局对象是唯一可以使用变量以这种方式设置键/值对的对象吗?如果是,为什么?在全球层面上工作时,我们为什么不被迫做以下事情:

this.key = "value";
或者

这只是对语言整体行为的一些警告,还是窗口对象与所有其他对象之间存在某种内部一致的逻辑来解释这一点?

全局变量(与函数中声明的局部变量相反)成为全局对象的属性

在浏览器中,全局对象是
窗口

全局变量(与函数中声明的局部变量相反)成为全局对象的属性


在浏览器中,全局对象是
窗口

全局环境是所谓的:

每个对象环境记录都与一个称为其绑定对象的对象相关联。对象环境记录绑定与其绑定对象的属性名称直接对应的标识符名称集

如您所见,为标识符创建属性的行为是显式定义的。在全局环境中,绑定对象是全局对象,在浏览器中是
window

有关环境的更多详细信息,请参阅:

本规范中使用了两种环境记录值:声明性环境记录和对象环境记录。声明性环境记录用于定义ECMAScript语言语法元素的效果,如FunctionDeclarations、VariableDeclarations和Catch子句,它们直接将标识符绑定与ECMAScript语言值关联。对象环境记录用于定义ECMAScript元素(如Program和WithStatement)的效果,这些元素将标识符绑定与某些对象的属性相关联


我不能告诉你为什么会有这两种类型。如果你想知道这一点,你可以在

上询问全球环境是一个所谓的:

每个对象环境记录都与一个称为其绑定对象的对象相关联。对象环境记录绑定与其绑定对象的属性名称直接对应的标识符名称集

如您所见,为标识符创建属性的行为是显式定义的。在全局环境中,绑定对象是全局对象,在浏览器中是
window

有关环境的更多详细信息,请参阅:

本规范中使用了两种环境记录值:声明性环境记录和对象环境记录。声明性环境记录用于定义ECMAScript语言语法元素的效果,如FunctionDeclarations、VariableDeclarations和Catch子句,它们直接将标识符绑定与ECMAScript语言值关联。对象环境记录用于定义ECMAScript元素(如Program和WithStatement)的效果,这些元素将标识符绑定与某些对象的属性相关联


我不能告诉你为什么会有这两种类型。如果你想知道这一点,你可以问

这是魔法。请参见每个变量范围都有一个保存变量的对象。恰好在全局范围内,我们可以直接访问该对象……它有点类似于函数中的
参数
对象。将参数传递给参数,可以通过参数标识符访问这些参数,但是有一个自动出现的对象也保存了传递的值。更改参数值,它会在
参数上更改,反之亦然(尽管严格模式下不存在此持久映射)。这很神奇。请参见每个变量范围都有一个保存变量的对象。恰好在全局范围内,我们可以直接访问该对象……它有点类似于函数中的
参数
对象。将参数传递给参数,可以通过参数标识符访问这些参数,但是有一个自动出现的对象也保存了传递的值。更改参数值,参数值会在
参数上更改,反之亦然(尽管此持久映射在严格模式下不存在)。SLaks,感谢您的回答,但我的问题不是是否会发生这种情况(很明显会发生这种情况),我的问题是为什么会发生这种情况。这种行为的改变是有内在原因的,还是仅仅是语言上的警告。无论如何,非常感谢您,我感谢您的输入。@AllanSocks:阅读spec.SLaks,感谢您的回答,但我的问题不是这是否会发生(很明显会发生),我的问题是为什么会发生。这种行为或行为的改变是否有内在原因
window.key = "value";