>웹 프론트엔드 >JS 튜토리얼 >Jquery_01_isPlainObject 분석 및 재구성_javascript 기술을 넘어서

Jquery_01_isPlainObject 분석 및 재구성_javascript 기술을 넘어서

WBOY
WBOY원래의
2016-05-16 18:18:22956검색

isPlainObject는 Jquery 1.4 이후에 제공되는 새로운 메서드로, 객체가 순수 객체("{}" 또는 "새 객체"를 통해 생성됨)인지 확인하는 데 사용됩니다.

isPlainObject 사용
먼저 '순수 객체'가 무엇인지 이해해 보겠습니다. '순수 객체'는 Object로 구성된 객체를 의미합니다. 그러면 어떤 객체가 Object로 구성됩니까? 부담을 가장 먼저 감당해야 하는 것은 new Object()에 의해 생성된 객체여야 합니다. 참고: Object 뒤의 괄호 안에는 아무것도 추가되지 않습니다. Object는 모든 '클래스'의 기초이기 때문에 몇 가지 특별한 동작을 갖습니다. 예를 들어 new Object(3)가 호출되면 Number 유형 객체가 생성됩니다. new Object('')는 String 유형의 객체를 생성합니다. 그러면 {} 형식으로 정의된 객체도 '순수 객체'에 속합니다. '{}'의 본질은 new Object()이지만 표현이 다릅니다. 자, 코드를 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.

var objStr = new Object('');
alert(objStr.constructor);//String
alert(isPlainObject(objStr));//false
var objNum = new Object(3) ;
alert(objNum.constructor);//Number
alert(isPlainObject(objNum));//false
function Person(){}
var person = new Person(); >alert(isPlainObject(person));//false
var obj01 = new Object();
obj01.name = '바보의 좌우명'
alert(isPlainObject(obj01));//true
alert( isPlainObject({name:'Motto of Idiot'}));//true

isPlainObject 소스 코드 분석
다음 코드는 Jquery의 isPlainObject의 전체 버전입니다. 의견은 매우 자세합니다. 더 이상 말할 것이 없습니다.

코드 복사 코드는 다음과 같습니다.
var toString = Object.prototype.toString,
hasOwnProperty = Object.prototype.hasOwnProperty;
function isPlainObject( obj ) {
// 객체여야 합니다.
// IE 때문에 생성자 속성도 확인해야 합니다. .
//DOM 노드와 창 객체도 통과하지 않도록 하세요.
//windows object:toString.call(window):IE [object Object] FF [object Window] chrome [window global] safari [객체 DOMWindow]
//DOM 노드:toString.call(#div01):IE [객체 객체] FF [객체 창] chrome [객체 전역] safari [객체 DOMWindow]
//결론: obj.nodeType || obj.setInterval은 주로 IE 브라우저를 판단하는 데 사용됩니다
//참고: 기록, 위치, 탐색기 및 화면의 setInterval은 정의되지 않습니다
if ( !obj || toString.call(obj) ! == "[object Object]" || obj.nodeType || obj.setInterval ) {
return false
}
// 자신의 생성자 속성이 Object여야 함
// 사용자 정의 개체 제거 그리고 function Person(){}과 같은 내장 객체의 판단 var p = new Person();String,Number
if ( obj.constructor //생성자 속성이 있습니다
&& !hasOwnProperty.call( obj, "constructor" ) //그리고 생성자 속성은 프로토타입 체인에 정의되어야 합니다
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")//그리고 프로토타입에는 isPrototypeOf 메서드가 있습니다. 일반적으로 Object의 프로토타입에서만 이 메서드만
) {
return false
}
// 고유한 속성이 먼저 열거되므로 속도를 높이기 위해
// 마지막 속성이
//복잡한 클래스 구조의 경우 상속이 있는 경우...
/*
//간단한 테스트
function Animal(name){
}
function Person(이름,나이){
Animal.call(this,name);
this.age =age
}
var p = new Person('jxl', 20);
for(key in p){
alert(hasOwnProperty.call( p, key ))//true , false
}
*/
var key; for ( key in obj ) {}
return key === 정의되지 않음 || hasOwnProperty.call( obj, key );


질문하세요
이 구현이 더 복잡하고 버그가 있다고 생각합니다.
간단한 BUG, ​​​​기록, 위치, 네비게이터, 화면은 isPlainObject 감지를 통해 순차적으로 true를 반환할 수 있습니다.
제 솔루션을 살펴보겠습니다(BUG 수정, 단순화):



코드 복사 코드는 다음과 같습니다. function isPlainObject(obj){
if(obj&&Object.prototype. toString.call(obj)= ==="[object Object]"&&obj.constructor===Object &&!hasOwnProperty.call(obj, "constructor")){
var key
for ( 키 입력; obj ) {}
return key === 정의되지 않음 || hasOwnProperty.call( obj, key )
}
return false
}


또한 있습니다. BUG이며 해결 불가능한 BUG입니다.


코드 복사 코드는 다음과 같습니다.

function m(){};
m.prototype.constructor=Object; //꼭 죽여야 함
obj=new m; //true

동일한 논리를 가진 또 다른 코드:

코드 복사 코드는 다음과 같습니다. 🎜>
function m(){};
m.prototype = {};
obj=new m
alert(isPlainObject(obj)) //true

이 답변은 해결할 수 없습니다!
해결 불가 문제
이 문제는 해결하기 쉬운 문제인 줄 알았는데, 좀 더 깊이 파고들어 보니 해결 불가능한 문제였습니다. 그 이유는 다음과 같습니다.



코드 복사 코드는 다음과 같습니다. function Person( ){};
Person.prototype.constructor=Object;
var person=new Person


person의 현재 상태를 살펴보겠습니다.

person 및 해당 구성 Person 함수에 대한 유일한 연결은 해당 프로토타입 체인의 생성자 속성입니다. '순수 객체'인지 판단할 때 주로 객체 인스턴스의 생성자를 기준으로 합니다. 그림에서 볼 수 있듯이 개체를 가리키면 사람과 사람은 코드에서 아무런 관계가 없습니다. 유형 판단에 문제가 발생하는 것은 바로 이 때문이다.
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.