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保留字
| 保留字 | 保留字 | 保留字 | 保留字 | 保留字 |
|---|---|---|---|---|
| break | case | catch | class | const |
| continue | debugger | default | delete | do |
| else | export | extends | finally | for |
| function | if | import | in | instanceof |
| new | return | super | switch | this |
| throw | try | typeof | var | void |
| while | with | yield |
其他全局属性
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
}
*/