Single Quotes ์ฌ์ฉ: (๐คท)
์ผ๋ฐ์ ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์์๋ ์ฑ๊ธ ์ฟผํธ(')๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค. ๋๋ธ ์ฟผํธ(")๋ ์ฌ์ฉํ ์ ์์ง๋ง, ์ฑ๊ธ ์ฟผํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ผ๋ฐ์ ์ธ ์ฝ๋ ์คํ์ผ๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์๋ค.
Before
const greeting = "Hello, world!";
After
const greeting = 'Hello, world!';
๋ฌธ์์ด์ ์ฑ๊ธ ์ฟผํธ๊ฐ ํฌํจ๋์ด ์๋ ๊ฒฝ์ฐ, ์ด์ค์ผ์ดํ(\') ๋์ ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋
์ฑ์ ๋์ธ๋ค.
Before
const message = 'It\'s a beautiful day!';
After
const message = `It's a beautiful day!`;
ํ
ํ๋ฆฟ ๋ฌธ์์ด ์ฌ์ฉ:
ํ
ํ๋ฆฟ ๋ฌธ์์ด์ ๋ฐฑํฑ(`)์ผ๋ก ๊ฐ์ธ๊ณ , ๋ฌธ์์ด ๋ด์์ ๋์ ๋ฐ์ดํฐ ์ฝ์
๊ณผ ์ฌ๋ฌ ์ค ๋ฌธ์์ด ์์ฑ์ ๊ฐ๋จํ ์ฒ๋ฆฌํ ์ ์๋ค.
๋ณต์กํ ๋ฌธ์์ด ์ฐ๊ฒฐ ์์
์ ํ
ํ๋ฆฟ ๋ฌธ์์ด๋ก ๋์ฒดํ๋ ๊ฒ์ด ๋ ๋ช
ํํ๊ณ ๊ฐ๋
์ฑ์ด ์ข๋ค.
Before
const message = 'Hello, ' + name + '! You have ' + count + ' messages.';
After
const message = `Hello, ${name}! You have ${count} messages.`;
์ค ๋ฐ๊ฟ(Line Continuation) ๊ธ์ง:
๋ฌธ์์ด์ ๋ฐฑ์ฌ๋์(\)๋ฅผ ์ฌ์ฉํด ์ค ๋ฐ๊ฟํ๋ฉด ์ฝ๋์ ๊ฐ๋
์ฑ์ด ๋จ์ด์ง๊ณ , ๊ณต๋ฐฑ๊ณผ ๊ด๋ จ๋ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค. ์๋ฅผ ๋ค์ด, ๋ฐฑ์ฌ๋์ ๋ค์ ๊ณต๋ฐฑ์ด ์์ผ๋ฉด ์๋ฌ๋ฅผ ์ด๋ํ๋ค.
์ค ๋ฐ๊ฟ์ด ํ์ํ ๊ฒฝ์ฐ, ๋ฌธ์์ด ์ฐ๊ฒฐ(+)์ ์ฌ์ฉํ๊ฑฐ๋ ํ
ํ๋ฆฟ ๋ฌธ์์ด์ ํ์ฉํ๋ค.
Before
const longString = 'This is a very long string that spans multiple lines. \
It can cause tricky errors if there is any trailing whitespace.';
After
// ๋ฌธ์์ด ์ฐ๊ฒฐ
const longString = 'This is a very long string ' +
'that spans multiple lines without issues.';
// ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด ์ฌ์ฉ
const longString = `This is a very long string
that spans multiple lines cleanly.`;
// ํ
ํ๋ฆฟ ๋ฌธ์์ด๋ก ์ฌ๋ฌ ์ค ์ฒ๋ฆฌ
function arithmetic(a, b) {
return `Here is a table of arithmetic operations:
${a} + ${b} = ${a + b}
${a} - ${b} = ${a - b}
${a} * ${b} = ${a * b}
${a} / ${b} = ${a / b}`;
}
์ซ์ ๋ฆฌํฐ๋ด ํ๊ธฐ๋ฒ:
JavaScript์์๋ ์ซ์๋ฅผ ๋ค์ํ ์ง๋ฒ(Decimal, Hexadecimal, Octal, Binary)์ผ๋ก ํํํ ์ ์๋ค. ์ซ์ ๋ฆฌํฐ๋ด์ ์ ๋์ฌ๋ ์๋ฌธ์๋ก ํต์ผํด์ผ ํ๋ค.
| ์ง๋ฒ | ํ๊ธฐ๋ฒ ์์ | ์ค๋ช |
|---|---|---|
| Decimal | 42 | 10์ง์ (๊ธฐ๋ณธ) |
| Hex | 0x2a | 16์ง์, ์ ๋์ฌ 0x |
| Octal | 0o52 | 8์ง์, ์ ๋์ฌ 0o |
| Binary | 0b101010 | 2์ง์, ์ ๋์ฌ 0b |
const decimal = 42; // 10์ง์
const hex = 0x2a; // 16์ง์
const octal = 0o52; // 8์ง์
const binary = 0b101010; // 2์ง์
์ ํ 0 ๊ธ์ง:
์ซ์ ๋ฆฌํฐ๋ด์ ์ ํ 0(leading zero)๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํผ๋์ ์ด๋ํ ์ ์๋ค. ์์ ์๋ ์ ํ 0์ด ์๋ ์ซ์๊ฐ 8์ง์๋ก ํด์๋์๊ธฐ ๋๋ฌธ์ด๋ค(ECMAScript 5 ์ด์ ).
ECMAScript 6 ์ด์์์๋ ์ ํ 0์ ์ฌ์ฉํ๋ ์ซ์ ๋ฆฌํฐ๋ด์ ๋ฌธ๋ฒ ์ค๋ฅ๋ก ๊ฐ์ฃผ๋๋ค. ๋ฐ๋ผ์ ์ ํ 0์ ๋ฐ๋์ 0x, 0o, 0b์ ๊ฐ์ด ์ฌ๋ฐ๋ฅธ ์ ๋์ฌ๊ฐ ๋ค๋ฐ๋ผ์ผ ํ๋ค.
Before
// ์์ JavaScript์์ ์ ํ 0์ 8์ง์๋ก ํด์๋์๋ค.
const octal = 052; // 42 (8์ง์)
After
// ์ฌ๋ฐ๋ฅธ 8์ง์ ํํ
const octal = 0o52;
์์์ ๊ฐ์ ๋ณํ(Implicit coercion) ์ง์ํ๊ธฐ:
์์์ ๊ฐ์ ๋ณํ์ ์ฝ๋์ ์๋๋ฅผ ๋ถ๋ถ๋ช
ํ๊ฒ ๋ง๋ค๊ณ , ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ด๋ํ ์ ์๋ค.
Before
if (!!foo) {...} // BAD:๋ถํ์ํ ์์์ ๊ฐ์ ๋ณํ
while (!!foo) {...}
After
if (foo) {...} // GOOD: ๊ฐ๊ฒฐํ๊ฒ ์์ฑ
while (foo) {...}
๋ฌธ์์ด ๋ช
์์ ๋ณํ์ String() ๋๋ Boolean() ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ:
const bool = Boolean(false); // false
const str = String(123); // "123"
const bool2 = !!str; // true
const str2 = `result: ${bool2}`; // "result: true"
!! ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ๋ช
์์ ์ผ๋ก boolean์ผ๋ก ๋ณํ์ด๊ฑฐํ ๊ฐ์ ๋ถ๋ฆฌ์ธ์ผ๋ก ๋ณํํ์ง ์๊ธฐ:
์ด๊ฑฐํ(Enum)์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ซ์ ๊ฐ๊ณผ ๋งคํ๋๋ฉฐ, ์ฒซ ๋ฒ์งธ ๊ฐ์ 0์ผ๋ก ํ ๋น๋๋ค.
Boolean(enumValue)๋ !!enumValue๋ฅผ ์ฌ์ฉํ๋ฉด:
0)์ falsy๋ก ํ๊ฐBefore
enum SupportLevel {
NONE,
BASIC,
ADVANCED,
}
const level: SupportLevel = SupportLevel.NONE;
let enabled = Boolean(level); // ์๋ชป๋ ๋ฐฉ์: `NONE`์ด `false`๋ก ํ๊ฐ๋จ
After
enum SupportLevel {
NONE,
BASIC,
ADVANCED,
}
const level: SupportLevel = SupportLevel.NONE;
let enabled = level !== SupportLevel.NONE; // ๋ช
์์ ๋น๊ต
์ซ์ํ ๋ณํ์ Number() ์ฌ์ฉํ๊ธฐ:
์ซ์ ๊ฐ์ ํ์ฑํ ๋๋ Number()๋ฅผ ์ฌ์ฉํ๊ณ , ๊ฒฐ๊ณผ๊ฐ ์ ํจํ์ง ๋ช
์์ ์ผ๋ก ํ์ธํด์ผ ํ๋ค:
isNaN: ์ซ์๊ฐ NaN์ธ์ง ํ์ธisFinite: ์ซ์๊ฐ ์ ํํ ๊ฐ์ธ์ง ํ์ธBefore
const x = +y; // ๊ฐ๋
์ฑ์ด ๋ฎ๊ณ , ์ค์ํ๊ธฐ ์ฌ์
const n = parseInt(someString, 10); // ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ
const f = parseFloat(someString); // ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ
After
let f = Number(someString); // ์ซ์๋ก ๋ณํ
if (!isFinite(f)) throw new Error('Invalid number'); // ์ ํจ์ฑ ํ์ธ
if (isNaN(f)) handleError(); // NaN์ธ์ง ํ์ธ
f = Math.floor(f); // ์ ์๋ก ๋ณํ
Number(''),Number(' '),Number('\t')๋NaN๋์0์ ๋ฐํํ๋ค.
Number('Infinity'),Number('-Infinity')๋Infinity์-Infinity๋ฅผ ๋ฐํํ๋ค.
์ง์ ํ๊ธฐ๋ฒ, ์๋ฅผ๋ค์ดNumber('1e+309'),Number('-1e+309')์ ๋ฌดํ๋๋ก ์ค๋ฒํ๋ก๋ ์ ์๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ํน๋ณํ ์ฒ๋ฆฌ๊ฐ ํ์ํ ์ ์๋ค.
๋ชจ๋ ์ ์ด ํ๋ฆ๋ฌธ(if, else, for, while, ๋ฑ)์ ํญ์ ์ค๊ดํธ๋ก ์ฝ๋ ๋ธ๋ก์ ๊ฐ์ธ์ผ ํ๋ค.
๋จ, if ๋ฌธ์ด ํ ์ค๋ก ๋๋๋ ๊ฒฝ์ฐ์๋ ์ค๊ดํธ ์๋ต์ด ํ์ฉ๋๋ค.
Before
if (x)
doSomething(); // ์ค๊ดํธ ์์ด ์ฌ๋ฌ ์ค ์ฝ๋ ์์ฑ ์ ๊ฐ๋
์ฑ ๋ฌธ์ ๋ฐ์
After
if (x) {
doSomething();
}
for (let i = 0; i < 10; i++) {
console.log(i);
}
if (x) x.doSomething(); // ํ ์ค ์ฝ๋์ธ ๊ฒฝ์ฐ์๋ง ์ค๊ดํธ ์๋ต ๊ฐ๋ฅ
์ ์ด๋ฌธ ๋ด๋ถ์์ ๋ณ์ ํ ๋น์ ์ง์ํด์ผ ํ๋ค.
์ด๋ ํ ๋น(=)๊ณผ ๋น๊ต(==)๋ฅผ ํผ๋ํ ๊ฐ๋ฅ์ฑ์ ์ค์ด๊ธฐ ์ํจ์ด๋ค.
๋จ, ์๋์ ์ผ๋ก ํ ๋นํ๋ ๊ฒฝ์ฐ ์ด์ค ๊ดํธ๋ฅผ ์ฌ์ฉํด ์๋๋ฅผ ๋ช
ํํ ํ์ํ๋ค.
Before
if (x = someFunction()) {
// ํ ๋น์ด ์กฐ๊ฑด๋ฌธ ๋ด๋ถ์ ์์ด ํผ๋ ๊ฐ๋ฅ
}
After
x = someFunction();
if (x) {
// x๋ฅผ ์ฌ์ฉ
}
while ((x = someFunction())) {
// ํ ๋น์ด ์๋์ ์์ ์ ์ ์์
}
๋ฐฐ์ด์ ๋ฐ๋ณต ์ฒ๋ฆฌํ ๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ ์ฐ์ ์ ์ผ๋ก ์ฌ์ฉํ๋ค:
for ... of: ๋ฐฐ์ด์ ๊ฐ์ ์ง์ ๋ฐ๋ณตArray.prototype.forEach: ๋ฐ๋ณต ๋์์ ์ฝ๋ฐฑ ํจ์๋ก ์ฒ๋ฆฌfor ๋ฃจํ: ์ธ๋ฑ์ค๊ฐ ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉfor (const value of someArr) {
console.log(value);
}
for (let i = 0; i < someArr.length; i++) {
const value = someArr[i]; // ์ธ๋ฑ์ค๊ฐ ํ์ํ ๊ฒฝ์ฐ
console.log(i, value);
}
for (const [i, value] of someArr.entries()) {
console.log(i, value);
}
for ... in์ ๋ฐฐ์ด์ด ์๋ ๊ฐ์ฒด ์ํ์ฉ์ด๋ฉฐ, ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ๋ฌธ์์ด๋ก ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋น์ง๊ด์ ์ด๋ฏ๋ก ๋ฐฐ์ด์ ์ฌ์ฉํ์ง ๋ง์.
๊ฐ์ฒด๋ฅผ ๋ฐ๋ณต ์ฒ๋ฆฌํ ๋๋ for ... in๋ณด๋ค Object.keys, Object.values, Object.entries๋ฅผ ๊ถ์ฅํ๋ค.
for (const key of Object.keys(obj)) {
console.log(key);
}
for (const value of Object.values(obj)) {
console.log(value);
}
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue;
doWork(key, obj[key]);
}
์ฝ๋๋ฅผ ์์ฑํ ๋ ๋ถํ์ํ ๊ดํธ ์ฌ์ฉ์ ํผํ๋, ์ฝ๊ธฐ ์ฝ๊ณ ์คํด์ ์์ง๊ฐ ์๋๋ก ์์ฑํ๋ผ.
์ ํ์ ์ธ ๊ทธ๋ฃนํ ๊ดํธ๋ ์์ฑ์์ ๊ฒํ ์๊ฐ ๊ทธ๋ฃนํ ๊ดํธ ์์ด๋ ์ฝ๋๊ฐ ์คํด๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์ ํ ์๊ณ , ์ฝ๋์ ์ฝ๊ธฐ๊ฐ ๋ ์ฌ์์ง์ง ์์ ๊ฒ์ ๋์ํ๋ ๊ฒฝ์ฐ์๋ง ์๋ตํ๋ค. (๋ชจ๋ ๋ ์๊ฐ ์ฐ์ฐ์ ์ฐ์ ์์ ํ ์ ์ฒด๋ฅผ ์๊ธฐํ๊ณ ์๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์ ํฉ๋ฆฌ์ ์ด์ง ์๋ค.)
delete, typeof, void, return, throw, case, in, of, yield ๋ค์์ ๋์ค๋ ์ ์ฒด ํํ์ ์ฃผ์์ ๋ถํ์ํ ๊ดํธ๋ฅผ ์ฌ์ฉํ์ง ๋ง์.
Before
return (a + b);
throw (new Error('Error message'));
After
return a + b;
throw new Error('Error message');
์์ธ๋ ์ธ์ด์ ์ค์ํ ๋ถ๋ถ์ด๋ฏ๋ก ์์ธ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ๋๋ง๋ค ์ฌ์ฉํด์ผ ํ๋ค.
์ฌ์ฉ์ ์ ์ ์์ธ๋ ํจ์์์ ์ถ๊ฐ์ ์ธ ์ค๋ฅ ์ ๋ณด๋ฅผ ์ ๋ฌํ๋ ์ข์ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
new๋ฅผ ์ฌ์ฉํ ์ธ์คํด์คํ ํ๊ธฐ:
throw Error()๋ณด๋ค๋ throw new Error()๋ฅผ ์ฌ์ฉ. ์ด๋ ๋ค๋ฅธ ๊ฐ์ฒด ์ธ์คํด์คํ ๋ฐฉ์๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ๋ค.
Before
throw Error('Foo is not a valid bar.');
After
throw new Error('Foo is not a valid bar.');
Error๋ง throw ํ๊ธฐ:
์ผ๋ฐ์ ์ผ๋ก JavaScript์์๋ throw ํค์๋๋ฅผ ์ฌ์ฉํด ์์ธ๋ฅผ ๋ฐ์์ํฌ ๋ Error ๊ฐ์ฒด๋ฅผ ๋์ง๋ค.
์์ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐฉ์(์ค๋ฅ ์ปจํ
์ด๋ ์ฐธ์กฐ ์ ํ ์ ๋ฌ์ด๋ ์ค๋ฅ ์์ฑ์ด ์๋ ๊ฐ์ฒด ๋ฐํ ๋ฑ)๋ณด๋ค ์์ธ๋ฅผ throwํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
Before
throw 'oh noes!';
new Promise((resolve, reject) => void reject('oh noes!'));
Promise.reject();
Promise.reject('oh noes!');
After
throw new Error('oh noes!');
class MyError extends Error {}
throw new MyError('my oh noes!');
new Promise((resolve) => resolve());
new Promise((resolve, reject) => void reject(new Error('oh noes!')));
Promise.reject(new Error('oh noes!'));
Error ๊ฐ์ฒด๋ง์ด ์๋ฏธ ์๋ ์คํ ์ถ์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.์ค๋ฅ๋ฅผ ์ก์ ๋ ์ฝ๋๋ ๋ฐ์ํ ๋ชจ๋ ์ค๋ฅ๊ฐ Error ์ธ์คํด์ค๋ผ๊ณ ๊ฐ์ ํด์ผ ํ๋ค.
function assertIsError(e: unknown): asserts e is Error {
if (!(e instanceof Error)) throw new Error("e is not an Error");
}
try {
doSomething();
} catch (e: unknown) {
// All thrown errors must be Error subtypes. Do not handle
// other possible values unless you know they are thrown.
assertIsError(e);
displayError(e.message);
// or rethrow:
throw e;
}
๊ณผ๋ํ๊ฒ ๋ฐฉ์ด์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ์ง ๋ง์:
๋๋ถ๋ถ์ ์ฝ๋์์ throw๋ Error ๊ฐ์ฒด๋ฅผ ๋์ง๊ธฐ ๋๋ฌธ์, ํญ์ ๋ชจ๋ ๊ฒฝ์ฐ์ ํ์
(string, number ๋ฑ)์ ๋ฐฉ์ด์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ์ฝ๋๋ ๋ถํ์ํ ๋ฐ๋ณต์ ๋ฐฉ์ด๊ฐ ๋๋ค.
๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ๊ฐ๋ฅ์ฑ์ด ์ ์ ์ํฉ์์ "๋ชจ๋ ๊ฒฝ์ฐ"๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ ๊ณผ๋ํ ๋ฐฉ์ด๋ ์ฝ๋ ๋ณต์ก์ฑ์ ๋์ด๊ณ ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
๋ง์ฝ ์ฌ์ฉํ๋ API๊ฐ
Error๊ฐ ์๋ ๋ค๋ฅธ ํ์ (์: ๋ฌธ์์ด)์ ๋์ง๋ ๋น์ ์์ ์ธ ๋์์ ํ๋ ๊ฒฝ์ฐ์ ํํ์ฌ ๋ฐฉ์ด์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ฃผ์์ ์ถ๊ฐํ์ฌ ๋ฌธ์ ์ ์ถ์ฒ๋ฅผ ๋ช ํํ ์ค๋ช ํ์.
๋น catch ๋ธ๋ก ํผํ๊ธฐ:
Before
try {
shouldFail();
} catch (e) {
// ์๋ฌด๊ฒ๋ ํ์ง ์์
}
After
try {
// ์์
์ํ
} catch (e: unknown) {
// ์ ์๋ฌด๊ฒ๋ ํ์ง ์๋์ง ์ฃผ์์ผ๋ก ์ค๋ช
// ์: ํน์ ์์ธ๋ ๋ฌด์ํด๋ ๋๋ ์ํฉ
}
๋ชจ๋ switch ๋ฌธ์ default ๊ทธ๋ฃน์ ํฌํจํ๊ธฐ:
switch ๋ฌธ์๋ ํญ์ default ๊ทธ๋ฃน์ ํฌํจํด์ผ ํ๋ฉฐ, ์ด ๊ทธ๋ฃน์ ํญ์ ๋ง์ง๋ง์ ์์นํ๋ค.
๋น ๊ทธ๋ฃน๋ ๊ด์ฐฎ๋ค. ์ฝ๋๊ฐ ์๋ ๊ฒฝ์ฐ๋ผ๋ ์ฃผ์์ผ๋ก ์๋๋ฅผ ๋ช
์ํ๋ผ.
๋ชจ๋ ๋น์ด ์์ง ์์ case ๊ทธ๋ฃน์ ๋ช
์์ ์ผ๋ก ์ข
๋ฃํ๊ธฐ:
case ๋ธ๋ก์ด ๋น์ด ์์ง ์๋ค๋ฉด, ๋ฐ๋์ ๋ช
์์ ์ผ๋ก ์ข
๋ฃํด์ผ ํ๋ค. ์ข
๋ฃ ๋ฐฉ๋ฒ์ break, return, ๋๋ throw๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
๋ช
์์ ์ผ๋ก ์ข
๋ฃํ์ง ์์ผ๋ฉด ๋ค์ case ๋ธ๋ก์ผ๋ก ์คํ์ด ๋์ด๊ฐ๋ fall-through๋ก ์๋์น ์์ ๋์์ ์ ๋ฐํ ์ ์๋ค.
๋ฌผ๋ก ์ฌ๋ฌ ์กฐ๊ฑด์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ถ์ ๋ ์๋์ ์ธ ๋ฌถ์ ์ฒ๋ฆฌ๋ ์ฌ์ฉํด๋ ๋๋ค.
switch (x) {
case 1:
doSomething();
break; // ๋ช
์์ ์ผ๋ก ์ข
๋ฃ
case 2: // fall-through! => ๋ค์ case๋ก ์คํ์ด ๋์ด๊ฐ
case 3:
doSomethingElse();
break;
default:
// nothing to do.
}
์ผ์ค ๋ฑํธ(===, !==) ์ฌ์ฉํ๊ธฐ:
JavaScript์ ๋๋ฑ ๋น๊ต ์ฐ์ฐ์(==, !=)์์ ๋ฐ์ํ๋ ํ์
๊ฐ์ ๋ณํ(type coercion)์ ๋ฐ๋ฅธ ์์ธก ๋ถ๊ฐ๋ฅํ ๋์์ ๋ฐฉ์งํ๊ธฐ ์ํด ํญ์ ์ผ์ค ๋ฑํธ(===, !==)๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํ๋ค.
==๋ ๋ ๊ฐ์ด ๋ค๋ฅธ ํ์
์ผ ๊ฒฝ์ฐ, ๋น๊ต๋ฅผ ์๋ํ๊ธฐ ์ํด ํ์ชฝ ๊ฐ์ ๋ค๋ฅธ ํ์
์ผ๋ก ๋ณํํ๋ค.
์ด๋ฌํ ๋ณํ์ ์์์น ๋ชปํ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์๋ค.
๋ํ, ํ์
๊ฐ์ ๋ณํ์ ์ํํ๋ ==๋ JavaScript ์์ง์ด ๋ ๋ง์ ์์
์ ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก ๋๋ฆฌ๋ค.
์ผ์ค ๋ฑํธ๋ ํ์
์ ์ฒดํฌํ ๋ค ๋ฐ๋ก ๊ฐ์ ๋น๊ตํ๋ฏ๋ก ์ฑ๋ฅ์ด ๋ ํจ์จ์ ์ด๋ค.
์์ธ: null ๋น๊ต์์๋ง ==์ != ํ์ฉ
๋จ, null๊ณผ undefined๋ฅผ ๋์์ ๋น๊ตํด์ผ ํ ๋๋ ์์ธ์ ์ผ๋ก ==์ !=๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
if (foo === null || foo === undefined) {
console.log('foo is null or undefined');
}
if (foo == null) {
console.log('foo is null or undefined'); // true
}
TypeScript์ ํ์ ๋จ์ธ(type assertions)๊ณผ null ๋ถ๊ฐ๋ฅ์ฑ ๋จ์ธ(non-nullability assertions)์ ์ ์คํ๊ฒ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํ๋ค.
ํ์
๋จ์ธ ์, as ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ผ:
<Foo>์ ๊ฐ์ ์ต๊ธ ๋ธ๋ํท ๋ฌธ๋ฒ์ ํผ๋์ ์ค ์ ์์ผ๋ฏ๋ก ์ง์ํ๋ค.
as๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉค๋ฒ ์ ๊ทผ ์ ๋ช
ํ์ฑ์ ๋์ด๊ธฐ ์ํด ๊ดํธ๊ฐ ์ถ๊ฐ๋๊ธฐ ๋๋ฌธ์ด๋ค.
Before
const x = (<Foo>z).length;
const y = <Foo>z.length; // ์คํด์ ์์ง๊ฐ ์์
After
const x = (z as Foo).length; // ๊ดํธ๊ฐ ๋ช
ํ์ฑ์ ๋ณด์ฅ
ํ์
๋จ์ธ๊ณผ null ๋ถ๊ฐ๋ฅ์ฑ ๋จ์ธ์ ๋ฐ๋์ ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๋ผ:
ํ์
๋จ์ธ (x as SomeType)๊ณผ null ๋ถ๊ฐ๋ฅ์ฑ ๋จ์ธ (y!)์ ์ปดํ์ผ๋ฌ์๊ฒ ํน์ ๊ฐ์ด ์ด๋ค ํ์
์์ ๊ฐ์ ๋ก ์๋ฆฌ๋ ๊ธฐ๋ฅ์ด๋ค.
ํ์ง๋ง ๋ฐํ์์์๋ ์ค์ ๋ก ํ์
์ด๋ null ์ฒดํฌ๋ฅผ ์ํํ์ง ์๋๋ค. ๋ฐ๋ผ์:
Before
const x: unknown = "hello";
console.log((x as number).toFixed(2)); // ๋ฐํ์ ์๋ฌ ๋ฐ์!
After
ํ์
์ฒดํฌ๋ null ์ฒดํฌ๋ฅผ ๋ช
์์ ์ผ๋ก ์์ฑํ๋ผ.
if (typeof x === "number") {
console.log(x.toFixed(2)); // ์์ ํ ์คํ
}
ํ์ ๋จ์ธ์ด๋ null ๋ถ๊ฐ๋ฅ์ฑ ๋จ์ธ์ ๋ฐ๋์ ์ฌ์ฉํด์ผ ํ ๊ฒฝ์ฐ, ์ฃผ์์ ํตํด ํด๋น ๋จ์ธ์ด ์์ ํ๋ค๊ณ ํ๋จํ ์ด์ ๋ฅผ ๊ธฐ๋กํ๋ค. (๋ช ๋ฐฑํ ๊ฒฝ์ฐ์๋ ์ฃผ์์ด ์๋ต ๊ฐ๋ฅํ๋ค.)
// x๋ Foo ํ์
์์ด ๋ณด์ฅ๋๋ค (์ด๋ค ์ด์ ๋๋ฌธ์ธ์ง ๋ช
์).
(x as Foo).foo();
// y๋ null์ด ๋ ์ ์์์ ์๊ณ ์๋ค (ํด๋น ์ํฉ ์ค๋ช
).
y!.bar();
์ด์ค ๋จ์ธ๋ฌธ (Double Assertions)
TypeScript๋ ์ผ๋ฐ์ ์ผ๋ก "๋ ๊ตฌ์ฒด์ ์ด๊ฑฐ๋ ๋ ์ผ๋ฐ์ ์ธ ํ์
"์ผ๋ก์ ๋จ์ธ๋ง ํ์ฉํ๋ค.
์์ ํ๋ค๊ณ ํ์ ํ๋ ๊ฒฝ์ฐ, ์ด์ค ๋จ์ธ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค.
์ค๊ฐ ํ์
์ผ๋ก any๋ {} ๋์ unknown์ ๊ถ์ฅํ๋ค.
Before
(x as any as Foo).fooMethod();
After
(x as unknown as Foo).fooMethod();
๊ฐ์ฒด ๋ฆฌํฐ๋ด์๋ ํ์
์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์๋ฌ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ๋ผ:
๊ฐ์ฒด ๋ฆฌํฐ๋ด์์๋ ํ์
๋จ์ธ (as Foo) ๋์ ํ์
์ด๋
ธํ
์ด์
(: Foo) ์ฌ์ฉ์ ๊ถ์ฅํ๋ค.
ํ์
์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ์ธํฐํ์ด์ค ๋ณ๊ฒฝ ์ ์๋ชป๋ ํ๋๊ฐ ์๋์ผ๋ก ๊ฐ์ง๋๋ค.
Before
interface Foo {
bar: number;
baz?: string;
}
const foo = {
bar: 123,
bam: 'abc', // ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์!
} as Foo;
After
interface Foo {
bar: number;
baz?: string;
}
const foo: Foo = {
bar: 123,
bam: 'abc', // bam์ด Foo์ ์ ์๋์ง ์์๋ค๊ณ ์๋ฌ ๋ฐ์
};
try ๋ธ๋ก์ ํฌํจ๋ ์ฝ๋๋ ์ต์ํํ๋ ๊ฒ์ด ์ข๋ค:
์ด๋ค ์ฝ๋๊ฐ ์์ธ๋ฅผ ๋์ง ๊ฐ๋ฅ์ฑ์ด ์๋์ง ๋ช
ํํ๊ฒ ๋๋ฌ๋๋๋ก ํ๊ธฐ ์ํจ์ด๋ค.
Before
try {
const result = methodThatMayThrow(); // ์์ธ๋ฅผ ๋์ง ๊ฐ๋ฅ์ฑ ์์
use(result); // ์์ธ๋ฅผ ๋์ง์ง ์์
} catch (error: unknown) {
// ...
}
use(result)๋ ์์ธ๋ฅผ ๋์ง์ง ์์ง๋ง try ๋ธ๋ก ์์ ํฌํจ๋์ด ์์ด ๋
์์๊ฒ ํผ๋์ ์ค ์ ์๋ค.let result;
try {
result = methodThatMayThrow(); // ์์ธ๋ฅผ ๋์ง ๊ฐ๋ฅ์ฑ์ด ์๋ ์ฝ๋๋ง ํฌํจ
} catch (error: unknown) {
// ...
}
use(result); // ์์ธ๋ฅผ ๋์ง์ง ์๋ ์ฝ๋๋ `try` ๋ธ๋ก ๋ฐ์ผ๋ก ์ด๋
methodThatMayThrow()๋ง ์์ธ๋ฅผ ๋์ง ๊ฐ๋ฅ์ฑ์ด ์์์ ๋ช
ํํ ์ ์ ์๋ค.try {
use(methodThatMayThrow()); // ์ฝ๋๊ฐ ๊ฐ๋จํ๋ฏ๋ก ๋ณ๋๋ก ๋๋ ํ์ ์์
} catch (error: unknown) {
// ...
}
๋ฃจํ ์์ try ๋ธ๋ก์ ๋ฐ๋ณต์ ์ผ๋ก ์ ์ธํ๋ฉด ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค:
์ด ๊ฒฝ์ฐ, try ๋ธ๋ก์ ๋ฒ์๋ฅผ ๋ฃจํ ์ ์ฒด๋ก ํ์ฅํ๋ ๊ฒ์ด ๋ซ๋ค.
Before
for (const item of items) {
try {
processItem(item); // ๋งค๋ฒ `try` ๋ธ๋ก์ด ์ฌ์์ฑ๋จ
} catch (error: unknown) {
// ...
}
}
After
try {
for (const item of items) {
processItem(item); // `try` ๋ธ๋ก์ด ํ ๋ฒ๋ง ์์ฑ๋จ
}
} catch (error: unknown) {
// ...
}
๋ฐ์ฝ๋ ์ดํฐ๋ ํด๋์ค, ๋ฉ์๋, ํ๋, ๋๋ ํ๋ผ๋ฏธํฐ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋, ๋์์ ์์ ํ ์ ์๋๋ก ๋์์ฃผ๋ ํน์ํ ๋ฌธ๋ฒ์ด๋ค.
๋ฐ์ฝ๋ ์ดํฐ๋ @ ๊ธฐํธ๋ก ์์ํ๋ฉฐ, ํจ์ ํํ๋ก ์ ์๋๋ค.
@Component({
selector: 'my-component',
template: '<p>My Component</p>',
})
class MyComponent {}
์๋ก์ด ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ํ์ง ๋ง๊ณ , ํ๋ ์์ํฌ ์ ๊ณต ๋ฐ์ฝ๋ ์ดํฐ๋ง ์ฌ์ฉํ๋ผ:
๋ฐ์ฝ๋ ์ดํฐ๋ TypeScript์์ ์คํ์ (Experimental)์ผ๋ก ๋์
๋์๋ค.
ํ์ง๋ง JavaScript ํ์คํ ๊ธฐ๊ตฌ์ธ TC39์ ์ต์ข
ํ์ค์๊ณผ๋ ๋ค๋ฅด๊ฒ ๋์ํ๋ ๋ถ๋ถ์ด ์๋ค.
์คํ์ ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ๋ฐ๊ฒฌ๋ ๋ช ๊ฐ์ง ๋ฒ๊ทธ๋ค์ด ์์ ๋์ง ์์ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ด๋ฐ ์ด์ ๋ก ์๋ก์ด ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ํ๊ฑฐ๋ ์ฌ์ฉํ๋ ๊ฒ์ด ์ํํ ์ ์๋ค.
ํ๋ ์์ํฌ์์ ์ ๊ณตํ๋ ๊ณต์ ๋ฐ์ฝ๋ ์ดํฐ๋ง ์ฌ์ฉํด์ผ ํ๋ค.
๋ฐ์ฝ๋ ์ดํฐ๋ ๋น ์ค ์์ด ๋ฐ๋ก ์ ์ฉ ๋์ ์์ ์์น์์ผ ๊ฐ๋
์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ฌ๋ผ:
Before
/** JSDoc comments */
@Component({...})
class MyComponent {} // ๋น ์ค์ด ์์ด์ ์๋ชป๋ ์
After
/** JSDoc comments */
@Component({...})
class MyComponent {} // ๋น ์ค ์์ด ๋ฐ๋ก ์ฐ๊ฒฐ
class MyComp {
@Input() myField: string; // ๊ฐ์ ์ค
@Input()
myOtherField: string; // ๋ค์ ์ค๋ก ๊ฐ์ธ๊ธฐ
}
๋ํผ ํด๋์ค(wrapper class)๋ JavaScript์ ์์ ํ์
(String, Boolean, Number)์ ๊ฐ์ฒด๋ก ๊ฐ์ธ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
์๋ฅผ ๋ค์ด, String, Boolean, Number๋ ๊ฐ๊ฐ ์์ ํ์
์ ๊ฐ์ฒด์ฒ๋ผ ๋ค๋ฃฐ ์ ์๊ฒ ํด ์ค๋ค.
const s = new String('hello'); // ๋ฌธ์์ด 'hello'๋ฅผ String ๊ฐ์ฒด๋ก ๊ฐ์
const b = new Boolean(false); // ๋ถ๋ฆฌ์ธ false๋ฅผ Boolean ๊ฐ์ฒด๋ก ๊ฐ์
const n = new Number(5); // ์ซ์ 5๋ฅผ Number ๊ฐ์ฒด๋ก ๊ฐ์
์์ ํ์
์ ๊ฐ์ธ๋ ๋ํผ ํด๋์ค๋ฅผ ์ง์ ์ธ์คํด์คํํ์ง ๋ง์:
๋ํผ ํด๋์ค๋ฅผ ์ธ์คํด์คํํ๋ฉด ์์ ๊ฐ์ด ์๋๋ผ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
์ด๋ก ์ธํด ์๋์ ๋ค๋ฅธ ๋์์ ์ด๋ํ ์ ์๋ค.
์์ ํ์
์ ๊ฐ์ฒด๋ก ๊ฐ์ธ๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฑ๋ฅ ์ธก๋ฉด์์ ๋ถํ์ํ ์ค๋ฒํค๋๋ฅผ ๋ฐ์์ํจ๋ค.
์์ ํ์
์์ฒด๋ ๊ฐ๋ณ๊ณ ๋น ๋ฅด๊ฒ ๋์ํ๋๋ก ์ค๊ณ๋์๋ค.
Before
const b = new Boolean(false);
console.log(b); // Boolean {false}
console.log(b == true); // true
console.log(b ? 'true' : 'false'); // 'true'
new Boolean(false)๋ ๋ถ๋ฆฌ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉฐ, ๊ฐ์ฒด๋ ํญ์ true๋ก ํ๊ฐ๋๋ค.
์ฆ, ์ค์ ๊ฐ์ด false์์๋ true๋ก ํ๊ฐ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
const s1 = 'hello';
const s2 = new String('hello');
console.log(s1 === s2); // false (๋ฌธ์์ด vs ๊ฐ์ฒด)
console.log(s1 == s2); // true (๋์จํ ๋น๊ต๋ก ๋๋ฑํ๋ค๊ณ ํ๊ฐ)
After
const s = 'hello'; // ์์ ๋ฌธ์์ด
const b = false; // ์์ ๋ถ๋ฆฌ์ธ
const n = 5; // ์์ ์ซ์
const s = String('hello'); // ๋ฌธ์์ด๋ก ๋ณํ
const b = Boolean(0); // ๋ถ๋ฆฌ์ธ์ผ๋ก ๋ณํ
const n = Number('42'); // ์ซ์๋ก ๋ณํ
๋ชจ๋ ๋ฌธ์ฅ์ ์ธ๋ฏธ์ฝ๋ก ์ผ๋ก ๋ช
์์ ์ผ๋ก ๋๋ด์ผ ํ๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์๋ชป๋ ์ธ๋ฏธ์ฝ๋ก ์ฝ์
์ผ๋ก ์ธํ ๋ฒ๊ทธ๋ฅผ ๋ฐฉ์งํ๊ณ ASI ์ง์์ด ์ ํ๋ ๋๊ตฌ(์: clang-format)์์ ํธํ์ฑ์ ๋ณด์ฅํ๋ค.
const enum์ ์ฌ์ฉํด์๋ ์ ๋๋ค:
const enum์ ์ปดํ์ผ ๊ฒฐ๊ณผ์์ ์ฌ๋ผ์ง๋ฏ๋ก, JavaScript๋ก ์์ฑ๋ ์ฝ๋๋ ๋ค๋ฅธ ๋ชจ๋์์ ์ด ์ด๊ฑฐํ์ ์ฐธ์กฐํ ์ ์๋ค. ๋ง์ฝ const enum์ ์ฌ์ฉํ TypeScript ์ฝ๋๊ฐ JavaScript ๋ชจ๋๊ณผ ํจ๊ป ์ฌ์ฉ๋ ๊ฒฝ์ฐ, ์์์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค.
const enum์ ๊ฐ์ด ์ธ๋ผ์ธ๋๊ธฐ ๋๋ฌธ์ ๋๋ฒ๊น
๊ณผ์ ์์ ์ด๊ฑฐํ ์ด๋ฆ์ ๋ณผ ์ ์๋ค. ์ด๋ ๋๋ฒ๊น
์ ๋ณด๋ฅผ ์๊ฒ ๋ง๋ค๊ณ , ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ํ๋ค. ๋ํ ์ด๊ฑฐํ์ ๊ฐ์ด ์ฌ๋ฌ ๊ณณ์ ์ธ๋ผ์ธ์ผ๋ก ์ฝ์
๋๋ฉด, ์ด๊ฑฐํ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ์ปดํ์ผ๋ JavaScript์ ๋ชจ๋ ์ฐธ์กฐ๋ฅผ ๋ค์ ์ปดํ์ผํด์ผ ํ๋ค.
const ์ด๊ฑฐํ์ ๋ชจ๋์ JavaScript ์ฌ์ฉ์์๊ฒ ์ด๊ฑฐํ์ ๋ณด์ด์ง ์๊ฒ ํ๋ ์ต์ ํ์ ๊ด๋ จ๋ ๋ณ๋์ ์ธ์ด ๊ธฐ๋ฅ์ด๋ฉฐ, JavaScript ํ์ค์ด ์๋๋ค. ๋ฐ๋ผ์ ๋ค๋ฅธ ํ๊ฒฝ์์ ํธํ๋์ง ์์ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
enum:
enum Color {
Red,
Green,
Blue,
}
console.log(Color.Red); // ์ถ๋ ฅ: 0
์ปดํ์ผ ํ JavaScript:
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
console.log(Color.Red); // ์ถ๋ ฅ: 0
const enum:
const enum Color {
Red,
Green,
Blue,
}
console.log(Color.Red); // ์ถ๋ ฅ: 0
์ปดํ์ผ ํ JavaScript:
console.log(0); // `Color.Red`๊ฐ ์์๋ก ๋์ฒด๋จ
debugger๋ฌธ์ ํ๋ก๋์
์ฝ๋์ ํฌํจ๋์ด์๋ ์ ๋๋ค.
debugger๋ JavaScript์์ ๋๋ฒ๊น
์ ์ํด ์ฌ์ฉ๋๋ ๋ช
๋ น์ด๋ก, ์ฝ๋ ์คํ์ ์ค๋จํ๊ณ ๋๋ฒ๊น
์ธ์
์ ์์ํ ์ ์๋๋ก ๋๋๋ค.
์ด ๋ช
๋ น์ด๋ ์ฃผ๋ก ๋ธ๋ผ์ฐ์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ Node.js์ ๋๋ฒ๊น
๋ชจ๋์์ ์คํ๋ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
function debugMe() {
debugger; // ๋๋ฒ๊ฑฐ๊ฐ ํ์ฑํ๋ ์ํ์์ ์คํ ์, ์ฝ๋๊ฐ ์ค๋จ๋๋ค.
console.log("This will not run unless debugger is removed.");
}
debugger๋ ์ฝ๋ ์คํ์ ์ค๋จ์ํค๋ฏ๋ก, ์ฌ์ฉ์๊ฐ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉํ ๋ ์๊ธฐ์น ์๊ฒ ํ์ด์ง๊ฐ ๋ฉ์ถ๊ฑฐ๋ ๋์์ด ์ค๋จ๋ ์ ์๋ค.
ํ๋ก๋์
ํ๊ฒฝ์์๋ ๋๋ฒ๊น
์ ์ํ ์ฝ๋ ์คํ ์ค๋จ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฐฉํดํ๊ฑฐ๋ ์๋น์ค์ ๊ฐ์ฉ์ฑ์ ์
์ํฅ์ ๋ฏธ์น ์ ์๋ค.
debugger ๋ฌธ์ด ์ฝ๋์ ๋จ์ ์์ผ๋ฉด, ํ๋ก๋์
ํ๊ฒฝ์์๋ ๋๋ฒ๊น
์ ํ ์ ์๋ ์ํ๋ก ๋จ๊ฒ ๋๋ค. ์ด๋ ๋ณด์ ์ํ์ ์ด๋ํ ์ ์๋ค.
๊ณต๊ฒฉ์๋ ๋ธ๋ผ์ฐ์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด ๋๋ฒ๊ฑฐ๋ฅผ ํ์ฑํํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ๋ฅผ ์ถ์ ํ๊ฑฐ๋ ์
์ฉํ ์ ์๋ค.
ํนํ, ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ์ ํ๋ฆฌ์ผ์ด์
์์๋ ์ด๋ฌํ ๋๋ฒ๊น
์ฝ๋๊ฐ ๋ณด์ ์ทจ์ฝ์ ์ ์ ๋ฐํ ์ ์๋ค.
๋ฐฐํฌ ํ ๋๋ฒ๊น ์ ์ค์ ์ฝ๋์ debugger๋ฅผ ์ฝ์ ํ๋ ๋์ , ๋ก๊ทธ ํ์ผ์ด๋ ์๋ฌ ์ถ์ ์์คํ ์ ํ์ฉํ์ฌ ๋๋ฒ๊น ์ ์ํํ๋ ๊ฒ์ด ์ข๋ค.
with ํค์๋ ์ฌ์ฉ ๊ธ์ง:
์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ ES5 ์ดํ๋ก strict ๋ชจ๋์์ ๊ธ์ง๋์๋ค.
eval์ด๋ Function(...string) ์์ฑ์๋ฅผ ์ฌ์ฉ ๊ธ์ง(์ฝ๋ ๋ก๋ ์ ์ธ).
์ด๋ฌํ ๊ธฐ๋ฅ์ ์ ์ฌ์ ์ผ๋ก ์ํํ๋ฉฐ ์๊ฒฉํ ์ฝํ
์ธ ๋ณด์ ์ ์ฑ
์ ์ฌ์ฉํ๋ ํ๊ฒฝ์์๋ ์ ๋๋ก ์๋ํ์ง ์๋๋ค.
const userInput = "alert('Hacked!')";
eval(userInput); // ์ํ: ์ฌ์ฉ์๊ฐ ์
์์ ์ธ ์ฝ๋๋ฅผ ์ฝ์
ํ ์ ์์
const userInput = "alert('Malicious code')";
const fn = new Function(userInput);
fn(); // ์ํ: ์
์์ ์ธ ์ฝ๋ ์คํ
ํ์คํ๋ ECMAScript ๋ฐ Web Platform ๊ธฐ๋ฅ๋ง ์ฌ์ฉํ์:
๋นํ์ค ECMAScript๋ ์น ํ๋ซํผ ๊ธฐ๋ฅ์ผ๋ก ๊ฐ์ฃผ๋๋ ๊ฒ๋ค์ ๋ค์๊ณผ ๊ฐ๋ค.
๋ด์ฅ ํ์
์ ์์ ํ์ง ๋ง๋ผ:
JavaScript์๋ ๋ด์ฅ๋ ํ์
๋ค, ์๋ฅผ ๋ค์ด Array, Object, String, Number, Boolean, Function ๋ฑ์ด ์๋ค.
๋ด์ฅ ํ์
์ ์์ ํ๋ฉด, ๊ธฐ์กด ์ฝ๋๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ํ ๋๋ก ๋์ํ์ง ์์ ์ ์๋ค. ์๋ฅผ ๋ค์ด, Array์ ์๋ก์ด ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ฉด, ๋ค๋ฅธ ์ฝ๋์์ ๊ธฐ์กด ๋ฉ์๋๋ค๊ณผ ์ถฉ๋ํ๊ฑฐ๋ ์๊ธฐ์น ์์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์๋ค.
Array.prototype์ newMethod๋ฅผ ์ถ๊ฐํ๋ค๊ณ ๊ฐ์ ํ์ ๋, ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๊ฐ์ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋, ์์์น ๋ชปํ ๋ฐฉ์์ผ๋ก ๋์ํ ์ ์๋ค.
ํ์ค JavaScript ๋์์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ฝ๋์ ํธํ์ฑ ๋ฌธ์ ๋ฅผ ์ ๋ฐํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, ์๋ก์ด ์๋ฐ์คํฌ๋ฆฝํธ ๋ฒ์ ์ด๋ ๋ค๋ฅธ ํ๊ฒฝ์์๋ ๋ค๋ฅด๊ฒ ๋์ํ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฉฐ, ์ด๋ ์์์น ๋ชปํ ๋ฒ๊ทธ๋ฅผ ์ด๋ํ ์ ์๋ค.
๋ด์ฅ ํ์ ์ ์์ ํ๋ฉด ๋๋ฒ๊น ์ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์๋ค. ์์ ๋ ๋ฉ์๋๋ JavaScript ์์ง์ ํ์ค ๋์์ ๋ณ๊ฒฝํ๋ฏ๋ก, ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ด๋ฅผ ์ถ์ ํ๊ธฐ๊ฐ ํ๋ค์ด์ง๋ค.
๊ธ๋ก๋ฒ ๊ฐ์ฒด์ ์ฌ๋ณผ์ ์ถ๊ฐํ์ง ๋ง๋ผ:
๊ธ๋ก๋ฒ ๊ฐ์ฒด๋ JavaScript ์คํ ํ๊ฒฝ์์ ์ ์ญ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ค. ๋ธ๋ผ์ฐ์ ์์๋ window, Node.js์์๋ global ๊ฐ์ฒด๊ฐ ํด๋น๋๋ค. ์ด ๊ท์น์ ๊ธ๋ก๋ฒ ๊ฐ์ฒด์ ์ฌ๋ณผ์ด๋ ์์ฑ์ ์ถ๊ฐํ์ง ๋ง๊ณ , ์ถ๊ฐ๊ฐ ํ์ํ๋ค๋ฉด ๊ผญ ํ์ํ ๊ฒฝ์ฐ์๋ง ํ๋ผ๋ ๊ฒ์ด๋ค.
๊ธ๋ก๋ฒ ๊ฐ์ฒด๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ด ๋ชจ๋ ์ฝ๋์์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค. ์ฌ๊ธฐ์ ์ฌ๋ณผ์ด๋ ์์ฑ์ ์ถ๊ฐํ๋ฉด, ์ ์ญ ๋ณ์์ ์ด๋ฆ์ด ์ถฉ๋ํ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋ฉฐ, ์ด๋ ์ฝ๋์ ์๊ธฐ์น ๋ชปํ ๋์์ ์ด๋ํ ์ ์๋ค. ํนํ, ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค๋ฅธ ๊ฐ๋ฐ์์ ํ์ ํ ๋ ๋ฌธ์ ๊ฐ ๋ ์ ์๋ค.
๊ธ๋ก๋ฒ ๊ฐ์ฒด์ ๋ถํ์ํ ์ฌ๋ณผ์ด๋ ์์ฑ์ด ๋ง์ด ์ถ๊ฐ๋๋ฉด, ์ฝ๋์ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํ๊ณ , ์ฑ๋ฅ์๋ ์ํฅ์ ๋ฏธ์น ์ ์๋ค. ์ด๋ ํนํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฌธ์ ๊ฐ ๋ ์ ์๋ค.
๊ธ๋ก๋ฒ ๊ฐ์ฒด์ ์๋์น ์์ ์์ฑ์ด ์ถ๊ฐ๋๋ฉด, ๋๋ฒ๊น ํ ๋ ํผ๋์ ์ด๋ํ ์ ์๋ค. ์ด๋ค ์ฝ๋์์ ํด๋น ์ฌ๋ณผ์ ์์ ํ๊ฑฐ๋ ์ฐธ์กฐํ ์ ์๊ธฐ ๋๋ฌธ์, ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ถ์ ์ด ์ด๋ ต๋ค.
๊ธ๋ก๋ฒ ๊ฐ์ฒด์ ์ฌ๋ณผ์ ์ถ๊ฐํ ๋๋ ๋ฐ๋์ ๊ทธ ์ด์ ๋ฅผ ๋ช ํํ ํ๊ณ , ์ธ๋ถ์์ ์ด ์ฌ๋ณผ์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ ๊ฐ๋ฅ์ฑ์ ์ต์ํํด์ผ ํ๋ค.