내 특별한 경우 :
callback instanceof Function
또는
typeof callback == "function"
중요합니까, 차이점은 무엇입니까?
추가 자료 :
JavaScript-Garden typeof 와 instanceof
Object.prototype.toString ecma-international.org/ecma-262/6.0/…을
.constructor대신 속성을.
내 특별한 경우 :
callback instanceof Function
또는
typeof callback == "function"
중요합니까, 차이점은 무엇입니까?
추가 자료 :
JavaScript-Garden typeof 와 instanceof
Object.prototype.toString ecma-international.org/ecma-262/6.0/…을
.constructor대신 속성을.
답변:
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
Use instanceof for complex built in types-여전히 오류가 발생하기 쉽습니다. ES5 Array.isArray()등 을 사용하는 것이 좋습니다 . 또는 권장 심.
둘 다 유형 정보를 반환하기 때문에 기능면에서 비슷하지만 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"
따라서 제 생각에는 어떤 유형의 가능한 데이터를 확인하고 있는지에 달려 있습니다.
instanceof기본 유형 인 typeof와 비교할 수 없습니다.
undefined instanceof Object는 false를 반환하고 예외를 throw하지 않습니다. 그 변화가 얼마나 최근인지는 모르겠지만 instanceof더 매력적입니다.
undefined instanceof Objecteh undefined가 정의되어 있으므로 예외를 throw하지 않습니다 . 상수는 네임 스페이스에 존재합니다. 변수가 존재하지 않으면 (예 : 오타로 인해) instanceof는 예외를 발생시킵니다. 존재하지 않는 변수에 typeof를 사용하면 'undefined'가됩니다.
일을 명확하게하려면 두 가지 사실을 알아야합니다.
Object.setPrototypeOf()메소드 (ECMAScript 2015) 또는 __proto__속성 (이전 브라우저, 더 이상 사용되지 않음) 으로 명시 적으로 설정할 수 있습니다 . 성능 문제로 인해 객체의 프로토 타입을 변경하지 않는 것이 좋습니다. 따라서 instanceof는 객체에만 적용 할 수 있습니다. 대부분의 경우 생성자를 사용하여 문자열이나 숫자를 만들지 않습니다. 할 수 있습니다. 그러나 당신은 거의하지 않습니다.
또한 instanceof는 확인할 수 없습니다. 정확히 어떤 생성자가 객체를 만드는 데 사용 되었는 지, 객체가 검사중인 클래스에서 파생 된 경우에도 true를 반환합니다. 대부분의 경우 이것은 바람직한 동작이지만 때로는 그렇지 않습니다. 그래서 당신은 그 마음을 유지해야합니다.
다른 문제는 다른 범위의 실행 환경이 다르다는 것입니다. 이것은 서로 다른 내장 기능 (다른 전역 객체, 다른 생성자 등)을 가지고 있음을 의미합니다. 예기치 않은 결과가 발생할 수 있습니다.
예를 들어, 배열은 전자로부터 상속 받기 때문에 [] instanceof window.frames[0].Array를 반환 합니다.
또한 프로토 타입이 없으므로 정의되지 않은 값으로 사용할 수 없습니다. falseArray.prototype !== window.frames[0].Array
이제 까다로운 한 가지에 대해 이야기 해 봅시다. 생성자를 사용하여 기본 유형을 만들면 어떻게됩니까?
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"
if an object is created by a given constructor 이것은 올바르지 않습니다. o instanceof Co가 C.prototype에서 상속되면 true를 반환합니다. 당신은 당신의 대답에서 나중에 이것에 대해 언급했지만 매우 명확하지 않습니다.
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
instanceofJavascript에서는 결함이있을 수 있습니다-주요 프레임 워크는 사용을 피하려고한다고 생각합니다. 다른 창은 깨질 수있는 방법 중 하나입니다. 클래스 계층 구조도 혼동 될 수 있다고 생각합니다.
객체가 특정 내장 유형 (보통 원하는 것)인지 테스트하는 더 좋은 방법이 있습니다. 유틸리티 기능을 작성하여 사용하십시오.
function isFunction(obj) {
return typeof(obj) == "function";
}
function isArray(obj) {
return typeof(obj) == "object"
&& typeof(obj.length) == "number"
&& isFunction(obj.push);
}
등등.
instanceof프리미티브 예를 들어 작동하지 않습니다 "foo" instanceof String반환 false하는 반면 typeof "foo" == "string"반환합니다 true.
반면 typeof에 사용자 정의 객체 (또는 클래스, 호출하려는 모든 객체)와 관련하여 원하는 것을 수행하지 않을 것입니다. 예를 들면 다음과 같습니다.
function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog // true, what we want in this case
함수는 'function'프리미티브와 'Function'인스턴스 일 수 있습니다. 예를 들어 다른 프리미티브 유형과 같은 방식으로 작동하지 않는 경우에는 약간 이상합니다.
(typeof function(){} == 'function') == (function(){} instanceof Function)
그러나
(typeof 'foo' == 'string') != ('foo' instanceof String)
기능을 확인할 때 항상 사용해야합니다 typeof 합니다.
차이점은 다음과 같습니다.
var f = Object.create(Function);
console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false
f(); // throws TypeError: f is not a function
그렇기 때문에 instanceof함수를 확인하기 위해 절대 사용해서는 안됩니다 .
typeof틀렸다고 주장 할 수 있습니다 f. Object(객체)와 Function(기능)입니다. 나를 제외하고는 instanceof모든 함수가 ECMAScript의 객체이기 때문에 그것이 함수라는 것을 알기 때문에 사용하는 것이 더 합리적 입니다. 반대의 사실이 아니다 -에서 알고 typeof그 것은 f참으로 object나는 그것이 또한 함수임을 모른다.
length, name그리고 call기능에서,하지만 그들 모두 소멸됩니다. 더 나쁜 것은 호출 할 수 없으며 TypeError말한다 : f is not a function.
실질적인 차이 :
var str = 'hello word';
str instanceof String // false
typeof str === 'string' // true
이유를 묻지 마십시오.
str에 문자열 객체가 아닌 문자열 프리미티브가 있기 때문 입니다. 숫자 프리미티브와 부울 프리미티브도 마찬가지입니다. 이들은 "구축 된"상대방 인 String, Number 및 Boolean 객체의 인스턴스가 아닙니다. JavaScript는 필요할 때이 세 가지 기본 요소를 오브젝트로 자동 변환합니다 (예 : 오브젝트의 프로토 타입 체인에서 메소드 활용). 실제 차이점의 반대 측면에서 instanceof 는 이후 배열을 확인하는 것이 좋습니다 typeof [] == "object" // true.
공연
typeofinstanceof둘 다 적용 가능한 상황 보다 빠릅니다 .
엔진에 따라 성능 차이는 typeof약 20 % 가 될 수 있습니다 . ( 마일리지는 다를 수 있습니다 )
다음은 벤치 마크 테스트입니다 Array.
var subject = new Array();
var iterations = 10000000;
var goBenchmark = function(callback, iterations) {
var start = Date.now();
for (i=0; i < iterations; i++) { var foo = callback(); }
var end = Date.now();
var seconds = parseFloat((end-start)/1000).toFixed(2);
console.log(callback.name+" took: "+ seconds +" seconds.");
return seconds;
}
// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
(subject instanceof Array);
}, iterations);
// Testing typeof
var tot = goBenchmark(function typeofTest(){
(typeof subject == "object");
}, iterations);
var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));
결과
instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
instanceof 항상 객체의 프로토 타입 체인을 따르기 때문에 성능 저하는 프로토 타입 체인이 클래스에서 얼마나 멀리 떨어져 있는지에 따라 instanceof테스트됩니다. 따라서 짧은 상속 체인의 경우 페널티가 낮아지고 (예 : [] instanceof Array, {} instanceof Object) 길어질 수 있습니다. 따라서 가상 코드의 관점에서 둘 다 동일 obj instanceof SomeClass하고 typeof obj !== 'string'의미가 같은 경우 ( 여러 클래스를 통해 테스트 if하지 않고 테스트를하는 경우 switch) 성능 측면에서 두 번째 코드를 선택하는 것이 좋습니다.
이 여기에 다른 모든 설명에 불과 보완 지식 - 내가 하지 사용하는 제안 .constructor사방.
TL; DR은 : 상황에서 어디는 typeof옵션이 아닙니다, 그리고 당신이 프로토 타입 체인에 대해 걱정하지 않는 것을 알고있을 때 , Object.prototype.constructor가능한 또는 더 나은 대안보다 수 있습니다 instanceof:
x instanceof Y
x.constructor === Y
1.1 이후 표준으로 사용되므로 이전 버전과의 호환성에 대해 걱정할 필요가 없습니다.
무함마드 우 메르 (Muhammad Umer)는이 글을 여기 어딘가에 간단히 언급했습니다. 전부는 아니다 - 그래서 그것은 프로토 타입 모두에서 작동 null또는 undefined:
// (null).constructor; // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties
(1).constructor; // function Number
''.constructor; // function String
([]).constructor; // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor; // function Boolean()
true.constructor; // function Boolean()
(Symbol('foo')).constructor; // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor
Array.prototype === window.frames.Array; // false
Array.constructor === window.frames.Array.constructor; // true
또한 사용 사례에 따라 전체 프로토 타입 체인을 확인할 필요가없는 것 보다 훨씬 빠를 수 있습니다 instanceof. 필자의 경우 값이 형식화 된 배열인지 확인하는 빠른 방법이 필요했습니다.
function isTypedArrayConstructor(obj) {
switch (obj && obj.constructor){
case Uint8Array:
case Float32Array:
case Uint16Array:
case Uint32Array:
case Int32Array:
case Float64Array:
case Int8Array:
case Uint8ClampedArray:
case Int16Array:
return true;
default:
return false;
}
}
function isTypedArrayInstanceOf(obj) {
return obj instanceof Uint8Array ||
obj instanceof Float32Array ||
obj instanceof Uint16Array ||
obj instanceof Uint32Array ||
obj instanceof Int32Array ||
obj instanceof Float64Array ||
obj instanceof Int8Array ||
obj instanceof Uint8ClampedArray ||
obj instanceof Int16Array;
}
https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
그리고 결과 :
Chrome 64.0.3282.167 (64 비트, Windows)
Firefox 59.0b10 (64 비트, Windows)
호기심으로, 나는 빠른 장난감 벤치 마크를했다 typeof; 놀랍게도 성능이 훨씬 떨어지고 Chrome에서는 조금 더 빠릅니다.
let s = 0,
n = 0;
function typeofSwitch(t) {
switch (typeof t) {
case "string":
return ++s;
case "number":
return ++n;
default:
return 0;
}
}
// note: no test for null or undefined here
function constructorSwitch(t) {
switch (t.constructor) {
case String:
return ++s;
case Number:
return ++n;
default:
return 0;
}
}
let vals = [];
for (let i = 0; i < 1000000; i++) {
vals.push(Math.random() <= 0.5 ? 0 : 'A');
}
https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
참고 : 기능이 나열된 순서는 이미지 간을 전환합니다!
Chrome 64.0.3282.167 (64 비트, Windows)
Firefox 59.0b10 (64 비트, Windows)
참고 : 기능이 나열된 순서는 이미지 간을 전환합니다!
var newObj = new Object;//instance of Object
var newProp = "I'm xgqfrms!" //define property
var newFunc = function(name){//define function
var hello ="hello, "+ name +"!";
return hello;
}
newObj.info = newProp;// add property
newObj.func = newFunc;// add function
console.log(newObj.info);// call function
// I'm xgqfrms!
console.log(newObj.func("ET"));// call function
// hello, ET!
console.log(newObj instanceof Object);
//true
console.log(typeof(newObj));
//"object"
에도 불구 의 instance 후 빠르게 조금있을 수 있습니다 대해서 typeof , 나 때문에 그런 가능한 마법의 두 번째를 선호 :
function Class() {};
Class.prototype = Function;
var funcWannaBe = new Class;
console.log(funcWannaBe instanceof Function); //true
console.log(typeof funcWannaBe === "function"); //false
funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function
한 가지 더 사례는 당신이 함께 수집 할 수 있다는 것입니다-true instanceof또는 false를 반환합니다. typeof당신 과 함께 제공되는 무언가의 유형을 얻을 수 있습니다
물론 중요합니다 .....!
예제를 통해이 과정을 살펴 보도록하겠습니다.이 예제에서는 두 가지 방식으로 함수를 선언합니다.
함수 생성자function declaration 와 둘 다를 사용할 것 입니다. 이 두 가지 시나리오에서 방법 과 동작을 살펴 보겠습니다 .typeofinstanceof
함수 선언을 사용하여 함수를 만듭니다.
function MyFunc(){ }
typeof Myfunc == 'function' // true
MyFunc instanceof Function // false
서로 다른 결과에 대한 가능한 설명은 우리가 함수 선언을 같이이며, typeof그것은 function.Because의 것을 이해할 수있다 typeof대해서 typeof가에 작동되는 발현 여부, 우리의 경우 검사 구현 호출 방법 여부 . 그것을 구현하는 경우 방법을 그것은 function.Otherwise하지 .FOR 설명 체크입니다 대해서 typeof의 ECMAScript 사양 .MyFunc Call
함수 생성자를 사용하여 함수 만들기 :
var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used
typeof MyFunc2 == 'function' // true
MyFunc2 instanceof Function // true
여기에 typeof그 주장 MyFunc2함수뿐만 아니라 같은 instanceofoperator.We은 이미 알고있는 typeof경우 검사를 MyFunc2구현 Call방법 또는 not.As이 MyFunc2함수이며 구현하는 call방법의 것을, 방법 typeof은 다른 한편으로는 function.On에게 있다고 알고, 우리가 사용 function constructor만드는 데 MyFunc2, 그것을 의 인스턴스가된다 Function constructor저놈이 이유 instanceof에 또한 결의 true.
사용하는 것이 더 안전합니까?
두 경우 모두에서 알 수 있듯이 typeof운영자는 여기에서 함수를 다루고 있다고 성공적으로 주장 할 수 있습니다 instanceof. 의 인스턴스가 아니기 때문에 instanceof실패 합니다.function declarationfunction declarationsFunction constructor
모범 사례 :
Gary Rafferty가 제안 했듯이 가장 좋은 방법은 typeof와 instanceof를 함께 사용하는 것입니다.
function isFunction(functionItem) {
return typeof(functionItem) == 'function' || functionItem instanceof Function;
}
isFunction(MyFunc) // invoke it by passing our test function as parameter
위의 예제들에 압도 할 필요가 없습니다. 단지 두 가지 관점을 명심하십시오 :
typeof var;단항 연산자는 var의 원래 유형 또는 루트 유형을 반환합니다. 그래서 기본 유형 (새 것으로 string, number, bigint, boolean, undefined, 및 symbol) 또는 object타입.
내장 객체 (String, Number, Boolean, Array ..) 또는 복잡한 객체 또는 사용자 정의 객체와 같은 상위 레벨 객체의 경우 모든 객체는 object루트 유형이지만 기본 객체 유형은 OOP 클래스와 같이 다릅니다. 상속 개념), 여기 a instanceof A-이진 연산자-가 도움이 될 것이며 프로토 타입 체인을 통해 올바른 피연산자 (A)의 생성자가 나타나는지 여부를 확인합니다.
따라서 "루트 유형"을 확인하거나 기본 변수를 사용할 때마다 "typeof"를 사용하고, 그렇지 않으면 "instanceof"를 사용하십시오.
null겉보기에 원시적 인 것처럼 보이는 특별한 경우이지만, 실제로는 물체의 특별한 경우입니다. a === null대신 null을 확인하는 데 사용 합니다.
반면에 function내장 된 객체이지만 typeof반환 되는 특수한 경우이기도합니다.function
보시 instanceof다시피 프로토 타입 체인을 거쳐야 typeof하지만 루트 유형을 한 번만 확인하면 왜 typeof더 빠른지 이해할 수 있습니다.instanceof
typeof 에 대한 MDN 설명서에 따르면 "new"키워드로 인스턴스화 된 객체는 'object'유형입니다.
typeof 'bla' === 'string';
// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String('abc') === 'object';
동안 의 instanceof에 대한 설명서를 점한다 :
const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true
예를 들어 어떤 방식으로 문자열이 생성되었는지 확인하려는 경우 가장 안전한 방법을 사용하는 것 instanceof입니다.