【辟邪劍法】探祕javascript中你所不知道的 void

和辟邪劍法同樣,欲練此功必先……javascript

void是什麼

導讀

public class Test {
	public static void main(String[] args) {
		for(int i=0;i<args.length;i++) {
			System.out.println(args[i]);
		}
	}
}
複製代碼

很差意思,放錯了,咱們換一個html

<a href="javascript:void(0);">
</a>
複製代碼

這下是否是就不陌生了呢java

void定義

MDN說明node

void expressionexpress

這個運算符能向指望一個表達式的值是undefined的地方插入會產生反作用的表達式。瀏覽器

void 運算符一般只用於獲取 undefined的原始值,通常使用void(0)(等同於void 0)。在上述狀況中,也可使用全局變量undefined 來代替(假定其還是默認值)。ide

ES5說明函數

The production UnaryExpression : void UnaryExpression is evaluated as follows:ui

  1. Let expr be the result of evaluating UnaryExpression.
  2. Call GetValue(expr).
  3. Return undefined.

怎麼理解

  • 運算符:void 是一元運算符,出如今操做數以前,操做數是任意類型。void 0;
  • 返回值:any -> undefined;
  • 有反作用的表達式:也就是說後面的表達式會照常計算,此表達式可能產生反作用。

表達式反作用

大部分表達式沒有反作用。 有關表達式的反作用的概念通常說計算一個表達式的值須要引用一些變量,在表達式求值過程當中,須要提取這些變量的值,但並不改變這些變量的值,這樣的表達式稱爲無反作用的表達式.從傳統意義上講,表達式的做用就是計算,它除了產生一個計算結果外,不該該改變參與計算過程的任何變量的值或產生其它的效應。lua

舉個例子

var a = 1;
var b = a++; //有反作用
var c = a+1; //無反作用
複製代碼

這也向咱們解釋了一個問題既然返回永遠是undefined,那麼GetValue有啥用?(知乎問題)

由於JavaScript的表達式是能夠有反作用(side effect)的,void會對其後的運算數做取值操做,所以若屬性有個getter函數,那麼就會調用getter函數(產生反作用)

var num = 0;
var test = {
    get plus() {
        num++;
    },
    get num() {
        return num;
    }
};

void test.plus; //調用了plus的get方法 而delete就不會觸發(不取值)
console.log(test.num); // 1
複製代碼

爲何不直接用undefined

void是關鍵字,而undefined並非!!!

先看這段代碼

let undefined = 123;
console.log(123 === undefined)//true
複製代碼

我只在瀏覽器端用,並且是現代瀏覽器是否是就沒問題了

function test() {
  let undefined = 123;
  console.log(123 === undefined)
}

test(); //true
複製代碼

在IE5.5~8中咱們能夠將undefined看成變量那樣對其賦值、node環境全局和局部環境均可以、瀏覽器環境中的局部做用域中也是能夠得,所以很容易被污染

因此通常嚴謹的庫的判斷都是使用void 0;來做爲undefined的值

let undefined = 123;
console.log(123 === void 0)//false
複製代碼

拓展

下面這些方法也能夠用來生成純粹的undefined

  • 未賦值的變量 var test;
  • 無返回值的函數 var test = function(){};
  • 未定義的屬性 var test = {}[''];
  • 未賦值實參
(function(window, document, undefined) {
    return undefined;
})(window, document);
複製代碼

void用途

用做定義或者判斷undefined

再也不贅述

當即執行函數

(function () {
  console.log(123)
})(); 

void function () {
  console.log(321)
}(); 
複製代碼

在使用當即執行的函數表達式時,能夠利用void運算符讓JavaScript引擎把一個function關鍵字識別成函數表達式而不是函數聲明(語句)。

URIs

保證點擊以後不會跳轉

<a href="javascript:void(0);">
  這個連接點擊以後不會作任何事情
</a>
<a href="javascript:void(document.body.style.backgroundColor='green');">
  點擊這個連接會讓頁面背景變成綠色。
</a>
<a href="javascript:void(0);" onclick="document.body.style.backgroundColor='green'">猜一下會發生什麼?
</a>
複製代碼

或許能夠這樣

function middleware(next) {
    somethingAsync((err, value) => {
            // 在錯誤的時候調用next,可是不使用next()的返回值
            // 區別於 next(err)
            if (err) {
                next(err)
                return; 
            } else {
                //dosomething
            })
    }
}

//寫成這樣
function middleware(next) {
    somethingAsync((err, value) => {
            if (err) {
                return void next(err)
            } else {
                //dosomething
            })
    }
}
複製代碼

必定有人會問,既然都是返回undefined,爲何使用void 0;而不是void其餘呢?

答案很簡單啦:覺得0比較短~(不要笑,在不少打包及代碼壓縮過程當中都會把undefined轉成void 0;就是由於它比較短)

相關文章
相關標籤/搜索