你真的知道為什麼要使用void(0)代替undefined嗎?

_Fatman發表於2021-02-01

我們平時用到的\(\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}\)的原因了。

相關文章