JavaScript 未定义替换为 null

发布于 2024-11-26 14:11:28 字数 1471 浏览 3 评论 0原文

在 JavaScript 中,undefined 可以重新分配,因此通常建议创建一个自执行函数来确保 undefined 实际上是未定义的。作为替代方案,nullundefined 肯定是 ==,但是还有其他值松散地等同于 null/undefined 吗?

TLDR

基本上你可以安全地替换这个:

(function(undefined){

   window.f = function(obj){
     if(obj===undefined || obj===null ){
       alert('value is undefined or null');
     }
   }

})();

与:

window.f = function(obj){
  if(obj==null){
    alert('value is undefined or null');
  }
}

如果上面是 100% 安全,为什么 JavaScript 社区/库不完全删除 undefined 并使用较短的 x == null 有条件同时检查 null/undefined 吗?

编辑:

我从来没有见过有人真正用“未定义”与null来表示“未知值”?我从未见过这种情况,这就是我最初问这个问题的原因。它似乎只是两个令人难以置信的混乱值,从未按照其最初意图使用过。标准化所有内容来进行比较 obj==null 将有利于大小并避免重新分配的任何问题。一切都会继续工作

var obj={};
obj.nonExistantProperty==null // true

var x;
ix==null // true

function(obj){
  obj==null // true
}

此规则的一个例外似乎是将 undefined/null 转换为整数时。这是一个相当年龄的情况,但绝对应该注意。

+(null)==0 尽管 isNaN(+undefined)

考虑到 NaN 是 JavaScript 中唯一不等于自身的值,您可以做一些非常疯狂的事情,例如:

+undefined == +undefined // false
+null == +null // true

使用 null 作为松散的等式 == 删除 undefined 的替换是安全的,前提是您不打算将值转换为整数。这是一个非常边缘的情况。

In JavaScript undefined can be reassigned, so it is often advised to create a self executing function that assures undefined is actually undefined. As an alternative null and undefined are definitely == but are any other values loosely equivalent to null/undefined?

TLDR

Basically can you safely replace this:

(function(undefined){

   window.f = function(obj){
     if(obj===undefined || obj===null ){
       alert('value is undefined or null');
     }
   }

})();

with:

window.f = function(obj){
  if(obj==null){
    alert('value is undefined or null');
  }
}

If the above is 100% safe, why doesn't the JavaScript community/libraries drop undefined altogether and use the shorter x == null conditional to check for both null/undefined at once?

EDIT:

I have never seen someone actually represent an "unknown value" with 'undefined' vs null? I have never seen this scenario, and is why I originally asked the question. It just appears to be two incredibly confused values that are never used in their original intent. Standardizing everything to do a comparison obj==null would be beneficial for size and avoid any issues with reassignment. Everything would continue to work

var obj={};
obj.nonExistantProperty==null // true

var x;
ix==null // true

function(obj){
  obj==null // true
}

The one exception to this rule appears to be when casting undefined/null to an integer. This is a pretty age case scenario, but definitely should be noted.

+(null)==0
while
isNaN(+undefined)

Considering NaN is the only value in JavaScript not equal to itself, you can do some pretty crazy things like:

+undefined == +undefined // false
+null == +null // true

Using null as a loose equality == drop in replacement for undefined is safe, provided you don't plan to cast the value to an integer. Which is a pretty edge case scenario.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

〗斷ホ乔殘χμё〖 2024-12-03 14:11:28

语言规范第 11.9.3 节中的 抽象相等算法 定义了 = =!= 并且它定义了它们,其中

null == void 0
null == null
void 0 == null

void 0 只是表示 undefined 的可靠方式(见下文)所以你的问题的答案是肯定的null 等于undefined 及其本身,仅此而已。

规范的相关部分是

<前><代码>1。如果 Type(x) 与 Type(y) 相同,则
如果 Type(x) 未定义,则返回 true。
如果 Type(x) 为 Null,则返回 true。
...
2. 如果 x 为 null 并且 y 未定义,则返回 true。
3. 如果 x 未定义且 y 为 null,则返回 true。
...

如果您担心 undefined 的含义与通常含义不同,请改用 void 0

null               ==  void 0           // True
({}).x             === void 0           // True
"undefined"        === typeof void 0    // True
(function () {})() === void 0           // True
(undefined = 42,
 undefined         === void 0)          // False
"undefined"        === typeof undefined // False
"undefined"        === typeof void 0    // True

来自语言规范

11.4.2 void 运算符

产生式 UnaryExpression : void UnaryExpression 的评估如下:

  1. expr 为计算 UnaryExpression/ 的结果。
  2. 调用GetValue(expr)
  3. 返回未定义

因此,void 前缀运算符会评估其参数并返回特殊值 undefined,无论全局变量 undefined 发生了什么更改(或者是否 <代码>未定义已定义:)。

编辑:为了回应评论,

如果您正在处理区分两者的库代码,那么您需要处理差异。语言委员会标准化的一些新库确实忽略了差异: JSON.stringify([void 0]) === "[null]" 但有太多处理它们的代码略有不同,并且还有其他差异:

+(null) === 0
isNaN(+undefined)

"" + null === "null"
"" + undefined === "undefined"

如果您正在编写任何类型的生成文本或序列化/反序列化的库,并且您想将两者合并,那么您不能传递 undefined 并期望它表现得像null——您需要显式地将您的输入规范化为其中一个或另一个。

The abstract equality algorithm from section 11.9.3 of the language spec is what defined == and != and it defines them such that

null == void 0
null == null
void 0 == null

where void 0 is just a reliable way of saying undefined (see below) so the answer to your question is yes, null is equal to undefined and itself and nothing else.

The relevant parts of the spec are

1. If Type(x) is the same as Type(y), then
     If Type(x) is Undefined, return true.
     If Type(x) is Null, return true.
     ...
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
...

If you're worried about undefined meaning something other than what it normally means, use void 0 instead.

null               ==  void 0           // True
({}).x             === void 0           // True
"undefined"        === typeof void 0    // True
(function () {})() === void 0           // True
(undefined = 42,
 undefined         === void 0)          // False
"undefined"        === typeof undefined // False
"undefined"        === typeof void 0    // True

From the language specification:

11.4.2 The void Operator

The production UnaryExpression : void UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression/.
  2. Call GetValue(expr).
  3. Return undefined.

So the void prefix operator evaluates its argument and returns the special value undefined regardless of to what the global variable undefined has been changed (or whether undefined is defined :).

EDIT: In response to comments,

If you are dealing with library code that distinguishes between the two, then you need to deal with the difference. Some of the new libraries standardized by the language committee do ignore the difference : JSON.stringify([void 0]) === "[null]" but there is too much code out there that treats them subtly differently, and there are other differences :

+(null) === 0
isNaN(+undefined)

"" + null === "null"
"" + undefined === "undefined"

If you're writing any kinds of libraries that produce text or serialize/deserialize and you want to conflate the two then you can't pass undefined through and expect it to behave as null -- you need to explicitly normalize your inputs to one or the other.

晨曦÷微暖 2024-12-03 14:11:28

因为 JavaScript 有这两个值。虽然其他语言可能只有 nil/null JavaScript 的成长过程中,undefined 是“未知值”,而null 显然是一个不代表任何内容的已知值。

比较 var x(其中 x 未定义,因为尚未分配任何值)和 var y = null(其中 y 为 <代码>空。它被设置为某种东西——代表“无”的句子。 JavaScript 中 undefinednull 的核心基本用法非常深入,其他情况包括:

  1. 缺失(或删除)的属性也会产生undefined 而不是 null(仅当已分配 null 时才会导致 null)。
  2. 未分配的函数参数是未定义
  3. getElementById 等标准函数返回 undefined。见评论。

因此,在 JavaScript 中,使用 undefined 而不是 null 通常更正确。它们都代表不同的事物。试图对抗这个问题的库正在对抗 JavaScript。

快乐编码。


就我个人而言,几乎在所有情况下,我都会避免显式检查 undefinednull。我相信在大多数(但不是全部)情况下,所有错误值都应该是等效的,并且调用者有责任遵守规定的公共合同。

由于这种信念,我会考虑比较 x == null 处于试图保护太多但又太少的边缘,但在捕获 null 未定义,它有效,正如所指出的那样。开始一个趋势;-)

Because JavaScript has both values. And while other languages may only have nil/null JavaScript grew up with undefined being the "unknown value" while null is clearly a known value to represent nothing.

Compare var x where x is undefined because no value has been assigned and var y = null where y is null. It was set to something -- a sentential representing "nothing". This core fundamental usage of undefined vs null in JavaScript runs very deep and other cases include:

  1. A missing (or delete'd) property also yield undefined and not null (it would result in null only if null had been assigned).
  2. Unassigned function parameters are undefined.
  3. undefined returned from standard functions like getElementById. See comments.

Thus, in Javascript, it is often more correct to use undefined and not null. They both represent different things. A library that tries to fight this is fighting JavaScript.

Happy coding.


Personally, in almost all cases I avoid an explicit check for undefined or null. I believe that in most -- but not all -- cases all false values should be equivalent and that it is the callers responsibility to conform to the public contract stated.

Because of this belief I would consider the comparison x == null on the verge of trying to guard too much and yet too little, but in the case of catching null or undefined, it works, as pointed out. Go start a trend ;-)

开始看清了 2024-12-03 14:11:28

因此:

var myVar1;
var myVar2 = null;

if (myVar1 === null) alert('myVar1 is null');
if (myVar1 === undefined) alert('myVar1 is undefined');
if (myVar2 === null) alert('myVar2 is null');
if (myVar2 === undefined) alert('myVar2 is undefined');

任何设置为 null 的内容都不是未定义的 - 它被定义为 null。

Because of this:

var myVar1;
var myVar2 = null;

if (myVar1 === null) alert('myVar1 is null');
if (myVar1 === undefined) alert('myVar1 is undefined');
if (myVar2 === null) alert('myVar2 is null');
if (myVar2 === undefined) alert('myVar2 is undefined');

Anything set to null is not undefined - it's defined as null.

灼疼热情 2024-12-03 14:11:28

阅读Javascript:好的部分,似乎只有 null 和 undefined 是等价的

JavaScript 有两组相等运算符:=== 和 !==,以及它们的邪恶双胞胎 == 和 !=。好的人
按照您期望的方式工作。如果两个操作数类型相同且值相同,则 ===
产生 true 并且 !== 产生 false。当操作数是时,邪恶的双胞胎会做正确的事情
相同类型,但如果它们属于不同类型,它们会尝试强制这些值。他们这样做的规则
是复杂且难以记忆的。以下是一些有趣的案例:

'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true

“JavaScript:Douglas Crockford 的优秀部分。版权所有 2008 Yahoo! Inc.,
978-0-596-51774-8。”

Reading Javascript: The Good parts, it seems that only null and undefined are equivalent

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones
work the way you would expect. If the two operands are of the same type and have the same value, then ===
produces true and !== produces false. The evil twins do the right thing when the operands are of the
same type, but if they are of different types, they attempt to coerce the values. The rules by which they do that
are complicated and unmemorable. These are some of the interesting cases:

'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true

"JavaScript: The Good Parts by Douglas Crockford. Copyright 2008 Yahoo! Inc.,
978-0-596-51774-8."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文