Baseline Widely available
å¯éé¾è¿ç®ç¬¦ï¼?.
ï¼ ç¨äºè®¿é®å¯¹è±¡ç屿§æè°ç¨å½æ°ãå¦æä½¿ç¨æ¤è¿ç®ç¬¦è®¿é®ç对象æè°ç¨ç彿°æ¯ undefined
æ null
ï¼å表达å¼ä¼ç路并计ç®ä¸º undefined
ï¼è䏿¯æåºé误ã
const adventurer = {
name: "Alice",
cat: {
name: "Dinah",
},
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// Expected output: undefined
console.log(adventurer.someNonExistentMethod?.());
// Expected output: undefined
è¯æ³
obj.val?.prop
obj.val?.[expr]
obj.func?.(args)
æè¿°
?.
è¿ç®ç¬¦ä¸ .
é¾å¼è¿ç®ç¬¦ç¸ä¼¼ï¼ä¸åä¹å¤å¨äºï¼å¦æå¼ç¨æ¯ç©ºå¼ï¼null
æ undefined
ï¼ï¼å®ä¸ä¼å¯¼è´é误ï¼èæ¯ä½¿è¡¨è¾¾å¼ç路并è¿å undefined
ãå½ç¨äºå½æ°è°ç¨æ¶ï¼å¦æç»å®å½æ°ä¸åå¨ï¼å®ä¹ä¼è¿å undefined
ã
å½è®¿é®é¾å¼å±æ§æ¶ï¼å¦æåå¨å¼ç¨å¯è½ç¼ºå¤±çæ åµï¼è¿å°ä½¿è¡¨è¾¾å¼æ´ç®æ´ãæ´ç®çã卿¢ç´¢å¯¹è±¡å 容䏿 æ³ç¡®å®åªäºå±æ§æ¯å¿ éçæ¶ï¼å®ä¹ä¼å¾æå¸®å©ã
ä¾å¦ï¼èèä¸ä¸ªå
·æåµå¥ç»æç对象 obj
ãå¦ææ²¡æå¯éé¾ï¼æ¥æ¾æ·±å±åµå¥çå屿§éè¦éªè¯ä¸é´çå¼ç¨ï¼ä¾å¦ï¼
const nestedProp = obj.first && obj.first.second;
å¨è®¿é® obj.first.second
ä¹åï¼è¦ä¿è¯ obj.first
çå¼ä¸æ¯ null
ï¼ä¹ä¸æ¯ undefined
ï¼ãè¿æ ·åå¯ä»¥é¿å
å¨ä¸å¯¹ obj.first
è¿è¡æ ¡éªæ
åµä¸ç´æ¥è®¿é® obj.first.second
èå¯è½å¼åçé误ã
è¿æ¯ JavaScript ä¸çä¸ä¸ªæ¯ç¨æ¨¡å¼ï¼ä½å½é¾å¾é¿æ¶ï¼å®ä¼åå¾åé¿ï¼ä¸ä¸å®å
¨ãä¾å¦ï¼å¦æ obj.first
æ¯ä¸ä¸ªé null
æ undefined
çåå¼ï¼æ¯å¦ 0
ï¼å®ä»ç¶ä¼ç路并使 nestedProp
å为 0
ï¼è¿å¯è½æ¯ä¸å¯åçã
ç¶èï¼ä½¿ç¨å¯éé¾è¿ç®ç¬¦ï¼?.
ï¼ï¼å¨è®¿é® obj.first.second
ä¹åï¼ä¸åéè¦åºäº obj.first
çç¶æè¿è¡æç¡®çæµè¯åçè·¯æä½äºï¼
const nestedProp = obj.first?.second;
éè¿ä½¿ç¨ ?.
è¿ç®ç¬¦å代 .
è¿ç®ç¬¦ï¼JavaScript ä¼å¨å°è¯è®¿é® obj.first.second
ä¹åï¼å
éå¼å°æ£æ¥å¹¶ç¡®å® obj.first
æ¢ä¸æ¯ null
ä¹ä¸æ¯ undefined
ã妿 obj.first
æ¯ null
æè
undefined
ï¼è¡¨è¾¾å¼å°ä¼èªå¨çè·¯ï¼å¹¶è¿å undefined
ã
è¿çä»·äºä»¥ä¸è¡¨è¾¾å¼ï¼ä½å®é 䏿²¡æå建临æ¶åéï¼
const temp = obj.first;
const nestedProp =
temp === null || temp === undefined ? undefined : temp.second;
å¯éé¾è¿ç®ç¬¦ä¸è½ç¨äºæªå£°æçæ ¹å¯¹è±¡ï¼ä½å¯ä»¥ç¨äºå¼ä¸º undefined
çæ ¹å¯¹è±¡ã
undeclaredVar?.prop; // ReferenceError: undeclaredVar is not defined
彿°è°ç¨ä¸çå¯éé¾
å½å°è¯è°ç¨ä¸ä¸ªå¯è½ä¸åå¨çæ¹æ³æ¶ä¹å¯ä»¥ä½¿ç¨å¯éé¾ãä¾å¦ï¼å½ä½¿ç¨æä¸ª API æ¶ï¼å¦æç±äºå®ç°çæ¬è¿æ§æç¨æ·è®¾å¤ä¸å ·å¤æé¡¹åè½èå¯¼è´æä¸ªæ¹æ³ä¸å¯ç¨æ¶ï¼å¯éé¾å°±å¾æç¨ã
彿°è°ç¨æ¶å¦æè¢«è°ç¨çæ¹æ³ä¸åå¨ï¼ä½¿ç¨å¯éé¾å¯ä»¥ä½¿è¡¨è¾¾å¼èªå¨è¿å undefined
è䏿¯æåºä¸ä¸ªå¼å¸¸ã
const result = someInterface.customMethod?.();
ç¶èï¼å¦æåå¨ä¸ä¸ªå
·æè¿æ ·åç§°ç屿§ä¸ä¸æ¯å½æ°ï¼ä½¿ç¨ ?.
ä»ç¶ä¼å¼åä¸ä¸ª TypeError
å¼å¸¸ï¼å³âsomeInterface.customMethod
is not a functionï¼ä¸æ¯ä¸ä¸ªå½æ°ï¼âã
夿³¨ï¼ 妿 someInterface
èªèº«æ¯ null
æè
undefined
ï¼TypeError
å¼å¸¸ä»ä¼è¢«æåºï¼someInterface is null
ï¼ãå¦æä½ å¸æå
许 someInterface
èªèº«ä¹ä¸º null
æè
undefined
ï¼ä½ éè¦å¨è¿ä¸ªä½ç½®ä½¿ç¨ ?.
ï¼someInterface?.customMethod?.()
ã
eval?.()
æ¯è¿å
¥é´æ¥æ±å¼æ¨¡å¼çæçæ¹å¼ã
ä½ ä¹å¯ä»¥å°å¯éé¾è¿ç®ç¬¦ä¸æ¹æ¬å·è¡¨ç¤ºæ³ç»å使ç¨ï¼å®å 许å°è¡¨è¾¾å¼ä½ä¸ºå±æ§åä¼ éï¼
const nestedProp = obj?.["prop" + "Name"];
è¿å¯¹äºæ°ç»å°¤å ¶æç¨ï¼å 为æ°ç»ç´¢å¼å¿ é¡»ä½¿ç¨æ¹æ¬å·æ¥ä½¿ç¨ã
function printMagicIndex(arr) {
console.log(arr?.[42]);
}
printMagicIndex([0, 1, 2, 3, 4, 5]); // undefined
printMagicIndex(); // undefinedï¼å¦ææªä½¿ç¨ ?. è¿ç®ç¬¦ï¼è¿å°æåºä¸ä¸ªé误ï¼âCannot read properties of undefined (reading '42')â
æ æçå¯éé¾
å°è¯ä¸ºå¯éé¾è¡¨è¾¾å¼çç»æèµå¼æ¯æ æçï¼
const object = {};
object?.property = 1; // SyntaxError: Invalid left-hand side in assignment
模æ¿å符串æ ç¾ä¸è½æ¯å¯éé¾ï¼åè§ SyntaxError: tagged template cannot be used with optional chainï¼ï¼
String?.raw`Hello, world!`;
String.raw?.`Hello, world!`; // SyntaxError: Invalid tagged template on optional chain
new
表达å¼çæé 彿°ä¸è½æ¯å¯éé¾ï¼åè§ SyntaxError: new keyword cannot be used with an optional chainï¼ï¼
new Intl?.DateTimeFormat(); // SyntaxError: Invalid optional chain from new expression
new Map?.();
çè·¯
å¨ä½¿ç¨å¯é龿¶ï¼å¦æå·¦æä½æ°æ¯ null
æ undefined
ï¼å表达å¼å°ä¸ä¼è¢«æ±å¼ãä¾å¦ï¼
const potentiallyNullObj = null;
let x = 0;
const prop = potentiallyNullObj?.[x++];
console.log(x); // x æªè¢«éå¢ï¼å æ¤ä¸º 0
åç»ç屿§è®¿é®ä¹ä¸ä¼è¢«æ±å¼ã
const potentiallyNullObj = null;
const prop = potentiallyNullObj?.a.b;
// è¿ä¸ä¼æåºé误ï¼å 为æ±å¼å·²ç»å¨ç¬¬ä¸ä¸ªå¯éé¾å¤åæ¢äº
è¿çä»·äºï¼
const potentiallyNullObj = null;
const prop =
potentiallyNullObj === null || potentiallyNullObj === undefined
? undefined
: potentiallyNullObj.a.b;
ç¶èï¼è¿ç§çè·¯è¡ä¸ºåªä¼å¨ä¸ä¸ªè¿ç»ç屿§è®¿é®âé¾âä¸åçãå¦æä½ å°é¾ä¸çæä¸é¨åè¿è¡åç»ï¼é£ä¹åç»ç屿§è®¿é®ä»ç¶ä¼è¢«æ±å¼ã
const potentiallyNullObj = null;
const prop = (potentiallyNullObj?.a).b;
// TypeError: Cannot read properties of undefined (reading 'b')
è¿çä»·äºï¼
const potentiallyNullObj = null;
const temp = potentiallyNullObj?.a;
const prop = temp.b;
é¤äºæ²¡æå建 temp
åéã
æ¤ç¤ºä¾å¨ä¸ä¸ªä¸å« bar
æåç Map 䏿¥æ¾ bar
æåç name
屿§ï¼å æ¤ç»ææ¯ undefined
ã
const myMap = new Map();
myMap.set("foo", { name: "baz", desc: "inga" });
const nameBar = myMap.get("bar")?.name;
å¤çå¯éçåè°å½æ°æäºä»¶å¤çå¨
å¦æä½¿ç¨è§£ææ¥è§£æçä¸ä¸ªå¯¹è±¡çåè°å½æ°æ fetch æ¹æ³ï¼ä½ å¯è½å¾å°ä¸è½å½å彿°ç´æ¥è°ç¨çä¸åå¨çå¼ï¼é¤éä½ å·²ç»æ ¡éªäºå®ä»¬çå卿§ãä½ å¯ä»¥ä½¿ç¨ ?.
æ¥å¿½ç¥è¿äºé¢å¤çæ ¡éªï¼
// ä¸ä½¿ç¨å¯éé¾çåæ³
function doSomething(onContent, onError) {
try {
// ç¨æ°æ®åäºäºæ
} catch (err) {
// æ ¡éª onError æ¯å¦ççåå¨
if (onError) {
onError(err.message);
}
}
}
// 使ç¨å¯éé¾è¿è¡å½æ°è°ç¨
function doSomething(onContent, onError) {
try {
// ç¨æ°æ®åäºäºæ
} catch (err) {
onError?.(err.message); // 妿 onError æ¯ undefined ä¹ä¸ä¼æå¼å¸¸
}
}
è¿ç¨å¯éé¾è¿ç®ç¬¦
å¨åµå¥ç»æä¸ï¼å¯ä»¥å¤æ¬¡ä½¿ç¨å¯éé¾ï¼
const customer = {
name: "Carl",
details: {
age: 82,
location: "Paradise Falls", // details ç address 屿§æªæå®ä¹
},
};
const customerCity = customer.details?.address?.city;
// å¯éé¾ä¹å¯ä»¥å彿°è°ç¨ä¸èµ·ä½¿ç¨
const customerName = customer.name?.getName?.(); // æ¹æ³ä¸åå¨ï¼customerName æªå®ä¹
使ç¨ç©ºå¼åå¹¶è¿ç®ç¬¦
彿ªæ¾å°ä»»ä½å¼æ¶ï¼å¯ä»¥å¨å¯éé¾ä¹å使ç¨ç©ºå¼åå¹¶è¿ç®ç¬¦æ¥æå»ºä¸ä¸ªé»è®¤å¼ï¼
function printCustomerCity(customer) {
const customerCity = customer?.city ?? "æªç¥åå¸";
console.log(customerCity);
}
printCustomerCity({
name: "Nathan",
city: "Paris",
}); // "Paris"
printCustomerCity({
name: "Carl",
details: { age: 82 },
}); // "æªç¥åå¸"
è§è æµè§å¨å
¼å®¹æ§ åè§
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4