Apa perbedaan antara typeof dan instanceof dan kapan harus satu digunakan vs yang lain?

394

Dalam kasus khusus saya:

callback instanceof Function

atau

typeof callback == "function"

apakah itu penting, apa bedanya?

Sumber Daya Tambahan:

JavaScript-Taman typeof vs instanceof

farinspace
sumber
2
Saya menemukan jawaban saya di sini sebagai solusi yang mudah digunakan
CrandellWS
1
Ada cara lain untuk memeriksa jenis menggunakan Object.prototype.toString ecma-international.org/ecma-262/6.0/…
rab
1
cukup gunakan .constructorproperti saja.
Muhammad Umer
Jika Anda bertanya-tanya tentang kinerja , lihat jawaban saya di bawah ini . typeof lebih cepat di mana keduanya berlaku (yaitu objek).
Martin Peter

Jawaban:

540

Gunakan instanceofuntuk jenis khusus:

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 

Gunakan typeofuntuk tipe bawaan yang sederhana:

'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

Gunakan instanceofuntuk tipe bawaan yang rumit:

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

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

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

Dan yang terakhir agak rumit:

typeof null; // object
Szymon Wygnański
sumber
11
Jawaban ini menjelaskan mengapa instaceof tidak boleh digunakan untuk tipe primitif. Sudah cukup jelas Anda tidak memiliki opsi ketika datang ke tipe kustom, serta manfaat untuk tipe 'objek'. Tapi apa yang membuat fungsi disatukan dengan "tipe bawaan sederhana"? Saya merasa aneh bagaimana suatu fungsi berperilaku seperti objek, namun tipenya adalah 'fungsi' membuat penggunaan 'typeof' layak. Namun, mengapa Anda tidak menganjurkan hal itu?
Assimilater
4
@ Assimilater Anda dapat menggunakan instanceof dengan fungsi juga namun saya menganggap 3 aturan ini sangat mudah diingat dan ya, fungsi adalah pengecualian :)
Szymon Wygnański
2
bagian rumit lain -> instance 'string contoh' dari String; // String String palsu tetapi baru ('string contoh') dari String; // benar
Luke
2
@ Lukas umumnya ide buruk untuk menggunakan "String baru" seperti ini. yang menciptakan "objek string" daripada string yang primitif. lihat bagian di sini developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Colin D
4
Use instanceof for complex built in types- ini masih rentan terhadap kesalahan. Lebih baik menggunakan ES5 Array.isArray()et al. atau shims yang direkomendasikan.
OrangeDog
122

Keduanya sama dalam fungsionalitas karena mereka berdua mengembalikan informasi tipe, namun saya pribadi lebih suka instanceofkarena membandingkan tipe yang sebenarnya daripada string. Perbandingan jenis kurang rentan terhadap kesalahan manusia, dan secara teknis lebih cepat karena membandingkan pointer dalam memori daripada melakukan perbandingan seluruh string.

Soviut
sumber
8
ada beberapa situasi di mana instanceof tidak akan berfungsi seperti yang diharapkan dan typeof berfungsi dengan baik ... developer.mozilla.org/En/Core_JavaScript_1.5_Reference/…
farinspace
55
instanceof bekerja dengan objek di jendela yang sama. Jika Anda menggunakan iframe / frame atau popup-windows, masing-masing (i) frame / window memiliki objek "function" sendiri dan instanceof akan gagal jika Anda mencoba membandingkan objek dari yang lain (i) frame / window. typeof akan bekerja dalam semua kasus karena mengembalikan "fungsi" string.
beberapa
14
jsperf.com/typeof-function-vs-instanceof/3 Saya mencoba di Chrome dan FF3.X, pendekatan "typeof" lebih cepat.
Morgan Cheng
10
Ini salah. Mereka tidak identik. Keduanya tidak bekerja dalam semua situasi yang sama, terutama di seluruh JavaScript VM dan browser yang berbeda.
Justin Force
8
Jawaban Anda mengatakan "keduanya pada dasarnya identik dalam hal fungsi." Dengan hormat, ini jelas-jelas salah. Sebagaimana dijabarkan dan dijelaskan dalam jawaban saya, tidak ada opsi yang berfungsi di setiap situasi — terutama di seluruh browser. Pendekatan yang lebih baik adalah menggunakan keduanya dengan | | operator.
Justin Force
103

Alasan yang baik untuk menggunakan typeof adalah jika variabel mungkin tidak terdefinisi.

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

Alasan yang baik untuk menggunakan instanceof adalah jika variabel mungkin nol.

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

Jadi menurut saya, itu tergantung pada jenis data apa yang Anda periksa.

Kenneth J
sumber
11
+1 juga mencatat bahwa instanceoftidak dapat dibandingkan dengan tipe primitif, typeof bisa.
Tino
3
Di Chrome 29.0.1541.0 dev undefined instanceof Objectmengembalikan false, dan tidak melempar pengecualian. Saya tidak tahu seberapa baru perubahan itu, tetapi itu membuat instanceoflebih menarik.
Cypress Frankenfeld
7
undefined instanceof Objecttidak melempar pengecualian karena, eh, undefineddidefinisikan. Konstanta ada di namespace. Ketika suatu variabel tidak ada (karena kesalahan ketik misalnya), instanceof akan melemparkan pengecualian. Menggunakan typeof pada variabel yang tidak ada menghasilkan 'tidak terdefinisi' di sisi lain.
cleong
31

Untuk memperjelas, Anda perlu mengetahui dua fakta:

  1. The instanceof tes Operator apakah properti prototype dari konstruktor muncul di mana saja di prototipe rantai dari sebuah objek. Dalam kebanyakan kasus ini berarti bahwa objek dibuat dengan menggunakan konstruktor ini atau pada turunannya. Tetapi juga prototipe dapat diatur secara eksplisit dengan Object.setPrototypeOf()metode (ECMAScript 2015) atau oleh __proto__properti (browser lama, usang). Mengubah prototipe suatu objek tidak dianjurkan, karena masalah kinerja.

Jadi instanceof hanya berlaku untuk objek. Dalam kebanyakan kasus, Anda tidak menggunakan konstruktor untuk membuat string atau angka. Kamu bisa. Tetapi Anda hampir tidak pernah melakukannya.

Juga instanceof tidak dapat memeriksa, konstruktor mana yang digunakan untuk membuat objek, tetapi akan mengembalikan true, bahkan jika objek berasal dari kelas yang diperiksa. Dalam kebanyakan kasus ini adalah perilaku yang diinginkan, tetapi kadang-kadang tidak. Jadi, Anda perlu menjaga pikiran itu.

Masalah lain adalah bahwa cakupan yang berbeda memiliki lingkungan eksekusi yang berbeda. Ini berarti bahwa mereka memiliki built-in yang berbeda (objek global yang berbeda, konstruktor yang berbeda, dll.). Ini dapat menghasilkan hasil yang tidak terduga.

Misalnya, [] instanceof window.frames[0].Arrayakan kembali false, karena Array.prototype !== window.frames[0].Arraydan array mewarisi dari yang sebelumnya.
Selain itu, tidak dapat digunakan pada nilai yang tidak ditentukan, karena tidak memiliki prototipe.

  1. The typeof tes Operator apakah nilai milik salah satu dari enam jenis dasar : " nomor ", " tali ", " boolean ", " objek ", " fungsi " atau " tidak terdefinisi ". Di mana string "objek" milik semua objek (kecuali fungsi, yang merupakan objek, tetapi memiliki nilai sendiri dalam typeof operator), dan juga "null" nilai dan array (untuk "null" itu adalah bug, tetapi bug ini sangat tua , jadi itu menjadi standar). Itu tidak bergantung pada konstruktor dan dapat digunakan bahkan jika nilainya tidak ditentukan. Tapi itu tidak memberikan detail tentang objek. Jadi jika Anda membutuhkannya, buka instanceof.

Sekarang mari kita bicara tentang satu hal yang rumit. Bagaimana jika Anda menggunakan konstruktor untuk membuat tipe primitif?

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

Sepertinya sihir. Tapi ternyata tidak. Ini disebut tinju (membungkus nilai primitif dengan objek) dan unboxing (mengekstraksi nilai primitif yang dibungkus dari objek). Kode semacam itu tampaknya rapuh "sedikit". Tentu saja Anda bisa menghindari membuat tipe primitif dengan konstruktor. Tetapi ada situasi lain yang mungkin terjadi, ketika tinju bisa mengenai Anda. Saat Anda menggunakan Function.call () atau Function.apply () pada tipe primitif.

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

Untuk menghindari ini, Anda dapat menggunakan mode ketat:

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

upd: Sejak ECMAScript 2015, ada satu jenis lagi yang disebut Simbol, yang memiliki typeof sendiri == "simbol" .

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

Anda dapat membacanya di MDN: ( Simbol , typeof ).

Vladimir Liubimov
sumber
2
if an object is created by a given constructor Ini salah. o instanceof Cakan mengembalikan true jika o mewarisi dari C.prototype. Anda telah menyebutkan sesuatu tentang ini nanti dalam jawaban Anda tetapi tidak terlalu jelas.
oyenamit
1
salah ... dari buku: " github.com/getify/You-Dont-Know-JS " sebuah instance dari Foo; // true Operator instanceof mengambil objek biasa sebagai operan kiri dan fungsi sebagai operan kanannya. Contoh pertanyaan dari jawaban adalah: dalam seluruh rantai [[Prototipe]] a, apakah objek yang secara sewenang-wenang ditunjukkan oleh Foo.prototype pernah muncul?
Deen John
1
Saya sudah mengedit jawabannya, agar lebih benar. Terima kasih atas komentar Anda.
Vladimir Liubimov
Juga, penjelasan tentang masalah tinju / unboxing telah ditambahkan.
Vladimir Liubimov
15

Saya telah menemukan beberapa perilaku yang sangat menarik (dibaca sebagai "mengerikan") di Safari 5 dan Internet Explorer 9. Saya menggunakan ini dengan sangat sukses di Chrome dan Firefox.

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

Lalu saya uji di IE9, dan tidak berfungsi sama sekali. Kejutan besar. Tapi di Safari, itu terputus-putus! Jadi saya mulai men-debug, dan saya menemukan bahwa Internet Explorer selalu kembali false. Tapi hal yang paling aneh adalah bahwa Safari tampaknya akan melakukan beberapa jenis optimasi di nya VM JavaScript di mana itu adalah trueyang pertama kalinya, tapi false setiap kali anda menekan ulang!

Otak saya hampir meledak.

Jadi sekarang saya sudah sepakat:

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

Dan sekarang semuanya bekerja dengan baik. Perhatikan bahwa Anda dapat menelepon "a string".toString()dan hanya mengembalikan salinan string, yaitu

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

Jadi saya akan menggunakan keduanya mulai sekarang.

Justin Force
sumber
8

Perbedaan praktis signifikan lainnya:

// 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
Amjad Farajallah
sumber
7

instanceofjuga berfungsi ketika callbacksubtipe Function, saya pikir

berita baru
sumber
4

instanceofdi Javascript bisa bersisik - saya percaya kerangka kerja utama mencoba untuk menghindari penggunaannya. Jendela yang berbeda adalah salah satu cara untuk memecahkannya - Saya percaya hierarki kelas dapat membingungkannya juga.

Ada cara yang lebih baik untuk menguji apakah suatu objek adalah tipe bawaan tertentu (yang biasanya Anda inginkan). Buat fungsi utilitas dan gunakan:

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

Dan seterusnya.

levik
sumber
2
Jika Anda tidak tahu: typeof tidak perlu tanda kurung karena kata kunci dan bukan fungsi. Dan IMHO Anda harus menggunakan === daripada ==.
Beberapa
5
@Beberapa Anda benar tentang typeof tetapi dalam kasus ini tidak perlu ===, itu hanya diperlukan ketika nilai yang dibandingkan bisa sama tanpa memiliki tipe yang sama. Ini tidak bisa.
Nicole
@ Beberapa apakah typeof pernah mengembalikan sesuatu selain string?
Kenneth J
Jadi isArray akan salah untuk, katakanlah, objek stack dengan metode push dan atribut panjang numerik. Dalam keadaan apa (instance Array) akan salah?
Chris Noe
@ChrisNoe Masalahnya muncul dengan benda yang dibagikan di antara banyak bingkai: groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/…
3

instanceoftidak akan bekerja untuk primitif misalnya "foo" instanceof Stringakan kembali falsesedangkan typeof "foo" == "string"akan kembali true.

Di sisi lain typeofmungkin tidak akan melakukan apa yang Anda inginkan ketika datang ke objek khusus (atau kelas, apa pun yang Anda ingin menyebutnya). Sebagai contoh:

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

Kebetulan fungsi keduanya adalah 'fungsi' primitif dan turunan dari 'Function', yang sedikit aneh karena tidak berfungsi seperti itu untuk tipe primitif lainnya misalnya.

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

tapi

(typeof 'foo' == 'string') != ('foo' instanceof String)
Omnimike
sumber
3

Saya akan merekomendasikan menggunakan prototipe callback.isFunction().

Mereka telah menemukan perbedaannya dan Anda dapat mengandalkan alasan mereka.

Saya kira kerangka kerja JS lainnya memiliki hal-hal seperti itu juga.

instanceOftidak akan bekerja pada fungsi yang didefinisikan di windows lain, saya percaya. Fungsinya berbeda dari Anda window.Function.

alamar
sumber
3

Saat memeriksa fungsi, seseorang harus selalu menggunakan typeof .

Inilah perbedaannya:

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

Inilah sebabnya mengapa seseorang tidak boleh menggunakan instanceofuntuk memeriksa suatu fungsi.

vitaly-t
sumber
Saya bisa berpendapat bahwa itu typeofyang salah - fsemuanya adalah sebagai berikut: Object(objek) dan Function(fungsi). Kecuali bagi saya itu lebih masuk akal untuk digunakan instanceofkarena mengetahui bahwa itu adalah fungsi saya tahu itu adalah objek juga, karena semua fungsi adalah objek dalam ECMAScript. Kebalikannya tidak benar - mengetahui dari typeofitu fmemang objectsaya tidak tahu itu juga berfungsi.
amn
@ am Bagi saya, ini adalah contoh fungsi yang rusak . Ia mendapat atribut seperti length, namedan calldari Function, tetapi semuanya tidak berfungsi. Yang lebih parah, hal itu tidak bisa disebut dan TypeErrormengatakan: f is not a function.
maaartinus
2

Perbedaan praktis yang signifikan:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Jangan tanya kenapa.

Barney
sumber
11
Karena di sini stradalah string primitif, bukan objek string. Hal yang sama berlaku untuk primitif bilangan dan boolean primitif, mereka bukan contoh dari rekan "dibangun", objek String, Number dan Boolean. JavaScript secara otomatis mengubah ketiga primitif ini menjadi objek bila diperlukan (seperti memanfaatkan metode pada rantai prototipe objek). Di sisi lain dari perbedaan praktis Anda, instanceof lebih baik untuk memeriksa array sejak itu typeof [] == "object" // true.
Andy E
2

Performa

typeoflebih cepat daripada instanceofdalam situasi di mana keduanya berlaku.

Tergantung pada mesin Anda, perbedaan kinerja yang mendukung typeofbisa sekitar 20% . ( Jarak tempuh Anda mungkin beragam )

Berikut ini adalah pengujian benchmark untuk 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));

Hasil

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
Martin Peter
sumber
1
typeof subject == "array" harus mengembalikan false. typeof subjek adalah "objek".
Shardul
kenapa typeof lebih cepat? Javascript menginternir string literal?
Gregory Magarshak
Alasannya adalah: instanceof selalu mengikuti rantai prototipe objek, sehingga penalti kinerja akan tergantung pada seberapa jauh dalam rantai prototipe kelas, instanceofdiuji terhadap. Jadi untuk rantai pewarisan pendek, penalti akan lebih rendah (seperti [] instanceof Array,, {} instanceof Object), dan untuk jangka panjang - lebih besar. Jadi, jika keduanya obj instanceof SomeClassdan typeof obj !== 'string'artinya sama dari perspektif beberapa kode hipotetis Anda (misalnya, jika Anda hanya melakukan tes if, dan tidak switchmelakukan beberapa kelas dll), maka Anda sebaiknya memilih yang kedua, berdasarkan kinerja,
ankhzet
2

Ini hanya pengetahuan pelengkap untuk semua penjelasan lainnya di sini - saya tidak menyarankan untuk digunakan di .constructormana-mana.

TL; DR: Dalam situasi di mana typeofbukan merupakan pilihan, dan ketika Anda tahu bahwa Anda tidak peduli dengan rantai prototipe , Object.prototype.constructorbisa menjadi alternatif yang lebih baik atau bahkan lebih baik daripada instanceof:

x instanceof Y
x.constructor === Y

Sudah dalam standar sejak 1.1, jadi jangan khawatir tentang kompatibilitas mundur.

Muhammad Umer secara singkat menyebutkan ini dalam komentar di suatu tempat di sini juga. Ini bekerja pada semuanya dengan prototipe - jadi semuanya tidak nullatau 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

Selain itu, tergantung pada kasus penggunaan Anda, ini bisa menjadi jauh lebih cepat daripada instanceof(alasannya adalah karena tidak perlu memeriksa seluruh rantai prototipe). Dalam kasus saya, saya membutuhkan cara cepat untuk memeriksa apakah suatu nilai adalah array yang diketik:

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

Dan hasilnya:

Chrome 64.0.3282.167 (64-bit, Windows)

Instance Array yang diketik dari vs konstruktor - 1.5x lebih cepat di Chrome 64.0.3282.167 (64-bit, Windows)

Firefox 59.0b10 (64-bit, Windows)

Contoh array Array diketik vs konstruktor - 30x lebih cepat di Firefox 59.0b10 (64-bit, Windows)

Karena penasaran, saya melakukan benchmark cepat terhadap mainan typeof; secara mengejutkan itu tidak berkinerja jauh lebih buruk, dan tampaknya bahkan lebih cepat di 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

CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!

Chrome 64.0.3282.167 (64-bit, Windows)

Tipe string / Angka vs konstruktor - 1.26x lebih cepat di Chrome 64.0.3282.167 (64-bit, Windows)

Firefox 59.0b10 (64-bit, Windows)

CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!

Tipe / Jenis huruf vs konstruktor - 0.78x lebih lambat di Firefox 59.0b10 (64-bit, Windows)

Pekerjaan
sumber
1

Gunakan instanceof karena jika Anda mengubah nama kelas Anda akan mendapatkan kesalahan kompilator.

Robert
sumber
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"

xgqfrms
sumber
Apa yang harus saya lakukan, bisakah saya mendapatkan UA (navigator.userAgent)?
xgqfrms
0

Saya berasal dari pengasuhan OO yang ketat

callback instanceof Function

String rentan terhadap salah ejaan saya atau kesalahan ketik lainnya. Ditambah lagi, saya merasa ini lebih baik.

Keplerf1
sumber
0

Meskipun instanceof mungkin sedikit lebih cepat daripada typeof , saya lebih suka yang kedua karena sihir yang mungkin:

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
Suprido
sumber
0

Satu kasus lagi adalah bahwa Anda hanya dapat menyusun instanceof- itu mengembalikan benar atau salah. Dengan typeofAnda bisa mendapatkan jenis sesuatu yang disediakan

Jarosław Wlazło
sumber
0

dengan mempertimbangkan kinerja, Anda sebaiknya menggunakan typeof dengan perangkat keras tipikal, jika Anda membuat skrip dengan loop 10 juta iterasi instruksi: typeof str == 'string' akan memakan waktu 9ms sementara 'string' instanceof String akan mengambil 19ms

Khalid Rafik
sumber
0

Tentu saja itu penting ........!

Mari kita berjalan dengan contoh-contoh ini. Dalam contoh kita, kita akan mendeklarasikan fungsi dengan dua cara berbeda.

Kami akan menggunakan keduanya function declarationdan Function Constructor . Kami akan melihat bagaimana typeofdan instanceofberperilaku dalam dua skenario yang berbeda.

Buat fungsi menggunakan deklarasi fungsi:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Penjelasan yang mungkin untuk hasil yang berbeda tersebut adalah, ketika kami membuat deklarasi fungsi, typeofdapat memahami bahwa itu adalah sebuah fungsi. Karena typeofmemeriksa apakah ekspresi pada tipe operasi beroperasi, dalam kasus kami diimplementasikan Metode Panggilan atau tidak . Jika menerapkan metode itu adalah fungsi. Sebaliknya tidak. Untuk klarifikasi periksa spesifikasi ecmascript untuk typeof .MyFunc Call

Buat fungsi menggunakan fungsi konstruktor:

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

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

Di sini typeofmenegaskan bahwa itu MyFunc2adalah fungsi serta instanceofoperator. Kami sudah tahu typeofmemeriksa apakah metode yang MyFunc2diterapkan Callatau tidak. Seperti MyFunc2fungsi dan menerapkan callmetode, itulah cara typeofmengetahui bahwa itu adalah fungsi. Di sisi lain, kami dulu function constructormembuat MyFunc2, menjadi contoh dari Function constructor. Itulah sebabnya instanceofjuga memutuskan untuk true.

Apa yang lebih aman untuk digunakan?

Seperti yang dapat kita lihat dalam kedua kasus, typeofoperator dapat dengan sukses menyatakan bahwa kita berurusan dengan suatu fungsi di sini, itu lebih aman daripada instanceof. instanceofakan gagal dalam kasus function declarationkarena function declarationsbukan merupakan contoh Function constructor.

Praktek terbaik :

Seperti yang disarankan Gary Rafferty , cara terbaik harus menggunakan kedua typeof dan instanceof bersama-sama.

  function isFunction(functionItem) {

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

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter
AL-zami
sumber
kritik konstruktif apa pun mengenai jawaban ini akan dihargai.
AL-zami
0

Untuk menjadi contoh yang sangat tepat harus digunakan di mana nilai dibuat melalui konstruktor (umumnya tipe khusus) untuk misalnya

var d = new String("abc")

sedangkan typeof untuk memeriksa nilai yang dibuat hanya dengan tugas misalnya

var d = "abc"
Sambhav
sumber
0

tidak perlu kewalahan dengan banyak contoh di atas, hanya perlu diingat dua sudut pandang:

  1. typeof var;adalah operator unary akan mengembalikan tipe asli atau jenis root var. sehingga akan kembali tipe primitif ( string, number, bigint, boolean, undefined, dan symbol) atau objectjenis.

  2. dalam kasus objek tingkat yang lebih tinggi, seperti objek bawaan (String, Number, Boolean, Array ..) atau objek kompleks atau kustom, semuanya adalah objecttipe root, tetapi tipe instance base yang dibangun pada mereka berbeda-beda (seperti kelas OOP konsep pewarisan), di sini a instanceof A- operator biner - akan membantu Anda, itu akan melalui rantai prototipe untuk memeriksa apakah konstruktor dari operan yang tepat (A) muncul atau tidak.

jadi setiap kali Anda ingin memeriksa "tipe root" atau bekerja dengan variabel primitif - gunakan "typeof", jika tidak gunakan "instanceof".

nulladalah kasus khusus, yang tampaknya primitif, tetapi memang merupakan kasus khusus untuk objek. Menggunakana === null untuk memeriksa null sebagai gantinya.

di sisi lain, functionjuga merupakan kasus khusus, yang merupakan objek bawaantypeof kembalifunction

seperti yang Anda lihat instanceofharus melalui rantai prototipe sementara itu typeofhanya memeriksa jenis root satu kali sehingga mudah untuk memahami mengapa typeoflebih cepat daripadainstanceof

Lam Phan
sumber
0

Menurut dokumentasi MDN tentang typeof , objek yang dipakai dengan kata kunci "baru" adalah dari tipe 'objek':

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

Sedangkan dokumentasi tentang instance poin itu:

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

Jadi jika seseorang ingin memeriksa misalnya bahwa sesuatu adalah string tidak peduli bagaimana itu dibuat, pendekatan teraman akan digunakan instanceof.

Laszlo Sarvold
sumber