Что лучше всего использовать: typeof или instanceof?

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

callback instanceof Function

или

typeof callback == "function"

действительно ли это имеет значение, какая разница?

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

JavaScript-Garden typeof vs instanceof

Ответ 1

Используйте 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

Ответ 2

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

Ответ 3

Причиной использования typeof является то, что переменная может быть undefined.

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"

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

Ответ 4

Чтобы все было ясно, вам нужно знать два факта:

  • Оператор instanceof возвращает true, если объект создан с помощью конструктора . Для этого он проверяет, находится ли конструктор в цепочке прототипов объекта.

Это означает, что instanceof применим только к объектам.

Именно по этой причине он не используется для проверки примитивных типов. В большинстве случаев вы не используете конструкторы для создания строк или чисел. Ты можешь. Но почти никогда не бывает.

Также он не может проверить, какой именно конструктор использовался для создания объекта, но вернет true, даже если объект получен из проверяемого класса. В большинстве случаев это желаемое поведение, но иногда это не так. Поэтому вам нужно держать этот ум.

Другая проблема заключается в том, что разные области применения имеют разные среды исполнения. Это означает, что они имеют разные встроенные функции (разные глобальные объекты, разные конструкторы и т.д.). Это может привести к неожиданным результатам.

Например, [] instanceof window.frames[0].Array вернет false, потому что Array.prototype !== window.frames[0].Array и массивы наследуются от первого.
Кроме того, он не может использоваться в значении undefined, потому что у него нет прототипа.

  1. Оператор typeof проверяет, принадлежит ли значение к одному из шести основных типов: " номер", " строка > ", " boolean", " объект", " функция" или " undefined". Если строка "объект" принадлежит всем объектам (кроме функций, которые являются объектами, но имеет собственное значение в операторе typeof), а также "нулевое" значение и массивы (для "null" это ошибка, но эта ошибка настолько старая, поэтому он становится стандартом). Он не полагается на конструкторы и может использоваться, даже если значение undefined. Но он не дает никаких подробностей об объектах. Поэтому, если вам это нужно, перейдите к instanceof.

Ответ 5

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

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

Затем я тестирую IE9, и он вообще не работает. Большой сюрприз. Но в Сафари это прерывисто! Поэтому я начинаю отладку, и обнаруживаю, что Internet Explorer всегда возвращает false. Но самое странное, что Safari, похоже, делает какую-то оптимизацию в своей виртуальной машине JavaScript, где она true в первый раз, но false при каждом нажатии на перезагрузку!

Мой мозг почти взорвался.

Итак, теперь я решил:

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

И теперь все работает отлично. Обратите внимание, что вы можете вызвать "a string".toString(), и он просто возвращает копию строки, т.е.

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

Итак, я буду использовать оба с этого момента.

Ответ 6

instanceof также работает, когда callback является подтипом Function, я думаю,

Ответ 7

Другие Значительные практические различия:

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

Ответ 8

instanceof в Javascript может быть flaky - я считаю, что основные структуры пытаются избежать его использования. Различные окна - один из способов, которыми он может сломаться - я считаю, что иерархии классов тоже могут смутить его.

Существуют ли более эффективные способы проверки того, является ли объект определенным встроенным типом (обычно это то, что вы хотите). Создайте служебные функции и используйте их:

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

И так далее.

Ответ 9

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

Они выяснили разницу, и вы можете рассчитывать на их разум.

Я думаю, что у других JS-фреймворков тоже есть такие вещи.

instanceOf не будет работать над функциями, определенными в других окнах. Их функция отличается от вашего window.Function.

Ответ 10

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", что является немного странным, учитывая, что он не работает так, как для других примитивных типов, например.

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

но

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

Ответ 11

Производительность

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

Ответ 12

При проверке функции всегда следует использовать 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 для проверки функции.

Ответ 13

Значительная практическая разница:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Не спрашивайте меня, почему.

Ответ 14

Используйте instanceof, потому что если вы измените имя класса, вы получите ошибку компилятора.

Ответ 15

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"

Ответ 16

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

callback instanceof Function

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

Ответ 17

Несмотря на то, что 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

Ответ 18

Еще один случай: вы можете сопоставлять только с instanceof - он возвращает true или false. С помощью typeof вы можете получить тип предоставленного something

Ответ 19

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