๋ฐ˜์‘ํ˜•

์˜ต์…”๋„ ์ฒด์ด๋‹ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ


๋น„๊ต์  ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์œผ๋กœ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋Š” ์ค‘์ฒฉ ๊ฐ์ฒด๋ฅผ ์—๋Ÿฌ์—†์ด ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์œ ์ € ์ •๋ณด๋ฅผ ๋‹ด์•„๋‘๋Š” user ๊ฐ์ฒด์— ์•„๋ฌด๋Ÿฐ ์ •๋ณด๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ address ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

const user = {};
console.log(user.address.street);
// TypeError: Cannot read property 'street' of undefined

 

React๋‚˜ Vue์˜ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ธ ๋•Œ ์•„์ง ์Šคํ† ์–ด์— ์žˆ๋Š” ์ •๋ณด๋ฅผ ๋‹ค ๋ถˆ๋Ÿฌ์˜ค์ง€ ์•Š์€ ์‹œ์ ์—์„œ ๊ฐ์ฒด์˜ ์†์„ฑ์— ์ ‘๊ทผํ•  ๋•Œ๋„ ๋น„์Šทํ•œ ํƒ€์ž…์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

// selectedMall์€ ์Šคํ† ์–ด์—์„œ ๋ถˆ๋Ÿฌ์˜ฌ ์ •๋ณด
// ์•„์ง ์Šคํ† ์–ด์—์„œ selectedMall ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋ผ๋ฉด
// ์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ์‹œ์ ์—์„  ํƒ€์ž…์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค
watch(
  () => selectedMall.value,
  (newValue, oldValue) => {
    if (oldValue.id === newValue.id) {
      return updateInboxState();
    }
    if (newValue.id) {
      updateInboxState();
    }
  },
);

 

์ค‘์ฒฉ ๊ฐ์ฒด์˜ ํŠน์ • ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ๋•Œ ๊ฑฐ์น˜๋Š” ์†์„ฑ๋“ค์„ AND ์—ฐ์‚ฐ์ž๋ฅผ ํ™œ์šฉํ•ด ์‹ค์ œ ํ•ด๋‹น ๊ฐ์ฒด๋‚˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ํƒ€์ž…์—๋Ÿฌ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฐ™์€ ๋ฐฉ์‹์€ ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์ง€๋Š” ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.

const user = {};
console.log(user && user.address && user.address.street);

 

์˜ต์…”๋„ ์ฒด์ด๋‹ ์‚ฌ์šฉ๋ฒ•


๐Ÿ’ก ๊ตฌํ˜• ๋ธŒ๋ผ์šฐ์ €์—์„  ํด๋ฆฌํ•„ ํ•„์š”

 

์˜ต์…”๋„ ์ฒด์ด๋‹์€ ์†์„ฑ์„ ๋ช…์‹œํ•˜๋Š” ์˜จ์  ์•ž์— ๋ฌผ์Œํ‘œ๋ฅผ ?. ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ํ‰๊ฐ€ ๋Œ€์ƒ์ด undefined๊ฑฐ๋‚˜ null์ด๋ฉด ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถ”๊ณ  undefined๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฆ‰ ์ ‘๊ทผํ•˜๋Š” ๊ฐ์ฒด๋‚˜ ๊ฐ์ฒด์˜ ์†์„ฑ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด undefined๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

const user = {};
console.log(user?.address?.street); // undefined
const user = null;
console.log(user?.address); // undefined

 

๋‹จ๋ฝ ํ‰๊ฐ€

?. ์™ผ์ชฝ ํ‰๊ฐ€ ๋Œ€์ƒ์— ๊ฐ’์ด ์—†์œผ๋ฉด ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถ˜๋‹ค. ์ด๋Ÿฐ ํ‰๊ฐ€ ๋ฐฉ์‹์„ ๋‹จ๋ฝ ํ‰๊ฐ€(short-circuit)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์™ผ์ชฝ ?.์˜ ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ท„๋‹ค๋ฉด ?. ์šฐ์ธก์— ์žˆ๋Š” ๋ถ€๊ฐ€๋™์ž‘๋„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.

const user = null;
let x = 0;

user?.sayHi(x++); // ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค
console.log(x); // 0
// user?.๊ฐ€ null์ด์–ด์„œ ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถฒ๊ธฐ ๋•Œ๋ฌธ์—
// ?. ์šฐ์ธก์— ์žˆ๋Š” ๋ถ€๊ฐ€๋™์ž‘์€ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค

 

?.() ?.[]

โถ ๋ฉ”์„œ๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ

`?.` ์€ ์—ฐ์‚ฐ์ž๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋‚˜ ๋Œ€๊ด„ํ˜ธ์™€ ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋Š” Syntax Construct๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์—์„œ `user` ๊ฐ์ฒด๋Š” ๋ชจ๋‘ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— `admin` ์†์„ฑ์—๋งŒ `?.` ์„ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผํ–ˆ๋‹ค.

const user1 = {
  admin() {
    console.log('๊ด€๋ฆฌ์ž ๊ณ„์ •');
  },
};

const user2 = {};

user1.admin?.(); // ๊ด€๋ฆฌ์ž ๊ณ„์ •
user2.admin?.(); // undefined

 

`user1` ๊ฐ์ฒด์—” `admin` ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ •์ƒ์ ์œผ๋กœ ํ˜ธ์ถœ๋๋‹ค. `user2` ๊ฐ์ฒด์—” `admin`์ด ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ํ˜ธ์ถœํ–ˆ์ง€๋งŒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถ”๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

โท `[]` ๋Œ€๊ด„ํ˜ธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
`?.[]` ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ž‘๋™ ๋ฐฉ์‹์€ ๋™์ผํ•˜๋‹ค. 

const user1 = { firstName: "John" };
const user2 = null;
const key = "firstName";

console.log(user1?.[key]); // John
console.log(user2?.[key]); // undefined

 

โธ `delete` ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ

delete user?.name; // user ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋ฉด user.name ์‚ญ์ œ

 

์ฃผ์˜ ์‚ฌํ•ญ

โถ ์˜ต์…”๋„ ์ฒด์ด๋‹์˜ `?.`์€ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ๊ดœ์ฐฎ์€ ๋Œ€์ƒ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹๋‹ค(๋””๋ฒ„๊น…์„ ์œ„ํ•ด). ์œ„ ์˜ˆ์‹œ์—์„œ ์‚ฌ์šฉ์ž ์ฃผ์†Œ๋ฅผ ๋‹ค๋ฃจ๋Š” `user`๋Š” ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ `address` ์†์„ฑ์€ ํ•„์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๋ฐ”๋žŒ์งํ•˜๋‹ค.

user.address?.street

 

โท ๊ฐ€์žฅ ์•ž์˜ `?.` ๋ฌผ์Œํ‘œ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ณ€์ˆ˜๋Š” ๊ผญ ์„ ์–ธ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ `user` ๊ฐ์ฒด๊ฐ€ `let` `const` ๋“ฑ์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ํ‰๊ฐ€์‹œ ์•„๋ž˜์ฒ˜๋Ÿผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

console.log(user?.address);
// ReferenceError: user is not defined

 

โธ `?.` ์€ ์ฝ๊ธฐ๋‚˜ ์‚ญ์ œ์—” ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์“ฐ๊ธฐ์—” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ๋•Œ๋ฌธ์— ์•„๋ž˜์ฒ˜๋Ÿผ ํ• ๋‹น ์—ฐ์‚ฐ์ž ์™ผ์ชฝ์—์„  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ `user`๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ `user.name`์— ์ƒˆ๋กœ์šด ๊ฐ’์„ ํ• ๋‹นํ•˜๋ ค๋Š” ์˜๋„๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

user?.name = 'John'; // SyntaxError: Invalid left-hand side in assignment
// ์œ„ ์—๋Ÿฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ undefined = "John"๋กœ ํ•ด์„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ๋‹ค

 

์ฐธ๊ณ 


 

์˜ต์…”๋„ ์ฒด์ด๋‹ '?.'

 

ko.javascript.info

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•