JavaScript深度指南系列之undefined

202 阅读3分钟

引用

世界也许是丑恶的,但人不必如此。 author @栾树

官方旗航店

undefined中文文档入口链接

前言

全局属性 undefined 表示原始值undefined。它是一个 JavaScript 的 原始数据类型

undefined 属性的属性特性:
writablefalse
enumerablefalse
configurablefalse

概念

undefined全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined

// 通过 window.undefined 获取全局属性 undefined 得到一个原始数据类型 undefined
console.log(window.undefined);

在js中访问某个对象的key 未获取到属性的时,会返回undefined

var item = {
    name: '栾树'
}
console.log(item.name);// 输出: 栾树
// 获取item上age属性值
console.log(item.age); // 输出: undefined

检查一个变量是否在全局上下文中存在可以通过检查全局对象上是否存在这个属性(比如使用in操作符)

if ('undefined' in window) {
    // 只有 undefined 被全局性的定义 才会执行这些语句
}

undefined既然属于window上的属性。也就是说,是否可以对其进行重新赋值

// 修改 undefined
window.undefined = '栾树';

// undefined 不允许被重写 
console.log(undefined); // 输出: undefined

undefined不可重写。undefinedwritable属性特性值为false。 尝试使用delete对其进行删除操作是否可行。

// 删除 window 上的 undefined 属性
delete window.undefined 

// undefined 不允许被删除
console.log(window.undefined); // 输出: undefined

undefined不可配置(不支持删除) 。也就是说,undefinedconfigurable属性特性值为false。那我就好奇了undefined是否支持枚举。

// 枚举 undefined
for(var key in window){
    if(key === undefined){
        console.log('undefined支持枚举'); // 未输出
    }
}

undefined不可枚举 。undefinedenumerable属性特性值为false

通过上述验证,得出以下结论:

  1. undefinedwritable 属性特性值为 false
  2. undefinedconfigurable 属性特性值为false
  3. undefinedenumerable 属性特性值为false

既然undefined这些属性特性值都为false。可以尝试修改这些属性特性值。

Object.defineProperty(window, 'undefined', {
    writable: true,
    configurable: true,
    enumerable: true,
})

// 执行代码会报错   Cannot redefine property: undefined 大致翻译为 无法重新定义属性:未定义
VM126:1 Uncaught TypeError: Cannot redefine property: undefined
    at Function.defineProperty (<anonymous>)
    at <anonymous>:1:8

undefied 问题

一个没有被赋值的变量的类型会被分配为 undefined

var name;
console.log(name); // 输出: undefined

我们使用typeof进一步验证未赋值的变量被分配undefined

var n;
console.log(typeof n === undefined);// 输出: true

如果方法或者是语句中操作的变量没有被赋值,则会返回 undefined

function test(a){
    console.log(typeof a);    // undefined
    return a;
}

test(); // 返回 undefined

局部作用域中undefined可作为变量名 因为undefined不是一个保留字 (en-US))

(function() {
    var undefined = 'luanshu';
    console.log(undefined); // 输出: luanshu
})();

局部作用域下可使用undefined做变量,即便事实并非如此,也要避免去重写它。可使用void表达式

console.log(void(0) === undefined); // 输出: true

总结

我们首先介绍 undefined 的概念, undefined 本质上在全局作用域下不允许被重新定义。 自 ECMAscript5 标准以来 undefined 是一个不能被配置(non-configurable),不能被重写(non-writable)的属性。即便事实并非如此,也要避免去重写它。检验是否是undefined值 可使用 in 或者 hasOwnProperty(前提是当前检测是对象),获取undefined可使用void(0)表达式代替。