ๆญค้ ้ข็”ฑ็คพ็พคๅพž่‹ฑๆ–‡็ฟป่ญฏ่€Œไพ†ใ€‚ไบ†่งฃๆ›ดๅคšไธฆๅŠ ๅ…ฅ MDN Web Docs ็คพ็พคใ€‚

View in English Always switch to English

ๅฏ้ธไธฒ้€ฃ

Baseline Widely available

This feature is well established and works across many devices and browser versions. Itโ€™s been available across browsers since โจ2020ๅนด7ๆœˆโฉ.

ๅฏ้ธไธฒ้€ฃ้‹็ฎ—ๅญ ?. ๅ…่จฑ้€ฒ่กŒๆทฑๅฑคๆฌก็š„็‰ฉไปถๅ€ผๅญ˜ๅ–๏ผŒ่€Œ็„ก้œ€้€้Žๆ˜Ž็ขบ็š„็‰ฉไปถๅ€ผไธฒ้€ฃ้ฉ—่ญ‰ใ€‚?. ้‹็ฎ—ๅญ็š„ๆ“ไฝœ่ˆ‡ . ๅฑฌๆ€งๅญ˜ๅ–้‹็ฎ—ๅญ็›ธไผผ๏ผŒๅพŒ่€…ๆœƒๅœจๅƒ็…งๅˆฐ nullish (null or undefined) ็š„ๅ€ผๆ™‚ๅ‡บ็พ้Œฏ่ชค๏ผŒ่€Œๅ‰่€…ๅฏ้ธไธฒ้€ฃๅ‰‡ๅ›žๅ‚ณ undefined ใ€‚ ็•ถ้œ€่ฆๅญ˜ๅ–ไธ€ๅ€‹ๅ‡ฝๆ•ธ๏ผŒ่€Œ้€™ๅ‡ฝๆ•ธไธฆไธๅญ˜ๅœจๆ™‚๏ผŒๅ‰‡ๆœƒๅ›žๅ‚ณ 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?.prop
obj?.[expr]
arr?.[index]
func?.(args)

ๆ่ฟฐ

็•ถไธฒ้€ฃ็‰ฉไปถ่ฃก้ข็š„ๅƒ็…งๆˆ–ๆ–นๆณ•ๅฏ่ƒฝๆ˜ฏundefined ๆˆ– null ๆ™‚๏ผŒๅฏ้ธไธฒ้€ฃ้‹็ฎ—ๅญๆไพ›็ฐกๅ–ฎ็š„ๆ–นๆณ•ๅŽปๅญ˜ๅ–้€™ไบ›ไธฒ้€ฃ็‰ฉไปถไธ‹็š„ๅ€ผใ€‚

่ˆ‰ไพ‹ไพ†่ชช๏ผŒ็•ถไธ€ๅ€‹็‰ฉไปถ obj ๆ˜ฏๅทข็‹€็ตๆง‹ๆ™‚๏ผŒๅœจๆฒ’ๆœ‰ๅฏ้ธไธฒ้€ฃไน‹ไธ‹๏ผŒ่ฆๅŽปๆŸฅๆ‰พไธ€ๆทฑๅฑค็š„ๅฑฌๆ€งๅ€ผ้œ€่ฆ้ฉ—่ญ‰ๆฏๅฑค้–“็š„ๅƒ็…ง้€ฃ็ต๏ผš

js
let nestedProp = obj.first && obj.first.second;

obj.first ็š„ๅ€ผ้œ€่ฆๅ…ˆ็ขบๅฎšไธๆ˜ฏ null ๅ€ผ๏ผˆๅ’Œไธฆ้ž undefined ๏ผ‰๏ผŒๆ‰่ƒฝๅญ˜ๅ– obj.first.second ็š„ๅ€ผใ€‚้€™ๆ‰่ƒฝ้ฟๅ…ๅœจๅญ˜ๅ–ๅ€ผๆ™‚๏ผŒๅ› ็‚บ็›ดๆŽฅไฝฟ็”จ obj.first.second ่€Œๆฒ’ๆœ‰ๆธฌ่ฉฆ obj.first ไน‹ไธ‹ๅธถไพ†็š„้Œฏ่ชคใ€‚

็•ถไฝฟ็”จไบ†ๅฏ้ธไธฒ้€ฃ้‹็ฎ—ๅญ๏ผˆ?.๏ผ‰๏ผŒไฝ ไธๅ†้œ€่ฆๆ˜Ž็ขบๅœฐ้€ฒ่กŒๆธฌๆธฌ๏ผŒไธฆ่ƒฝๅœจๅŸบๆ–ผ obj.first ็š„็‹€ๆ…‹ไธ‹็›ดๆŽฅๅ›žๅ‚ณ๏ผŒๅฟฝ็•ฅๅญ˜ๅ– obj.first.second ็š„ๅ‹•ไฝœ๏ผš

js
let nestedProp = obj.first?.second;

ๅพžๅชๆ˜ฏ . ๆ”น็”จไฝœ ?. ้‹็ฎ—ๅญ๏ผŒJavaScript ๆœƒ็Ÿฅ้“ๅœจๅญ˜ๅ– obj.first.second ไน‹ๅ‰๏ผŒ้œ€่ฆ้–“ๆŽฅๅœฐๆชขๆŸฅไธฆ็ขบไฟ obj.first ไธฆไธๆ˜ฏ null ๆˆ– undefined ใ€‚็•ถ obj.first ๆ˜ฏ null ๆˆ– undefined ๏ผŒ้‹็ฎ—ๅผๆœƒๅƒ็Ÿญ่ทฏไธ€ๆจฃ่ทณ้Žๆ•ดๅ€‹ไธฒ้€ฃๅญ˜ๅ–ๅผ๏ผŒ่€Œๅ›žๅ‚ณ undefined ใ€‚

้€™ๆ˜ฏ่ทŸไปฅไธ‹ๆ˜ฏ็›ธ็ญ‰ๅŒ็š„๏ผŒไฝ†ๆ˜ฏๅฏฆ้š›ไธŠๆ˜ฏไธๆœƒๅปบ็ซ‹่‡จๆ™‚่ฎŠๆ•ธ๏ผš

js
let temp = obj.first;
let nestedProp = temp === null || temp === undefined ? undefined : temp.second;

ๅฏ้ธไธฒ้€ฃๅ‘ผๅซๅ‡ฝๆ•ธ

ไฝ ๅฏไปฅไฝฟ็”จๅฏ้ธไธฒ้€ฃไพ†ๅ˜—่ฉฆๅ‘ผๅซไธ€ๅ€‹ๆˆ–่จฑๆฒ’ๆœ‰ๅญ˜ๅœจ็š„ๆ–นๆณ•ใ€‚้€™ๅฏ่ƒฝๆœ‰ๅŠฉๆ–ผ๏ผŒ่ˆ‰ไพ‹ไพ†่ชช๏ผŒไฝฟ็”จไธ€ไบ›ๆœช่ƒฝๆไพ›ๆœๅ‹™็š„ API ๏ผŒ้€™ๅฏ่ƒฝๅ› ็‚บ้Žๆ™‚็š„ๆ‡‰็”จๆˆ–ๆ˜ฏไฝฟ็”จ่€…็š„่ฃ็ฝฎๆœช่ƒฝๆ”ฏๆดๆŸ็จฎๅŠŸ่ƒฝใ€‚

็•ถ้œ€่ฆไฝฟ็”จ็š„ๆ–นๆณ•ไธฆไธๅญ˜ๅœจๆ™‚๏ผŒ้€้Žๅฏ้ธไธฒ้€ฃๅŽป้€ฒ่กŒๅ‘ผๅซๅฐ‡ไธๆœƒๆŠ›ๅ‡บ้Œฏ่ชค๏ผŒๅ–่€Œไปฃไน‹็š„ๆ˜ฏๅ›žๅ‚ณ undefined ๏ผš

js
let result = someInterface.customMethod?.();

ๅ‚™่จป๏ผš ๅ‡ๅฆ‚็‰ฉไปถๆœ‰ๅŒๆจฃ็š„ๅฑฌๆ€งๅ็จฑ๏ผŒ่€Œไธๆ˜ฏไธ€ๅ€‹ๆ–นๆณ•๏ผŒไฝฟ็”จ ?. ๅฐ‡ๆœƒๆŠ›ๅ‡บ TypeError ้Œฏ่ชค๏ผˆx.y ไธๆ˜ฏไธ€ๅ€‹ๅ‡ฝๆ•ธ๏ผ‰ใ€‚

่™•็†ๅ›žๅ‘ผๅ‡ฝๅผๆˆ–ไบ‹ไปถ่™•็†ๅ™จ

ๅฆ‚ๆžœไฝ ไฝฟ็”จๅ›žๅ‘ผๅ‡ฝๅผ๏ผŒๆˆ–ๆ˜ฏ้€้Ž่งฃๆง‹ไพ†ๆ“ทๅ–็‰ฉไปถไธญ็š„ๆ–นๆณ•๏ผŒไฝ ๅฏ่ƒฝๆœƒๅ› ็‚บ้€™ไบ›ๆ–นๆณ•ๆฒ’ๆœ‰ๅญ˜ๅœจ๏ผŒ่€Œ็„กๆณ•้€ฒ่กŒๅ‘ผๅซ๏ผŒ้™ค้žไฝ ไบ‹ๅ…ˆ้ฉ—่ญ‰ๅ…ถๅญ˜ๅœจๆ€งใ€‚ๆ‰€ไปฅ๏ผŒไฝ ๅฏไปฅๅˆฉ็”จ ?. ไพ†้ฟๅ…้€™ๆจฃ็š„ๆธฌ่ฉฆ๏ผš

js
// ๅœจ ES2019 ไธ‹ๆ’ฐๅฏซ
function doSomething(onContent, onError) {
  try {
    // ... ๅฐ่ณ‡ๆ–™้€ฒ่กŒไธ€ไบ›่™•็†
  } catch (err) {
    if (onError) {
      // ๆธฌ่ฉฆ onError ๆ˜ฏๅฆ็œŸ็š„ๅญ˜ๅœจ
      onError(err.message);
    }
  }
}
js
// ไฝฟ็”จๅฏ้ธไธฒ้€ฃ้€ฒ่กŒๅ‡ฝๅผๅ‘ผๅซ
function doSomething(onContent, onError) {
  try {
    // ... ๅฐ่ณ‡ๆ–™้€ฒ่กŒไธ€ไบ›่™•็†
  } catch (err) {
    onError?.(err.message); // ๅฐฑ็ฎ— onError ๆ˜ฏ undefined ไนŸไธๆœƒๆŠ›ๅ‡บ้Œฏ่ชค
  }
}

ๅฏ้ธไธฒ้€ฃ่กจ่ฟฐๅผ

ไฝ ไนŸๅฏไปฅๅœจๆ–นๆ‹ฌ่™Ÿๅฑฌๆ€งๅญ˜ๅ–่กจ้”ๅผไธญไฝฟ็”จๅฏ้ธไธฒ้€ฃ๏ผš

js
let nestedProp = obj?.["prop" + "Name"];

็Ÿฉ้™ฃ้ …็›ฎ็š„ๅฏ้ธไธฒ้€ฃ

js
let arrayItem = arr?.[42];

็ฏ„ไพ‹

ๅŸบๆœฌ็ฏ„ไพ‹

้€™ๅ€‹็ฏ„ไพ‹ๆœƒๆ‰พๅ‡บ Map ็‰ฉไปถไธญไธ€ๅ€‹้ต็‚บ bar ๆˆๅ“ก็š„ name ๅฑฌๆ€งๅ€ผ๏ผŒไฝ†ไบ‹ๅฏฆไธŠไธฆๆฒ’ๆœ‰็›ธ้—œๆˆๅ“กใ€‚ๆ‰€ไปฅ็ตๆžœ็‚บ undefined ใ€‚

js
let myMap = new Map();
myMap.set("foo", { name: "baz", desc: "inga" });

let nameBar = myMap.get("bar")?.name;

็Ÿญ่ทฏๅผ้‹็ฎ—

็•ถๅฏ้ธไธฒ้€ฃๆŽฅไธŠ่กจ่ฟฐๅผๆ™‚๏ผŒๅฆ‚ๆžœๅทฆ้‚Š็š„้‹็ฎ—ๆ•ธๅ€ผๆ˜ฏ null ๆˆ– undefined ๏ผŒ่กจ่ฟฐๅผๅ‰‡ไธๆœƒ่ขซ้‹็ฎ—ใ€‚่ˆ‰ไพ‹ไพ†่ชช๏ผš

js
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];

console.log(x); // ๅ› ็‚บ x ๆฒ’ๆœ‰้žๅขž๏ผŒๆ‰€ไปฅ็‚บ 0

ไธฒๆŽฅๅคšๅ€‹ๅฏ้ธไธฒ้€ฃ

ๅœจๅทข็‹€็ตๆง‹ไธญๅฏไปฅไฝฟ็”จๅคšๆฌก็š„ๅฏ้ธไธฒ้€ฃ๏ผš

js
let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls", // ่ฉณ็ดฐๅœฐๅ€ address ไธฆไธ็Ÿฅ้“
  },
};
let customerCity = customer.details?.address?.city;

// โ€ฆ ๅŒๆจฃๅœฐ๏ผŒไธฒๆŽฅๅคšๅ€‹ๅฏ้ธไธฒ้€ฃไพ†ๅ‘ผๅซๅ‡ฝๅผไนŸๆ˜ฏๆนŠๆ•ˆ็š„
let duration = vacations.trip?.getTime?.();

ไฝฟ็”จ็ฉบๅ€ผๅˆไฝต้‹็ฎ—ๅญ

ๅœจๅฏ้ธไธฒ้€ฃๅพŒๅฏไปฅไฝฟ็”จ็ฉบๅ€ผๅˆไฝต้‹็ฎ—ๅญไพ†็ทจ้…้ ่จญๅ€ผ๏ผŒๅฆ‚ๆžœ็„กๆณ•ๅœจๅฑฌๆ€งไธฒ้€ฃไธญๅ–ๅพ—ๅ€ผ๏ผš

js
let customer = {
  name: "Carl",
  details: { age: 82 },
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city

่ฆ็ฏ„

Specification
ECMAScriptยฎ 2026 Language Specification
# prod-OptionalExpression

็€่ฆฝๅ™จ็›ธๅฎนๆ€ง

ๅƒ่ฆ‹