В чем разница между typeof и instanceof и когда один из них должен использоваться по сравнению с другим?

394

В моем конкретном случае:

callback instanceof Function

или

typeof callback == "function"

это вообще имеет значение, какая разница?

Дополнительный ресурс:

JavaScript-сад тип против экземпляра

farinspace
источник
2
Я нашел свой ответ здесь как простое в использовании решение
CrandellWS
1
Есть еще один способ проверить тип, используя Object.prototype.toString ecma-international.org/ecma-262/6.0/…
rab
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
Szymon Wygnański
источник
11
Этот ответ проясняет, почему instaceof не должен использоваться для примитивных типов. Совершенно очевидно, что у вас нет выбора, когда дело касается пользовательских типов, а также преимуществ для типов «объект». Но что делает функции смешанными с «простыми встроенными типами»? Я нахожу странным, как функция ведет себя как объект, но ее тип - это «функция», что делает возможным использование «typeof». Почему вы не одобряете instanceof для этого, хотя?
Ассимилятор
4
@Assimilater вы также можете использовать instanceof с функциями, однако я считаю, что эти 3 правила очень просты для запоминания, и да, функции являются исключением :)
Szymon Wygnański
2
другая сложная часть -> 'пример строки' instanceof String; // ложь, но новая строка (пример строки) instanceof String; // правда
Люк
2
@ Люк вообще плохая идея использовать "новую строку", как это. это создает «строковый объект», а не строковый примитив. см. раздел здесь developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Колин Д.
4
Use instanceof for complex built in types- это все еще подвержено ошибкам. Лучше использовать ES5 Array.isArray()и соавт. или рекомендуемые прокладки.
OrangeDog
122

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

Soviut
источник
8
В некоторых случаях instanceof не будет работать
должным образом,
55
instanceof работает с объектами в одном окне. Если вы используете iframe / frame или popup-windows, то каждый (i) frame / window имеет свой собственный объект «function», и instanceof завершится ошибкой, если вы попытаетесь сравнить объект из другого (i) frame / window. typeof будет работать во всех случаях, так как он возвращает строку «function».
некоторые
14
jsperf.com/typeof-function-vs-instanceof/3 Я пробовал на Chrome и FF3.X, «typeof» подход быстрее.
Морган Ченг
10
Это просто ложь. Они не идентичны. Они не работают во всех одинаковых ситуациях, особенно в разных виртуальных машинах 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 может.
Tino
3
В Chrome 29.0.1541.0 dev undefined instanceof Objectвозвращает false и не выдает исключение. Я не знаю, насколько недавнее это изменение, но оно делает его instanceofболее привлекательным.
Кипарис Франкенфельд
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 проверяет, принадлежат ли значения одному из шести основных типов : « число », « строка », « логическое значение », « объект », « функция » или « неопределенное ». Где строка «объект» принадлежит всем объектам (кроме функций, которые являются объектами, но имеют собственное значение в операторе typeof), а также «нулевым» значением и массивами (для «нулевого» это ошибка, но эта ошибка очень старая так что стало стандартом). Он не зависит от конструкторов и может использоваться, даже если значение не определено. Но это не дает никаких подробностей об объектах. Так что, если вам это нужно, перейдите на instanceof.

Теперь поговорим об одной хитрой вещи. Что если вы используете конструктор для создания примитивного типа?

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

Похоже на магию. Но это не так. Это так называемый бокс (перенос значения примитива по объекту) и распаковка (извлечение значения примитива из объекта). Такой код кажется «немного» хрупким. Конечно, вы можете просто избежать создания примитивного типа с помощью конструкторов. Но есть и другая возможная ситуация, когда бокс может ударить вас. Когда вы используете Function.call () или Function.apply () для примитивного типа.

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

Чтобы избежать этого, вы можете использовать строгий режим:

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

upd: Начиная с ECMAScript 2015, есть еще один тип, называемый Symbol, который имеет свой собственный typeof == "symbol" .

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

Вы можете прочитать об этом на MDN: ( Symbol , typeof ).

Владимир Любимов
источник
2
if an object is created by a given constructor Это неверно o instanceof Cвернет true, если o наследуется от C.prototype. Вы упомянули что-то об этом позже в своем ответе, но это не очень понятно.
oyenamit
1
неверно ... из книги: " github.com/getify/You-Dont-Know-JS " экземпляр Foo; // true Оператор instanceof принимает простой объект в качестве своего левого операнда, а функцию - в качестве своего правого операнда. Вопрос instanceof ответов таков: во всей цепочке [[Prototype]] объекта 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, я думаю,

newacct
источник
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 не нуждается в скобках, так как это ключевое слово, а не функция. И ИМХО, вы должны использовать === вместо ==.
некоторые
5
@ some Вы правы насчет typeof, но в этом случае нет необходимости в ===, он нужен только тогда, когда сравниваемое значение может быть равным без использования того же типа. Здесь не может.
Николь
@some typeof когда-нибудь возвращает что-то кроме строки?
Кеннет Дж
Поэтому isArray был бы неправильным, скажем, для стекового объекта с методом push и числовым атрибутом длины. При каких обстоятельствах (например, 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)
Omnimike
источник
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 Для меня это сломанный экземпляр Function. Он получает атрибуты , как length, nameи callот функции, но все они несуществующие. Что еще хуже, это нельзя назвать, и TypeErrorон говорит это f is not a function.
Маартин
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 == "array" должен возвращать false. Тип предмета - «объект».
Шардул
почему typeof быстрее? Javascript интернализует буквальные строки?
Григорий Магаршак
Причина в том, что instanceof всегда следует цепочке прототипов объекта, поэтому снижение производительности будет зависеть от того, насколько далеко в цепочке прототипов находится класс instanceof. Так что для короткой цепочки наследования штраф будет меньше (как, [] instanceof Array, {} instanceof Object), и долго - больше. Таким образом, если и то obj instanceof SomeClassи другое typeof obj !== 'string'означает одно и то же с точки зрения некоторого вашего гипотетического кода (например, если вы просто проводите тестирование if, а не switchизучаете несколько классов и т. Д.), То вам лучше выбрать второй, с точки зрения производительности,
Анхзет
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 экземпляра против конструктора - в 1,5 раза быстрее в Chrome 64.0.3282.167 (64-разрядная версия, Windows)

Firefox 59.0b10 (64-разрядная версия, Windows)

Типизированный массив Array экземпляра vs конструктор - в 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)

ПРИМЕЧАНИЕ. Порядок, в котором перечислены функции, переключает изображения!

Строка / Число typeof против конструктора - в 0,78 раза медленнее в 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"

xgqfrms
источник
Что мне делать, могу ли я получить UA (navigator.userAgent)?
xgqfrms
0

Исходя из строгого ОО воспитания я бы пошел на

callback instanceof Function

Строки подвержены либо моему ужасному правописанию, либо другим опечаткам. Плюс я чувствую, что это читается лучше.

Keplerf1
источник
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
Suprido
источник
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Потому что проверяет, является ли выражение, над которым работает typeof, реализованным в нашем случае Call Method или нет . Если он реализует метод, то это функция. Иначе нет. Для уточнения проверьте спецификацию 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это функция, а также instanceofoperator.We уже знаете typeofпроверку , если MyFunc2реализован Callметод или not.As MyFunc2является функцией и реализует callметод, это как typeofзнает , что это function.On с другой стороны, мы использовали 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-З
источник
любая конструктивная критика в отношении этого ответа будет принята с благодарностью.
AL-zami
0

Чтобы быть очень точным, instanceof должен использоваться там, где значение создается с помощью конструктора (обычно пользовательских типов), например, для

var d = new String("abc")

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

var d = "abc"
Sambhav
источник
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 , объекты, созданные с помощью ключевого слова «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';

При этом документация об экземплярах пунктов, которые:

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

Поэтому, если кто-то хочет проверить, например, что что-то является строкой, независимо от того, как оно было создано, самым безопасным подходом будет использование instanceof.

Ласло Сарволд
источник