JavaScript 其他運算符,運算順序

2023-03-20 15:56 更新

void 運算符

void運算符的作用是執(zhí)行一個表達式,然后不返回任何值,或者說返回undefined

void 0 // undefined
void(0) // undefined

上面是void運算符的兩種寫法,都正確。建議采用后一種形式,即總是使用圓括號。因為void運算符的優(yōu)先性很高,如果不使用括號,容易造成錯誤的結(jié)果。比如,void 4 + 7實際上等同于(void 4) + 7。

下面是void運算符的一個例子。

var x = 3;
void (x = 5) //undefined
x // 5

這個運算符的主要用途是瀏覽器的書簽工具(Bookmarklet),以及在超級鏈接中插入代碼防止網(wǎng)頁跳轉(zhuǎn)。

請看下面的代碼。

<script>
function f() {
  console.log('Hello World');
}
</script>
<a  rel="external nofollow" target="_blank"  onclick="f(); return false;">點擊</a>

上面代碼中,點擊鏈接后,會先執(zhí)行onclick的代碼,由于onclick返回false,所以瀏覽器不會跳轉(zhuǎn)到 example.com。

void運算符可以取代上面的寫法。

<a href="javascript: void(f())">文字</a>

下面是一個更實際的例子,用戶點擊鏈接提交表單,但是不產(chǎn)生頁面跳轉(zhuǎn)。

<a href="javascript: void(document.form.submit())">
  提交
</a>

逗號運算符

逗號運算符用于對兩個表達式求值,并返回后一個表達式的值。

'a', 'b' // "b"

var x = 0;
var y = (x++, 10);
x // 1
y // 10

上面代碼中,逗號運算符返回后一個表達式的值。

逗號運算符的一個用途是,在返回一個值之前,進行一些輔助操作。

var value = (console.log('Hi!'), true);
// Hi!

value // true

上面代碼中,先執(zhí)行逗號之前的操作,然后返回逗號后面的值。

運算順序

優(yōu)先級

JavaScript 各種運算符的優(yōu)先級別(Operator Precedence)是不一樣的。優(yōu)先級高的運算符先執(zhí)行,優(yōu)先級低的運算符后執(zhí)行。

4 + 5 * 6 // 34

上面的代碼中,乘法運算符(*)的優(yōu)先性高于加法運算符(+),所以先執(zhí)行乘法,再執(zhí)行加法,相當于下面這樣。

4 + (5 * 6) // 34

如果多個運算符混寫在一起,常常會導(dǎo)致令人困惑的代碼。

var x = 1;
var arr = [];

var y = arr.length <= 0 || arr[0] === undefined ? x : arr[0];

上面代碼中,變量y的值就很難看出來,因為這個表達式涉及5個運算符,到底誰的優(yōu)先級最高,實在不容易記住。

根據(jù)語言規(guī)格,這五個運算符的優(yōu)先級從高到低依次為:小于等于(<=)、嚴格相等(===)、或(||)、三元(?:)、等號(=)。因此上面的表達式,實際的運算順序如下。

var y = ((arr.length <= 0) || (arr[0] === undefined)) ? x : arr[0];

記住所有運算符的優(yōu)先級,是非常難的,也是沒有必要的。

圓括號的作用

圓括號(())可以用來提高運算的優(yōu)先級,因為它的優(yōu)先級是最高的,即圓括號中的表達式會第一個運算。

(4 + 5) * 6 // 54

上面代碼中,由于使用了圓括號,加法會先于乘法執(zhí)行。

運算符的優(yōu)先級別十分繁雜,且都是硬性規(guī)定,因此建議總是使用圓括號,保證運算順序清晰可讀,這對代碼的維護和除錯至關(guān)重要。

順便說一下,圓括號不是運算符,而是一種語法結(jié)構(gòu)。它一共有兩種用法:一種是把表達式放在圓括號之中,提升運算的優(yōu)先級;另一種是跟在函數(shù)的后面,作用是調(diào)用函數(shù)。

注意,因為圓括號不是運算符,所以不具有求值作用,只改變運算的優(yōu)先級。

var x = 1;
(x) = 2;

上面代碼的第二行,如果圓括號具有求值作用,那么就會變成1 = 2,這是會報錯了。但是,上面的代碼可以運行,這驗證了圓括號只改變優(yōu)先級,不會求值。

這也意味著,如果整個表達式都放在圓括號之中,那么不會有任何效果。

(expression)
// 等同于
expression

函數(shù)放在圓括號中,會返回函數(shù)本身。如果圓括號緊跟在函數(shù)的后面,就表示調(diào)用函數(shù)。

function f() {
  return 1;
}

(f) // function f(){return 1;}
f() // 1

上面代碼中,函數(shù)放在圓括號之中會返回函數(shù)本身,圓括號跟在函數(shù)后面則是調(diào)用函數(shù)。

圓括號之中,只能放置表達式,如果將語句放在圓括號之中,就會報錯。

(var a = 1)
// SyntaxError: Unexpected token var

左結(jié)合與右結(jié)合

對于優(yōu)先級別相同的運算符,同時出現(xiàn)的時候,就會有計算順序的問題。

a OP b OP c

上面代碼中,OP表示運算符。它可以有兩種解釋方式。

// 方式一
(a OP b) OP c

// 方式二
a OP (b OP c)

上面的兩種方式,得到的計算結(jié)果往往是不一樣的。方式一是將左側(cè)兩個運算數(shù)結(jié)合在一起,采用這種解釋方式的運算符,稱為“左結(jié)合”(left-to-right associativity)運算符;方式二是將右側(cè)兩個運算數(shù)結(jié)合在一起,這樣的運算符稱為“右結(jié)合”運算符(right-to-left associativity)。

JavaScript 語言的大多數(shù)運算符是“左結(jié)合”,請看下面加法運算符的例子。

x + y + z

// 引擎解釋如下
(x + y) + z

上面代碼中,xy結(jié)合在一起,它們的預(yù)算結(jié)果再與z進行運算。

少數(shù)運算符是“右結(jié)合”,其中最主要的是賦值運算符(=)和三元條件運算符(?:)。

w = x = y = z;
q = a ? b : c ? d : e ? f : g;

上面代碼的解釋方式如下。

w = (x = (y = z));
q = a ? b : (c ? d : (e ? f : g));

上面的兩行代碼,都是右側(cè)的運算數(shù)結(jié)合在一起。

另外,指數(shù)運算符(**)也是右結(jié)合。

2 ** 3 ** 2
// 相當于 2 ** (3 ** 2)
// 512


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號