探索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 "]".
