우리는 객체가 생성자의 인스턴스인지 여부를 확인하는 데 objectof 연산자가 사용된다는 것을 알고 있습니다. true를 반환하는 다양한 시나리오는 다음과 같습니다.
1. obj 객체가 new Constructor를 통해 생성된 다음 obj 인스턴스of Constructor가 true입니다.
다음과 같이 코드 코드를 복사합니다.
함수 사람(n, a) {
this.name = n;
this.나이 = a;
}
var p = new Person('존 배커스', 82);
console.log(p 인스턴스ofPerson); // 참
2. 상속 관계가 있는 경우 하위 클래스와 상위 클래스의 인스턴스도 true를 반환합니다.
다음과 같이 코드 코드를 복사합니다.
함수 A(){}
함수 B(){}
B.prototype = new A(); // B는 A에서 상속됩니다.
var b = 새로운 B();
console.log(b 인스턴스A); // 참
3. Object가 루트 클래스이므로 다른 모든 사용자 정의 클래스는 이 클래스에서 상속되므로 생성자의 Object 인스턴스는 true를 반환합니다.
다음과 같이 코드 코드를 복사합니다.
함수 A() {}
var a = 새로운 A();
console.log(Object의 인스턴스); // true
var str = new String('hello');
console.log(str 인스턴스 오브 객체); // 참
var num = 새로운 숫자(1);
console.log(개체 인스턴스 수); // 참
심지어 생성자 자체도
다음과 같이 코드 코드를 복사합니다.
함수 A() {}
console.log(Objectof 인스턴스); // 참
console.log(String instanceof Object); // 참
console.log(객체 인스턴스 수); // true
4. Function의 모든 생성자 인스턴스는 true를 반환합니다.
다음과 같이 코드 코드를 복사합니다.
함수 A() {}
console.log(함수 인스턴스); // true
console.log(StringinstanceofFunction); // 참
console.log(함수 인스턴스 수); // true
위의 네 가지 사항은 한 문장으로 요약됩니다. 특정 클래스나 그 하위 클래스에 의해 인스턴스가 생성되면 instanceof는 true를 반환합니다. 또는 특정 생성자의 프로토타입이 객체 obj의 내부 프로토타입 체인에 존재하는 경우 true가 반환됩니다. 즉, instanceof의 결과는 생성자 자체와 직접적인 관계가 없습니다. 이것은 많은 언어에서 일반적입니다.
Person 클래스는 Java로 정의되고 인스턴스 p는 Person과 Object 모두에 대해 true를 반환합니다.
다음과 같이 코드 코드를 복사합니다.
클래스 사람 {
공개 문자열 이름;
공개 연령;
사람(문자열 n, int a) {
this.name = 이름;
this.나이 = a;
}
공개 정적 무효 메인(String[] args) {
Person p = new Person("John Backus", 82);
System.out.println(p 인스턴스ofPerson); // 참
System.out.println(p 인스턴스 오브 객체); // 참
}
}
Java에 상속 관계가 있는 경우 하위 클래스의 상위 클래스 인스턴스도 true를 반환합니다.
다음과 같이 코드 코드를 복사합니다.
// 부모 클래스
클래스 사람 {
공개 문자열 이름;
공개 연령;
사람(문자열 n, int a) {
이름 = 이름;
나이=a;
}
}
// 서브클래스
공개 클래스 Man은 Person{을 확장합니다.
공립 스트링 대학교;
Man(문자열 n, int a, 문자열 s) {
슈퍼(n,a);
대학 = s;
}
공개 정적 무효 메인(String[] args) {
Man mm = new Man("John Resig", 29, "PKU");
System.out.println(mm 인스턴스of Man); // 참
System.out.println(mminstanceofPerson); //역시 참
}
}
이를 알면 JS에서 다음과 같은 성능은 놀라운 일이 아닙니다.
다음과 같이 코드 코드를 복사합니다.
//두 개의 생성자를 정의합니다.
함수 A(){}
함수 B(){}
A.prototype = B.prototype = {a: 1};
//서로 다른 생성자의 두 인스턴스를 각각 생성합니다.
var a = 새로운 A();
var b = 새로운 B();
console.log(B 인스턴스); // true
console.log(b 인스턴스of A); // 참
a와 b는 각각 A와 B로 생성되었지만 B의 인스턴스와 A의 b 인스턴스는 모두 참입니다. 즉, 생성자 B를 사용하여 a를 생성하지 않더라도 여전히 true를 반환합니다. 왜냐하면 B.prototype은 a의 내부 프로토타입 체인에 존재하기 때문입니다.
JS의 동적 언어 특성으로 인해 프로토타입은 런타임에 수정될 수 있으므로 다음이 false를 반환하는 것은 놀라운 일이 아닙니다. A.prototype이 더 이상 a의 내부 프로토타입 체인에 없기 때문에 체인이 중단됩니다.
다음과 같이 코드 코드를 복사합니다.
함수 A(){}
var a = 새로운 A();
A.prototype = {}; // 프로토타입을 동적으로 수정합니다. 프로토타입을 생성한 후에 수행해야 합니다.
console.log(A 인스턴스) // false
이것을 작성하면 위에 요약된 첫 번째 요점도 깨집니다. 객체 obj는 new Constructor를 통해 생성되고 obj 인스턴스of Constructor는 true입니다.
실제로 ECMAScript 표준(5.1 적용)에서, instanceof의 내부 구현은 생성자의 내부 메소드 [[HasInstance]]를 호출하며, 이는 다음과 같이 설명됩니다.
F가 함수 객체인 경우 F(V)가 실행되면 다음 단계가 발생합니다.
1. instanceof의 왼쪽 피연산자 V가 객체 유형이 아닌 경우 false를 직접 반환합니다.
다음과 같이 코드 코드를 복사합니다.
var a, b = 1, c = true, d = '안녕하세요';
console.log(a instanceof Object); // false 여기서 값은 정의되지 않았습니다.
console.log(b 인스턴스 오브 객체); // 거짓
console.log(c 인스턴스 오브 객체); // 거짓
console.log(d 인스턴스 오브 객체); // 거짓
2/3. 생성자 F의 프로토타입 속성을 가져옵니다. 객체 유형이 아닌 경우 TypeError 예외가 발생해야 합니다.
다음과 같이 코드 코드를 복사합니다.
함수 A(){}
A.prototype = 1; // A의 프로토타입을 비객체 유형으로 설정합니다.
var a = 새로운 A();
console.log(A 인스턴스);
각 브라우저에서 발생하는 예외 프롬프트는 다릅니다.
파이어폭스18:
크롬24:
사파리6:
오페라12:
IE10:
4. 다음 논리를 지속적으로 실행합니다. V를 내부 프로토타입의 V로 설정하고, V가 null이면 false를 반환하고, V와 O가 모두 동일한 객체를 가리키면 true를 반환합니다.