instanceof
Ключевое слово в JavaScript может быть довольно запутанным , когда он впервые встречается, так как люди склонны думать , что JavaScript не является объектно-ориентированный язык программирования.
- Что это?
- Какие проблемы это решает?
- Когда это уместно, а когда нет?
javascript
operators
instanceof
Алон Губкин
источник
источник
"foo" instanceof String
=> ложь,1 instanceof Number
=> ложь,{} instanceof Object
=> ложь. Чего-чего?!"foo" instanceof String => false
это правильно, потому чтоtypeof "foo" == 'string'
.new String("foo") instanceof String => true
, потому чтоtypeof String == 'function'
- вы должны относиться к функции как к классу (определение класса). Переменная становитсяinstanceof
некоторойfunction
(класс), когда вы назначаете ее какvar v = new AnythingWhatTypeofEqualsFunction()
. То же самое относится и к1
.typeof 1 == 'number'
- «номер» не «функция» :) Далее -{} instanceof Object
этоTRUE
в узле и современных браузерах({}) instanceof Object
вернетсяtrue
. На самом деле код, который вы написали, выдаст вам ошибку.Ответы:
случай
Операнд левой стороны (LHS) - это фактический объект, проверяемый с операндом правой стороны (RHS), который является фактическим конструктором класса. Основное определение:
Вот несколько хороших примеров, и вот пример, взятый непосредственно с сайта разработчика Mozilla :
Одна вещь, о которой стоит упомянуть,
instanceof
оценивается как true, если объект наследуется от прототипа classe:Это
p instanceof Person
правда, так какp
наследуется отPerson.prototype
.По запросу ОП
Я добавил небольшой пример с примером кода и объяснением.
Когда вы объявляете переменную, вы присваиваете ей определенный тип.
Например:
Выше показать вам некоторые переменные, а именно
i
,f
иc
. Эти типыinteger
,float
и определенный пользователемCustomer
тип данных. Типы, подобные приведенным выше, могут быть для любого языка, а не только для JavaScript. Однако в JavaScript, когда вы объявляете переменную, вы явно не определяете типvar x
, x может быть числом / строкой / определяемым пользователем типом данных. Итак, чтоinstanceof
же он проверяет объект, чтобы определить, относится ли он к указанному типу, взявCustomer
объект, который мы можем сделать:Выше мы видели, что
c
было объявлено с типомCustomer
. Мы new'd его и проверили, имеет ли он типCustomer
или нет. Конечно, это возвращает истину. Затем, продолжая использоватьCustomer
объект, мы проверяем, является ли онString
. Нет, определенно неString
мы обновилиCustomer
объект, а неString
объект. В этом случае возвращается false.Это действительно так просто!
источник
color1 instanceof String;
это вернет true, потому что color1 является строкой.person p = new person()
р теперь тип человека, а не тип строки.var zero = 0; alert(zero); zero = "0"; alert(zero)
мы прошли путь от примитиваint
к примитивуstring
без каких-либо проблем.int
на примитивstring
.В экземпляре экземпляра есть важный аспект, который пока не рассматривается ни в одном из комментариев: наследование. Переменная, оцениваемая с использованием instanceof, может возвращать true для нескольких «типов» из-за наследования прототипа.
Например, давайте определим тип и подтип:
Теперь, когда у нас есть пара «классов», давайте создадим несколько экземпляров и выясним, к чему они относятся:
Видишь эту последнюю строчку? Все «новые» вызовы функции возвращают объект, который наследуется от Object. Это верно даже при использовании сокращения объекта:
А как насчет самих «классовых» определений? Что они являются примерами?
Я чувствую, что понимание того, что любой объект может быть экземпляром MULTIPLE-типов, важно, поскольку вы, я (ошибочно), допускаете, что вы можете различать, скажем, объект и функцию с помощью
instanceof
. Как видно из последнего примера, функция является объектом.Это также важно, если вы используете какие-либо шаблоны наследования и хотите подтвердить потомство объекта с помощью методов, отличных от типизации по типу утки.
Надеюсь, что это помогает любому исследовать
instanceof
.источник
SubFoo.prototype = new Foo();
вы можете добавить к нему больше методов, иsubfoo instanceof Foo
проверка все равно пройдет, а такжеsubfoo instanceof SubFoo
Другие ответы здесь верны, но они не касаются того, как на
instanceof
самом деле работает, что может представлять интерес для некоторых языковых юристов.У каждого объекта в JavaScript есть прототип, доступный через
__proto__
свойство. Функции также имеютprototype
свойство, которое является начальным__proto__
для любых созданных ими объектов. Когда функция создается, ей присваивается уникальный объектprototype
.instanceof
Оператор использует эту уникальность , чтобы дать вам ответ. Вот чтоinstanceof
может выглядеть, если вы написали это как функцию.Это в основном перефразирует ECMA-262 издание 5.1 (также известное как ES5), раздел 15.3.5.3.
Обратите внимание, что вы можете переназначить любой объект в
prototype
свойство функции , и вы можете переназначить__proto__
свойство объекта после его создания. Это даст вам некоторые интересные результаты:источник
__proto__
свойством " " не допускается в IE. Если я правильно помню, прямое манипулирование свойством также не включено в спецификацию ECMA, так что, вероятно, это плохая идея использовать его для задания, отличного от академического.Object.getPrototypeOf(o)
, это будет то же самое, что__proto__
вы описываете, но соответствует ECMAScript.Я думаю, что стоит отметить, что instanceof определяется использованием ключевого слова «new» при объявлении объекта. В примере от JonH;
То, что он не упомянул, это;
Указание «new» фактически копировало конечное состояние функции конструктора String в переменную color1, а не просто устанавливало его в возвращаемое значение. Я думаю, что это лучше показывает, что делает новое ключевое слово;
Использование «new» присваивает значение «this» внутри функции объявленной переменной, в то время как его использование вместо этого присваивает возвращаемое значение.
источник
new
любой из типов JavaScript, что делает принятый ответ более запутанным для начинающих.text = String('test')
иoptions = {}
не собираюсь проверяться,instanceof
а, скорее, сtypeof
вместо этого.И вы можете использовать его для обработки ошибок и отладки, например так:
источник
источник
Javascript - это язык прототипов, что означает, что он использует прототипы для «наследования».
instanceof
оператор проверяет , если функция конструктораprototype
propertype присутствует в__proto__
цепи объекта. Это означает, что он будет делать следующее (при условии, что testObj является функциональным объектом):obj.__proto__ === testObj.prototype
>> еслиtrue
instanceof
он вернетсяtrue
.obj.__proto__.__proto__ === testObj.prototype
>> если этоtrue
instanceof
вернетсяtrue
.testObj.prototype
тоinstanceof
оператор будет возвращатьfalse
.Пример:
Это решило проблему удобной проверки, является ли объект производным от определенного прототипа. Например, когда функция получает объект, который может иметь различные прототипы. Затем, прежде чем использовать методы из цепочки прототипов, мы можем использовать
instanceof
оператор, чтобы проверить, находятся ли эти методы на объекте.Пример:
Здесь, в
talk()
функции сначала проверяется, находится ли прототип на объекте. После этого выбирается соответствующий метод для выполнения. Невыполнение этой проверки может привести к выполнению метода, который не существует, и, следовательно, к ошибке ссылки.Мы вроде уже прошли через это. Используйте его, когда вам нужно проверить прототип объекта, прежде чем что-то делать с ним.
источник
PersonX.prototype.talk
, чтобыtalk
функция могла просто делатьperson.talk()
.__proto__
в документации, это устарело - пишитеObject.getPrototype()
вместо этогоНа вопрос «Когда это уместно, а когда нет?», Мои 2 цента:
instanceof
редко используется в производственном коде, но полезен в тестах, где вы хотите утверждать, что ваш код возвращает / создает объекты правильных типов. Будучи явным в отношении типов объектов, которые ваш код возвращает / создает, ваши тесты становятся более мощными инструментами для понимания и документирования вашего кода.источник
instanceof
это просто синтаксический сахар дляisPrototypeOf
:instanceof
зависит только от прототипа конструктора объекта.Конструктор - это просто нормальная функция. Строго говоря, это функциональный объект, поскольку в Javascript все является объектом. И у этого функционального объекта есть прототип, потому что у каждой функции есть прототип.
Прототип - это просто обычный объект, который находится в цепочке прототипов другого объекта. Это означает, что нахождение в цепочке прототипов другого объекта превращает объект в прототип:
instanceof
Оператора следует избегать , поскольку она фальсифицирует классов, которые не существуют в JavaScript. Несмотря на то, чтоclass
ключевое слово отсутствует в ES2015,class
оно опять-таки просто синтаксический сахар для ... но это уже другая история.источник
instanceof
происходит отisPrototypeOf
. Я называю это синтаксическим сахаром. А ваш источник MDN - это шутка?instanceof
не делаю то же самое, что иisPrototypeOf
. Вот и все.Я только что нашел реальное приложение и теперь буду использовать его чаще, я думаю.
Если вы используете события jQuery, иногда вы хотите написать более общую функцию, которая также может быть вызвана напрямую (без события). Вы можете использовать,
instanceof
чтобы проверить, является ли первый параметр вашей функции экземпляром,jQuery.Event
и реагировать соответствующим образом.В моем случае, функция должна была вычислять что-то либо для всех (через событие нажатия на кнопку), либо только для одного конкретного элемента. Код, который я использовал:
источник