1. 程式人生 > >JS魔法堂:從void 0 === undefined說起

JS魔法堂:從void 0 === undefined說起

一、前言                                    

  當使用coffeescript書寫如下程式碼時 name = person?.name 會被預編譯為 var name = typeof person !== "undefined" && person !== null ? person.name : void0; ,那麼void 0到底是什麼意思呢?執行得知void 0===undefined為true。那為什麼不直接使用undefined而要使用void 0呢?而一元運算子void具體又有什麼作用呢?下面將展開來說明。

二、為什麼不直接用undefined                          

  undefined在JavaScript中並不屬於保留字/關鍵字,因此在IE5.5~8中我們可以將其當作變數那樣對其賦值(IE9+及其他現代瀏覽器中賦值給undefined將無效)

複製程式碼
var undefinedBackup = undefined;
undefined = 1;
// 顯示"undefined"
console.log(typeof undefinedBackup);  
// 在IE5.5~8中顯示"number",其他瀏覽器中則顯示"undefined"
console.log(typeof undefined);
複製程式碼

  於是採用void方式獲取undefined則成了通用準則。

三、一元運算子void的作用                         

  void在ECMAScript 262規範如下:

The void Operator

The production UnaryExpression : void UnaryExpression is evaluated as follows:

  • Let expr be the result of evaluating UnaryExpression.
  • Call GetValue(expr).
  • Return undefined.

NOTE: GetValue must be called even though its value is not used because it may have observable side-effects.

   void的行為特點為:

  1. 不管void後的運算數是什麼,只管返回純正的undefined;

  2. void會對其後的運算數作取值操作,因此若屬性有個getter函式,那麼就會呼叫getter函式(因此會產生副作用)

複製程式碼
var article = {
    _view: 0,
    get view(){
        console.log(this._view);
    return this._view++;
    }
};
var test = void article.view; // 顯示0
console.log(test); // 顯示undefined
console.log(article._view); // 顯示1
複製程式碼

   通過一元運算子 delete 作對比,delete的其中一個行為特點是不對其運算數進行取值操作(delete的其他行為特點比我們想的複雜得多,這裡就不詳細記錄了)

複製程式碼
var article = {
    _view: 0,
    get view(){
    console.log(this._view);
    return this._view++;
    }
};
var ret = delete article.view;
console.log(ret); // 顯示true
console.log(article._view); // 顯示0
複製程式碼

四、還有啥方式可以得到純正的undefined?                

  除了通過一元運算子void獲取純正的undefined,其實我們還有如下方法來獲取:

  1. 未賦值的變數

var myUndefined;
console.log(typeof myUndefined); // 顯示"undefined"

  2. 未賦值的實參(和未賦值的變數同理)

複製程式碼
var getUndefined = function(undefined){
  return undefined;
};
var myUndefined = getUndefined();
// 或通過arguments獲取
var getUndefined = function(){
  return arguments[arguments.length];
};
複製程式碼

  3. 無返回值函式

var getUndefined = function(){};
var myUndefined = getUndefined();

  4. 未定義的屬性

var myUndefined1 = {}[''];
var myUndefined2 = [][0];

五、總結                              

  一個小小的void和undefined就這麼好玩,前端的世界還有很多事情要深入研究哦!!