null和undefined

349 阅读2分钟

null

null是一个字面量,不是全局对象的一个属性。null是表示缺少的标识,变量未指向任何对象。通常把null作为尚未创建的对象。

let null = 1231; //  Uncaught SyntaxError: Unexpected token 'null'

var null = 222; // Uncaught SyntaxError: Unexpected token 'null'

undefined

基础知识

undefined是全局对象的一个属性。也就是说,他是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined。 它有可能在非全局作用域中作为标识符(变量名)来使用(undefined不是一个保留字)
自ES5标准以来全局对象属性undefined是一个不能被配置的(non-configurable),不能被重写(no-wirtable)的。

// 全局作用域下
let undefined = 111; // Uncaught SyntaxError: Identifier 'undefined' has already been declared
var undefined = 222; // 不会报错,但是访问undefined属性的值还是undefined

// 当然不建议这么写
(() => {
    let undefined = 'ki';
    console.log(undefined, typeof undefined);
})();
// 输出内容:ki string

undefined = 'ki';
console.log(undefined, typeof undefined);
// 输出内容:undefined 'undefiend'

Object.getOwnPropertyDescriptor(window, 'undefined');
/*
{
    configurable: false
    enumerable: false
    value: undefined
    writable: false
}
*/

严格相等和undefined

我们可以使用undefined和严格相等或不想等操作符来决定一个变量是否拥有值。

let x;
if (x === undefined) {
    // 执行这些语句
}
else {
    // 这些语句不会执行
}

在这里必须使用严格相等操作符(===)而不是标准相等操作符(==), 因为 x == undefined 会检查x是不是null,但是严格相等不会检查。

Typeof操作符和undefined

使用typeof:

let x;
if(typeof x === 'undefined') {
    // 执行这些语句
}

使用typeof的原因是它不会在一个变量没有被声明的时候抛出一个错误。

// 没有声明变量y
if (typeof y === 'undefiend') { // 不会报错
    console.log('y is ' + typeof y); // y is undefiend
}
console.log(y); // Uncaught ReferenceError: y is not defined at

Void操作符和undefined

void操作符:

let x;
if (x === void 0) {
    // 执行这些语句
}

if (y === void 0) { // Uncaught ReferenceError: y is not defined at
}

null 和 undefined的不同点

定义typeof是否为保留字是否标识符+
null字面量'object'不可以Number(null) // 0
undefined全局变量'undefiend'可以Number(undefined) // NaN

补充知识

ECMAScript5保留字

保留字保留字保留字保留字保留字
breakcasecatchclassconst
continuedebuggerdefaultdeletedo
elseexportextendsfinallyfor
functionifimportininstanceof
newreturnsuperswitchthis
throwtrytypeofvarvoid
whilewithyield

其他全局属性

NaN

Object.getOwnPropertyDescriptor(window, 'NaN')
/* 
{
    configurable: false
    enumerable: false
    value: NaN
    writable: false
}
*/

Infinity

Object.getOwnPropertyDescriptor(window, 'Infinity')
/* 
{
    configurable: false
    enumerable: false
    value: Infinity
    writable: false
}
*/