- typeof의 핵심 구현 원리
자바스크립트 내부의 타입 태그 메커니즘
자바스크립트 엔진 내부에서는 각 값이低位비트에 타입 태그(type tag)로 저장되어 있습니다. 이를 통해 typeof 연산자는 빠른 시간 내에 값의 타입을 식별할 수 있습니다.
// typeof의 내부 로직을 모방한 구현
function detectType(value) {
// 1. null 값에 대한 예외 처리
if (value === null) {
return 'object';
}
// 2. 함수 객체에 대한 특수 처리
if (typeof value === 'function') {
return 'function';
}
// 3. 내부 [[Class]] 속성을 기반으로 타입 판별
const internalType = Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
// 4. undefined에 대한 처리
if (value === undefined) {
return 'undefined';
}
// 5. 기본 타입 매핑 테이블
const typeMapping = {
number: 'number',
string: 'string',
boolean: 'boolean',
symbol: 'symbol',
bigint: 'bigint',
object: 'object'
};
return typeMapping[internalType] || 'object';
}
실제 엔진에서의 구현 개요
// V8 엔진 기반 타입 판별 로직
function V8Detect(value) {
// 내부 클래스 정보 조회
const classInfo = %_ClassOf(value);
switch (classInfo) {
case 'Number': return 'number';
case 'String': return 'string';
case 'Boolean': return 'boolean';
case 'Symbol': return 'symbol';
case 'BigInt': return 'bigint';
case 'Function': return 'function';
case 'Undefined': return 'undefined';
case 'Null': return 'object'; // 역사적 원인
default: return 'object';
}
}
typeof의 특수 동작 설명
// 역사적 문제로 인한 동작
typeof null === 'object' // true
// 함수对象的 특수 처리
typeof function() {} === 'function' // true
typeof class {} === 'function' // true
// 기타 객체들
typeof [] === 'object' // true
typeof {} === 'object' // true
typeof new Date() === 'object' // true
- instanceof의 핵심 구현 원리
instanceof의底层实现
// instanceof의 폴리필 구현
function checkInstance(target, constructor) {
// 1. 기본 타입은 즉시 false 반환
if (target === null || typeof target !== 'object' && typeof target !== 'function') {
return false;
}
// 2. 대상 객체의 프로토타입 참조 획득
let prototypeChain = Object.getPrototypeOf(target);
// 3. 프로토타입 체인 순회
while (prototypeChain !== null) {
// 4. 생성자의 프로토타입과 일치하면 true 반환
if (prototypeChain === constructor.prototype) {
return true;
}
// 5. 상위 프로토타입으로 이동
prototypeChain = Object.getPrototypeOf(prototypeChain);
}
// 6. 체인 끝까지 없으면 false 반환
return false;
}
경계 상황을 포함한 완전한 구현
function fullInstanceofCheck(target, constructor) {
// 생성자 유효성 검증
if (typeof constructor !== 'function') {
throw new TypeError('오른쪽 피연산자는 함수가 아닙니다');
}
// null이 아닌 객체 또는 함수인지 확인
if (target === null || (typeof target !== 'object' && typeof target !== 'function')) {
return false;
}
// 생성자의 프로토타입 참조
const constructorPrototype = constructor.prototype;
// 프로토타입이 유효한 객체가 아니면 예외 발생
if (typeof constructorPrototype !== 'object' && constructorPrototype !== null) {
throw new TypeError('프로토타입이 유효하지 않습니다');
}
// 프로토타입 체인 탐색
let current = Object.getPrototypeOf(target);
while (current !== null) {
if (current === constructorPrototype) {
return true;
}
current = Object.getPrototypeOf(current);
}
return false;
}
- 실전 활용 예제
typeof 활용 시나리오
function analyzeValue(data) {
const typeInfo = typeof data;
switch (typeInfo) {
case 'string':
return `문자열: ${data}`;
case 'number':
return `숫자: ${data}`;
case 'boolean':
return `불리언: ${data}`;
case 'undefined':
return '미정의 상태';
case 'function':
return '함수';
default:
if (data === null) return 'null';
return `객체: ${data.constructor.name}`;
}
}
console.log(analyzeValue('hello')); // 문자열: hello
console.log(analyzeValue(42)); // 숫자: 42
console.log(analyzeValue(null)); // null
instanceof 활용 시나리오
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
const dog = new Dog();
const cat = new Cat();
console.log(checkInstance(dog, Dog)); // true
console.log(checkInstance(dog, Animal)); // true
console.log(checkInstance(dog, Cat)); // false
console.log(checkInstance([], Array)); // true
console.log(checkInstance([], Object)); // true
- 성능 최적화 버전
캐시를 활용한 최적화 구현
function createOptimizedChecker() {
const memoCache = new WeakMap();
return function(target, constructor) {
// 기본 타입 빠른 경로
if (target === null || typeof target !== 'object') {
return false;
}
// 캐시 키 생성
const cacheKey = `${constructor.name}-${typeof target}`;
if (memoCache.has(cacheKey)) {
return memoCache.get(cacheKey);
}
// 프로토타입 체인 탐색
let chain = Object.getPrototypeOf(target);
while (chain !== null) {
if (chain === constructor.prototype) {
memoCache.set(cacheKey, true);
return true;
}
chain = Object.getPrototypeOf(chain);
}
memoCache.set(cacheKey, false);
return false;
};
}
const fastInstanceof = createOptimizedChecker();
- 핵심 차이점 요약
| 특성 | typeof | instanceof |
|---|---|---|
| 검사 대상 | 값의 타입 | 프로토타입 체인 관계 |
| 반환값 | 문자열 | 불리언 |
| null 처리 | 'object' 반환 | false 반환 |
| 성능 | O(1) | O(n) - 체인 길이 |
| 적합한场景 | 기본 타입 검사 | 상속 관계 검사 |
실무 사용 권장사항
// 기본 타입 검사에는 typeof 사용
if (typeof variable === 'string') {
// 문자열 처리
}
// 객체 타입 및 상속 관계 검사에는 instanceof 사용
if (variable instanceof Error) {
// 에러 객체 처리
}
// 배열 검사는 Array.isArray 권장
if (Array.isArray(variable)) {
// 배열 처리
}