为什么undefined在JavaScript中不可写?


59

根据MDN的文档undefined

在现代浏览器(JavaScript 1.8.5 / Firefox 4+)中,根据ECMAScript 5规范,undefined是不可配置的,不可写的属性。即使不是这种情况,也请避免覆盖它。

undefined的属性属性之一是不可写的。

但是,如果我这样做:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);
//string

这是否意味着我可以覆盖的值undefined?如果有人这样做会怎样?JavaScript是否应该对此发出警告?


5
您能告诉我们您使用哪种浏览器吗?(Linux上的Firefox 72.0b10(64位)可按预期使用typeof test === "undefined"
jonatjano

3
@DmitryReutov 在正常情况下会typeof undefined返回"undefined"
艾米

3
@DmitryReutov当然"undefined"是一个字符串。问题不在于要typeof (typeof undefined)评估什么。它问什么typeof undefined评估。它返回"undefined",而不是"string"
艾米

2
@DmitryReutov typeof ______是一个表达式,其结果为包含的类型的字符串______。您误解了这个问题。
艾米(Amy)

3
@Amy我知道,但是Edge返回“字符串”和Chrome“未定义”
Alon Eitan

Answers:


50

艾米删除评论后给出了解决方案。您正在创建一个名为的变量undefined,如果您在全局范围内执行摘要,该变量将无效:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);

但是,如果您在未定义的引用不再引用全局变量的本地范围内执行此操作,则它会有效:

(()=>{
  var undefined = 'hello';
  var test = undefined;
  console.log(typeof test);
})()

为防止此错误,可以使用'use strict';指令:

'use strict';
var undefined = 'hello';
var test = undefined;
console.log(typeof test);

如果您在无法控制执行位置的地方编写代码(例如,库,嵌入等),则使用IIFE是一种很好的模式,它使它可以使您保证未定义始终正确/可用。这是一个例子:

(function(undefined){
  // undefined will equal `undefined` because we didn't pass in an argument to the IIFE
  
  console.log(undefined); // always `undefined`, even if undefined !== `undefined`outside of the IIFE scope
})(); // No argument supplied


我所有的测试都是在Ubuntu上使用Firefox 72.0b10(64位)进行的,第一个代码段的结果在较旧的浏览器上可能会有所不同。


3
@pmiranda不是我的,发现它很有趣
jonatjano 19/12/26

2
再次感谢。所有这些怀疑都源于此:这里的一位新开发人员正在将一些西班牙名称变量翻译成英语。在我们的代码中,我们有一个名为的变量let indefinido= dataArray( (a) => (anotherArray.includes(someName)));,用于检查var是否为'undefined'(find未找到元素的结果)。然后他翻译indefinidoundefined我看到我在Chrome和Edge上进行了测试,看到了一些区别。这就是为什么我来这里询问其他人的意见的原因,因为我也在学习。
pmiranda

@pmiranda此答案未严格回答“为什么”部分。但这是一个很好的答案。
伊斯梅尔·米格尔

2
如果最终需要undefined的实际值,请使用void 0
不是用户的用户

2
@Jon,因为某些 原因,Ecmascript联盟选择不是将undefined 保留为关键字,而是将全局对象的属性设为undefined
jonatjano 19/12/27

17

尽管可以将其用作全局范围以外的任何范围的标识符(变量名)(因为undefined不是保留字),但这是一个非常糟糕的主意,它将使您的代码难以维护和调试。

来源https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

undefined不保留因此可以为其分配一个新的值。

当您不使用strict mode时,实际上是undefined在本地范围内创建一个变量,并string为其分配一个值。

undefined是全局对象的属性。undefined的初始值是原始值undefined

use strict 这将有助于防止在全局范围内发生此错误,同时仍然可以在本地范围内将其覆盖。

如果您想更加安全,则应该使用,void 0而不是undefined 总是返回undefined

'use stict'

const test = (() => {
  let undefined = "test"
  console.log(typeof undefined)
  console.log(typeof void 0)
})()


1
这是更多信息的关键字列表
jonatjano 19/12/26

1
值得注意的是,在这样的IIFE中,也可以undefined通过将其作为参数来引用。由于IIFE从未通过过任何争论,因此它们将undefined在其中。例如((undefined) => console.log(typeof undefined))()
-SeinopSys
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.