instanceof
사람들이 JavaScript를 객체 지향 프로그래밍 언어가 아니라고 생각하는 경향이 있기 때문에 JavaScript 의 키워드는 처음 접했을 때 상당히 혼란 스러울 수 있습니다.
- 무엇입니까?
- 어떤 문제가 해결됩니까?
- 적절한시기와시기는?
답변
대신에
LHS (Left Hand Side) 피연산자는 클래스의 실제 생성자 인 RHS (Right Hand Side) 피연산자로 테스트되는 실제 객체입니다. 기본 정의는 다음과 같습니다.
Checks the current object and returns true if the object
is of the specified object type.
다음은 좋은 예 이며 Mozilla 개발자 사이트 에서 직접 가져온 예 입니다 .
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)
언급 할 가치가있는 것은 instanceof
객체가 클래스의 프로토 타입에서 상속되면 true 로 평가됩니다.
var p = new Person("Jon");
p instanceof Person
즉는 p instanceof Person
이후 사실 p
에서 상속 Person.prototype
.
OP의 요청에 따라
샘플 코드와 설명이있는 작은 예제를 추가했습니다.
변수를 선언하면 특정 유형을 지정합니다.
예를 들어 :
int i;
float f;
Customer c;
위의 변수 i
는 f
, 및 일부 변수를 보여줍니다 c
. 유형은 integer
, float
및 사용자 정의 Customer
데이터 타입. 위와 같은 유형은 JavaScript뿐만 아니라 모든 언어에 대한 것일 수 있습니다. 그러나 JavaScript를 사용하면 변수를 선언 할 때 유형을 명시 적으로 정의하지 않으며 var x
x는 숫자 / 문자열 / 사용자 정의 데이터 유형일 수 있습니다. 따라서 객체가 instanceof
위에서 지정한 객체 인지 확인하여 객체가 지정된 유형인지 확인합니다 Customer
.
var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!
위에서 우리는 c
type으로 선언 된 것을 보았습니다 Customer
. 우리는 그것을 새로 만들고 유형인지 여부를 확인했습니다 Customer
. 물론, 그것은 true를 반환합니다. 그런 다음 여전히 Customer
객체를 사용하여 객체인지 확인합니다 String
. 아니, 확실히 String
우리는 Customer
객체가 아닌 객체를 새롭게했습니다 String
. 이 경우 false를 반환합니다.
정말 간단합니다!
답변
지금까지 어떤 주석에서도 다루지 않은 것으로 보이는 인스턴스의 중요한 측면이 있습니다 : 상속. instanceof를 사용하여 평가되는 변수는 프로토 타입 상속으로 인해 여러 “유형”에 대해 true를 리턴 할 수 있습니다.
예를 들어, 타입과 서브 타입을 정의 해 봅시다 :
function Foo(){ //a Foo constructor
//assign some props
return this;
}
function SubFoo(){ //a SubFoo constructor
Foo.call( this ); //inherit static props
//assign some new props
return this;
}
SubFoo.prototype = Object.create(Foo.prototype); // Inherit prototype
SubFoo.prototype.constructor = SubFoo;
이제 몇 개의 “클래스”가 있으므로 인스턴스를 만들고 인스턴스가 무엇인지 알아볼 수 있습니다.
var
foo = new Foo()
, subfoo = new SubFoo()
;
alert(
"Q: Is foo an instance of Foo? "
+ "A: " + ( foo instanceof Foo )
); // -> true
alert(
"Q: Is foo an instance of SubFoo? "
+ "A: " + ( foo instanceof SubFoo )
); // -> false
alert(
"Q: Is subfoo an instance of Foo? "
+ "A: " + ( subfoo instanceof Foo )
); // -> true
alert(
"Q: Is subfoo an instance of SubFoo? "
+ "A: " + ( subfoo instanceof SubFoo )
); // -> true
alert(
"Q: Is subfoo an instance of Object? "
+ "A: " + ( subfoo instanceof Object )
); // -> true
마지막 줄 보여? 함수에 대한 모든 “새”호출은 Object에서 상속 된 오브젝트를 리턴합니다. 이것은 객체 생성 속기를 사용할 때도 마찬가지입니다.
alert(
"Q: Is {} an instance of Object? "
+ "A: " + ( {} instanceof Object )
); // -> true
“클래스”정의 자체는 어떻습니까? 그들은 무엇입니까?
alert(
"Q: Is Foo an instance of Object? "
+ "A:" + ( Foo instanceof Object)
); // -> true
alert(
"Q: Is Foo an instance of Function? "
+ "A:" + ( Foo instanceof Function)
); // -> true
필자는 객체를 MULTIPLE 유형의 인스턴스가 될 수 있다는 것을 이해하는 것이 중요하다고 생각합니다 instanceof
. 이 마지막 예에서 함수 는 객체 라는 것을 분명히 보여줍니다 .
상속 패턴을 사용하고 있고 오리 타이핑 이외의 방법으로 개체의 자손을 확인하려는 경우에도 중요합니다.
누군가가 탐험하는 데 도움이되기를 바랍니다 instanceof
.
답변
여기에있는 다른 대답은 정확하지만 instanceof
실제로 어떻게 작동 하는지 알지 못 하므로 일부 언어 변호사가 관심을 가질 수 있습니다.
JavaScript의 모든 객체에는 __proto__
속성을 통해 액세스 할 수있는 프로토 타입이 있습니다. 함수에는 prototype
속성 이 있습니다.이 속성은 __proto__
객체에 의해 생성 된 객체 의 초기 값 입니다. 함수가 작성되면에 대한 고유 한 오브젝트가 제공됩니다 prototype
. instanceof
운영자는 당신에게 대답을 줄이 고유성을 사용합니다. 여기에 무슨 instanceof
당신이 함수로 쓴 경우처럼 보일 수 있습니다.
function instance_of(V, F) {
var O = F.prototype;
V = V.__proto__;
while (true) {
if (V === null)
return false;
if (O === V)
return true;
V = V.__proto__;
}
}
이것은 기본적으로 ECMA-262 판 5.1 (ES5라고도 함) 15.3.5.3 절을 설명합니다.
객체를 함수의 prototype
속성에 재 할당 할 수 있으며 객체의 __proto__
속성을 생성 한 후 다시 할당 할 수 있습니다 . 이것은 당신에게 흥미로운 결과를 줄 것입니다 :
function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();
f instanceof F; // returns true
f instanceof G; // returns true
g instanceof F; // returns true
g instanceof G; // returns true
F.prototype = {};
f instanceof F; // returns false
g.__proto__ = {};
g instanceof G; // returns false
답변
objectof를 선언 할 때 “new”키워드를 사용하여 instanceof를 정의한다는 점에 주목할 가치가 있다고 생각합니다. JonH의 예제에서;
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
그가 언급하지 않은 것은 이것입니다.
var color1 = String("green");
color1 instanceof String; // returns false
“new”를 지정하면 실제로 문자열 생성자 함수의 종료 상태를 반환 값으로 설정하지 않고 color1 var에 복사했습니다. 새 키워드의 기능을 더 잘 보여줍니다.
function Test(name){
this.test = function(){
return 'This will only work through the "new" keyword.';
}
return name;
}
var test = new Test('test');
test.test(); // returns 'This will only work through the "new" keyword.'
test // returns the instance object of the Test() function.
var test = Test('test');
test.test(); // throws TypeError: Object #<Test> has no method 'test'
test // returns 'test'
“new”를 사용하면 함수 내의 “this”값이 선언 된 var에 할당되고, 사용하지 않으면 반환 값이 할당됩니다.
답변
다음과 같이 오류 처리 및 디버깅에 사용할 수 있습니다.
try{
somefunction();
}
catch(error){
if (error instanceof TypeError) {
// Handle type Error
} else if (error instanceof ReferenceError) {
// Handle ReferenceError
} else {
// Handle all other error types
}
}
답변
//Vehicle is a function. But by naming conventions
//(first letter is uppercase), it is also an object
//constructor function ("class").
function Vehicle(numWheels) {
this.numWheels = numWheels;
}
//We can create new instances and check their types.
myRoadster = new Vehicle(4);
alert(myRoadster instanceof Vehicle);
답변
무엇입니까?
자바 스크립트는 프로토 타입 언어로 ‘상속’에 프로토 타입을 사용합니다. instanceof
생성자 함수의 경우 운전자는 테스트 prototype
propertype이에 존재 __proto__
객체의 체인. 이것은 다음을 수행한다는 것을 의미합니다 (testObj가 함수 객체라고 가정).
obj instanceof testObj;
- 객체의 프로토 타입이 생성자의 프로토 타입과 같은지 확인하십시오 :
obj.__proto__ === testObj.prototype
>> if this istrue
instanceof
returntrue
. - 프로토 타입 체인을 올라갈 것입니다. 예를 들면 다음과 같습니다.
obj.__proto__.__proto__ === testObj.prototype
>> if is istrue
instanceof
returntrue
. - 전체 객체 프로토 타입이 검사 될 때까지 2 단계를 반복합니다. 아무 객체의 프로토 타입 체인이 일치하지 않을 경우
testObj.prototype
다음instanceof
연산자를 반환합니다false
.
예:
function Person(name) {
this.name = name;
}
var me = new Person('Willem');
console.log(me instanceof Person); // true
// because: me.__proto__ === Person.prototype // evaluates true
console.log(me instanceof Object); // true
// because: me.__proto__.__proto__ === Object.prototype // evaluates true
console.log(me instanceof Array); // false
// because: Array is nowhere on the prototype chain
어떤 문제가 해결됩니까?
객체가 특정 프로토 타입에서 파생되는지 편리하게 확인하는 문제를 해결했습니다. 예를 들어, 함수가 다양한 프로토 타입을 가질 수있는 객체를 수신 할 때. 그런 다음 프로토 타입 체인의 메소드를 사용하기 전에 instanceof
연산자를 사용 하여 이러한 메소드가 오브젝트에 있는지 여부를 확인할 수 있습니다 .
예:
function Person1 (name) {
this.name = name;
}
function Person2 (name) {
this.name = name;
}
Person1.prototype.talkP1 = function () {
console.log('Person 1 talking');
}
Person2.prototype.talkP2 = function () {
console.log('Person 2 talking');
}
function talk (person) {
if (person instanceof Person1) {
person.talkP1();
}
if (person instanceof Person2) {
person.talkP2();
}
}
const pers1 = new Person1 ('p1');
const pers2 = new Person2 ('p2');
talk(pers1);
talk(pers2);
여기서 talk()
함수에서 프로토 타입이 객체에 있는지 먼저 확인합니다. 그런 다음 적절한 방법을 선택하여 실행합니다. 이 검사를 수행하지 않으면 존재하지 않는 메소드가 실행되어 참조 오류가 발생할 수 있습니다.
적절한시기와시기는?
우리는 이미 이것을 극복했습니다. 객체의 프로토 타입을 확인해야 할 때 사용하십시오.