今天要講的是 優先性 及 相依性
首先所謂 優先性 ,就是只說我們運算子在運行的時候,會先進行哪種運算。而圖片上面提到的 優先性較高的運算子會成為優先性較低的運算子的運算元 這個概念指的是,運算子是一種表達式,只要是表達式,就會有一個 回傳的值 。而這個回傳的值,會再成為 優先姓較低的運算子 的 運算元 (好饒口~)
接下來我們就來看個實例
var a = 2 * 2 + 2 * 3;
console.log(a);
看到這樣的運算,有學過數學的人就知道,先加減後乘除,所以照這個觀念,我們可以算出 a = 10 的結果。
沒錯,答案是 10 ,而這裡先加減後乘除的觀念就是 運算子的優先性。
我們可以從這個 MDN的連結查看各種運算子的優先性
點開以後直接看到表格的部分
乘法跟除法的優先性都是15,大於加法跟減法的13,所以會優先執行乘除之後再執行加減,而別忘了, =
也是運算子的一種喔,只是因為他的優先性很低 只有 3 爾以,所以最後通常算完的結果才會執行這個運算子。
再來介紹相依性,相依性就是運算子執行的方向,通常分為 從左至右 以及 從右至左,少部分是 無相依性 。
這邊 加減乘除 4 個都是屬於 從左至右 ,而賦值的 =
則是屬於 從右至左。
好~有了上面這些觀念以後,我們就可以知道, a 透過 運算子優先序 以及 運算子相依性,他的運算邏輯如下
// 先乘除 相依性左到右
2 * 2 = 4
2 * 3 = 6
// 加減 相依性左到右
4 + 6 = 10
// 賦值 相依性右到左
a = 10
那再來提一些特別的案例
console.log(1 < 2 < 3); // true
這個好像還蠻符合預期的。
但當反過來的時候
console.log(3 > 2 > 1); // false
為什麼會這樣呢????
讓我們來解析一下
// 小於大於的符號,優先度一樣是11,那再來就是先相依性的順序都為 從左至右,但這裡必須拆開來看
3 > 2 // 回傳 true, true 在javascript 中會自己型別轉換為 1, 相反 false 就是轉換成 0。
// 所以就變成
1 > 1 // 這邊當然是回傳 false
喔~所以我們的多運算子判斷式,還是會依照相依性的方向,兩個運算元一個運算子一組的進行運算,因為這樣的運算結果的回傳值成為接下來運算子的運算元,應證了一開始圖片上所講的觀念喔!
有興趣的人也可以照著上面的觀念,自己推導看看 console.log(1 < 2 < 3);
為什麼會是 true。
那再來看另一個例子
var a = 1;
var b = 2;
a = b = 3;
console.log(a, b); // 3 , 3
這個結果其實也蠻符合預期的吧~
雖然a, b分別在一開始的時候賦予了不同的值,但最後都被指派成3
順序依照目前的理解是
// 因為 = 是由右邊到左邊的相依性,所以會是這樣
b = 3;
a = b;
所以自然而然,a跟b就是3了阿~
怎麼說呢? 我們先在來看一個例子喔!
var b = {};
Object.defineProperty(b, 'a', {
value: 2,
writable: false
});
上述這個code是指說,我現在宣告一個物件叫b,我要在這個物件b裡面,新增一個屬性,他的keyname是a,並且a的值指派是數字2,更重要的是這個值是不能被複寫的。
所以沒有辦法透過 b.a = 3;
來複寫這個值。
var b = {};
Object.defineProperty(b, 'a', {
value: 2,
writable: false
});
b.a = 3; // 2
console.log('b.a', b.a);
var a = 3;
a = b.a = 1;
所以這段程式碼執行的結果應該b.a = 2,因為他不會被複寫。
但是下方的 a = b.a = 1;
大家覺得 a 的結果會是多少?
這裡直接公布答案喔,答案是1 ,為甚麼呢,因為同樣,優先性一樣高,依照相依性,由右到左來分析
b.a = 1;
// 這裡雖然b.a的值還是2,但這個表達式會 回傳的值 其實是1喔
// 而重點是回傳的值會再次成為其他運算子的運算元,所以接下來的表達式是等同於
a = 1(b.a = 1的回傳值)
// 所以 a 才等於 1喔!!
就是這個精神,所以如果今天在更複雜改成
var b = {};
Object.defineProperty(b, 'a', {
value: 2,
writable: false
});
Object.defineProperty(b, 'b', {
value: 3,
writable: false
});
b.a = 3; // 2
console.log('b.a', b.a);
var a = 3;
a = b.b =b.a = 1;
這樣最後a的值呢?還是會是 1喔!
但是b.a也還是2 b.b也還是3喔!
最後再回到
var a = 1;
var b = 2;
a = b = 3;
console.log(a, b); // 3 , 3
所以這邊的順序應該是因為
b = 3; // 回傳 3
a = 3(b = 3的回傳值);
所以這樣a跟b才都是等於3,並非是因為a取得了b的值,所以才等於3。
這篇可能理解上要稍微想過一下,可以想清楚以後在進入下一篇文章喔~汪汪
console.log(1 > 2 > 3);
這段應該是要寫
console.log(3 > 2 > 1);
感謝大大糾正!