[javascript] typeof와 instanceof의 차이점은 무엇이며 언제 사용해야합니까?

내 특별한 경우 :

callback instanceof Function

또는

typeof callback == "function"

중요합니까, 차이점은 무엇입니까?

추가 자료 :

JavaScript-Garden typeofinstanceof



답변

사용하여 instanceof사용자 정의 유형 :

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

typeof단순 내장 유형에 사용하십시오 .

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

사용 instanceof유형에 내장 된 복잡한을 위해 :

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

그리고 마지막 것은 조금 까다 롭습니다.

typeof null; // object


답변

둘 다 유형 정보를 반환하기 때문에 기능면에서 비슷하지만 instanceof문자열보다는 실제 유형을 비교하기 때문에 개인적으로 선호합니다 . 타입 비교는 인적 오류가 덜 발생하며 전체 문자열 비교보다는 메모리의 포인터를 비교하기 때문에 기술적으로 더 빠릅니다.


답변

typeof를 사용하는 좋은 이유는 변수가 정의되지 않은 경우입니다.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

instanceof를 사용하는 좋은 이유는 변수가 null 일 수 있기 때문입니다.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

따라서 제 생각에는 어떤 유형의 가능한 데이터를 확인하고 있는지에 달려 있습니다.


답변

일을 명확하게하려면 두 가지 사실을 알아야합니다.

  1. instanceof를 여부 오퍼레이터 테스트 prototype 속성 (A)의 생성자 어디서나 나타나는 원형 체인 물체. 대부분의 경우 이는 이 생성자를 사용하거나 해당 하위 항목을 사용하여 오브젝트를 작성 했음을 의미합니다 . 또한 프로토 타입은 Object.setPrototypeOf()메소드 (ECMAScript 2015) 또는 __proto__속성 (이전 브라우저, 더 이상 사용되지 않음) 으로 명시 적으로 설정할 수 있습니다 . 성능 문제로 인해 객체의 프로토 타입을 변경하지 않는 것이 좋습니다.

따라서 instanceof는 객체에만 적용 할 수 있습니다. 대부분의 경우 생성자를 사용하여 문자열이나 숫자를 만들지 않습니다. 할 수 있습니다. 그러나 당신은 거의하지 않습니다.

또한 instanceof는 확인할 수 없습니다. 정확히 어떤 생성자가 객체를 만드는 데 사용 되었는 지, 객체가 검사중인 클래스에서 파생 된 경우에도 true를 반환합니다. 대부분의 경우 이것은 바람직한 동작이지만 때로는 그렇지 않습니다. 그래서 당신은 그 마음을 유지해야합니다.

다른 문제는 다른 범위의 실행 환경이 다르다는 것입니다. 이것은 서로 다른 내장 기능 (다른 전역 객체, 다른 생성자 등)을 가지고 있음을 의미합니다. 예기치 않은 결과가 발생할 수 있습니다.

예를 들어, 배열은 전자로부터 상속 받기 때문에 [] instanceof window.frames[0].Array를 반환 합니다.
또한 프로토 타입이 없으므로 정의되지 않은 값으로 사용할 수 없습니다. falseArray.prototype !== window.frames[0].Array

  1. 과 typeof 연산자 테스트 여부 값 속하는 여섯 가지 기본 유형의 하나의숫자 “, ” 스트링 “, ” 부울 “, ” 개체 “, ” 기능 “또는 ” 정의되지 않은 “. 문자열 “object”가 모든 객체에 속하는 경우 (객체는 있지만 typeof 연산자에 자체 값이있는 함수 제외) “null”값과 배열 ( “null”의 경우 버그 임)이 버그는 너무 낡음 표준이되었습니다). 생성자에 의존하지 않으며 값이 정의되지 않은 경우에도 사용할 수 있습니다. 그러나 객체에 대한 세부 정보는 제공하지 않습니다. 따라서 필요한 경우 instanceof로 이동하십시오.

이제 까다로운 한 가지에 대해 이야기 해 봅시다. 생성자를 사용하여 기본 유형을 만들면 어떻게됩니까?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

마술처럼 보입니다. 그러나 그렇지 않습니다. 이른바 복싱 (객체별로 프리미티브 값 래핑) 및 언 박싱 (객체에서 래핑 된 프리미티브 값 추출)입니다. 이러한 종류의 코드는 “약간”깨지기 쉬운 것 같습니다. 물론 생성자를 사용하여 기본 유형을 만드는 것을 피할 수 있습니다. 그러나 권투가 당신을 칠 수있는 또 다른 가능한 상황이 있습니다. 기본 유형에서 Function.call () 또는 Function.apply ()를 사용하는 경우

function test(){
  console.log(typeof this);
}
test.apply(5);

이를 피하기 위해 엄격 모드를 사용할 수 있습니다.

function test(){
  'use strict';
  console.log(typeof this);
}
test.apply(5);

upd :
ECMAScript 2015부터 Symbol이라는 유형이 있는데, 자체 typeof == “symbol” 입니다.

console.log(typeof Symbol());
// expected output: "symbol"

MDN에서 읽을 수 있습니다 : ( Symbol , typeof ).


답변

Safari 5와 Internet Explorer 9에서 정말 흥미로운 ( “끔찍한”것으로 읽힌) 동작을 발견했습니다. Chrome과 Firefox에서이 기능을 성공적으로 사용하고있었습니다.

if (typeof this === 'string') {
    doStuffWith(this);
}

그런 다음 IE9에서 테스트했는데 전혀 작동하지 않습니다. 큰 놀라움. 그러나 Safari에서는 간헐적입니다! 그래서 디버깅을 시작하면 Internet Explorer가 항상 반환 false됩니다. 하지만 이상한 점은 사파리가 자사의 자바 스크립트 VM에 최적화 어떤 종류의 일을 할 것이다 첫 번째 시간,하지만 때마다 당신은 다시로드를 맞았다!truefalse

내 뇌는 거의 폭발했다.

이제 나는 이것에 정착했습니다.

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

이제 모든 것이 잘 작동합니다. 호출 할 수 "a string".toString()있으며 문자열의 사본을 반환합니다.

"a string".toString() === new String("a string").toString(); // true

이제부터 둘 다 사용하겠습니다.


답변

다른 중요한 실제 차이점 :

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true


답변

instanceof경우에도 작동 callback의 하위 유형은 Function내가 생각하기에,