Javascript 배열 형식 검사: 더 강 한 isArray 함수 작성

더 읽 기
일상적인 개발 에서 우 리 는 특정한 대상 이 배열 유형 인지 아 닌 지 를 판단 해 야 한다. js 에서 대상 유형 을 검사 하 는 흔 한 방법 은 몇 가지 가 있다.
1. type: of 연산 자.Function, String, Number, Undefined 등 몇 가지 유형의 대상 에 게 는 아무런 문제 가 없 지만 Array 의 대상 에 게 는 아무런 용도 가 없습니다.

alert(typeof null); // "object"
alert(typeof []); // "object"

2. instanceof 연산 자.이 조작 자 는 대상 의 원형 체인 이 구조 함수 의 prototype 대상 을 가리 키 는 지 여 부 를 검사 합 니 다. 네, 괜 찮 은 것 같 습 니 다. 우리 의 배열 검 측 문 제 를 해결 할 수 있 을 것 입 니 다.

var arr = []; 
alert(arr instanceof Array); // true 

3. 대상 의 constructor 속성 입 니 다.instanceof 를 제외 하고 우 리 는 모든 대상 이 constructor 의 속성 을 가지 고 그 유형 을 판단 할 수 있 기 때문에 우 리 는 이렇게 할 수 있다.
var arr = []; 
alert(arr.constructor == Array); // true

뒤의 두 가지 해결 방안 은 흠 잡 을 데 가 없 는 것 같 지만 정말 그런 가?하늘 에 예측 할 수 없 는 풍운 이 있 습 니 다. 여러 프레임 을 오 갈 때 우울 한 문제 가 발생 했 습 니 다.

var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array; 
var arr = new xArray(1,2,3); // [1,2,3] 
//   ! 
arr instanceof Array; // false 
//    ! 
arr.constructor === Array; // false

모든 iframe 은 자신의 실행 환경 을 가지 기 때문에 frame 을 뛰 어 넘 는 실례 화 된 대상 은 서로 원형 체인 을 공유 하지 않 기 때문에 상기 검 측 코드 가 효력 을 잃 습 니 다!어 떡 해, 어 떡 해?음, javascript 은 동적 언어 입 니 다. 아마도 만금 유 '오리 식 분별 형' (Duck type) 은 우리 에 게 도움 을 줄 수 있 습 니 다. "만약 에 길 을 걷 는 것 이 오리 같 고 소리 지 르 는 것 도 오리 같다 면 그 가 오리 라 고 생각 하 세 요." 같은 이치 로 일부 배열 대상 의 독특한 능력 을 측정 하여 판단 할 수 있 습 니 다. 이 방법 은 이미 누군가가 사용 하고 있 습 니 다. 예 를 들 어 Prototype 프레임 워 크 등 입 니 다.이 를 실현 하 는 Object. isArray 방법 을 살 펴 보 자.

isArray: function(object) { 
return object != null && typeof object == "object" &&
 'splice' in object && 'join' in object; 
}

isArray: "object, splice, join 두 배열 특유 의 방법 이 있 습 니까?"
object: "응, 맞 아. 나 있어!"
isArray: "그래, 그럼 너 는 배열 이 야. 네가 사칭 하 더 라 도 멘 붕..."

var trickster = { splice: 1, join: 2 }; 
Object.isArray(trickster); //     , 

맞 아, 이 솔 루 션 은 사람 에 게 어색 한 느낌 을 주 고 'plice' 와 'join' 속성 을 가 진 모든 대상 이 이 검 사 를 통과 할 수 있어!어 떡 해, 어 떡 해, 어 떡 해?조급해 하지 말고 곰 곰 이 생각해 보 세 요. 사실 우리 에 게 필요 한 것 은 대상 의 실제 유형 을 얻 을 수 있 고 frame 을 뛰 어 넘 을 수 있 는 방법 입 니 다.아니, 세심 한 외국인 이 ECMA 262 기준 을 뒤 졌 을 때 이 걸 발 견 했 어. (btw, 나 도 봤 는데 왜 이 용 도 를 발견 하지 못 했 지? 멘 붕)
ECMA - 262 적 혀 있 습 니 다.
Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)
위의 규범 은 Object. prototype. toString 의 행 위 를 정의 합 니 다. 우선 대상 의 내부 속성 [Class] 을 얻 은 다음 에 이 속성 에 따라 '[object Array]' 와 유사 한 문자열 을 결과 로 되 돌려 줍 니 다.... 이 방법 을 이용 하여 콜 에 맞 추 면 우 리 는 모든 대상 의 내부 속성 [Class] 을 얻 을 수 있 습 니 다. 그리고 유형 검 사 를 문자열 로 비교 하여 우리 의 목적 을 달성 할 수 있 습 니 다. ECMA 표준 에서 Array 의 설명 을 먼저 살 펴 보 겠 습 니 다.
ECMA - 262 적 혀 있 습 니 다.
new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”.
따라서 이 기능 을 이용 하여 이전의 isArray 함 수 를 바 꿀 수 있 습 니 다. 다음 과 같 습 니 다.

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}

call 은 toString 의 this 인용 을 검 측 대상 으로 바 꾸 고 이 대상 의 문자열 을 되 돌려 표시 한 다음 이 문자열 이 '[object Array]' 인지 비교 하여 Array 의 인 스 턴 스 인지 아 닌 지 를 판단 합 니 다. 왜 o. toString () 을 직접 하지 않 는 지 물 어 봐 야 할 지도 모 릅 니 다.? 네, Array 는 Object 로부터 계승 되 고 toString 방법 도 있 지만 이 방법 은 우리 의 요구 에 미 치지 못 할 수도 있 습 니 다. Object. prototype 은 호랑이 의 엉덩이 로 감히 건 드 리 는 사람 이 별로 없 기 때문에 어느 정도 '순결 성' 을 보장 할 수 있 습 니 다.)
앞의 몇 가지 방안 과 달리 이 방법 은 크로스 프레임 대상 구축 문 제 를 잘 해결 하고 테스트 를 통 해 각 브 라 우 저 호환성 도 좋아 서 안심 하고 사용 할 수 있 습 니 다. 좋 은 소식 은 jQuery, Base 2 등 여러 프레임 워 크 가 이 방법 을 참고 하여 특정한 특수 한 것 을 실현 할 계획 입 니 다. 예 를 들 어 배열, 정규 표현 식 등 대상 의 유형 판정 은 우리 가 사용 하지 않 아 도 됩 니 다.자기가 썼어.

좋은 웹페이지 즐겨찾기