Skip to content

Commit

Permalink
[ru] update 'Web/JavaScript/Reference/Operators/in' translation (#21442)
Browse files Browse the repository at this point in the history
* [ru] update 'Web/JavaScript/Reference/Operators/in' translation

* feat: add sourceCommit for files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: Leonid Vinogradov <[email protected]>

* [ru] improve wording and add missing link

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update files/ru/web/javascript/reference/operators/in/index.md

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update files/ru/web/javascript/reference/operators/in/index.md

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Leonid Vinogradov <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 29, 2024
1 parent 8f59e7e commit 53324c5
Showing 1 changed file with 205 additions and 25 deletions.
230 changes: 205 additions & 25 deletions files/ru/web/javascript/reference/operators/in/index.md
Original file line number Diff line number Diff line change
@@ -1,97 +1,276 @@
---
title: in operator
title: in
slug: Web/JavaScript/Reference/Operators/in
l10n:
sourceCommit: 13b2fe46243beed6dc29f5d3defa716abe79c1f9
---

{{jsSidebar("Operators")}}

**Оператор `in`** возвращает `true`, если свойство содержится в указанном объекте или в его цепочке прототипов.
Оператор `in` возвращает `true`, если свойство содержится в указанном объекте или в его цепочке прототипов.

Оператор `in` не может быть использован для поиска значений в других видах коллекций. Чтобы проверить, существует ли определённое значение в массиве, можно использовать {{jsxref("Array.prototype.includes()")}}. А у наборов есть метод {{jsxref("Set.prototype.has()")}}.

{{EmbedInteractiveExample("pages/js/expressions-inoperator.html")}}

## Синтаксис

```
```js-nolint
prop in object
#prop in object
```

### Параметры

- `prop`
- : Строка или symbol, представляющий название свойства или индекс массива (non-symbols будут конвертированы в строки).

<!---->
- : Строковое или символьное значение, представляющее название свойства (несимвольные значения будут [преобразованы в строки](/ru/docs/Web/JavaScript/Reference/Global_Objects/String#приведение_к_строке)). Также может быть [именем приватного свойства](/ru/docs/Web/JavaScript/Reference/Classes/Private_properties).

- `object`
- : Объект, в котором нужно проверить содержание свойства с заданным именем.
- : Объект, для которого будет производится проверка, содержит ли он (или его цепочка прототипов) свойство с указанным именем (`prop`).

### Исключения

- {{jsxref("TypeError")}}:
- : Возникает, если `object` не является объектом (например, является примитивом).

## Описание

Оператор `in` проверяет, существует ли указанное свойство в объекте или его цепочке прототипов. Для проверки наличия только собственных свойств следует использовать {{jsxref("Object.hasOwn()")}}.

Свойство может существовать в объекте, но иметь значение `undefined`. Поэтому `x in obj` не то же самое, что `obj.x !== undefined`. Для того, чтобы оператор `in` возвращал значение `false`, используйте оператор [`delete`](/ru/docs/Web/JavaScript/Reference/Operators/delete) вместо присваивания свойству значения `undefined`.

Также можно использовать оператор `in`, чтобы проверить, существует ли в объекте [приватное поле класса или метод](/ru/docs/Web/JavaScript/Reference/Classes/Private_properties). Оператор `in` возвращает `true`, если свойство определено и `false` в противном случае. Такая проверка называется _бренд-чек_, потому что `in` возвращает `true` только в том случае, когда объект был создан с помощью конструктора класса и имеет доступ к приватным свойствам.

В этом случае используется особый синтаксис: левая сторона оператора `in` является идентификатором свойства, а не выражением, но без кавычек (иначе это будет свойством с типом строка, а не приватным свойством).

Поскольку обращение к приватным свойствам объекта не связанного с текущим классом приводит к появлению {{jsxref("TypeError")}} вместо возвращения `undefined`, то оператор `in` позволяет сократить запись такой проверки:

```js
class C {
#x;
static isC(obj) {
try {
obj.#x;
return true;
} catch {
return false;
}
}
}
```

До более короткой:

```js
class C {
#x;
static isC(obj) {
return #x in obj;
}
}
```

Оператор `in` также позволяет избежать необходимости обрабатывать ошибки доступа к несуществующим приватным свойствам.

Однако, оператор `in` по-прежнему требует предварительно объявлять приватные свойства заранее в окружающем классе, иначе будет выброшена ошибка {{jsxref("SyntaxError")}} ("Private field '#x' must be declared in an enclosing class") такая же, как и когда вы пытаетесь получить доступ к необъявленному приватному свойству.

```js-nolint example-bad
class C {
foo() {
#x in this;
}
}
new C().foo(); // SyntaxError: Private field '#x' must be declared in an enclosing class
```

## Примеры

### Обычное использование

В примере ниже показаны некоторые способы использования оператора `in`.

```js
// Массивы
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
0 in trees; // true
3 in trees; // true
6 in trees; // false
"bay" in trees; // false (вы должны указать индекс элемента в массиве, а не значение в этом индексе)
"bay" in trees; // false (необходимо указать индекс элемента в массиве, а не значение)
"length" in trees; // true (length является свойством Array)
Symbol.iterator in trees; // true

// Уже существующие объекты
"PI" in Math; // true

// Пользовательские объекты
var mycar = { make: "Honda", model: "Accord", year: 1998 };
const mycar = { make: "Honda", model: "Accord", year: 1998 };
"make" in mycar; // true
"model" in mycar; // true
```

Вы должны указать объект справа от оператора `in`. Например, вы можете указать строку, созданную через конструктор объекта `String`, но вы не можете указать строковый литерал.
Необходимо указать объект справа от оператора `in`. Например, можно указать строку, созданную с помощью конструктора `String`, но нельзя использовать строковый литерал.

```js
var color1 = new String("green");
"length" in color1; // returns true
const color1 = new String("green");
"length" in color1; // true

var color2 = "coral";
// сгенерирует ошибку (color2 is not a String object)
const color2 = "coral";
// сгенерирует ошибку (color2 не является объектом String)
"length" in color2;
```

### Использование оператора `in` с неопределёнными или с уже удалёнными свойствами

Если вы удалили свойство при помощи оператора [`delete`](/ru/docs/Web/JavaScript/Reference/Operators/delete), то оператор `in` возвратит `false` для этого свойства.
Если удалить свойство при помощи оператора [`delete`](/ru/docs/Web/JavaScript/Reference/Operators/delete), то оператор `in` возвратит `false` для этого свойства.

```js
var mycar = { make: "Honda", model: "Accord", year: 1998 };
const mycar = { make: "Honda", model: "Accord", year: 1998 };
delete mycar.make;
"make" in mycar; // false

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
delete trees[3];
3 in trees; // false
```

Если вы зададите свойству значение {{jsxref("Global_Objects/undefined", "undefined")}}, но не удалите его, то для этого свойства оператор `in` вернёт значение `true`.
Если задать свойству значение {{jsxref("undefined")}}, а не удалять его, то для этого свойства оператор `in` вернёт значение `true`.

```js
var mycar = { make: "Honda", model: "Accord", year: 1998 };
const mycar = { make: "Honda", model: "Accord", year: 1998 };
mycar.make = undefined;
"make" in mycar; // true
```

```js
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
trees[3] = undefined;
3 in trees; // returns true
3 in trees; // true
```

Оператор `in` вернёт `false` для [пустых слотов в массиве](/ru/docs/Web/JavaScript/Guide/Indexed_collections#sparse_arrays), несмотря на то, что прямой доступ к свойству вернёт `undefined`.

```js
const empties = new Array(3);
empties[2]; // undefined
2 in empties; // false
```

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

```js
const empties = new Array(3).fill(undefined);
2 in empties; // true
```

### Наследуемые свойства

Оператор `in` возвратит `true` для свойств, которые унаследованы по цепочке прототипов. (Если вы хотите проверить только не наследованные свойства, используйте {{jsxref("Object.prototype.hasOwnProperty()")}}.)
Оператор `in` возвратит `true` для свойств, которые унаследованы по цепочке прототипов. Это может быть нежелательно при использовании объектов для хранения произвольных пар ключ-значение.

```js example-bad
const ages = { alice: 18, bob: 27 };

function hasPerson(name) {
return name in ages;
}

hasPerson("hasOwnProperty"); // true
```

Можно использовать {{jsxref("Object.hasOwn()")}}, чтобы проверить, существует ли в объекте данный ключ.

```js
const ages = { alice: 18, bob: 27 };

function hasPerson(name) {
return Object.hasOwn(ages, name);
}

hasPerson("hasOwnProperty"); // false
```

Также можно использовать [объект с прототипом null](/ru/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects) или {{jsxref("Map")}}, чтобы избежать других ошибок.

```js example-good
const ages = new Map([
["alice", 18],
["bob", 27],
]);

function hasPerson(name) {
return ages.has(name);
}

hasPerson("hasOwnProperty"); // false
```

### Использование оператора `in` для реализации _бренд-чека_

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

```js
"toString" in {}; // true
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)); // -10
console.log(Person.isPerson(p1)); // true

if (Person.isPerson(p1) && Person.isPerson(p2)) {
console.log(p1.ageDifference(p2)); // -10
}
```

Это помогает предотвратить следующую ошибку:

```js
const p2 = {};

p1.ageDifference(p2); // TypeError: Cannot read private member #age from an object whose class did not declare it
```

Без оператора `in` пришлось бы использовать блок `try...catch`, чтобы проверить, есть ли в объекте приватное свойство.

Также это можно реализовать с помощью метода класса [`@@hasInstance`](/ru/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance), и в дальнейшем использовать оператор [`instanceof`](/ru/docs/Web/JavaScript/Reference/Operators/instanceof) для выполнения такой же проверки (которая по умолчанию проверяет только наличие `Person.prototype` в цепочке прототипов объекта).

```js
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
}
```

Дополнительные примеры есть в разделе «[Приватные свойства](/ru/docs/Web/JavaScript/Reference/Classes/Private_properties)» и в [руководстве по классам](/ru/docs/Web/JavaScript/Guide/Using_classes#private_fields).

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

{{Specifications}}
Expand All @@ -102,7 +281,8 @@ trees[3] = undefined;

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

- [`for...in`](/ru/docs/Web/JavaScript/Reference/Statements/for...in)
- [`delete`](/ru/docs/Web/JavaScript/Reference/Operators/delete)
- {{jsxref("Object.prototype.hasOwnProperty()")}}
- {{jsxref("Object.hasOwn()")}}
- {{jsxref("Reflect.has()")}}
- [Enumerability and ownership of properties](/ru/docs/Enumerability_and_ownership_of_properties)
- [Перечисляемость и владение свойствами](/ru/docs/Web/JavaScript/Enumerability_and_ownership_of_properties)

0 comments on commit 53324c5

Please sign in to comment.