- typeof 연산자 사용 (기본 타입을 객체와 구별하는데 가장 유용)
- typeof undefined 는 'undefined', typeof null은 'object'
- 배열은 객체이기 때문에 타입도 'object'
- 함수는 객체이긴 하지만 타입은 'function'
instanceof 와 constructor
-
- instanceof
- - 기본타입이나 함수가 아니라 객체일때 더 많은 정보를 얻기 위해 사용
x instanceof Array // x가 배열이라면 true
-
- - 왼쪽은 테스트될 값, 오른쪽은 클래스를 정의할 수 있는 생성자 함수
- - 객체는 자신이 속한 클래스와 상위 클래스의 인스턴스가 된다 (객체 o에 대해서 o instanceof Object는 항상 true)
- - 함수에 대해서도 작동
// 아래 모든 표현은 함수 f에 대해 true typeof f == "function" f instanceof Function f instanceof Object
-
- constructor
- - 객체가 특정한 클래스의 인스턴스고 그 클래스의 하위 클래스의 인스턴수는 아니라는 사실을 테스트할 때 그 객체의 constructor 프로퍼티를 검사
var d = new Date(); var isobject = d instanceof Object; // true var realobject = d.constructor == Object; // false
-
- instanceof 와 constructor의 한 가지 단점 : 이미 알고 있는 클래스만 테스트 가능
객체 타입 지정을 위한 Object.toString()
- 모르는 객체를 조사하는데 유용
- 확장된 typeof 검사
function getType(x) { if(x == null) return 'null'; var t = typeof x; if(t != "object") return t; // 객체의 클래스 값을 얻기 위해 시본 toString() 메서드 사용 var c = Object.prototype.toString.apply(x); // '[object class]' 반환 c = c.substring(8, c.length-1); // '[object'와 ']' 를 벗겨낸다 if(c != "Object") return c; // c가 'Object'라는 결과 얻으면, 여기로 온다 // x가 실제로 그냥 일반적인 객체인지 검사 if(x.constructor == Object) return c; // 사용자가 정의한 클래스를 위해서 객체의 프로토타입에서 상속받았으며 문자열 값을 가진 classname이란느 프로퍼티 찾음 if("classname" in x.constructor.prototype && typeof x.constructor.prototype.classname == "string") return x.constructor.prototype.classname; return "<unknown type>"; } |
오리 타이핑
-
- 어떤 클래스가 정의한 모든 메서드를 구현하면, 그것은 그 클래스의 인스턴스이다
- 다른 클래스에서 메서드를 빌려오는 클래스들을 연결할 때 유용
- 객체가 다른 클래스에서 메서드를 빌려왔는지 검사 예)
// c.prototype 에서 있는 각 메서드 프로퍼티가 o에서 빌려온 것이라면 true반환 // 만약 o가 객체라기 보다 함수라면 o자체보다 o의 프로토타입을 테스트한다 // 이 함수에서 메서드는 재구현된 것이 아니라 복사된 것이어야 한다 // 만약 클래스가 메서드를 빌려온 후 이를 재작성하면, false 반환 function borrow(o,c) { // 만약 무언가의 인스턴스라면, 당연히 그것의 메서드가 있으므로 true if(o instanceof c) return ture; // 내장 타입의 메서드는 열거될 수 없기 때문에 이런 메서드를 빌려온 것인지 검사하는 것은 불가능 // 이럴 때는 예외를 발생시키는 대신 "알수 없다" 라는 대답의 일종으로 undefined 반환 // undefined 는 false와 상당히 유사하게 작동하지만 필요하다면 호출자가 이를 false와 구별할 수 있다. if(c == Array || c == Boolean || c == Date || c == Error || c == Function || c == Number || c == RegExp || c == String) return undefined; if(typeof o == "function") o = o.prototype; var proto = c.prototype; for(var p in proto) { // 함수가 아닌 프로퍼티는 무시 if(typeof proto[p] != "function") continue; if(o[p] != proto[p]) return false; } return true; }
-
- 객체가 메서드를 제공하는지 검사 예)
// 만약 o의 메서드가 c.prototype에 있는 모든 메서드와 이름이 같고 인자 개수가 같다면 true 반환, 그렇지 않다면 false // 만약 c가 열거될 수 없는 메서드의 내장 타입이면 예외를 발생 function provides(o,c) { // 만약 o가 실제로는 c의 인스턴스라면 명백히 c처럼 보인다 if(o instanceof c) return true; // 만약 객체대신 생성자가 전달되면, 그것의 프로토타입을 사용 if(typeof o == "function") o = o.prototype; // 내장 타입의 메서드는 얼거될 수 없기 때문에 undefined 반환 // 그렇지 않으면 객체가 내장 타입을 제공하는 것처럼 보인다 if(c == Array || c == Boolean || c == Date || c == Error || c == Function || c == Number || c == RegExp || c == String) return undefined; var proto = c.prototype; for(var p in proto) { // c.prototype 에 있는 모든 프로퍼티에 대해 반복 // 함수가 아닌 프로퍼티는 무시 if(typeof proto[p] != "function") continue; // o에 같은 이름의 프로퍼티가 없으면 false 반환 if(!(p in o)) return false; // 만약 프로퍼티가 함수가 아니면 false 반환 if(typeof o[p] != "function") return false; // 두 함수의 전달인자 개수가 다르면 false 반환 if(o[p].length != proto[p].length) return false; } return true; }
-
- 배열과 유사한 객체를 테스트하기 예)
function isArrayLike(x) { if(x instanceof Array) return true; // 실제 배열은 배열과 유사하다고 판단 if(!("length" in x)) return false; // 배열에는 length 프로퍼티가 있어야 함 if(typeof x.length != "number") return false; // length 는 숫자여야 함 if(x.length < 0) return false; // 음수가 아니어야 함 if(x.length > 0) { // 배열이 비어있지 않다면, 최소한 length-1이라는 이름의 프로퍼티가 있다 if(!((x.length-1) in x)) return false; } return true; }
'IT_Programming > JavaScript' 카테고리의 다른 글
[펌] 안드로이드 레이어 이벤트 투과 문제 (0) | 2015.01.23 |
---|---|
자바스크립트 완벽가이드 - 9.8 예:유틸리티 메서드인 defineClass() (0) | 2015.01.02 |
[펌] 자바스크립트의 호이스팅(hoisting)이란? - 함수내 정의된 var, 함수, 클로저 동작의 진실 (0) | 2015.01.02 |
[펌_JQuery] jQuery의 JSONP을 사용한 크로스도메인간 통신 (0) | 2014.04.18 |
[펌] Live-Reload, 브라우저 자동 새로고침 (0) | 2013.07.03 |