TIL 1
TIL 1
๐ Q1. ์ var ๋์ let๊ณผ const๋ฅผ ๊ถ์ฅํ ๊น?
- var๋ ํจ์ ์ค์ฝํ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋ธ๋ก ์์์ ์ ์ธํด๋ ์ ์ญ/ํจ์ ๋ฐ์์๋ ์ ์ฒด์ ์ํฅ์ ์ค ์ ์๋ค.
- ๋ํ var๋ ์ฌ์ ์ธ์ด ๊ฐ๋ฅํ๊ณ ํธ์ด์คํ ์ ์ด๊ธฐ์ undefined๋ก ํ ๋น๋์ด ์์ธกํ๊ธฐ ์ด๋ ค์ด ๋์์ ์ ๋ฐํ ์ ์๋ค.
- let๊ณผ const๋ ๋ธ๋ก์ค์ฝํ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋ธ๋ก ์์์ ์ฌ์ ์ธ ํ ์ ์๋ค.
- ํธ์ด์คํ
์ด ๋๋๋ผ๋ Temporal Dead Zone (TDZ)๋๋ฌธ์ ๋ธ๋ก ๋ฐ์์์ ์ ๊ทผํ ๊ฒฝ์ฐ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- ๋ณ์๊ฐ ํธ์ด์คํ ์ ๋์์ง๋ง, ์์ง ์ด๊ธฐํ๋๊ธฐ ์ ์ํ์ ์๋ ๊ตฌ๊ฐ์ TDZ๋ผ๊ณ ํฉ๋๋ค.
- ์ด ๊ตฌ๊ฐ์์๋ ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ค ํ๋ฉด ReferenceError๊ฐ ๋ฐ์ํ๋ค.
์ฝ๋ ์์
// var ์์: ๊ฐ์ ์ค์ฝํ์์ ์ฌ์ ์ธ ๊ฐ๋ฅ
var name = 'Alice';
var name = 'Bob';
console.log(name); // Bob
// let ์์: ๊ฐ์ ์ค์ฝํ์์ ์ฌ์ ์ธ ๋ถ๊ฐ
let age = 20;
// let age = 30; // SyntaxError: Identifier 'age' has already been declared
// var ํธ์ด์คํ
console.log(a); // undefined (ํธ์ด์คํ
๋จ)
var a = 10;
// let ํธ์ด์คํ
(TDZ)
console.log(b); // ReferenceError
let b = 20;let๊ณผ const ์ค์์๋ ์ด๋ค ๊ฒ์ ๊ธฐ๋ณธ์ผ๋ก ์ฐ๋๊ฒ ์ข์๊น?
- const๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. let์ ์ฌํ ๋น์ด ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๋ฉด ๋๊ณ const๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉํ๋ฉด ๊ฐ์ด ๋ณํ์ง๋ ์๋๋ค๋ ๊ฒ์ ์๋์ ์ผ๋ก ์ ๊ณตํ ์ ์์ด ํ์ ์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ์ข์์ง๋ค.
const๋ก ์ ์ธํ ๊ฐ์ฒด์ ๋ด๋ถ ํ๋กํผํฐ๋ฅผ ์์ ํ ์ ์๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
- const๋ ์ฐธ์กฐ๊ฐ ์ฆ ๋ฉ๋ชจ์ง ์ฃผ์๋ฅผ ๋ณ๊ฒฝํ์ง ๋ชปํ ๋ฟ ๊ฐ์ฒด ์์ฒด๋ฅผ ๋ถ๋ณ์ผ๋ก ๋ง๋๋ ๊ฒ์ ์๋๋ค.
- ์ํ ๊ด๋ฆฌ ์ ์ฐธ์กฐํ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ณ๊ฒฝํ์ง ์๋๋ก ์ฃผ์ํด์ผ ํ๊ณ , ํ์ํ๋ค๋ฉด Object.freeze๋ Immer.js ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํด ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ๊ธฐ๋ ํฉ๋๋ค.
Object.freeze
์ ์: ์๋ฐ์คํฌ๋ฆฝํธ์์ ๊ฐ์ฒด๋ฅผ ๋๊ฒฐ(freeze) ์์ผ ์์ ๋ถ๊ฐ๋ฅํ๊ฒ ๋ง๋๋ ๋ฉ์๋.
ํน์ง:
- ์์ฑ ์ถ๊ฐ โ
- ์์ฑ ์ญ์ โ
- ์์ฑ ๊ฐ ๋ณ๊ฒฝ โ
- ์์ฑ ์ฌ์ ์ โ
- ์์ ๋๊ฒฐ(shallow freeze)๋ง ์ง์ โ ์ค์ฒฉ ๊ฐ์ฒด๋ ์ฌ์ ํ ๋ณ๊ฒฝ ๊ฐ๋ฅ
const obj = { name: 'Alice', info: { age: 20 } };
Object.freeze(obj);
obj.name = 'Bob'; // โ ๋ฌด์๋จ
obj.info.age = 25; // โญ ๊ฐ๋ฅ (์์ freeze๋ผ์ ๋ด๋ถ ๊ฐ์ฒด๋ ๋ฐ๋)
console.log(obj); // { name: "Alice", info: { age: 25 } }Immer.js
์ ์: ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ถ๋ณ์ฑ(immutability)์ ๊ฐ๋จํ ์ ์งํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ.
๋์ ์๋ฆฌ:
- Immer๋ draft๋ผ๋ ํ๋ก์(proxy) ๊ฐ์ฒด๋ฅผ ์ ๊ณต
- draft๋ฅผ ์์ ๋กญ๊ฒ ๋ณ๊ฒฝํ๋ฉด, Immer๊ฐ ๋ด๋ถ์ ์ผ๋ก ๋ถ๋ณ ๊ฐ์ฒด๋ก ๋ณํํด์ค
- React + Redux ํ๊ฒฝ์์ ํนํ ๋ง์ด ์ฌ์ฉ๋ผ์.
import { produce } from 'immer';
const state = { todos: [{ text: '๊ณต๋ถํ๊ธฐ', done: false }] };
const nextState = produce(state, (draft) => {
draft.todos[0].done = true; // ๋ง์น ๊ฐ๋ณ์ฒ๋ผ ์์ฑ
});
console.log(state.todos[0].done); // false (์๋ณธ ์ ์ง)
console.log(nextState.todos[0].done); // true (์๋ก์ด ๋ถ๋ณ ๊ฐ์ฒด)๋ถ๋ณ์ฑ์ ์ ์ค์ํ ๊น?
๋ถ๋ณ์ฑ์ ๋ฐ์ดํฐ๊ฐ ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ์ ์ง๋๋๋ก ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์ ์ค์ํ๋ค.
๋ง์ฝ ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ๋ผ๋ฉด, ์ฌ๋ฌ ๊ณณ์์ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ๊ณต์ ํ ๋ ์๋์น ์๊ฒ ๊ฐ์ด ๋ฐ๋์ด์ ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, ๋ถ๋ณ์ฑ์ ์ ์งํ๋ฉด ์ถ์ ์ด ํจ์ผ ์ฌ์์ง๋ค.
ํนํ React ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ ์ํ ๋ณ๊ฒฝ์ ๊ฐ์งํ ๋ ์ฐธ์กฐ ๋น๊ต(shallow compare) ๋ฅผ ์ฌ์ฉํ๋ค. ๊ฐ์ฒด๊ฐ ๋ถ๋ณ์ด๋ฉด === ๋น๊ต๋ง์ผ๋ก๋ ์ํ๊ฐ ๋ฐ๋์๋์ง ์ฝ๊ฒ ์ ์ ์์ด, ๋ ๋๋ง ์ฑ๋ฅ ์ต์ ํ์๋ ํฐ ๋์์ด ๋๋ค.
์ฌ์ด๋ ์ดํํธ: ํ๋ก๊ทธ๋๋ฐ์์ ์ด๋ค ํจ์๋ ์ฝ๋๊ฐ ์๊ธฐ ์์ญ ๋ฐ๊นฅ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋, ์ธ๋ถ ํ๊ฒฝ์ ์ํฅ์ ์ฃผ๋๊ฑธ ๋งํ๋ค.
๐ Q2. == vs ===
==
-
๋ ๊ฐ์ ๋น๊ตํ ๋, ํ์ ์ด ๋ค๋ฅด๋ฉด ๊ฐ์ ํ๋ณํ์ ํ๊ณ ๋น๊ตํ๋ค.
-
์์:
1 == '1'; // true (๋ฌธ์์ด "1" โ ์ซ์ 1๋ก ๋ณํ ํ ๋น๊ต) 0 == false; // true (false โ 0์ผ๋ก ๋ณํ) null == undefined; // true (ํน๋ณ ๊ท์น)
===
-
๊ฐ๋ฟ ์๋๋ผ ํ์ ๊น์ง ๋์ผํด์ผ true๋ฅผ ๋ฐํํ๋ค.
-
์์:
1 === '1'; // false (์ซ์ vs ๋ฌธ์์ด) 0 === false; // false (์ซ์ vs ๋ถ๋ฆฌ์ธ) null === undefined; // false (ํ์ ๋ค๋ฆ)