Suggest an editImprove this articleRefine the answer for “The in operator”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The `in` operator checks whether a given property exists in an object or an index exists in an array, and returns `true` or `false`.** It looks at the presence of the key, not the value: `'a' in { a: undefined }` is `true`. The lookup walks both own properties and the whole prototype chain, so `'toString' in {}` is `true` as well. To check own keys only, use `Object.hasOwn(obj, key)` or `obj.hasOwnProperty(key)`. ```javascript const user = { name: 'Alice', email: undefined }; 'name' in user; // true 'email' in user; // true (the key exists even though the value is undefined) 'phone' in user; // false 'toString' in user; // true (inherited from Object.prototype) ``` **Key point:** `in` answers "does this key exist", not "does it hold a value", and it takes the prototype chain into account.Shown above the full answer for quick recall.Answer (EN)Image**The `in` operator in JavaScript checks whether a given property exists in an object or an index exists in an array.** It is one of the basic operators that is often misunderstood: it looks at the presence of a key, not at its value, and it takes the whole prototype chain into account. ## Theory ### TL;DR - Syntax: `propName in object`, the result is always `true` or `false`. - It checks that a key exists, not its value: `'a' in { a: undefined }` is `true`. - It works with objects, arrays and functions; array indexes are ordinary keys. - It respects the prototype chain: `'toString' in {}` is `true`. - For own properties only use `Object.hasOwn(obj, key)` or `obj.hasOwnProperty(key)`. - If the right side is not an object (`null`, `undefined`, a number, a string), you get a `TypeError`. ### Quick example ```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 (inherited) console.log(Object.hasOwn(user, 'toString')); // false (not an own property) ``` ### Syntax ```javascript propName in object ``` Where: - `propName` is a string (or an expression that is converted to a string or a symbol), - `object` is an object, an array or another structure with keys. A number on the left is allowed too: it is converted to a string, so `0 in arr` really checks the key `'0'`. ### Working with objects ```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 ``` > The `in` operator returns `true` when the property exists in the object, even if its value is `undefined`. That is exactly the main subtlety: ```javascript const obj = { a: undefined }; console.log('a' in obj); // true console.log(obj.a === undefined); // true ``` > So `in` checks that a key is present, not what it holds. The comparison `obj.a === undefined` cannot tell "no such key" from "the key exists but holds undefined", while `in` can. ### Working with arrays ```javascript const arr = ['a', 'b', 'c']; console.log(0 in arr); // true, index 0 exists console.log(2 in arr); // true, index 2 exists console.log(3 in arr); // false, no such index ``` > JavaScript treats array indexes as ordinary properties: `arr[0]` is equivalent to `arr['0']`. Because of this, `in` sees holes in sparse arrays: in `['a', , 'c']` the expression `1 in arr` is `false`, although `arr.length` is 3. ### Inheritance through the prototype The `in` operator checks not only own properties but also the ones inherited through the prototype chain. ```javascript const person = { name: 'Alice' }; console.log('toString' in person); // true, because it is inherited from Object.prototype ``` > To check own properties only, use `Object.hasOwn(person, 'key')` or the older `person.hasOwnProperty('key')`: > > ```javascript > person.hasOwnProperty('toString'); // false > person.hasOwnProperty('name'); // true > ``` The same holds for classes: ```javascript class User { constructor() { this.name = 'Alex'; } } User.prototype.age = 25; const u = new User(); console.log('name' in u); // true (own property) console.log('age' in u); // true (inherited from the prototype) ``` ### Error when the right side is not an object If the right-hand side is not an object and cannot be converted to one, JavaScript throws: ```javascript 'length' in null; // TypeError 'length' in undefined; // TypeError 'length' in 'text'; // TypeError (a primitive, not an object) ``` > So make sure the variable is neither `null` nor `undefined` before the check, for example with `obj && 'key' in obj`. ### Summary | Question | Answer | | --- | --- | | What it checks | Presence of a key (property or index) | | What it works with | Objects, arrays, functions | | What it returns | `true` / `false` | | Does it respect the prototype | Yes | | Does it check the value | No | Examples for comparison: | Check | Result | Explanation | | --- | --- | --- | | `'name' in { name: 'Alice' }` | true | the key exists | | `'email' in { name: 'Alice' }` | false | there is no such key | | `0 in ['a', 'b']` | true | index 0 exists | | `2 in ['a', 'b']` | false | index 2 is missing | | `'toString' in {}` | true | inherited from `Object.prototype` | ### Common mistakes - Expecting `in` to check the value. A key whose value is `undefined` or `null` still returns `true`. - Forgetting the prototype: `'constructor' in obj` and `'toString' in obj` are always `true` for a plain object. - Using `in` to look for an element in an array. `'b' in ['a','b']` is `false`, because indexes are checked; for values you need `arr.includes('b')`. - Calling `in` on `null` or `undefined` and getting a `TypeError` instead of `false`. - Confusing `in` with `for...in` and with `instanceof`: they are different constructs despite the similar names. - Calling `obj.hasOwnProperty(key)` on an object created with `Object.create(null)`; such an object has no such method, so `Object.hasOwn(obj, key)` is safer.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.