探索JavaScript中Null和Undefined的深渊
探索JavaScript中Null和Undefined的深渊
本文翻译自:
https://modernweb.com/exploring-the-abyss-of-null-and-undefined-in-javascript/
在讨论JavaScript
中的原始数据类型时,大多数人都了解基本知识,从String
,Number
和Boolean
开始。这些原语非常简单,可以像您期望的那样起作用。但是,本文将重点介绍称为Null
和Undefined
的更独特的原始数据类型。是什么使它们相似,不相似以及总体上与众不同。
了解 null
和 undefined
在JavaScript
中,null
是语言关键字,不代表可识别的对象值。换句话说,这表示“没有值”。虽然相似,但undefined
实际上表示值不存在。两者都是完全不变的,没有属性或方法,并且无法进行属性分配。实际上,尝试访问或定义属性会引发TypeError
。顾名思义,它们完全没有值。
值的缺失导致它们被描述为虚假值,这意味着当它们在条件(如if语句)的上下文中使用时,它们的值为假。使用相等运算符(==)将这两个虚假值与其他虚假值进行比较,可以发现它们除了自身之外不等于其他任何值:
null == 0; // false
undefined == ""; // false
null == false; // false
undefined == false; // false
null == undefined; // true
尽管有此与其他相似之处,null
和 undefined
并不等效。每个都充当其自己独特类型的唯一成员;undefined
是类型的未定义和null
类型为空。将二者与值和类型均等的严格相等运算符(===)进行比较就足以证明:
undefined === null; // false
这是一个重要的区别; 两者都有不同的目的,这样做是合理的。为了区分两者,您可能希望将其undefined
视为代表值的意外缺失和null
代表预期的值缺失。
屈服 undefined
undefined
在代码中产生值的方法有很多种。尝试访问不存在值的值时通常会遇到此问题。在这种情况下,JavaScript
是一种动态的,弱类型的语言,它将仅默认为一个undefined
值,而不会引发错误。
任何未提供初始值的已声明变量将具有默认值undefined
:
var foo; // defaults to undefined
undefined
尝试访问不存在的对象属性或数组项时,将发出一个值:
var array = [1, 2, 3];
var foo = array.foo; // foo property doesn't exist, returns undefined
var item = array[5]; // no item exists in the array at index 5, returns undefined
如果函数中省略了return
语句,undefined
则返回:
var value = (function(){})(); // returns undefined
未提供给函数调用的undefined
参数:
(function(undefined){
// parameter is undefined
})();
该void 0
还可以用来返回一个undefined
值。诸如Underscore
之类的库将其用作类型检查的防弹手段,因为它是不可变的,undefined
在任何情况下都可以依赖于返回:
function isUndefined(obj){
return obj === void 0;
}
最后,undefined
是一个预定义的全局变量(不是类似的关键字null
),它已初始化为以下undefined
值:
'undefined' in window; // true
从ECMAScript 5
开始,此变量是只读的,以前不是这种情况。
null
实例
用例null
是将其区分的主要方面,因为与相比undefined
,null
它被视为更多的分配值。这就是为什么typeof运算符与值一起使用时返回“对象”的原因null
。最初的理由是,null
过去和现在通常用作需要对象的空引用,非常类似于占位符。typeof
此后,与之相关的这种行为已被识别为错误,尽管已提出纠正建议,但出于向后兼容的目的,到目前为止,该行为未更改。
这就是JavaScript
环境从不将值设置为的原因null
。它必须以编程方式完成。正如有关MDN
的文档所述:
在API中,null通常是在可以期望有对象但没有对象相关的地方进行检索。
对于DOM
来说确实如此,它是独立于语言的,并且不属于ECMAScript
规范的范围。由于它是一个外部API
,因此尝试检索不存在的元素会返回一个null
值,而不是undefined
。
通常,如果您需要为变量或属性分配非值,将其传递给函数或从函数返回,null
则几乎总是最佳选择。
另一个可行的用例null
也被认为是良好实践,object = null
当不再需要引用时,显式变量无效。通过分配一个null
值,您可以有效地清除引用,并假定未在代码的其他位置引用该对象,将其指定为垃圾回收,从而回收内存。
深层发掘
是什么让null
和undefined
这样的黑洞不仅仅是在他们的行为,而且在方式,他们在内部JavaScript
环境中进行处理。它们似乎不具有通常与其他图元或内置对象关联的相同特征。
作为ES5
的,该Object.prototype.toString
方法,这已成为进行类型检查的事实标准,被证明是在这方面两者一致的null
和undefined
:
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(undefined); // [object Undefined]
但是,该Object.prototype.toString
方法实际上并没有检索构造函数的内部[[Class]]
属性null
或undefined
公开其构造函数。根据文档,调用时将采取以下步骤:
If the this value is undefined, return "[object Undefined]". If the this value is null, return "[object Null]". Let O be the result of calling ToObject passing the this value as the argument. Let class be the value of the [[Class]] internal property of O. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".