Instanceof js что это
Перейти к содержимому

Instanceof js что это

  • автор:

instanceof

Оператор instanceof проверяет, принадлежит ли объект к определённому классу. Другими словами, object instanceof constructor проверяет, присутствует ли объект constructor.prototype в цепочке прототипов object .

Интерактивный пример

Синтаксис

object instanceof constructor

Параметры

Функция-конструктор, на которую идёт проверка.

Описание

Оператор instanceof проверяет, присутствует ли объект constructor.prototype в цепочке прототипов object .

// объявляем конструкторы function C() > function D() > var o = new C(); // true, так как: Object.getPrototypeOf(o) === C.prototype o instanceof C; // false, так как D.prototype не присутствует в цепочке прототипов o o instanceof D; o instanceof Object; // true, так как: C.prototype instanceof Object; // true C.prototype = >; var o2 = new C(); o2 instanceof C; // true // false, так как C.prototype отсутствует в цепочке прототипов o o instanceof C; D.prototype = new C(); // add C to [[Prototype]] linkage of D var o3 = new D(); o3 instanceof D; // true o3 instanceof C; // true, так как C.prototype теперь присутствует в цепочке прототипов o3 

Обратите внимание: результат оператора instanceof зависит от свойства constructor.prototype , поэтому результат оператора может поменяться после изменения этого свойства. Также результат может поменяться после изменения прототипа object (или цепочки прототипов) с помощью Object.setPrototypeOf или нестандартного свойства __proto__ .

instanceof и множественные контексты (например, фреймы или окна)

Различные контексты имеют разные среды выполнения. Это означает, что они имеют различные built-ins (разный глобальный объект, различные конструкторы и т.д.). Это может давать неожиданные результаты. Например, [] instanceof window.frames[0].Array вернёт false , потому что Array.prototype !== window.frames[0].Array а массив наследуется от Array .

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

Например, для проверки того, что Node является SVGElement (en-US) в разных контекстах можно использовать myNode instanceof myNode.ownerDocument.defaultView.SVGElement .

Примечание: Использование XPCOM instanceof в коде имеет специальный эффект: obj instanceof xpcomInterface (например Components.interfaces.nsIFile ) вызывает obj.QueryInterface(xpcomInterface) и возвращает true если проверка на QueryInterface прошла успешно. Побочным эффектом этого вызова является то, что можно использовать свойства xpcomInterface на obj после успешной проверки с помощью instanceof . В отличии от стандартных глобальных JavaScript типов, проверка obj instanceof xpcomInterface работает как ожидается, даже если obj относится к другому контексту.

Примеры

Показывает, что String и Date имеют тип Object и граничные случаи

Следующий код использует instanceof , чтобы показать что объекты String и Date также имеют тип Object (они являются наследниками Object ).

Однако, объекты, созданные с помощью литералов, являются исключениями — хотя их prototype равен undefined , выражение instanceof Object возвращает true .

var simpleStr = "Это обычная строка"; var myString = new String(); var newStr = new String("Строка, созданная с помощью конструктора"); var myDate = new Date(); var myObj = >; simpleStr instanceof String; // возвращает false, проверяет цепочку прототипов myString instanceof String; // возвращает true newStr instanceof String; // возвращает true myString instanceof Object; // возвращает true myObj instanceof Object; // возвращает true, несмотря на прототип, равный undefined (>) instanceof Object; // возвращает true, аналогично предыдущей строчке myString instanceof Date; // возвращает false myDate instanceof Date; // возвращает true myDate instanceof Object; // возвращает true myDate instanceof String; // возвращает false 

Показывает, что mycar имеет тип Car и тип Object

Следующий код создаёт тип Car и экземпляр этого типа, mycar . Оператор instanceof показывает, что объект mycar имеет тип Car и тип Object .

function Car(make, model, year)  this.make = make; this.model = model; this.year = year; > var mycar = new Car("Honda", "Accord", 1998); var a = mycar instanceof Car; // возвращает true var b = mycar instanceof Object; // возвращает true 

Спецификации

Specification
ECMAScript Language Specification
# sec-relational-operators

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 6 янв. 2024 г. by MDN contributors.

Your blueprint for a better internet.

Приватные методы и свойства, оператор instanceof

Согласно концепции инкапсуляции ООП в классах можно создавать как открытые (публичные) методы и свойства, так и закрытые, доступные только внутри класса или его объектов. До сих пор все методы и свойства у нас были публичные. Но, что если мы хотим некоторые из них указать как приватные, закрытые? Например, в классе Users такими сделать свойства name и old:

class Users { constructor(name, old) { this.name = name; this.old = old; } getName() { return this.name; } }
  • _name, _old – приватные свойства;
  • _setProperty(key, value) – приватный метод.
constructor(name, old) { this._name = name; this._old = old; }

Мы к ним, тем не менее, можем совершенно спокойно обращаться из вне:

console.log( u1._name );

Но это уже остается на совести программиста и, вообще, считается порочной практикой, т.к. такие свойства в будущем (в другой версии модуля) могут измениться или совсем исчезнуть и тогда придется переделывать и саму программу, что не очень приятно. Поэтому, отмеченные таким образом атрибуты, следует использовать исключительно внутри класса. Таково общепринятое соглашение. Разумеется, как обычные свойства, условно-приватные также наследуются и доступны в дочерних классах. Например, объявим метод getName как приватный:

_getName() { return this._name; }

и создадим дочерний класс Admin:

class Admin extends Users { constructor(name, old, login, psw) { super(name, old); this.login = login; this.psw = psw; } }

Тогда после создания объекта:

let u2 = new Admin("Кирилл", 22, "admin", "1111");

мы совершенно спокойно можем вызвать метод базового класса:

console.log( u2._getName() );

даже, если он по соглашению приватный. Это еще раз показывает, что закрытые методы – это лишь соглашение между программистами, языком JavaScript они воспринимаются как обычные методы и свойства.

Настоящие приватные свойства

Совсем недавно в JavaScript появилась возможность объявлять «настоящие» приватные свойства, которые становятся защищенными на уровне языка, а не просто соглашения между программистами. Для их обозначения перед именами ставится символ шарп: # <имя свойства>— защищенное свойство. Например, в классе Users для объявления таких свойств мы должны, во-первых, указать их непосредственно в классе:

class Users { #name; #old; constructor(name, old) { this.#name = name; this.#old = old; } getName() { return this.#name; } }

А, затем, уже можем использовать в экземплярах классов:

let u1 = new Users("Михаил", 19); let u2 = new Admin("Кирилл", 22, "admin", "1111"); console.log( u1.getName() ); // Михаил console.log( u2.getName() ); // Кирилл

Как видите, в консоли выводятся разные имена, следовательно, для каждого объекта приватное свойство является уникальным и хранится непосредственно в нем. Если же мы попытаемся обратиться к такому свойству из вне:

console.log( u1.#name );

то возникнет ошибка. Это как раз и показывает, что такие свойства по-настоящему приватные и могут изменяться только внутри класса или его объектах. У таких свойств есть один нюанс: обращаться к ним по синтаксису: this[<ключ>] нельзя. Например, если в методе getName записать:

getName() { return this['#name']; }

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

Оператор instanceof

В JavaScript есть довольно полезный и часто используемый оператор obj instanceof Class который проверяет принадлежность объекта obj классу Class, то есть, возвращает true, если obj действительно является экземпляром класса Class (или, любому базовому классу) и false – в противном случае. Например, в нашей программе можно реализовать следующую проверку:

console.log( u1 instanceof Admin); // false console.log( u2 instanceof Admin ); // true

А, вот если вместо Admin написать Users:

console.log( u1 instanceof Users); console.log( u2 instanceof Users);

то в обоих случаях получим true. Это, как раз, и показывает, что оператор instanceof выполняет проверку принадлежности с учетом наследования классов. Это отличает данный оператор от простого сравнения:

console.log( u1.constructor == Users); console.log( u2.constructor == Users);

Здесь свойство constructor (если оно есть и не было искусственно изменено) хранит ссылку на функцию-конструктор, с помощью которой и был создан текущий объект. А, так как класс – это и есть функция-конструктор, то мы, таким образом, проверяем соответствие объекта тому или иному классу. Вот так в JavaScript можно определять тип объекта с помощью оператор instanceof и простой проверкой на равенство.

Как работает instanceof?

5e183195b44cc380495024.png

Подскажите не могу понять почему alert( new F() instanceof F ); выведет false ?

  • Вопрос задан более трёх лет назад
  • 1096 просмотров

Комментировать
Решения вопроса 1

MrDecoy

Вадим @MrDecoy Куратор тега JavaScript
Верставший фронтендер

Instance — Это экземпляр.
Используя A instanceof B , Вы как бы спрашиваете: является ли А экземпляром класса B ?
Классов у нас нет, но есть прототипное наследование и функции-консструкторы взамен.

Экземпляр возвращается конструктором через new неявно, или же если в конструкторе Вы строго укажите какой объект, в качестве экземпляра, будет возвращён.

В примере же указано что функция-конструктор должна возвращать себя же.
Таким образом, фукнция — не экземпляр самой себя.
Отсюда и new F() instanceof F — false;

Но!
Функции в JS являются экземплярами класса Function.
А в примере, как уже писалось выше, функция конструтор возвращает саму себя, следовательно, возвращает объект-экземпляр клаcса Function.
Отсюда и new F() instanceof Function — true;

Сравнение JavaScript операторов typeof и insanceof

В JavaScript есть операторы typeof и instanceof, на первый взгляд они похоже, но они выполняют разные функции.

В этой статье будет рассмотрена разница между ними и показаны примеры использования.

Typeof оператор

Оператор typeof используется, в основном, для того, чтобы узнать тип примитивного значения.

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

К примеру, у нас есть :

console.log(typeof 1); 

В терминале отобразится ‘number’.

Более полезно, когда у нас есть переменные:

 let foo = 1; console.log(typeof foo); 

В таком случае мы можем использовать typeof, чтобы узнать тип переменной foo.

Важно запомнить, что typeof не следует использовать для null, если мы напишем:

 console.log(typeof null);

В терминале отобразится ‘object’. Вместо этого следует использовать оператор === ://

 foo === null

Другой пример содержит boolean значения.

typeof false === 'boolean'; typeof Boolean(0) === 'boolean';

Мы также можем проверить числа следующим образом:

typeof Number('1') === 'number'; typeof Number('foo') === 'number'; typeof NaN === 'number';

Обратите внимание, что NaN и вычисления, которые возвращают NaN, такие как Number(‘foo’ ), также относятся к типу ‘number’ . Мы должны проверить их с помощью метода Number.isNaN().

 typeof 2n === 'bigint';
typeof '' === 'string'; typeof 'foo' === 'string';
typeof Symbol() === 'symbol' typeof Symbol('bar') === 'symbol'

Также, можно использовать typeof для определения типа undefined:

typeof undefined === 'undefined'; let x; typeof x === 'undefined';

Можно использовать для объектов, однако все объекты возвращают тип ‘object’, так что это не очень полезно:

typeof new String('foo') === 'object'; typeof new Number(1) === 'object';

Некоторые старые браузеры возвращают «функцию», когда мы применяем оператор typeof к литералам регулярных выражений. Однако сегодня это не должно быть проблемой.

Исключения

Typeof document.all всегда возвращает undefined, даже если он определен во всех браузерах.

Оператор instanceof

Оператор instanceof проверяет, появляется ли свойство прототипа конструктора где-либо в цепочке прототипов объекта.

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

Он возвращает true, если объект является экземпляром класса или функции-конструктора, и false в противном случае.

Например, если у нас есть:

class Foo <>; let foo = new Foo(); console.log(foo instanceof Foo); function Bar ()<>; let bar = new Bar(); console.log(bar instanceof Bar);

В терминале будет два «true».

Все, что создано с помощью new, можно проверить с помощью оператора instanceof.

Instanceof полезен для проверки всего, что создано с помощью оператора new, включая строки, логические значения и числа.

Например, если у нас есть:

let foo = new String('foo'); console.log(typeof foo); console.log(foo instanceof String);

Затем мы получаем ‘object’ из первого console.log и true для второго.

Это связано с тем, что мы создали экземпляр объекта String вместо строки примитивного значения, хотя в противном случае мы можем использовать примитивную строку и строковые объекты таким же образом.

Литеральные объекты

Литералы объектов, созданные без оператора new, являются экземплярами Object.

Итак, если у нас есть:

console.log(<> instanceof Object);

Все объекты являются экземплярами Object в дополнение к тому, что они являются экземплярами конструктора, из которого они созданы. Например, если у нас есть:

let date = new Date(); console.log(date instanceof Object); console.log(date instanceof Date);

В обоих случаях выведутся значение true, поскольку date является экземпляром конструктора Date, а все непримитивные объекты являются экземплярами Object.

Выводы

Оператор typeof и instanceof совершенно разные. typeof возвращает тип объекта, над которым он работает.

Instanceof of возвращает true, если объект создан из данного конструктора, и false в противном случае.

Все непримитивные объекты являются экземплярами Object, поэтому он всегда будет возвращать true.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *