最近 開始接觸到一些ES6之後的新特性 使用起來確實方便了很多markdown
尤爲是最近有一個項目 在方法中須要傳入index 可是在作非空驗證的時候 若是傳入的index是0 也會被判斷爲false 這就十分頭疼了app
冗餘的判斷不只使代碼的可讀性變差 並且會使代碼變得不簡潔ide
可是在接觸到可選鏈操做符後 emmmmm 這也太香了 避免了 && 和 多餘的非空校驗函數
因此決定以此爲開始 陸續的寫一些ES6 ES7...以後的新特性ui
這裏我引用一段MDN上的解釋lua
可選鏈操做符( ?. )容許讀取位於鏈接對象鏈深處的屬性的值,而沒必要明確驗證鏈中的每一個引用是否有效。?. 操做符的功能相似於 . 鏈式操做符,不一樣之處在於,在引用爲空(nullish ) (null 或者 undefined) 的狀況下不會引發錯誤,該表達式短路返回值是 undefined。與函數調用一塊兒使用時,若是給定的函數不存在,則返回 undefined。url
或許 你仍是?????spa
不要急 咱們來看一道例題3d
const adventurer = {
name: '林克',
weapon: {
name: '大師劍'
}
};
const weaponName = adventurer.weapon?.name;
console.log(weaponName);
// expected output: 大師劍
console.log(adventurer.savePrincess?.());
// expected output: undefined
const shieldName = adventurer.shield?.name;
console.log(shieldName);
// expected output: undefined
複製代碼
上述例子adventurer.weapon?.name
code
咱們試圖去尋找adventurer對象下的weapon屬性下的name屬性
adventurer對象有weapon屬性 因此返回咱們能夠取出咱們的大師劍
而後是adventurer.savePrincess?.()
顯然adventurer下沒有savePrincess這個方法 因此救公主??? 不存在的 直接返回undefined
最後是adventurer.shield?.name
一樣的 咱們發現 adventurer對象下也沒有shield屬性 因此直接返回undefined
好啦 至此 咱們大概理解了可選鏈是怎麼一回事
接下來 咱們來看看 可選鏈有什麼須要注意的地方
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
複製代碼
當在表達式中使用可選鏈時,若是左操做數是 null 或 undefined,表達式將不會被計算,例如:
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // x 將不會被遞增,依舊輸出 0
複製代碼
最後再舉一個本身在實際開發中的例子
假若有一個方法setStudentResult(action)
它接收一個對象action
爲了讓咱們的代碼健壯 咱們必須在方法內部作出參數的非空校驗 顯然下面這樣是不行的
const list = {};
/** * @param {*} action */
function setStudent (action) {
list[action.index] = action.student;
}
複製代碼
若是咱們直接調用setStudent()
顯然整個程序都會崩潰
因此在之前 咱們能夠將方法體改爲這樣
// 同時包含函數接收了action參數 而且參數中有咱們須要的內容
function setStudent(action) {
if (action) {
if (action.index && action.student) {
list[action.index] = action.student;
}
}
}
複製代碼
可是 若是使用可選鏈操做符 咱們就能夠將方法定義成以下
function setStudent (action) {
if (action?.index && action?.student) {
list[action.index] = action.student;
}
}
複製代碼
能夠看到 不管是可讀性 仍是簡潔程度 可選鏈操做符都更勝一籌
仍是引用一段MDN上解釋
空值合併操做符(??)是一個邏輯操做符,當左側的操做數爲 null 或者 undefined 時,返回其右側操做數,不然返回左側操做數。
咱們知道 || 邏輯或運算符 也具備類似的功能
也就是在 || 左側操做數爲假值時 會返回右側 操做數
JS中的假值有
0
''
NaN
null
undefined
因此設想一個場景 咱們對一個function中的參數使用 || 運算符 來判斷用戶是否輸入
function addNum(a,b) {
var a = a || 0
var b = b || 0
return a + b
}
複製代碼
上述代碼咱們用 || 運算符來判斷用戶 用戶輸入的合法性
可是這樣咱們就沒法排除 0 這種狀況
若是用戶就是輸入了0 可是0依舊是一個假值 因此仍是會返回 || 操做符右側是操做數
這就與咱們的預期不一致了
而 ?? 空值合併操做符就只是檢驗了 null 和 undefined
與 OR 和 AND 邏輯操做符類似,當左表達式不爲 null 或 undefined 時,不會對右表達式進行求值
var a = 1;
undefined ?? a++;
console.log(a); // 1
var b = 1;
true ?? b++;
console.log(b); // 2
複製代碼
null || undefined ?? "foo"; // 拋出 SyntaxError
true || undefined ?? "foo"; // 拋出 SyntaxError
複製代碼
兩個操做符都是針對 undefined 和 null 兩個值
因此咱們能夠結合這兩個操做符
let customer = {
name: "chou",
details: { age: 100 }
};
let customerCity = customer?.city ?? "荒野之息";
console.log(customerCity); // 荒野之息
複製代碼