Question

Check Whether an Object Has a Key in JavaScript

Question

What is the correct way to check whether a JavaScript object contains a key? For example, which approach should be used for myObj and the key "key"?

if (myObj["key"] == undefined) {
  // ...
}

if (myObj["key"] == null) {
  // ...
}

if (myObj["key"]) {
  // ...
}

How do these checks differ, and how can I reliably determine whether the object has the property?

Short Answer

You will learn the difference between checking whether a property exists and checking whether its value is truthy. The recommended modern way to test whether an object owns a key is Object.hasOwn(obj, key).

Concept

A JavaScript object stores properties as key–value pairs:

const user = {
  name: "Ava",
  active: false,
  score: 0
};

Checking whether a key exists is different from checking the value stored at that key.

For example, active, score, and a property whose value is undefined may all exist, even though their values are not truthy:

const settings = {
  enabled: false,
  retries: 0,
  label: "",
  token: undefined
};

The most reliable modern check for an object's own property is:

Object.hasOwn(settings, "enabled"); // true
Object.hasOwn(settings, "missing"); // false

An own property is a property stored directly on that object. This matters because objects can also inherit properties through their prototype.

The original checks inspect values instead:

  • myObj["key"] == undefined is true when the value is undefined or null.
  • myObj["key"] == null has the same behavior because loose equality treats null and undefined as equal.
  • myObj["key"] checks whether the value is truthy, so it fails for valid values such as false, 0, and "".

Use a key-existence check when you need to know whether the property is present. Use a value check only when the actual value is what matters.

Mental Model

Think of an object as a set of labeled drawers.

  • Checking Object.hasOwn(cabinet, "key") asks: “Does this cabinet have a drawer labeled key?”
  • Reading cabinet["key"] asks: “What is inside that drawer?”
  • Writing if (cabinet["key"]) asks: “Is what is inside useful/truthy?”

A drawer can exist while holding 0, false, an empty string, or even undefined. Therefore, its contents do not reliably tell you whether the drawer exists.

Take Quiz

Syntax and Examples

Use Object.hasOwn() to check for a property stored directly on an object:

Object.hasOwn(object, propertyName);
const product = {
  name: "Notebook",
  stock: 0,
  featured: false
};

console.log(Object.hasOwn(product, "name"));     // true
console.log(Object.hasOwn(product, "stock"));    // true
console.log(Object.hasOwn(product, "price"));    // false

Even though product.stock is 0 and product.featured is false, those keys exist:

console.log(Object.hasOwn(product, "stock"));    // true
console.log(Object.hasOwn(product, "featured")); // true

console.log(Boolean(product.stock));    // false
console.log(Boolean(product.featured)); // false

If you specifically need to include inherited properties, use the in operator:

const account = Object.create({ type: "member" });
account.name = "Mina";

console.log("name" in account); // true: own property
console.log("type" in account); // true: inherited property

console.log(Object.hasOwn(account, "type")); // false

For older environments where Object.hasOwn() is unavailable, use:

Object.prototype.hasOwnProperty.call(object, propertyName);
const data = { id: 42 };
const hasId = Object.prototype.hasOwnProperty.call(data, "id");

console.log(hasId); // true

Step by Step Execution

Consider this object:

const preferences = {
  darkMode: false,
  fontSize: 0,
  nickname: "",
  timezone: undefined
};

console.log(Object.hasOwn(preferences, "darkMode"));
console.log(Object.hasOwn(preferences, "timezone"));
console.log(Object.hasOwn(preferences, "language"));
console.log(Boolean(preferences.darkMode));

Step by step:

  1. preferences is created with four keys: darkMode, fontSize, nickname, and timezone.
  2. Object.hasOwn(preferences, "darkMode") returns true because darkMode is directly stored in preferences.
  3. Object.hasOwn(preferences, "timezone") also returns true, even though its value is undefined.
  4. Object.hasOwn(preferences, "language") returns false because that key was never added.
  5. Boolean(preferences.darkMode) returns false because the value of darkMode is false. That does not mean the key is missing.

Output:

true
true
false
false

Real World Use Cases

Property-existence checks are useful whenever an object represents optional input or changing data.

  • API responses: Determine whether an API actually sent a field before applying defaults.
  • Form updates: Tell the difference between a field omitted from an update and a field intentionally set to false or "".
  • Configuration: Check whether a user supplied a setting, including valid settings such as 0 retries.
  • Feature flags: A flag set to false exists and should not be mistaken for a missing flag.
  • Data validation: Verify required keys before processing JSON-like data.

Example: preserving a deliberate false value in an update:

const update = { emailNotifications: false };

if (Object.hasOwn(update, "emailNotifications")) {
  savePreference(update.emailNotifications);
}

A truthiness check would skip this update because false is falsy.

Take Quiz

Real Codebase Usage

In production code, developers usually choose the check based on intent.

Validate required fields

function createOrder(payload) {
  if (!Object.hasOwn(payload, "productId")) {
    throw new Error("productId is required");
  }

  return { productId: payload.productId };
}

Apply a default only when a key was omitted

function getPageSize(options) {
  if (Object.hasOwn(options, "pageSize")) {
    return options.pageSize;
  }

  return 20;
}

getPageSize({ pageSize: 0 }); // 0, not 20

Safely inspect untrusted dictionary-like data

Objects from JSON, user input, or external libraries may not have the usual hasOwnProperty method. Prefer Object.hasOwn() rather than calling a method on the object itself:

function hasPermission(permissions, permission) {
  return Object.hasOwn(permissions, permission);
}

Check inherited behavior only when intended

The in operator is sometimes useful for class instances or prototype-based objects, but it is not usually the right choice for validating JSON/API payload fields.

if ("toString" in {}) {
  // true, because toString is inherited
}

Common Mistakes

Using truthiness to test key existence

This is incorrect when valid values can be falsy:

const options = { timeout: 0 };

if (options.timeout) {
  console.log("Timeout was provided");
}

The message does not run, even though timeout exists. Use:

if (Object.hasOwn(options, "timeout")) {
  console.log("Timeout was provided");
}

Comparing with undefined when undefined is a valid value

const record = { middleName: undefined };

console.log(record.middleName === undefined); // true

This cannot distinguish a missing key from an existing key set to undefined:

console.log(Object.hasOwn(record, "middleName")); // true
console.log(Object.hasOwn(record, "lastName"));   // false

Assuming == null means “missing”

const data = { note: null };

console.log(data.note == null); // true

This is true for both null and undefined; it does not check key ownership. Use it only when you intentionally want to treat null and undefined as equivalent absent values.

Calling obj.hasOwnProperty() directly

A key can shadow that method, or the object may not inherit from Object.prototype:

const dangerous = {
  hasOwnProperty: () => false,
  id: 1
};

console.log(dangerous.hasOwnProperty("id")); // false: misleading

Prefer:

console.log(Object.hasOwn(dangerous, "id")); // true

Forgetting that in includes inherited properties

console.log("toString" in {}); // true
console.log(Object.hasOwn({}, "toString")); // false

Use in only if inherited properties should count.

Comparisons

CheckWhat it testsfalse, 0, "" count as present?Inherited properties count?
Object.hasOwn(obj, "key")Whether key is an own propertyYesNo
"key" in objWhether key exists anywhere on the object or prototype chainYesYes
obj["key"] !== undefinedWhether the value is not undefinedNo, if value is undefinedValue lookup can find inherited values
obj["key"] == nullWhether the value is null or undefinedNot a key-existence checkValue lookup can find inherited values
if (obj["key"])Whether the value is truthyNoValue lookup can find inherited values

Use Object.hasOwn() for ordinary object-key validation. Use in when prototype-inherited members are deliberately part of the check. Use truthiness checks only when you truly need a truthy value.

Take Quiz

Cheat Sheet

// Recommended: own key exists
Object.hasOwn(obj, "key");

// Include own and inherited keys
"key" in obj;

// Older compatible own-key check
Object.prototype.hasOwnProperty.call(obj, "key");

// Read a value
const value = obj["key"];

Key rules:

  • Object.hasOwn(obj, "key") is true even if the value is false, 0, "", null, or undefined.
  • if (obj.key) is a truthiness check, not an existence check.
  • obj.key == null is true for null and undefined.
  • "key" in obj includes inherited properties.
  • Use bracket notation for dynamic key names:
const key = "email";
Object.hasOwn(user, key);

FAQ

How do I check whether a JavaScript object has a key?

Use Object.hasOwn(object, "key"). It returns true only when the key is directly stored on the object.

Why does if (obj.key) not work for checking a property?

It checks whether the value is truthy. Existing properties with values such as false, 0, "", null, or undefined will not pass the check.

Does Object.hasOwn() work when the value is undefined?

Yes.

Object.hasOwn({ value: undefined }, "value"); // true

What is the difference between Object.hasOwn() and in?

Object.hasOwn() checks direct properties only. The in operator also returns true for properties inherited from an object's prototype.

Should I use obj.hasOwnProperty("key")?

Usually no. It can fail if the object has its own property named hasOwnProperty or does not inherit that method. Prefer Object.hasOwn(obj, "key").

When should I use obj.key == null?

Use it when you intentionally want to treat both null and undefined as “no usable value.” It is not a reliable test for whether a key exists.

Can I check a key stored in a variable?

Yes, use bracket-style arguments:

const key = "status";
Object.hasOwn(response, key);
Take Quiz

Mini Project

Description

Build a small profile-update validator. It demonstrates why an existence check is necessary when an update can intentionally set values to false, 0, or an empty string.

Goal

Accept only allowed profile keys and apply every provided update, including falsy values.

Requirements

  • Create a profile object with default values.
  • Accept an update object containing zero or more fields.
  • Allow only displayName, age, and newsletter fields.
  • Apply a field when it exists in the update object, even if its value is falsy.
  • Ignore keys that are not allowed.
Take Quiz

Keep learning

Related questions

View more