我們平時用到的\(\color{#FF3030}{undefined}\)只是\(\color{#FF3030}{window}\)物件下的一個屬性。
Object.getOwnPropertyDescriptor(window, undefined);
//{value: undefined, writable: false, enumerable: false, configurable: false}
也正是因為如此,導致它在函式作用域中是可以修改。
但前提要加宣告,因為不加宣告,操作的\(\color{#FF3030}{window.undefined}\),而\(\color{#FF3030}{window.undefined}\)的屬性描述符是:
屬性 | 值 |
---|---|
value | undefined |
writable | false |
enumerable | false |
configurable | false |
\(\color{#FF3030}{value}\)不能修改,不能遍歷,並且\(\color{#FF3030}{屬性描述符}\)也不能修改(不能用\(\color{#FF3030}{Object.defineProperty}\)來修改\(\color{#FF3030}{writable、enumerable、configurable}\)的值)。
但是我們是可以在\(\color{#FF3030}{函式作用域}\)或者\(\color{#FF3030}{塊級作用域}\)對\(\color{#FF3030}{undefined}\)的值進行\(\color{#FF3030}{“修改”}\)的,比如:
function fn(){
undefined = 1111;
console.log('undefined : ' + undefined);
}
fn();//undefined : undefined
function fn(){
var undefined = 1111;
console.log('undefined : ' + undefined);
}
fn();//undefined : 1111
{
let undefined = 1111;
console.log('undefined : ' + undefined);//undefined : 1111
}
這是因為在\(\color{#FF3030}{函式作用域}\)或者\(\color{#FF3030}{塊級作用域}\)中也定義了一個\(\color{#FF3030}{undefined}\)變數,在此作用域中就會優先使用新定義的變數,而不會去使用\(\color{#FF3030}{window.undefined}\),從而造成一種我們將\(\color{#FF3030}{window.undefined}\)的值改變了的假象。
所以我們在判斷變數的型別時,最好使用:
var obj;
typeof obj === 'undefined';
而不要去使用:
var obj;
obj === undefined;
使用\(\color{#FF3030}{void關鍵字}\)也是可以的,因為\(\color{#FF3030}{void關鍵字}\)無論如何都會返回\(\color{#FF3030}{undefined}\):
var obj;
obj === void(0);
這也是在實際開發中經常使用\(\color{#FF3030}{void(0)}\)來代替\(\color{#FF3030}{undefined}\)的原因了。