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

IT技术 javascript undefined
2021-01-16 16:03:22

每次有人提到针对 进行测试时undefined都会指出thatundefined不是关键字,因此可以将其设置为"hello",因此您应该 typeof x == "undefined"改用 。这对我来说似乎很荒谬。没有人会这样做,如果他们这样做了,那就有足够的理由从不使用他们编写的任何代码......对吗?

我发现了一个不小心设置undefined为 的例子null,这是为了避免假设它undefined没有被覆盖。但是如果他们这样做了,这个错误就不会被发现,而且我看不出这有什么好处。

在 C++ 中,每个人都清楚说 是合法的#define true false,但没有人建议您避免true使用0 == 0你只是假设没有人会是一个足够大的混蛋来做那件事,如果他们这样做了,永远不要再相信他们的代码。

这是否真的咬过其他人undefined(故意)分配给的人并破坏了您的代码,或者这更像是一种假设的威胁?我愿意抓住机会使我的代码更具可读性。这真的是个坏主意吗?

重申一下,我不是在问如何防止重新分配未定义。我已经看到这些技巧写了 100 次了。我在问不使用这些技巧有多危险。

6个回答

不,我从来没有。这主要是因为我在现代浏览器上开发,这些浏览器大多符合 ECMAScript 5。ES5 标准规定它undefined现在是只读的。如果你使用严格模式(你应该),如果你不小心尝试修改它,将会抛出一个错误。

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

你应该有什么不能做的是建立自己的作用域,可变undefined

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

恒定就好。仍然没有必要,但很好。

(function () {
    const undefined = void 0;
})();
@bennedich:我知道,我是说我从来没有遇到过这个问题,但这是你应该做的
2021-03-17 16:03:22
@bennedich 你不是有同样的机会意外覆盖任何其他变量吗?
2021-03-22 16:03:22
您的第一条语句只能确保您在开发时不会意外覆盖 undefined,在客户端计算机上与其他代码一起运行时,它仍然会构成相同的威胁。
2021-04-12 16:03:22

没有合适的代码会做这样的事情。但是您永远无法知道您正在使用的某些想成为聪明的开发人员或插件/库/脚本做了什么。另一方面,这是极不可能的,现代浏览器根本不允许覆盖undefined,所以如果你使用这样的浏览器进行开发,你会很快注意到是否有任何代码试图覆盖它。


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

无论浏览器有多老,都有一个很好的方法来获得真正的未定义 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'实际上是必要的:如果变量x从未设置为值(与设置相反undefined),x以不同的方式读取,例如if(x === undefined)会抛出错误。但这不适用于对象属性,因此如果您知道它y始终是一个对象,if(y.x === undefined)则是完全安全的。

我使用过一个代码库,它有一个覆盖未定义的缩小遗留脚本,我们没有时间或预算来重写脚本,这是一个需要 typeof x == "undefined" 的例子,这并不奇怪,可能一个好习惯。
2021-03-18 16:03:22
@Oleksandr_DJ 没错。做一个值,你知道的undefined,并分配到undefined的范围。如果您传入“太多”参数,请不要undefined为覆盖保留开放。这会导致错误,并且是一种固有的非防御性模式,尤其是当,正如Lucero 指出的那样,有非常简单的替代方法可以undefined在范围内获得可靠的值。
2021-03-28 16:03:22
您关于x未设置为值的说法并不完全正确(请参阅jsfiddle.net/MgADz);而是如果它实际上真的没有定义(参见jsfiddle.net/MgADz/1)。
2021-03-31 16:03:22
再说一次,如果有人不小心说undefined = someVariable这是一个错误,而您希望事情崩溃。至少我是这样。
2021-04-01 16:03:22
我对为什么所有示例都使用“未定义”作为函数中的附加参数感兴趣?但是,如果有人错误地传递了一个额外的参数(定义)并且所有逻辑都将失败,则可能会出现这种情况。为什么不使用类似 function() { var _undef; 之类的东西?if( someVal == _undef) {做某事} };
2021-04-10 16:03:22

对此有一个简单的解决方案:与void 0始终未定义的哪个进行比较

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

也就是说,如果有人写入=而不是==将某些内容与undefined.

IMO,这是最好的答案。
2021-03-14 16:03:22
考虑到这foo === void 0可能不像您在兼容性表中看到的那样流畅,foo === undefined并且undefined现代浏览器(IE 9+)完全支持不可变
2021-03-16 16:03:22

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

1)创建团队策略,禁止重新定义未定义,保留它以供更流行的使用。扫描您现有的代码以获取未定义的左分配。

2)如果您不控制所有场景,如果您的代码在您或您的策略控制的情况之外使用,那么显然您的答案是不同的。扫描使用您的脚本的代码。oop,如果您愿意,可以扫描网络以获取未定义的左分配的统计信息,但我怀疑这已经为您完成了,因为在这里只追求答案 #1 或 #3 更容易。

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

(function( window, undefined ) {

只有您才能以您寻求的特定方式回答您的问题。还有什么好说的?

编辑:ps,如果你真的想要我的意见,我会告诉你这根本不危险。任何很可能导致缺陷的东西(例如分配给未定义,这显然是一种有据可查的风险行为)本身就是一个缺陷。缺陷就是风险。但这只是在我的场景中,我可以承受这种观点。正如我建议你做的那样,我回答了我的用例的问题。

对 undefined 进行测试是安全的。正如你已经提到的。如果您遇到一些覆盖它的代码(这是高度可改进的),请不要再使用它。

也许如果您正在创建一个公共使用的库,您可以使用一些技术来避免用户更改它。但即使在这种情况下,这也是他们的问题,而不是您的图书馆。