This page was translated from English by the community.Learn more and join the MDN Web Docs community.
in
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since июль 2015 г..
Операторin возвращаетtrue, если свойство содержится в указанном объекте или в его цепочке прототипов.
Операторin не может быть использован для поиска значений в других видах коллекций. Чтобы проверить, существует ли определённое значение в массиве, можно использоватьArray.prototype.includes(). А у наборов есть методSet.prototype.has().
In this article
Интерактивный пример
const car = { make: "Honda", model: "Accord", year: 1998 };console.log("make" in car);// Expected output: truedelete car.make;if ("make" in car === false) { car.make = "Suzuki";}console.log(car.make);// Expected output: "Suzuki"Синтаксис
prop in object#prop in objectПараметры
propСтроковое или символьное значение, представляющее название свойства (несимвольные значения будутпреобразованы в строки). Также может бытьименем приватного свойства.
objectОбъект, для которого будет производится проверка, содержит ли он (или его цепочка прототипов) свойство с указанным именем (
prop).
Исключения
TypeError:Возникает, если
objectне является объектом (например, является примитивом).
Описание
Операторin проверяет, существует ли указанное свойство в объекте или его цепочке прототипов. Для проверки наличия только собственных свойств следует использоватьObject.hasOwn().
Свойство может существовать в объекте, но иметь значениеundefined. Поэтомуx in obj не то же самое, чтоobj.x !== undefined. Для того, чтобы операторin возвращал значениеfalse, используйте операторdelete вместо присваивания свойству значенияundefined.
Также можно использовать операторin, чтобы проверить, существует ли в объектеприватное поле класса или метод. Операторin возвращаетtrue, если свойство определено иfalse в противном случае. Такая проверка называетсябренд-чек, потому чтоin возвращаетtrue только в том случае, когда объект был создан с помощью конструктора класса и имеет доступ к приватным свойствам.
В этом случае используется особый синтаксис: левая сторона оператораin является идентификатором свойства, а не выражением, но без кавычек (иначе это будет свойством с типом строка, а не приватным свойством).
Поскольку обращение к приватным свойствам объекта не связанного с текущим классом приводит к появлениюTypeError вместо возвращенияundefined, то операторin позволяет сократить запись такой проверки:
class C { #x; static isC(obj) { try { obj.#x; return true; } catch { return false; } }}До более короткой:
class C { #x; static isC(obj) { return #x in obj; }}Операторin также позволяет избежать необходимости обрабатывать ошибки доступа к несуществующим приватным свойствам.
Однако, операторin по-прежнему требует предварительно объявлять приватные свойства заранее в окружающем классе, иначе будет выброшена ошибкаSyntaxError ("Private field '#x' must be declared in an enclosing class") такая же, как и когда вы пытаетесь получить доступ к необъявленному приватному свойству.
class C { foo() { #x in this; }}new C().foo(); // SyntaxError: Private field '#x' must be declared in an enclosing classПримеры
>Обычное использование
В примере ниже показаны некоторые способы использования оператораin.
// Массивыconst trees = ["redwood", "bay", "cedar", "oak", "maple"];0 in trees; // true3 in trees; // true6 in trees; // false"bay" in trees; // false (необходимо указать индекс элемента в массиве, а не значение)"length" in trees; // true (length является свойством Array)Symbol.iterator in trees; // true// Уже существующие объекты"PI" in Math; // true// Пользовательские объектыconst mycar = { make: "Honda", model: "Accord", year: 1998 };"make" in mycar; // true"model" in mycar; // trueНеобходимо указать объект справа от оператораin. Например, можно указать строку, созданную с помощью конструктораString, но нельзя использовать строковый литерал.
const color1 = new String("green");"length" in color1; // trueconst color2 = "coral";// сгенерирует ошибку (color2 не является объектом String)"length" in color2;Использование оператораin с неопределёнными или с уже удалёнными свойствами
Если удалить свойство при помощи оператораdelete, то операторin возвратитfalse для этого свойства.
const mycar = { make: "Honda", model: "Accord", year: 1998 };delete mycar.make;"make" in mycar; // falseconst trees = ["redwood", "bay", "cedar", "oak", "maple"];delete trees[3];3 in trees; // falseЕсли задать свойству значениеundefined, а не удалять его, то для этого свойства операторin вернёт значениеtrue.
const mycar = { make: "Honda", model: "Accord", year: 1998 };mycar.make = undefined;"make" in mycar; // trueconst trees = ["redwood", "bay", "cedar", "oak", "maple"];trees[3] = undefined;3 in trees; // trueОператорin вернётfalse дляпустых слотов в массиве, несмотря на то, что прямой доступ к свойству вернётundefined.
const empties = new Array(3);empties[2]; // undefined2 in empties; // falseЧтобы избежать подобного, следует заполнять новый массив непустыми значениями и не записывать значения по индексам, превышающим длину массива.
const empties = new Array(3).fill(undefined);2 in empties; // trueНаследуемые свойства
Операторin возвратитtrue для свойств, которые унаследованы по цепочке прототипов. Это может быть нежелательно при использовании объектов для хранения произвольных пар ключ-значение.
const ages = { alice: 18, bob: 27 };function hasPerson(name) { return name in ages;}hasPerson("hasOwnProperty"); // trueМожно использоватьObject.hasOwn(), чтобы проверить, существует ли в объекте данный ключ.
const ages = { alice: 18, bob: 27 };function hasPerson(name) { return Object.hasOwn(ages, name);}hasPerson("hasOwnProperty"); // falseТакже можно использоватьобъект с прототипом null илиMap, чтобы избежать других ошибок.
const ages = new Map([ ["alice", 18], ["bob", 27],]);function hasPerson(name) { return ages.has(name);}hasPerson("hasOwnProperty"); // falseИспользование оператораin для реализациибренд-чека
Фрагмент кода ниже демонстрирует статическую функцию, которая проверяет, был ли объект создан конструктором классаPerson, и следовательно безопасно ли использовать методы этого класса.
class Person { #age; constructor(age) { this.#age = age; } static isPerson(o) { return #age in o; } ageDifference(other) { return this.#age - other.#age; }}const p1 = new Person(20);const p2 = new Person(30);console.log(p1.ageDifference(p2)); // -10console.log(Person.isPerson(p1)); // trueif (Person.isPerson(p1) && Person.isPerson(p2)) { console.log(p1.ageDifference(p2)); // -10}Это помогает предотвратить следующую ошибку:
const p2 = {};p1.ageDifference(p2); // TypeError: Cannot read private member #age from an object whose class did not declare itБез оператораin пришлось бы использовать блокtry...catch, чтобы проверить, есть ли в объекте приватное свойство.
Также это можно реализовать с помощью метода класса@@hasInstance, и в дальнейшем использовать операторinstanceof для выполнения такой же проверки (которая по умолчанию проверяет только наличиеPerson.prototype в цепочке прототипов объекта).
class Person { #age; constructor(age) { this.#age = age; } static [Symbol.hasInstance](o) { // Проверяем `this` для предотвращения ложно-положительных // результатов при вызове `instanceof SubclassOfPerson` return this === Person && #age in o; } ageDifference(other) { return this.#age - other.#age; }}const p1 = new Person(20);const p2 = new Person(30);if (p1 instanceof Person && p2 instanceof Person) { console.log(p1.ageDifference(p2)); // -10}Дополнительные примеры есть в разделе «Приватные свойства» и вруководстве по классам.
Спецификации
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-relational-operators> |