Skip to main content

The in operator

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

QuestionAnswer
What it checksPresence of a key (property or index)
What it works withObjects, arrays, functions
What it returnstrue / false
Does it respect the prototypeYes
Does it check the valueNo

Examples for comparison:

CheckResultExplanation
'name' in { name: 'Alice' }truethe key exists
'email' in { name: 'Alice' }falsethere is no such key
0 in ['a', 'b']trueindex 0 exists
2 in ['a', 'b']falseindex 2 is missing
'toString' in {}trueinherited 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.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.