type right - Lee-hyuna/33-js-concepts-kr GitHub Wiki
typeof ์ instanceof ์ดํด๋ณด๊ธฐ
์๋ฌธ: Beyond
typeofandinstanceof: simplifying dynamic type checks
์ด ํฌ์คํ ์ instanceof๋ฅผ ๋ ๋ง์ ๊ฐ(ํผ์ฐ์ฐ์)์ ์ ์ฉํ ์ ์๋ ๊ธฐ๋ฒ์ ์ค๋ช ํ๋ค. ํนํ ์์ ๊ฐ์ ๊ดํด ์ง์คํ ๊ฒ์ด๋ค.
1. ๋ฐฐ๊ฒฝ์ง์: typeof vs. instanceof
Javascript์์ ๊ฐ์ ํ์ ํ์ธ์ ์ธ์ ํด์ผํ ๊น? ๋๋ต ์ ์ธ ๊ท์น์ ๋ค์๊ณผ ๊ฐ๋ค.
-
typeof๋ ๊ฐ์ด ์์ ํ์ ์ ์์์ธ์ง ํ์ธํ๋ค.if (typeof value === 'string') -
instanceof๋ ๊ฐ์ด ํด๋์ค ๋๋ ์์ฑ์ ํจ์์ ์ธ์คํด์ค์ธ์ง ํ์ธํ๋ค.if (value instanceof Map)(๋ํ value.constructor ๋ฐ value.constructor.name๋ ์ ์ฉํ๋ค)
ํ์ง๋ง ์ด๊ฒ์ ์ด์์ ์ด์ง ๋ชปํ๋ค. ์๋ํ๋ฉด ์์ ๊ฐ๊ณผ ๊ฐ์ฒด์ ์ฐจ์ด์ ์ด ์ข ์ข ๋ชจํธํด์ง๊ธฐ ๋๋ฌธ์ด๋ค. ์ถ๊ฐ๋ก ๋ช๊ฐ์ง ์ด์ํ ์ ์ด ์ํฉ์ ๋์ฑ ๋ณต์กํ๊ฒ ๋ง๋ ๋ค.
-
typeof null์'object'์ด๋ค.'null'์ด ์๋๋ค. ์ด๊ฒ์ ๋ฒ๊ทธ๋ก ๊ฐ์ฃผ๋๋ค. -
typoeof๋ ๊ฐ์ฒด์ ํจ์๋ฅผ ๊ตฌ๋ถํ ์ ์๋ค.> typeof {} 'object' > typeof function () {} 'function'๋ฐ๋ผ์
typeof๋ฅผ ํตํด ๊ฐ์ฒด์ฑ์ ํ์ธํ ์ ์๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. -
๋ชจ๋ ๊ฐ์ฒด๊ฐ Object์ ์ธ์คํด์ค๋ ์๋๋ค.
> Object.create(null) instanceof Object false
2. ์์ ๊ฐ์ instaceof ์ ์ฉํด๋ณด๊ธฐ
PrimitiveNumber ํด๋์ค๊ฐ ์ฃผ์ด์ง๋ฉด, ์๋์ ์ฝ๋๋ x instanceof PrimitiveNumber ํํ์์ด true๋ฅผ ๋ฐํํ๋ ๊ฐ x๋ฅผ ๊ตฌ์ฑํ๋ค. PrimitiveNumber์ ๋ํ ์ ์ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ํค๊ฐ ๊ณต์ฉ ์ฌ๋ณผ ์ธ Symbol.hasInstance๊ฐ ๋๋ค.
class PrimitiveNumber {
static [Symbol.hasInstance](x) {
return typeof x === 'number';
}
}
console.log(123 instanceof PrimitiveNumber); // true
3. TypeRight library๋ฅผ ํตํ ๋์ ํ์ ํ์ธ
TypeRight์ ๋์ ํ์ ํ์ธ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ๋ค๋ฅธ ๊ธฐ๋ฅ ์ค์์๋ ๋ค์ ์์ ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ์ด์ ์์ ์์ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ ์ด์ฉํ๋ค. ์ด๊ฒ์ ์ ์ผํ ๋ชฉ์ ์ instanceof ์ฐ์ฐ์์ ์ค๋ฅธ์ชฝ ์๋ ๊ฒ์ด๋ค.
PrimitiveUndefinedPrimitiveNullPrimitiveBooleanPrimitiveNumberPrimitiveStringPrimitiveSymbol
TypeRight๋ ๊ฐ์ด ๊ฐ์ฒด์ธ์ง ํ์ธํ๋ ํด๋์ค๋ฅผ ์ ๊ณตํ์ง ์์ง๋ง ์ฝ๊ฒ ์ถ๊ฐํ ์ ์๋ค.
์ด๋ฌํ ๊ธฐ์ด๋ฅผ ๋ฐํ์ผ๋ก TypeRight๋ฅผ ์ฌ์ฉํ์ฌ ํจ์์ ๋งค๊ฐ ๋ณ์์ ์ ์ ํ ํ์ ์ด ์๋์ง ํ์ธํ ์ ์๋ค.
import * as tr from 'type-right';
function dist(x, y) {
tr.force(x, tr.PrimitiveNumber, y, tr.PrimitiveNumber);
return Math.hypot(x, y);
}
dist(3, 4); // 5
dist(3, undefined); // TypeError
4. ๊ฐ๋จํ ํ์ ํ์ธ์ ์ํ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ๋ฒ
์ ํ ๊ฒ์ฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ์ํ ๋ ๊ฐ์ง ์ ์์ ํ์ฌ statge-0 ๋จ๊ณ์ ์๋ค. ์ฆ, ํฅํ์ ๋ ์ด์ ํ๊ตฌ๋์ง ์์ ์๋ ์๋ ๋ป์ด๋ค.
4.1. ํจํด ๋งค์นญ
Brian Terlson๊ณผ Sebastian Markbรฅge์ ์ํด ์ ์๋ "ECMAScript Pattern Matching Syntax"์ด ์๋ค. Symbol.matches ๊ฐ ์กด์ฌํ๋ฉฐ ๊ฐ์ "machable"ํ๊ฒ ๋ง๋ ๋ค.
match (val) {
MyClass:
console.log('val is an instance of MyClass');
}
์ด ์์ฑ์ ๋ค์๊ณผ ๊ฐ์ด ์๋์ผ๋ก ์์ฑ๋๊ฑฐ๋ ์๋์ผ๋ก ์ถ๊ฐ ๋ ์ ์๋ค. (A ํ).
class PrimitiveNumber {
static [Symbol.matches](x) { // (A)
return x instanceof this;
}
}
4.2. Builtin.is() and Builtin.typeOf()
James M. Snell์ "Builtin.is and Builtin.typeOf" ์ ์์ ํ์ ๊ฒ์ฌ๋ฅผ ์ํ ๋ช ๊ฐ์ง ๋ฉ์ปค๋์ฆ์ ์๊ฐํ๋ค.
Builtin.is(value1, value2)๋ value1๊ณผ value2๊ฐ ๋์ผํ ์์ฑ์๋ฅผ ์ฐธ์กฐํ๋์ง ํ์ธํ๋ค. value1๊ณผ value2๋ ํ์ฌ ์์ญ์ด๋ ๋ค๋ฅธ ์์ญ์์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
> Builtin.is(Date, vm.runInNewContext('Date'))
true
> Builtin.is(Date, Date)
true
Builtin.typeOf()๋ ์์ ๊ฐ๊ณผ ๋ด์ฅ ํด๋์ค ๋ชจ๋์์ ์๋ํ๋ typeof์ ํ์ฅ์ผ๋ก ๋ณผ ์ ์๋ค.
Builtin.typeOf(undefined); // 'undefined'
Builtin.typeOf(null); // 'null'
Builtin.typeOf(123); // 'number'
Builtin.typeOf(new Number()); // 'Number'
Builtin.typeOf([]); // 'Array'
Builtin.typeOf(new Map()); // 'Map'
// The builtin counts, not the user-defined class
class MyArray extends Array {}
Builtin.typeOf(new MyArray()); // 'Array'
5.์ถ๊ฐ ์ฝ์ ๊ฑฐ๋ฆฌ
- Sect. โThe
constructorproperty of instancesโ in โSpeaking JavaScriptโ - Sect. โPitfall:
typeof nullโ in โSpeaking JavaScriptโ - Sect. โ
typeof: Categorizing Primitivesโ in โSpeaking JavaScriptโ - Sect. โPitfall: objects that are not instances of Objectโ in โSpeaking JavaScriptโ
- Sect. โProperty key
Symbol.hasInstanceโ in โExploring ES6โ