Skip to main content

Оператор in

Оператор in у JavaScript перевіряє, чи існує вказана властивість в об'єкті або індекс у масиві. Це один із базових операторів, який часто розуміють неправильно: він дивиться на наявність ключа, а не на його значення, і враховує весь ланцюжок прототипів.

Теорія

TL;DR

  • Синтаксис: propName in object, результат завжди true або false.
  • Перевіряє наявність ключа, а не значення: 'a' in { a: undefined } дає true.
  • Працює з об'єктами, масивами та функціями; індекси масиву це звичайні ключі.
  • Враховує прототип: 'toString' in {} дає true.
  • Тільки власні властивості перевіряють через Object.hasOwn(obj, key) або obj.hasOwnProperty(key).
  • Якщо праворуч не об'єкт (null, undefined, число, рядок), буде TypeError.

Швидкий приклад

javascript
const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log('email' in user); // false console.log('toString' in user); // true (успадковано) console.log(Object.hasOwn(user, 'toString')); // false (не власна властивість)

Синтаксис

javascript
propName in object

Де:

  • propName це рядок (або вираз, який приводиться до рядка чи символа),
  • object це об'єкт, масив або інша структура з ключами.

Число ліворуч теж допустиме: воно буде приведене до рядка, тому 0 in arr насправді перевіряє ключ '0'.

Робота з об'єктами

javascript
const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log('age' in user); // true console.log('email' in user); // false

Оператор in повертає true, якщо властивість існує в об'єкті, навіть коли її значення дорівнює undefined.

Саме в цьому головна особливість:

javascript
const obj = { a: undefined }; console.log('a' in obj); // true console.log(obj.a === undefined); // true

Тобто in перевіряє наявність ключа, а не значення. Порівняння obj.a === undefined не дозволяє відрізнити «ключа немає» від «ключ є, але значення undefined», а in дозволяє.

Робота з масивами

javascript
const arr = ['a', 'b', 'c']; console.log(0 in arr); // true, індекс 0 існує console.log(2 in arr); // true, індекс 2 існує console.log(3 in arr); // false, такого індексу немає

JavaScript сприймає індекси масиву як звичайні властивості: arr[0] еквівалентне arr['0'].

Через це in бачить «дірки» у розріджених масивах: у ['a', , 'c'] вираз 1 in arr дасть false, хоча arr.length дорівнює 3.

Успадкування через прототип

Оператор in перевіряє не лише власні властивості, а й успадковані через прототип.

javascript
const person = { name: 'Alice' }; console.log('toString' in person); // true, бо успадковано від Object.prototype

Щоб перевірити тільки власні властивості, використовуйте Object.hasOwn(person, 'key') або старіший person.hasOwnProperty('key'):

javascript
person.hasOwnProperty('toString'); // false person.hasOwnProperty('name'); // true

Те саме працює і з класами:

javascript
class User { constructor() { this.name = 'Alex'; } } User.prototype.age = 25; const u = new User(); console.log('name' in u); // true (власна властивість) console.log('age' in u); // true (успадковано від прототипу)

Помилка при використанні з не-об'єктом

Якщо права частина не є об'єктом і не може бути до нього приведена, JavaScript викине помилку:

javascript
'length' in null; // TypeError 'length' in undefined; // TypeError 'length' in 'text'; // TypeError (примітив, а не об'єкт)

Тому перед перевіркою переконайтеся, що змінна не null і не undefined, наприклад через obj && 'key' in obj.

Підсумок

ПитанняВідповідь
Що перевіряєНаявність ключа (властивості або індексу)
Працює зОб'єктами, масивами, функціями
Що повертаєtrue / false
Чи враховує прототипТак
Чи перевіряє значенняНі

Приклади для порівняння:

ПеревіркаРезультатПояснення
'name' in { name: 'Alice' }trueключ існує
'email' in { name: 'Alice' }falseключа немає
0 in ['a', 'b']trueіндекс 0 є
2 in ['a', 'b']falseіндексу 2 немає
'toString' in {}trueуспадковано від Object.prototype

Типові помилки

  • Очікувати, що in перевіряє значення. Ключ зі значенням undefined або null усе одно дає true.
  • Забувати про прототип: 'constructor' in obj і 'toString' in obj завжди true для звичайного об'єкта.
  • Використовувати in для пошуку елемента в масиві. 'b' in ['a','b'] дає false, бо перевіряються індекси; для значень потрібен arr.includes('b').
  • Викликати in на null чи undefined і отримувати TypeError замість false.
  • Плутати in з for...in та з instanceof: це різні конструкції, попри схожі назви.
  • Викликати obj.hasOwnProperty(key) на об'єкті, створеному через Object.create(null); такий об'єкт не має цього методу, тому безпечніше Object.hasOwn(obj, key).

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.