null 和 undefined的区别
在用法上几乎没有区别:
if (!undefined)
console.log('undefined is false');
// undefined is false
if (!null)
console.log('null is false');
// null is false
undefined == null
// true
最初设计
JavaScript的最初版本是这样区分的:null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
// 对于 null
let nullValue = null;
let nullToNumber = Number(nullValue);
console.log(nullToNumber); // 输出: 0
// 对于 undefined
let undefinedValue;
let undefinedToNumber = Number(undefinedValue);
console.log(undefinedToNumber); // 输出: NaN
项目实践中的区别
但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
Object.getPrototypeOf(Object.prototype)
// null
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var o = new Object();
o.p // undefined
var x = f();
x // undefined
typeof null 的结果是什么,为什么?
参考:https://www.jianshu.com/p/68c69bd329ee
typeof null 的结果是Object。
在 JavaScript 第一个版本中,所有值都存储在 32 位的单元中,每个单元包含一个小的 类型标签(1-3 bits) 以及当前要存储值的真实数据。类型标签存储在每个单元的低位中,共有五种数据类型:
javascript复制代码000: object - 当前存储的数据指向一个对象。
1: int - 当前存储的数据是一个 31 位的有符号整数。
010: double - 当前存储的数据指向一个双精度的浮点数。
100: string - 当前存储的数据指向一个字符串。
110: boolean - 当前存储的数据是布尔值。
如果最低位是 1,则类型标签标志位的长度只有一位;如果最低位是 0,则类型标签标志位的长度占三位,为存储其他四种数据类型提供了额外两个 bit 的长度。
有两种特殊数据类型:
undefined的值是 (-2)30(一个超出整数范围的数字);
null 的值是机器码 NULL 指针(null 指针的值全是 0)
那也就是说null的类型标签也是000,和Object的类型标签一样,所以会被判定为Object。
如何安全获取undefined的值
直接使用undefined会出现什么问题?undefined是JavaScript的一个全局变量,也就是挂载在window对象上的一个变量,并不是关键字,这意味着可以使用 undefined 来作为一个变量名,但是这样的做法是非常危险的,它会影响对 undefined 值的判断。
因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值,
但是这样会影响 undefined 的正常判断。表达式 void ___ 没有返
回值,因此返回结果是 undefined。void 并不改变表达式的结果,
只是让表达式不返回值。因此可以用 void 0 来获得 undefined。
// Case 1: 使用undefined作为变量名
let undefined = "你好";
console.log(undefined); // Output: "你好"
// Case 2: 使用 void 0
let safeUndefined = void 0;
console.log(safeUndefined); // Output: undefined
isNaN 和 Number.isNaN
函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。
函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。