Яка різниця між typeof та instanceof і коли слід використовувати один проти іншого?


394

У моєму конкретному випадку:

callback instanceof Function

або

typeof callback == "function"

це навіть має значення, яка різниця?

Додатковий ресурс:

Тип JavaScript-Сад vs instanceof


2
Свою відповідь я знайшов тут як просте у використанні рішення
CrandellWS

1
Є ще один спосіб перевірити тип за допомогою Object.prototype.toString ecma-international.org/ecma-262/6.0/…
раб

1
просто використовуйте .constructorвласність замість цього.
Мухаммед Умер

Якщо вам цікаво ефективність , дивіться мою відповідь нижче . typeof швидше там, де застосовуються обидва (а саме об'єкти).
Мартін Пітер

Відповіді:


540

Використовувати 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

11
Ця відповідь дає зрозуміти, чому instaceof не слід використовувати для примітивних типів. Цілком очевидно, що у вас немає можливості, коли мова йде про користувацькі типи, а також користь для типів "об'єкт". Але що робить функції, зв'язані "простими вбудованими типами"? Мені здається дивним, як функція поводиться як об’єкт, але тип - це "функція", що робить можливим використання "typeof". Чому б ти не відштовхував примірників цього?
Асимілатор

4
@Assimilater ви також можете використовувати instanceof з функціями, проте я вважаю, що ці 3 правила дуже прості в запам'ятовуванні, і так, функції - виняток :)
Szymon Wygnański,

2
ще одна хитра частина -> 'example string' instanceof String; // хибний, але новий String ('example string') екземпляр String; // правда
Лука

2
@Luke взагалі погана ідея використовувати подібну "нову рядок". що створює "рядковий об'єкт", а не рядковий примітив. дивіться розділ тут developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Colin D

4
Use instanceof for complex built in types- це все ще схильне до помилок. Краще використовувати ES5 Array.isArray()та ін. або рекомендовані прокладки.
OrangeDog

122

Обидва вони схожі за функціональністю, оскільки обидва повертають інформацію про тип, однак я особисто вважаю instanceofза краще, оскільки вона порівнює фактичні типи, а не рядки. Порівняння типів менш схильне до людських помилок, і технічно швидше, оскільки воно порівнює вказівники в пам'яті, а не проводить порівняння цілих рядків.


8
є деякі ситуації, коли instanceof не працюватиме так, як очікувалося, а typeof працює добре ... developer.mozilla.org/En/Core_JavaScript_1.5_Reference/…
farinspace

55
instanceof працює з об’єктами в одному вікні. Якщо ви використовуєте iframe / frame або спливаючі вікна, кожен (i) кадр / вікно має власний "функціональний" об'єкт, і instanceof не вдасться, якщо ви спробуєте порівняти об'єкт з іншим (i) кадром / вікном. typeof буде працювати у всіх випадках, оскільки повертає рядок "функція".
десь

14
jsperf.com/typeof-function-vs-instanceof/3 Я спробував на Chrome і FF3.X, "typeof" підхід швидше.
Morgan Cheng

10
Це просто помилково. Вони не тотожні. Вони не працюють у всіх одних і тих же ситуаціях, особливо в різних VM та JavaScript.
Джастін Форс

8
У Вашій відповіді сказано, що "обоє по суті однакові за функціональністю". З повагою це очевидно помилково. Як було окреслено та пояснено у моїй відповіді, жоден варіант не працює у будь-якій ситуації, особливо у веб-переглядачах. Кращим підходом є використання обох із || оператор.
Джастін Форс

103

Хороший привід використовувати typeof - це якщо змінна може бути невизначена.

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

Хороший привід використовувати instanceof, якщо змінна може бути нульовою.

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

Так що, на мою думку, це залежало б від того, який тип можливих даних ви перевіряєте.


11
+1 також зауважте, що instanceofне можна порівняти з примітивними типами, typeof can.
Тіно

3
У Chrome 29.0.1541.0 dev undefined instanceof Objectповертає false, і не кидає винятку. Я не знаю, наскільки останніми є ці зміни, але це робить instanceofбільш привабливим.
Cypress Frankenfeld

7
undefined instanceof Objectне кидає виняток, тому що, е. undefinedвизначено. Константа існує в просторі імен. Якщо змінна не існує (через типову помилку), instanceof видасть виняток. Використання typeof для неіснуючої змінної дає "undefined" з іншого боку.
cleong

31

Щоб зрозуміти, потрібно знати два факти:

  1. У InstanceOf тестів операторських чи прототип властивість з конструктори з'являється де - небудь в прототипах ланцюг об'єкта. У більшості випадків це означає, що об'єкт був створений за допомогою цього конструктора або його нащадка. Але також прототип може бути встановлений явно Object.setPrototypeOf()методом (ECMAScript 2015) або __proto__властивістю (старі браузери, застарілі). Зміна прототипу об'єкта не рекомендується через проблеми з продуктивністю.

Таким чином, instanceof застосовується лише до об'єктів. У більшості випадків ви не використовуєте конструктори для створення рядків чи чисел. Ти можеш. Але ти майже ніколи цього не робиш.

Також instanceof не може перевірити, який саме конструктор був використаний для створення об'єкта, але поверне true, навіть якщо об'єкт походить із класу, який перевіряється. У більшості випадків це бажана поведінка, але іноді це не так. Тож вам потрібно пам’ятати про це.

Інша проблема полягає в тому, що різні області застосування мають різні середовища виконання. Це означає, що вони мають різні вбудовані (різний глобальний об’єкт, різні конструктори тощо). Це може призвести до несподіваних результатів.

Наприклад, [] instanceof window.frames[0].Arrayповернеться false, тому що Array.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 == "символ" .

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

Про це можна прочитати на MDN: ( Символ , тип ).


2
if an object is created by a given constructor Це неправильно. o instanceof Cповернеться істинним, якщо o успадковує від C.prototype. Ви щось згадали про це пізніше у своїй відповіді, але це не дуже зрозуміло.
oyenamit

1
неправильно ... з книги: " github.com/getify/You-Dont-Know-JS " екземпляр Foo; // вірно Оператор instanceof приймає звичайний об'єкт як його операнд зліва, а функцію - як правий операнд. На питання instanceof відповіді: у всьому [[прототипі]] ланцюжку a, чи з'являється об'єкт, який довільно вказується Foo.prototype?
Дін Джон,

1
Я відредагував відповідь, щоб бути більш правильним. Дякуємо за ваші коментарі.
Володимир Любімов

Також було додано роз'яснення щодо питання про бокс / розблокування.
Володимир Любімов

15

Я виявив дійсно цікаву (читається як "жахливу") поведінку в Safari 5 та Internet Explorer 9. Я користувався цим з великим успіхом у Chrome та Firefox.

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

Тоді я тестую в IE9, і він взагалі не працює. Великий сюрприз. Але в Safari це переривчасте! Тож я починаю налагоджувати, і виявляю, що Internet Explorer завжди повертається false. Але найдивніше в тому , що Safari , здається, робити якісь - то оптимізації в своїй JavaScript VM , де це перший раз, але кожен раз , коли ви натиснете перезавантаження!truefalse

Мій мозок майже вибухнув.

Тож тепер я зупинився на цьому:

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

А зараз все чудово працює. Зауважте, що ви можете зателефонувати, "a string".toString()і він просто повертає копію рядка, тобто

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

Тож я відтепер буду використовувати обидва.


8

Інші суттєві практичні відмінності:

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

instanceofтакож працює, коли callbackце підтип Function, я думаю


4

instanceofу Javascript може бути лускатим - я вважаю, що основні рамки намагаються уникати його використання. Різні вікна - це один із способів його зламати - я вважаю, що ієрархії класів можуть це також сплутати.

Є кращі способи перевірити, чи об’єкт певного вбудованого типу (як правило, те, що ви хочете). Створіть утилітні функції та використовуйте їх:

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

І так далі.


2
Якщо ви не знали: typeof не потребують дужок, оскільки це ключове слово, а не функція. І IMHO слід використовувати === замість ==.
десь

5
@some Ви маєте рацію щодо typeof, але в цьому випадку немає потреби в ===, він потрібен лише тоді, коли значення, яке порівнюється, може бути рівним, не маючи одного типу. Тут не можна.
Ніколь

@some, typeof коли-небудь повертає щось інше, ніж рядок?
Кеннет J

Тож isArray було б неправильним для, скажімо, об'єкта стека з методом push та атрибутом числової довжини. За яких обставин помилка (instanceof Array) помиляється?
Кріс Ное

@ChrisNoe Проблема виникає з об'єктами, які поділяються між декількома кадрами: groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/…

3

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)

3

Я б рекомендував використовувати прототипи callback.isFunction().

Вони з’ясували різницю, і ви можете розраховувати на їх причину.

Я думаю, що в інших структурах JS теж є такі речі.

instanceOfя не вважаю, що це працює на функціях, визначених в інших вікнах. Їх функція відрізняється від вашої window.Function.


3

Перевіряючи функцію, завжди потрібно використовувати 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це все наступне: an Object(об’єкт) і a Function(функція). Крім мене, це має більш сенс використовувати, instanceofоскільки знаючи, що це функція, я знаю, що це і об’єкт, оскільки всі функції є об'єктами в ECMAScript. Зворотне не вірно - знаючи, typeofщо fце насправді, objectя поняття не маю, що це також функція.
amn

@amn Для мене це зламаний екземпляр Функції. Він отримує атрибути , як length, nameі callвід функції, але всі вони неіснуючі. Що ще гірше, це не можна назвати і TypeErrorкаже , що це: f is not a function.
maaartinus

2

Суттєва практична різниця:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Не питайте мене, чому.


11
Тому що тут strрядок примітивного, а не рядкового об’єкта. Те саме стосується числових примітивів та булевих примітивів, вони не є примірниками їх "сконструйованих" аналогів, об'єктів String, Number та Boolean. JavaScript автоматично перетворює ці три примітиви в об'єкти, коли це потрібно (наприклад, використання методу в ланцюзі прототипу об'єкта). Що стосується вашої практичної різниці, instanceof краще перевіряти на наявність масивів typeof [] == "object" // true.
Енді Е

2

Продуктивність

typeofшвидше, ніж instanceofу ситуаціях, коли застосовуються обидва.

Залежно від вашого двигуна різниця в роботі на користь 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

1
typeof subject == "масив" повинен повертати false. typeof предмет - "об'єкт".
Шардул

як прийти typeof швидше? чи інтерпретує Javascript буквальні рядки?
Григорій Магаршак

Причина: instanceof завжди слід за прототипом ланцюга об'єкта, тому покарання продуктивності буде залежати від того, наскільки в прототипі ланцюга знаходиться клас, на instanceofякий перевіряється. Так що для короткого ланцюжка успадкування штраф буде менше (як, [] instanceof Array, {} instanceof Object), і довго - більше. Отже, якщо і те, obj instanceof SomeClassі інше typeof obj !== 'string'означає те саме з точки зору якогось вашого гіпотетичного коду (наприклад, якщо ви просто робите тест if, а не switchвказуєте через декілька класів тощо), то вам краще вибрати другий, з врахуванням продуктивності,
ankhzet

2

Це лише додаткові знання до всіх інших пояснень тут - я не пропоную використовувати .constructorвсюди.

TL; DR: У ситуаціях, коли typeofце не є варіантом, і коли ви знаєте, що вам не байдуже ланцюг прототипу , це Object.prototype.constructorможе бути життєздатною або навіть кращою альтернативою, ніж instanceof:

x instanceof Y
x.constructor === Y

Це в стандарті з 1.1, тому не турбуйтеся про зворотну сумісність.

Мухаммад Умер коротко згадав про це у коментарі десь і тут. Вона працює на все з прототипом - так що все не 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)

Введений Array instanceof відновлення конструктора - на 1,5 рази швидше в Chrome 64.0.3282.167 (64-розрядні, Windows)

Firefox 59.0b10 (64-розрядні, Windows)

Набраний Array instanceof проти конструктора - на 30 разів швидше у 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)

Тип рядка / числа в порівнянні з конструктором - на 1,26 рази швидше в Chrome 64.0.3282.167 (64-бітний, Windows)

Firefox 59.0b10 (64-розрядні, Windows)

ПРИМІТКА: Порядок, у якому перераховані функції перемикає зображення між собою!

Тип рядка / числа в порівнянні з конструктором - 0,78x повільніше у Firefox 59.0b10 (64-розрядні, Windows)


1

Використовуйте instanceof, оскільки якщо ви зміните ім'я класу, ви отримаєте помилку компілятора.


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"


Що робити, чи можу я отримати UA (navigator.userAgent)?
xgqfrms

0

Я виходив із суворого виховання в ОО, я би пішов

callback instanceof Function

Рядки схильні або до мого жахливого написання, або до інших друкарських помилок. Плюс я відчуваю, що вона читає краще.


0

Незважаючи на instanceof може бути трохи швидше, ніж 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

0

Ще один випадок - це те, що ви можете лише порівнювати instanceof- воно повертає істинне чи хибне. З typeofвами можна отримати тип наданого чогось


0

маючи на увазі продуктивність, вам краще використовувати typeof з типовим обладнанням, якщо ви створите сценарій з циклом 10 мільйонів ітерацій, інструкція: typeof str == 'string' займе 9 мс, тоді як 'string' instanceof String займе 19 мс


0

Звичайно, це має значення ........!

Давайте розглянемо це з прикладами. У нашому прикладі ми оголосимо функцію двома різними способами.

Ми будемо використовувати function declarationі Конструктор функцій . Ми розберемо, як typeofі як instanceofповодиться у цих двох різних сценаріях.

Створіть функцію за допомогою декларації функції:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Можливе пояснення такого різного результату полягає в тому, що коли ми зробили декларацію функції, typeofможна зрозуміти, що це функція. Тому що typeofперевіряється, чи є вираз, над яким типом функціонує, у нашому випадку реалізований метод виклику чи ні . Якщо він реалізує метод, це функція. Інше не. Для роз'яснення перевірте специфікацію ecmascript для typeof .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це функція, як і instanceofоператор. Ми вже знаємо, typeofперевіряємо, чи MyFunc2реалізований Callметод чи ні. MyFunc2Як функція, і вона реалізує callметод, ось як typeofвідомо, що це функція. З іншого боку, ми використовували function constructorдля створення MyFunc2, це стає екземпляром Function constructor. Тому instanceofі вирішується true.

Що безпечніше використовувати?

Як ми бачимо, в обох випадках typeofоператор може успішно стверджувати, що ми маємо справу з функцією тут, це безпечніше instanceof. instanceofне вдасться в тому випадку, function declarationоскільки function declarationsвони не є примірником Function constructor.

Найкраща практика :

Як запропонував Гері Рафферті , найкращим способом має бути використання як typeof, так і instanceof разом.

  function isFunction(functionItem) {

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

  }

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

будь-яка конструктивна критика стосовно цієї відповіді буде оцінена.
AL-zami

0

Щоб бути дуже точним, instanceof слід використовувати там, де значення створюється за допомогою конструктора (як правило, спеціальні типи), наприклад

var d = new String("abc")

тоді як typeof для перевірки значень, створених саме за призначенням, наприклад

var d = "abc"

0

немає необхідності переповнювати тонни наведених вище прикладів, просто пам’ятайте про дві точки зору:

  1. typeof var;є одинарним оператором поверне початковий тип або тип кореня var. так що він буде повертати примітивні типи ( string, number, bigint, boolean, undefined, і symbol) або objectтипу.

  2. у випадку об'єктів вищого рівня, таких як вбудовані об'єкти (String, Number, Boolean, Array ..) або складні або власні об'єкти, усі вони є objectкореневим типом, але тип побудованої на них екземпляра базується (наприклад, клас OOP концепція успадкування), тут a instanceof A- бінарний оператор - допоможе вам, він пройде по прототипу ланцюга, щоб перевірити, з’являється конструктор правого операнда (A) чи ні.

тож коли ви хочете перевірити "тип кореня" або працювати з примітивною змінною - використовуйте "typeof", інакше використовуйте "instanceof".

nullце особливий випадок, який, здавалося б, примітивний, але дійсно є особливим випадком для об'єкта. Використовуйте a === nullдля перевірки нуля натомість.

з іншого боку, functionце також окремий випадок, який є вбудованим об'єктом, але typeofповерненнямfunction

як ви бачите, instanceofпотрібно тим часом typeofпройти ланцюжок прототипу просто перевірити тип кореня один раз, щоб зрозуміти, чому typeofшвидше, ніжinstanceof


0

Відповідно до документації MDN про typeof , об'єкти, інстанціонізовані "новим" ключовим словом, мають тип "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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.