在JavaScript中有多危险,假设undefined不会被覆盖?

每当有人提到对undefinedtesting时, 就会指出 undefined不是关键字,所以可以设置为"hello" ,所以应该使用 typeof x == "undefined" 。 这对我来说似乎是荒谬的。 没有人会做到这一点,如果他们这样做,将是足够的理由,永远不会使用他们写的任何代码…对不对?

我发现一个人偶然将undefined设置为null 例子 ,这是为了避免假定undefined不被覆盖而给出的。 但是如果他们这样做了,这个bug就不会被发现,我也看不出有什么更好的了。

在C ++中,每个人都清楚,说#define true false是合法的,但是没有人build议你避免使用#define true false ,而是使用0 == 0 。 你只是假设没有人会这么做,如果他们这样做,不要再信任他们的代码。

这有没有真的把别人分配给undefined (有意的),并打破了你的代码,或者这是更多的假设的威胁? 我愿意趁机让我的代码更具可读性。 这是一个非常糟糕的主意吗?

重申一下,我不是要求如何保护不被重新分配的未定义的。 我已经看过那些写过100次的技巧了。 我在问,不使用这些技巧是多么危险。

不,我从来没有。 这主要是因为我在现代浏览器上开发,主要是兼容ECMAScript 5。 ES5标准规定undefined现在是只读的。 如果您使用严格模式(您应该),如果您不小心尝试修改它,则会引发错误。

 undefined = 5; alert(undefined); // still undefined 
 'use strict'; undefined = 5; // throws TypeError 

你不应该做的是创build你自己的范围,可变的undefined

 (function (undefined) { // don't do this, because now `undefined` can be changed undefined = 5; })(); 

常量很好。 仍然没有必要,但很好。

 (function () { const undefined = void 0; })(); 

没有适当的代码会做这样的事情。 但是,你永远无法知道你正在使用的一些智能开发者或插件/库/脚本。 另一方面,现在的浏览器是不太可能的,现代浏览器根本不允许覆盖undefined ,所以如果你正在使用这样的浏览器进行开发,你会很快注意到是否有代码试图覆盖它。


即使你没有要求 – 很多人在寻找更常见的“如何防止重新定义的undefined ”问题时可能会发现这个问题,所以我会回答:

不pipe浏览器有多老,有一个非常好的方法可以得到一个未定义的 undefined

 (function(undefined) { // your code where undefined is undefined })(); 

这是有效的,因为没有指定的参数总是undefined 。 你也可以用一个接受一些真实参数的函数来实现,比如当你使用jQuery的时候。 通过这种方式确保一个健康的环境通常是一个好主意:

 (function($, window, undefined) { // your code where undefined is undefined })(jQuery, this); 

那么你可以肯定的是,在这个匿名函数里面,以下的事情是正确的:

  • $ === jQuery
  • window === [the global object]
  • undefined === [undefined]

但是,请注意,有时typeof x === 'undefined'实际上是必要的:如果variablesx从未被设置为一个值(与被设置undefined相反),以不同的方式读取x ,如if(x === undefined)会抛出一个错误。 这不适用于对象属性,所以如果你知道y总是一个对象, if(yx === undefined)是完全安全的。

有一个简单的解决scheme:与void 0进行比较,总是未定义的。

请注意,您应该避免==因为它可能会强制值。 改用=== (和!== )。

也就是说,未定义的variables可能会被设置错误,如果有人写的=而不是==比较对undefined东西。

只有你知道你使用什么代码,因此它有多危险。 这个问题不能以你澄清你想要的方式来回答。

1)创build一个团队策略,禁止重新定义未定义的,保留它的更受欢迎的用法。 扫描您的现有代码未定义的左侧分配。

2)如果你不控制所有的情况,如果你的代码是在你或你的政策控制的外部情况下使用,那么显然你的答案是不同的。 扫描使用您的脚本的代码。 哎呀,如果你愿意的话,可以扫描一下网站上关于未定义的左侧任务的统计信息,但是我怀疑你已经完成了这个工作,因为在这里find答案#1或#3会更容易。

3)如果答案不够好,可能是因为你需要一个不同的答案。 也许你正在编写一个在公司防火墙内部使用的stream行库,并且你无法访问调用代码。 然后在这里使用其他的好答案之一。 注意stream行的jQuery库实践声音封装,并开始:

 (function( window, undefined ) { 

只有你可以用你寻找的具体方式回答你的问题。 还有什么可说的?

编辑:如果你真的想要我的意见,我会告诉你这根本不危险。 任何可能导致缺陷的事情(例如分配给未定义的,这显然是一个logging良好的风险行为)本身就是一个缺陷。 这是风险的缺陷。 但是,这只是在我的情况下,我可以负担得起这个观点。 正如我build议你那样,我回答了我的使用案例的问题。

testing未定义是安全的。 正如你已经提到的。 如果你得到一些覆盖它的代码(这是非常可以改进的),只是不要再使用它了。

也许如果你正在创build一个供公众使用的库,你可以使用一些技巧来避免用户改变它。 但即使在这种情况下,这是他们的问题,而不是你的图书馆。

编码支持ECMAScript 5.1的浏览器时,您可以在代码中使用undefined的代码,因为它根据语言规范是不可变的 。

另请参阅此兼容性表或ECMAScript 5以查看所有现代浏览器(IE 9 +)已实现immutable undefined

这根本不危险 它只能在ES3引擎上运行时被覆盖,而且不太可能再被使用。

首先,如果你的代码被打破了,那可能不是因为其他开发者“正在努力成为一个混蛋”。

undefined不是关键字,这是事实。 但这一个全球性的原始水平。 它的目的是像这样使用(请参阅developer.mozilla.org上的 “undefined”):

 var x; if (x === undefined) { // these statements execute } else { // these statements do not execute } 

这也是通用的select(也来自MDN ),在我看来更好的方法是:

 // x has not been declared before if (typeof x === 'undefined') { // evaluates to true without errors // these statements execute } if(x === undefined){ // throws a ReferenceError } 

这有几个好处,显而易见的(从注释)是,它不会触发一个exception,当没有声明x。 另外值得一提的是,MDN也指出在第一种情况下使用=== over ==很重要,因为:

 var x=null; if (x === undefined) { // this is probably what you meant to do // these lines will not execute in this case } else if (x == undefined) { // these statements will execute even though x *is* defined (as null) } else { // these statements do not execute } 

这是另一个经常被忽视的原因,为什么在所有情况下使用第二种select可能会更好。

结论:以第一种方式编码并没有错,当然也不是危险的。 你所看到的,你用它作为例子(它可以被覆盖)的论点并不是用typeof编码替代的最强的论据。 但是,使用typeof更强一些,具体来说就是:当你的var没有声明的时候,它不会抛出exception。 也可以这样说,使用==而不是===是一个常见的错误,在这种情况下,它不会达到你期望的效果。 那么为什么不使用typeof