Typeof ve instanceof arasındaki fark nedir ve biri diğerine karşı ne zaman kullanılmalıdır?


394

Benim özel durumumda:

callback instanceof Function

veya

typeof callback == "function"

fark eder mi, fark nedir?

Ek Kaynak:

JavaScript-Garden typeof vs instanceof


2
Cevabımı burada kullanımı kolay bir çözüm olarak buldum
CrandellWS

1
Object.prototype.toString Ecma-international.org/ecma-262/6.0/…
rab

1
Sadece kullanmak .constructoryerine özelliğini.
Muhammed Umer

Performansı merak ediyorsanız , aşağıdaki cevabıma bakın . typeof , her ikisinin de geçerli olduğu yerlerde (yani nesneler) daha hızlıdır.
Martin Peter

Yanıtlar:


540

instanceofÖzel türler için kullanın :

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 

typeofBasit dahili tipler için kullanın :

'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

Yerleşik instanceofkarmaşık tipler için kullanın :

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

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

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

Ve sonuncusu biraz zor:

typeof null; // object

11
Bu cevap instaceof neden o temizlemek yapar değil ilkel türleri için kullanılabilir. Özel türler söz konusu olduğunda bir seçeneğinizin yanı sıra 'nesne' türleri için avantajınız olmadığı oldukça açıktır. Peki "basit yerleşik türler" ile işlevleri bir araya getiren nedir? Bir fonksiyonun bir nesne gibi nasıl davrandığını garip buluyorum, ancak bu tip 'fonksiyon' kullanımını 'typeof' kullanımını mümkün kılıyor. Yine de bunun için neden cesaretini kırdın ki?
Assimilater

4
@Assimilater, instanceof'i işlevlerle de kullanabilirsiniz, ancak bu 3 kuralın hatırlanması çok basit olduğunu düşünüyorum ve evet, işlevler bir istisnadır :)
Szymon Wygnański

2
başka bir zor bölüm -> 'örnek dize' instanceof Dize; // false but new String ('örnek dize') instanceof Dize; // doğru
Luke

2
@Bunun gibi "yeni String" kullanmak genellikle kötü bir fikirdir. ilkel bir dize yerine bir "dize nesnesi" oluşturur. buradaki bölüme bakınız developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
Colin D

4
Use instanceof for complex built in types- bu hala hataya açıktır. ES5 Array.isArray()ve ark. veya tavsiye edilen şimler.
OrangeDog

122

Her ikisi de işlevsellik benzer çünkü her ikisi de tür bilgilerini döndürür, ancak ben instanceofdizeleri yerine gerçek türleri karşılaştırdığından şahsen tercih ederim . Tür karşılaştırması insan hatasına daha az eğilimlidir ve teknik olarak daha hızlıdır, çünkü tüm dize karşılaştırmaları yapmak yerine bellekteki işaretçileri karşılaştırır.


8
instanceof'in beklendiği gibi çalışmadığı ve
typeof'in

55
instanceof aynı penceredeki nesnelerle çalışır. İframe / frame veya popup-windows kullanıyorsanız, her (i) frame / pencerenin kendi "function" nesnesi vardır ve instanceof, başka bir (i) frame / pencereden bir nesneyi karşılaştırmaya çalışırsanız başarısız olur. typeof "function" dizesini döndürdüğü için her durumda çalışır.
bazıları

14
jsperf.com/typeof-function-vs-instanceof/3 Chrome ve FF3.X üzerinde denedim, "typeof" yaklaşımı daha hızlı.
Morgan Cheng

10
Bu sadece yanlış. Aynı değiller. Her ikisi de aynı durumların hepsinde, özellikle de farklı JavaScript VM'lerinde ve tarayıcılarında çalışmaz.
Justin Force

8
Cevabınız "her ikisi de işlevsellik açısından aynıdır" diyor. Saygılarımızla, bu kesinlikle yanlıştır. Cevabımda belirtildiği ve açıklandığı gibi, her iki seçenek de (özellikle tarayıcılar arasında) her durumda çalışmaz. Daha iyi yaklaşım, her ikisini de || Şebeke.
Justin Force

103

Typeof kullanmanın iyi bir nedeni, değişkenin tanımsız olup olmadığıdır.

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

İnstanceof kullanmanın iyi bir nedeni, değişkenin null olup olmadığıdır.

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

Gerçekten bence, ne tür olası verileri kontrol ettiğinize bağlı.


11
+1 ayrıca instanceofilkel tiplerle kıyaslanamayacağını da not edebilir, typeof can.
Tino

3
Chrome 29.0.1541.0'da dev undefined instanceof Object, false değerini döndürür ve bir istisna atmaz. Bu değişimin ne kadar yeni olduğunu bilmiyorum, ama bu instanceofdaha cazip geliyor.
Cypress Frankenfeld

7
undefined instanceof Objectbir istisna atmaz çünkü undefinedtanımlanır. Sabit, ad alanında bulunur. Bir değişken yoksa (örneğin yazım hatası nedeniyle), instanceof bir istisna atar. Mevcut olmayan bir değişken üzerinde typeof kullanımı ise 'undefined' verir.
15'de cleong

31

İşleri netleştirmek için iki gerçek bilmeniz gerekir:

  1. İnstanceof ister operatör testleri prototip özelliği a yapıcısı yerde görünür prototipler zincirle bir nesnenin. Çoğu durumda bu, nesnenin bu yapıcı kullanılarak veya onun neslinin altından oluşturulduğu anlamına gelir . Ancak prototip ayrıca Object.setPrototypeOf()yöntemle (ECMAScript 2015) veya __proto__mülkle (eski tarayıcılar, kullanımdan kaldırıldı) açıkça belirlenebilir . Performans sorunları nedeniyle bir nesnenin prototipinin değiştirilmesi önerilmez.

Dolayısıyla instanceof sadece nesneler için geçerlidir. Çoğu durumda dize veya sayı oluşturmak için yapıcılar kullanmazsınız. Yapabilirsin. Ama neredeyse hiç yapmıyorsun.

Ayrıca instanceof, nesneyi oluşturmak için tam olarak hangi kurucunun kullanıldığını kontrol edemez, ancak nesne kontrol edilen sınıftan türetilmiş olsa bile true değerini döndürür. Çoğu durumda bu istenen davranıştır, ancak bazen değildir. Yani bu aklı tutmalısın.

Başka bir sorun, farklı kapsamların farklı yürütme ortamlarına sahip olmasıdır. Bu, farklı yerleşik özelliklere sahip oldukları anlamına gelir (farklı küresel nesne, farklı kurucular, vb.) Bu beklenmeyen sonuçlara neden olabilir.

Örneğin, [] instanceof window.frames[0].Arraydönecektir false, çünkü Array.prototype !== window.frames[0].Arrayve diziler öncekinden miras alır.
Ayrıca, bir prototipi olmadığı için tanımsız değerde kullanılamaz.

  1. Typeof operatör testleri olup değeri ait altı temel türde bir " sayı ", " dizge ", " boole ", " nesne ", " fonksiyon " ya da " tanımsız ". "Object" dizesinin tüm nesnelere ait olduğu (nesneler olan ancak typeeof operatörünün kendi değeri olan işlevler hariç) ve ayrıca "null" değer ve diziler ("null" için bu bir hatadır, ancak bu hata çok eskidir , bu yüzden bir standart haline geldi). Yapıcılara güvenmez ve değer tanımlanmamış olsa bile kullanılabilir. Ancak nesneler hakkında herhangi bir ayrıntı vermez. Eğer ihtiyacınız varsa, anlamaya gidin.

Şimdi zor bir şeyden bahsedelim. İlkel tür oluşturmak için yapıcı kullanırsanız ne olur?

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

Sihir gibi görünüyor. Ama öyle değil. Bokslama (ilkel değeri nesneye göre sarma) ve kutuyu açma (sarılmış ilkel değeri nesneden ayıklama). Bu tür bir kod "biraz" kırılgan görünmektedir. Tabii ki yapıcılar ile ilkel tip oluşturmaktan kaçınabilirsiniz. Ancak boksun size çarpabileceği başka bir durum daha var. İlkel türde Function.call () veya Function.apply () öğesini kullandığınızda.

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

Bundan kaçınmak için katı modu kullanabilirsiniz:

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

upd: ECMAScript 2015'ten beri, kendi typeof == "symbol" sembolüne sahip olan Symbol adında bir tür daha var .

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

Bunu MDN'de okuyabilirsiniz: ( Symbol , typeof ).


2
if an object is created by a given constructor Bu yanlış. o instanceof Co, C.prototype'den miras alırsa true değerini döndürür. Daha sonra cevabınızda bunun hakkında bir şey söylediniz, ancak bu çok açık değil.
oyenamit

1
yanlış ... kitaptan: " github.com/getify/You-Dont-Know-JS " Foo örneği; // true instanceof operatörü düz iş nesnesini sol işlenen olarak ve bir işlevi sağ işlenen olarak alır. Cevaplar anında soru şudur: a'nın [[Prototip]] zincirinin tamamında, Foo.prototype tarafından keyfi olarak işaret edilen nesne ortaya çıkıyor mu?
Deen John

1
Daha doğru olmak için cevabı düzenledim. Yorumlarınız için teşekkürler.
Vladimir Liubimov

Ayrıca, boks / kutudan çıkarma sorununun açıklaması da eklendi.
Vladimir Liubimov

15

Safari 5 ve Internet Explorer 9'da bazı gerçekten ilginç ("korkunç" olarak okuyun) davranışları keşfettim. Bunu Chrome ve Firefox'ta büyük bir başarıyla kullanıyordum.

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

Sonra IE9'da test ediyorum ve hiç çalışmıyor. Büyük sürpriz. Ancak Safari'de aralıklı! Bu yüzden hata ayıklamaya başladım ve Internet Explorer'ın her zaman geri döndüğünü görüyorum false. Ama tuhaf şey Safari öyle onun JavaScript VM optimizasyon çeşit yapıyor gibi görünüyor olmasıdır ilk kez, ancak her zaman yeniden yüklenmesine vurdu!truefalse

Beynim neredeyse patladı.

Şimdi buna karar verdim:

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

Ve şimdi her şey harika çalışıyor. Arayabileceğinizi "a string".toString()ve dizenin bir kopyasını döndürdüğünü, yani

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

Bundan sonra ikisini de kullanacağım.


8

Diğer Önemli pratik farklılıklar:

// 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

7

instanceofcallbackbir alt türü olduğunda da çalışır Function, sanırım


4

instanceofJavascript lapa lapa olabilir - büyük çerçevelerin kullanımından kaçınmaya çalıştığına inanıyorum. Farklı pencereler kırılma yollarından biridir - inanıyorum ki sınıf hiyerarşileri de onu karıştırabilir.

Bir nesnenin belirli bir yerleşik tür olup olmadığını test etmenin daha iyi yolları vardır (genellikle istediğiniz şeydir). Yardımcı programlar oluşturun ve kullanın:

function isFunction(obj) {
  return typeof(obj) == "function";
}
function isArray(obj) {
  return typeof(obj) == "object" 
      && typeof(obj.length) == "number" 
      && isFunction(obj.push);
}

Ve bunun gibi.


2
Bilmiyorsanız: typeof bir işlev değil, bir anahtar kelime olduğundan parantez gerekmez. Ve IMHO == yerine === kullanmalısınız.
bazıları

5
@some typeof konusunda haklısınız ancak bu durumda === 'a gerek yoktur, ancak karşılaştırılan değerin aynı türe sahip olmadan eşit olabilmesi gerekir. Burada olamaz.
Nicole

@some, bir dize dışında bir şey döndürür mü?
Kenneth J

Yani isArray, örneğin, push yöntemine ve sayısal uzunluk özelliğine sahip bir yığın nesnesi için yanlış olur. Hangi koşullar altında (Array örneği) yanlış olur?
Chris Noe

@ChrisNoe Sorun, birden çok çerçeve arasında paylaşılan nesnelerde ortaya çıkıyor: groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/…

3

instanceofİlkel örn için çalışmaz "foo" instanceof Stringdönecektir falseoysa typeof "foo" == "string"dönecektir true.

Öte yandan typeof, özel nesneler (veya sınıflar, ne çağırmak istersen) söz konusu olduğunda, muhtemelen istediğini yapmayacaktır. Örneğin:

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

Öyle ki, işlevler hem 'işlev' ilkelleri hem de diğer işlevler gibi çalışmadığı göz önüne alındığında biraz garip olan 'İşlev' örnekleridir.

(typeof function(){} == 'function') == (function(){} instanceof Function)

fakat

(typeof 'foo' == 'string') != ('foo' instanceof String)

3

Prototiplerin kullanılmasını tavsiye ederim callback.isFunction() .

Farkı anladılar ve nedenlerine güvenebilirsiniz.

Diğer JS çerçevelerinde de böyle şeyler var sanırım.

instanceOfdiğer pencerelerde tanımlanan işlevler üzerinde çalışmayacağını düşünüyorum. Fonksiyonları sizinkinden farklıdır window.Function.


3

Bir işlevi kontrol ederken, her zaman typeof .

Fark şu:

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

Bu yüzden hiç kimse instanceofbir işlevi kontrol etmek için kullanmamalıdır .


Bunun typeofyanlış olduğunu iddia edebilirim - faşağıdakilerin hepsi: bir Object(bir nesne) ve bir Function(bir işlev). Benim dışımda kullanmak daha mantıklı instanceofçünkü bir fonksiyon olduğunu bilmek onun da bir nesne olduğunu biliyorum, çünkü tüm fonksiyonlar ECMAScript'teki nesneler. Tersi doğru değildir - dan bilerek typeofo fbir gerçekten de objectben aynı zamanda bir fonksiyonu olduğunu hiçbir fikrim yok.
amn

@amn Benim için, bu Fonksiyonun kırık bir örneğidir. Sanki özelliklerini alır length, nameve callFonksiyonundan, ancak bunların tümünün feshedilmiş bulunmaktadır. Daha da kötüsü, adı ve olamaz TypeErrordiyor: f is not a function.
maaartinus

2

Önemli pratik fark:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Bana nedenini sorma.


11
Çünkü burada strbir dize ilkesi var, bir dize nesnesi değil. Aynı şey sayı ilkelleri ve boole ilkelleri için de geçerlidir, bunlar "inşa edilmiş" meslektaşlarının, String, Number ve Boolean nesnelerinin örnekleri değildir. JavaScript gerektiğinde bu üç ilkeyi otomatik olarak nesnelere dönüştürür (nesnenin prototip zincirinde bir yöntem kullanmak gibi). Pratik farkınızın kapak tarafında, o zamandan beri dizileri kontrol etmek için instanceof daha iyidir typeof [] == "object" // true.
Andy E

2

Verim

typeofinstanceofher ikisinin de geçerli olduğu durumlardan daha hızlıdır .

Motorunuza bağlı olarak, lehine performans farkı % 20typeof civarında olabilir . ( Kilometreniz değişebilir )

İşte aşağıdakiler için bir kıyaslama testi 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));

Sonuç

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198

1
typeof topic == "dizi" yanlış döndürmelidir. konu türü "nesne" dir.
Shardul

nasıl gelir daha hızlı? değişmez dizeleri stajyer mi?
Gregory Magarshak 30'17

Nedeni: instanceof her zaman nesnenin prototip zincirini takip eder, bu nedenle performans cezası, prototip zincirinde sınıfın ne kadar olduğuna bağlı olarak instanceoftest edilir. Yani kısa miras zinciri için ceza daha düşük olacaktır ( [] instanceof Array,{} instanceof Object ) ve uzun süre - büyük. Yani, eğer hem obj instanceof SomeClassve hem de typeof obj !== 'string'varsayımsal kodunuzun perspektifinden aynı anlama gelirse (sadece bir test yapıyorsanız ifve switchbirden fazla sınıftan geçmiyorsan, fe ), o zaman ikincisini, performans açısından seçmeniz daha iyi olur,
ankhzet

2

Bu Buradaki diğer açıklamalar sadece tamamlayıcı bilgi - ı am değil kullanımına düşündüren.constructor her yerde.

TL; DR:typeof Bir seçenek olmayan durumlarda ve prototip zincirini umursamadığınızı bildiğinizde , Object.prototype.constructoraşağıdakilerden daha uygun veya daha iyi bir alternatif olabilir instanceof:

x instanceof Y
x.constructor === Y

1.1'den beri standarttır, bu nedenle geriye dönük uyumluluk konusunda endişelenmeyin.

Muhammed Umer burada da bir yorumda kısaca bahsetti. Bir prototip ile her şey üzerinde çalışır - yani her şey değil nullveya 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

Ayrıca, kullanım durumunuza bağlı olarak çok daha hızlı olabilir instanceof(bunun nedeni muhtemelen tüm prototip zincirini kontrol etmek zorunda olmamasıdır). Benim durumumda bir değerin yazılan bir dizi olup olmadığını kontrol etmek için hızlı bir yol gerekli:

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

Ve sonuçlar:

Chrome 64.0.3282.167 (64 bit, Windows)

Typed Array instanceof vs constructor - Chrome 64.0.3282.167'de (64 bit, Windows) 1,5 kat daha hızlı

Firefox 59.0b10 (64 bit, Windows)

Typed Array instanceof vs constructor - Firefox 59.0b10'da (64 bit, Windows) 30 kat daha hızlı

Merakla, hızlı bir oyuncak kıyaslama yaptım typeof ; şaşırtıcı bir şekilde daha kötü performans göstermiyor ve Chrome'da biraz daha hızlı görünüyor:

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

NOT: İşlevlerin listelenme sırası görüntüler arasında geçiş yapar!

Chrome 64.0.3282.167 (64 bit, Windows)

String / Number typeof vs constructor - Chrome 64.0.3282.167 (64 bit, Windows) sürümünde 1.26x daha hızlı

Firefox 59.0b10 (64 bit, Windows)

NOT: İşlevlerin listelenme sırası görüntüler arasında geçiş yapar!

String / Number typeof vs constructor - Firefox 59.0b10'da (64 bit, Windows) 0.78x daha yavaş


1

Sınıfın adını değiştirirseniz bir derleyici hatası alırsınız çünkü instanceof kullanın.


1

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"


Ne yapmalıyım, UA (navigator.userAgent) alabilir miyim?
xgqfrms

0

Ben sıkı bir OO yetiştirme geliyor

callback instanceof Function

Dizeler ya kötü yazım ya da diğer yazım hatalarına eğilimlidir. Artı daha iyi okuduğunu hissediyorum.


0

Rağmen instanceof sonra biraz daha hızlı olabilir typeof , çünkü böyle bir olası sihirli ikincisini tercih:

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

0

Bir başka durum da sadece harmanlayabileceğinizdir instanceof- doğru veya yanlış döndürür. İle typeofsağlanan bir şey türü alabilirsiniz


0

performansı göz önünde bulundurarak, 10 milyon yinelemelik bir döngü içeren bir komut dosyası oluşturursanız, typeof'i tipik bir donanımla kullanmanız daha iyi olur: talimat: typeof str == 'string' 9ms, 'string' instanceof String 19ms alacak


0

Tabii ki önemli ........!

Bunu örneklerle inceleyelim. Örneğimizde işlevi iki farklı şekilde ilan edeceğiz.

Her ikisini function declarationve İşlev Yapıcısını kullanacağız . Bu iki farklı senaryoda nasıl davranacağımızı typeofve instanceofdavranacağımızı göreceğiz .

İşlev bildirimini kullanarak işlev oluşturma:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Böyle farklı bir sonuç için olası bir açıklama biz bir işlev açıklama yaptı gibi olduğu typeofbir fonksiyonunda olduğunu anlayabiliriz typeoftypeof üzerinde operasyondur hangi ifadesi olsun veya olmasın, bizim durumumuzda çekler uygulanan Çağrı Yöntemi ya da değil . O uyguluyorsa yöntemini bir function.Otherwise değil .Çalıştırıcılı açıklama çek typeof için ECMAScript şartname .MyFunc Call

İşlev yapıcısını kullanarak işlev oluşturma:

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

İşte typeofo iddia MyFunc2bir işlevdir yanı sıra instanceofoperator.We zaten biliyor typeofeğer çek MyFunc2uygulanan Callyöntem veya not.As MyFunc2bir fonksiyondur ve uygulayan callnasıl en yani yöntemini typeofdiğer yandan bir function.On olduğunu bilir, kullandığımız function constructoroluşturmak için MyFunc2, onu bir örneği haline gelir Function constructor.O yüzden instanceofde giderir true.

Kullanması daha güvenli olan nedir?

Her iki durumda da görebileceğimiz gibi, typeofoperatör burada bir fonksiyonla uğraştığımızı başarılı bir şekilde iddia edebilir, bundan daha güvenlidir instanceof. instanceofdurumunda başarısız olur function declarationçünkü function declarationsbir örneği değildir Function constructor.

En iyi pratik :

As Gary Rafferty önerdi iyi yolu hem typeof ve instanceof birlikte kullanılarak yapılmalıdır.

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter

bu cevaba ilişkin yapıcı eleştiriler takdir edilecektir.
AL-zami

0

Çok hassas olması için, instanceof değeri örneğin yapıcısına (genellikle özel tipleri) ile oluşturulur burada kullanılmalıdır

var d = new String("abc")

oysa typeof sadece örn için atamaları yarattığı değerleri kontrol etmek

var d = "abc"

0

Yukarıdaki örneklerin tonuyla boğulmaya gerek yok, sadece iki bakış açısını unutmayın:

  1. typeof var;tekli bir operatör var orijinal türü veya kök türü döndürecektir. bu nedenle basit türler (dönecek string, number, bigint, boolean, undefined, ve symbol) ya da objecttürü.

  2. yerleşik nesneler (String, Number, Boolean, Array ..) veya karmaşık veya özel nesneler gibi daha üst düzey bir nesne söz konusu olduğunda, bunların tümü objectkök türündedir, ancak üzerlerinde yerleşik temel türü değişir (OOP sınıfı gibi) kalıtım kavramı), burada a instanceof A- bir ikili operatör - size yardımcı olacaktır, doğru işlenenin (A) yapıcısının görünüp görünmediğini kontrol etmek için prototip zincirinden geçecektir.

"kök türü" nü kontrol etmek veya ilkel değişkenle çalışmak istediğinizde - "typeof" kullanın, aksi takdirde "instanceof" kullanın.

nullgörünüşte ilkel görünen özel bir durumdur, ama aslında nesne için özel bir durumdur. Kullanılması a === nullyerine null adlı kontrol etmek.

Öte yandan, functionyerleşik nesne olan ancak typeofgeri dönen özel bir durumfunction

Gördüğünüz gibi instanceofbu arada prototip zincirinden geçmelisiniz, typeofsadece kök tipini bir kez kontrol edin, böylece neden typeofdaha hızlı olduğunu anlamak kolaydırinstanceof


0

Typeof hakkındaki MDN belgelerine göre , "new" anahtar sözcüğüyle başlatılan nesneler 'object' türündedir:

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';

İnstanceof ile ilgili belgeler şu noktalara işaret ederken :

const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true

Dolayısıyla, eğer bir şey nasıl oluşturulursa oluşturulsun bir dizge olup olmadığını kontrol etmek isterse, en güvenli yaklaşım instanceof .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.