В моем конкретном случае:
callback instanceof Function
или
typeof callback == "function"
это вообще имеет значение, какая разница?
Дополнительный ресурс:
JavaScript-сад тип против экземпляра
javascript
instanceof
typeof
farinspace
источник
источник
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
свойство вместо.Ответы:
Используйте
instanceof
для пользовательских типов:Используйте
typeof
для простых встроенных типов:Используйте
instanceof
для сложных встроенных типов:И последний немного сложнее:
источник
Use instanceof for complex built in types
- это все еще подвержено ошибкам. Лучше использовать ES5Array.isArray()
и соавт. или рекомендуемые прокладки.Оба схожи по функциональности, потому что оба возвращают информацию о типах, однако я лично предпочитаю,
instanceof
потому что она сравнивает реальные типы, а не строки. Сравнение типов менее подвержено человеческим ошибкам и технически быстрее, поскольку сравнивает указатели в памяти, а не выполняет сравнение целых строк.источник
Хорошая причина использовать typeof, если переменная может быть неопределенной.
Хорошая причина использовать instanceof, если переменная может быть нулевой.
Так что на самом деле, на мой взгляд, это будет зависеть от того, какой тип возможных данных вы проверяете.
источник
instanceof
не может сравниться с примитивными типами, typeof может.undefined instanceof Object
возвращает false и не выдает исключение. Я не знаю, насколько недавнее это изменение, но оно делает егоinstanceof
более привлекательным.undefined instanceof Object
не выдает исключение, потому чтоundefined
оно определено. Константа существует в пространстве имен. Когда переменная не существует (например, из-за опечатки), instanceof выдаст исключение. Использование typeof для несуществующей переменной дает «undefined» с другой стороны.Чтобы прояснить ситуацию, вам нужно знать два факта:
Object.setPrototypeOf()
методом (ECMAScript 2015) или__proto__
свойством (старые браузеры, не рекомендуется). Однако изменение прототипа объекта не рекомендуется из-за проблем с производительностью.Таким образом instanceof применим только к объектам. В большинстве случаев вы не используете конструкторы для создания строк или чисел. Вы можете. Но вы почти никогда не делаете.
Также instanceof не может проверить, какой именно конструктор использовался для создания объекта, но вернет true, даже если объект является производным от класса, который проверяется. В большинстве случаев это желаемое поведение, но иногда это не так. Так что вам нужно держать это в уме.
Другая проблема заключается в том, что разные области имеют разные среды выполнения. Это означает, что они имеют разные встроенные модули (разные глобальные объекты, разные конструкторы и т. Д.). Это может привести к неожиданным результатам.
Например,
[] instanceof window.frames[0].Array
вернетfalse
, потому чтоArray.prototype !== window.frames[0].Array
и массивы наследуют от первого.Кроме того, его нельзя использовать для неопределенного значения, потому что у него нет прототипа.
Теперь поговорим об одной хитрой вещи. Что если вы используете конструктор для создания примитивного типа?
Похоже на магию. Но это не так. Это так называемый бокс (перенос значения примитива по объекту) и распаковка (извлечение значения примитива из объекта). Такой код кажется «немного» хрупким. Конечно, вы можете просто избежать создания примитивного типа с помощью конструкторов. Но есть и другая возможная ситуация, когда бокс может ударить вас. Когда вы используете Function.call () или Function.apply () для примитивного типа.
Чтобы избежать этого, вы можете использовать строгий режим:
upd: Начиная с ECMAScript 2015, есть еще один тип, называемый Symbol, который имеет свой собственный typeof == "symbol" .
Вы можете прочитать об этом на MDN: ( Symbol , typeof ).
источник
if an object is created by a given constructor
Это неверноo instanceof C
вернет true, если o наследуется от C.prototype. Вы упомянули что-то об этом позже в своем ответе, но это не очень понятно.Я обнаружил действительно интересное (читаемое как «ужасное») поведение в Safari 5 и Internet Explorer 9. Я с большим успехом использовал его в Chrome и Firefox.
Затем я тестирую в IE9, и он совсем не работает. Большой сюрприз. Но в Safari это периодически! Итак, я начинаю отладку и обнаруживаю, что Internet Explorer всегда возвращается
false
. Но самое странное в том , что Safari , кажется, делать какие - то оптимизации в своей JavaScript VM , где это первый раз, но каждый раз , когда вы нажмете перезагрузки!true
false
Мой мозг почти взорвался.
Итак, теперь я остановился на этом:
И теперь все отлично работает. Обратите внимание, что вы можете позвонить,
"a string".toString()
и он просто возвращает копию строки, т.е.Так что теперь я буду использовать оба.
источник
Другие существенные практические различия:
источник
instanceof
также работает, когдаcallback
это подтипFunction
, я думаю,источник
instanceof
в Javascript может быть нестабильным - я считаю, что основные фреймворки стараются избегать его использования. Различное окно - один из способов, которым оно может сломаться - я верю, что иерархия классов может также запутать это.Существуют более эффективные способы проверки того, является ли объект определенного встроенного типа (который обычно является тем, что вы хотите). Создайте служебные функции и используйте их:
И так далее.
источник
instanceof
не будет работать для примитивов, например"foo" instanceof String
, вернется,false
тогда какtypeof "foo" == "string"
вернетсяtrue
.С другой стороны
typeof
, вероятно, не будет делать то, что вы хотите, когда речь идет о пользовательских объектах (или классах, как вы хотите их называть). Например:Просто так получилось, что функции являются и примитивами 'function', и экземплярами 'Function', что немного странно, если учесть, что это не работает так же, как и для других примитивных типов, например.
но
источник
Я бы порекомендовал использовать прототипы
callback.isFunction()
.Они выяснили разницу, и вы можете рассчитывать на их причину.
Я думаю, что другие JS-фреймворки тоже есть.
instanceOf
я не думаю, что он будет работать с функциями, определенными в других окнах. Их функция отличается от вашейwindow.Function
.источник
При проверке функции всегда нужно использовать
typeof
.Вот разница:
Вот почему никогда не следует использовать
instanceof
для проверки функции.источник
typeof
так -f
это все из следующего: anObject
(объект) и aFunction
(функция). Кроме меня, это имеет больше смысла в использовании,instanceof
потому что зная, что это функция, я знаю, что это тоже объект, так как все функции являются объектами в ECMAScript. Обратное неверно - зная изtypeof
этогоf
, действительно,object
я понятия не имею, что это тоже функция.length
,name
иcall
от функции, но все они несуществующие. Что еще хуже, это нельзя назвать, иTypeError
он говорит этоf is not a function
.Значительная практическая разница:
Не спрашивай меня почему.
источник
str
строковый примитив, а не строковый объект. То же самое касается числовых примитивов и логических примитивов, они не являются экземплярами своих «созданных» аналогов, объектов String, Number и Boolean. JavaScript автоматически преобразует эти три примитива в объекты при необходимости (например, используя метод в цепочке прототипов объекта). С другой стороны вашего практического различия, instanceof лучше для проверки массивов, так какtypeof [] == "object" // true
.Представление
typeof
быстрее, чемinstanceof
в ситуациях, когда оба применимы.В зависимости от вашего двигателя разница в производительности
typeof
может составить около 20% . ( Ваш пробег может отличаться )Вот тестирование производительности для
Array
:Результат
источник
instanceof
всегда следует цепочке прототипов объекта, поэтому снижение производительности будет зависеть от того, насколько далеко в цепочке прототипов находится классinstanceof
. Так что для короткой цепочки наследования штраф будет меньше (как,[] instanceof Array
,{} instanceof Object
), и долго - больше. Таким образом, если и тоobj instanceof SomeClass
и другоеtypeof obj !== 'string'
означает одно и то же с точки зрения некоторого вашего гипотетического кода (например, если вы просто проводите тестированиеif
, а неswitch
изучаете несколько классов и т. Д.), То вам лучше выбрать второй, с точки зрения производительности,Это просто дополнительное знание ко всем другим объяснениям здесь - я не предлагаю использовать
.constructor
везде.TL; DR: В ситуациях, когда
typeof
это невозможно, и когда вы знаете, что вас не волнует цепочка прототипов , этоObject.prototype.constructor
может быть жизнеспособной или даже лучшей альтернативой, чемinstanceof
:Он был в стандарте с 1.1, поэтому не стоит беспокоиться о обратной совместимости.
Мухаммед Умер кратко упомянул об этом в комментарии где-то здесь тоже. Он работает на все с прототипом - так что все,
null
или нетundefined
:Кроме того, в зависимости от вашего варианта использования это может быть намного быстрее, чем
instanceof
(вероятно, причина в том, что ему не нужно проверять всю цепочку прототипов). В моем случае мне нужен был быстрый способ проверить, является ли значение типизированным массивом:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
И результаты:
Chrome 64.0.3282.167 (64-разрядная, Windows)
Firefox 59.0b10 (64-разрядная версия, Windows)
Из любопытства я сделал быстрый тест игрушек против
typeof
; Удивительно, но он работает не намного хуже, а в Chrome кажется даже немного быстрее:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
ПРИМЕЧАНИЕ. Порядок, в котором перечислены функции, переключает изображения!
Chrome 64.0.3282.167 (64-разрядная, Windows)
Firefox 59.0b10 (64-разрядная версия, Windows)
ПРИМЕЧАНИЕ. Порядок, в котором перечислены функции, переключает изображения!
источник
Используйте instanceof, потому что если вы измените имя класса, вы получите ошибку компилятора.
источник
источник
Исходя из строгого ОО воспитания я бы пошел на
Строки подвержены либо моему ужасному правописанию, либо другим опечаткам. Плюс я чувствую, что это читается лучше.
источник
Несмотря на то, что instanceof может быть немного быстрее, чем typeof , я предпочитаю второй из-за такой возможной магии:
источник
Еще одним случаем является то, что Вы можете сопоставлять только с
instanceof
- он возвращает истину или ложь. С помощьюtypeof
вы можете получить тип предоставленного что-тоисточник
с точки зрения производительности, вам лучше использовать typeof с типичным оборудованием, если вы создадите скрипт с циклом в 10 миллионов итераций, инструкция: typeof str == 'string' займет 9 мс, а 'string' instanceof String займет 19 мс
источник
Конечно, это важно ........!
Давайте рассмотрим это на примерах. В нашем примере мы объявим функцию двумя различными способами.
Мы будем использовать
function declaration
и функцию конструктора . Мы увидим, какtypeof
и какinstanceof
вести себя в этих двух разных сценариях.Создайте функцию, используя объявление функции:
Возможное объяснение такого другого результата состоит в том, что, как мы сделали объявление функции, мы
typeof
можем понять, что это функция.typeof
Потому что проверяет, является ли выражение, над которым работает typeof, реализованным в нашем случае Call Method или нет . Если он реализует метод, то это функция. Иначе нет. Для уточнения проверьте спецификацию ecmascript для typeof .MyFunc
Call
Создать функцию с помощью конструктора функций:
Здесь
typeof
утверждается , чтоMyFunc2
это функция, а такжеinstanceof
operator.We уже знаетеtypeof
проверку , еслиMyFunc2
реализованCall
метод или not.AsMyFunc2
является функцией и реализуетcall
метод, это какtypeof
знает , что это function.On с другой стороны, мы использовалиfunction constructor
для созданияMyFunc2
, его становится примером.Function constructor
Вот почемуinstanceof
также решаетtrue
.Что безопаснее использовать?
Как мы видим, в обоих случаях
typeof
оператор может успешно утверждать, что здесь мы имеем дело с функцией, это безопаснее, чемinstanceof
.instanceof
потерпит неудачу в случае,function declaration
потому чтоfunction declarations
не является экземпляромFunction constructor
.Лучшая практика:
Как предположил Гэри Рафферти , лучше всего использовать вместе typeof и instanceof.
источник
Чтобы быть очень точным, instanceof должен использоваться там, где значение создается с помощью конструктора (обычно пользовательских типов), например, для
в то время как typeof для проверки значений, созданных только с помощью присваиваний, например,
источник
не нужно перегружать тонны приведенных выше примеров, просто имейте в виду две точки зрения:
typeof var;
Унарный оператор вернет исходный тип или корневой тип var. так что он будет возвращать примитивные типы (string
,number
,bigint
,boolean
,undefined
, иsymbol
) илиobject
типа.в случае объектов более высокого уровня, таких как встроенные объекты (String, Number, Boolean, Array ..) или сложные или пользовательские объекты, все они являются
object
корневым типом, но тип экземпляра, основанный на них, различен (например, класс OOP) концепция наследования), здесьa instanceof A
- бинарный оператор - он поможет вам, он пройдет цепочку прототипов, чтобы проверить, появляется ли конструктор правого операнда (A) или нет.поэтому, когда вы хотите проверить «корневой тип» или работать с примитивной переменной - используйте «typeof», в противном случае используйте «instanceof».
null
это особый случай, который кажется примитивным, но на самом деле это особый случай для объекта. Используетсяa === null
для проверки нуля.с другой стороны,
function
это также особый случай, который является встроенным объектом, ноtypeof
возвращаетfunction
как вы можете видеть,
instanceof
нужно пройти через цепочку прототипов,typeof
просто один раз проверьте тип корня, чтобы легко понять, почемуtypeof
это быстрее, чемinstanceof
источник
Согласно документации MDN о typeof , объекты, созданные с помощью ключевого слова «new», имеют тип «object»:
При этом документация об экземплярах пунктов, которые:
Поэтому, если кто-то хочет проверить, например, что что-то является строкой, независимо от того, как оно было создано, самым безопасным подходом будет использование
instanceof
.источник