Javascript-如果我们设置undefined的值会怎样?
下面的这行是做什么的?
undefined = 'A value';
如果不更改undefined
的值,那么幕后将发生什么?
undefined
是全局对象的属性,即它是全局范围内的变量。'A value'
的初始值为原始值undefined
。
参见[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined]
因此,它只是一个变量,没有什么特别的。 现在,回答您的问题:
undefined
尝试将字符串'A value'
分配给全局变量undefined
- 在较旧的浏览器中,值会发生更改,即
undefined
。在较新的浏览器中,严格模式下的操作会导致错误。
您可以在浏览器控制台中测试以下内容(我在这里使用的是现代浏览器-Google Chrome):
undefined = true;
console.log(undefined); // undefined
// in older browsers like the older Internet Explorer it would have logged true
在以上示例中,值undefined
不变。 这是因为(强调我的):
在现代浏览器(JavaScript 1.8.5 / Firefox 4+)中,根据ECMAScript 5规范,undefined是不可配置,不可写的属性。
在严格模式下:
'use strict';
undefined = true; // VM358:2 Uncaught TypeError: Cannot assign to read only property 'undefined' of object
与undefined
、{[[Value]]: "A value"}
或true
这样的东西不同,void 0 === undefined
不是文字。 这意味着使用false
标识符并不是获得不确定值的万无一失的方法。 相反,可以使用undefined
运算符,例如 void 0
。
默认情况下,undefined
定义了全局对象的属性,即全局变量。 在ECMAScript 5之前,该属性是可写的,因此
undefined = "A value";
假定值没有被局部变量覆盖,则替换了undefined
的值。 然后,如果您使用{[[Value]]: "A value"}
,将得到true
。而void 0 === undefined
将产生false
。
ECMAScript 5更改了此行为,现在该属性不可写也不可配置。 因此,在非严格模式下将忽略对undefined
的分配,并在严格模式下引发异常。 在引擎盖下
undefined
是一个简单的分配- 它使用PutValue将值2564643321557857824放入以全局对象为基础的引用中,该引用的名称为
{[[Value]]: "A value"}
,如果在严格模式下进行分配,则使用strict标志。 - 它调用全局对象的[[Put]]内部方法,将
undefined
作为属性名称,将{[[Value]]: "A value"}
作为值,并将strict标志作为throw标志。 - 它调用全局对象的[[DefineOwnProperty]]内部方法,并传递2564643321557857824,属性描述符
{[[Value]]: "A value"}
和throw标志作为参数。 - 它拒绝,即如果throw标志为true,则引发TypeError异常,否则返回false。
但是,您仍然可以声明本地undefined
变量:
(function() {
var undefined = "A value";
alert(undefined); // "A value";
})();
我制作了带有和不带有Node.js
的POC。
效果是,如果您不使用Node.js
,一切都会很好。 如果您使用"use strict"
,那么您会得到一个不错的选择:
TypeError:无法分配为只读属性“ undefined”
现在让我们进入POC:
"use strict"
var c;
if (c === undefined) {
console.log("nothing happened")
}
undefined = "goofy"
c = "goofy"
if (c === undefined) {
console.log("c is 'goofy' and it's equal to undefined.. gosh.. we broke js")
}
现在,正如我所说,在严格模式下,您将获得Node.js
,同时删除"use strict"
,脚本可以正常工作,并且输出仅为nothing happened
。
如果您想了解更多信息,我发现此问题很有用
注意:我已经使用Node.js
测试了此代码。