const obj = { name: 'John', age: 30, [Symbol('id')]: 123 };
1. `in` Operator
console.log('name' in obj);
console.log('gender' in obj);
Pros:
- Easy to use.
- Can check for inherited properties (properties from the prototype chain).
Cons:
- Includes inherited properties, not just own properties.
2. `hasOwnProperty()`
console.log(obj.hasOwnProperty('name'));
console.log(obj.hasOwnProperty('gender'));
Pros:
- Checks only own properties of the object, not inherited ones.
Cons:
- If the object has a property that overrides this method, the result might be unexpected.
3. `Object.prototype.hasOwnProperty.call()`
console.log(Object.prototype.hasOwnProperty.call(obj, 'name'));
console.log(Object.prototype.hasOwnProperty.call(obj, 'gender'));
Pros:
- Avoids issues if the object has a property that overrides `hasOwnProperty`.
Cons:
- More verbose compared to using `hasOwnProperty` directly.
4. Direct Property Access
console.log(obj.name !== undefined);
console.log(obj.gender !== undefined);
Pros:
- Very simple and easy to understand.
Cons:
- Cannot distinguish between properties that don't exist and properties that exist but have the value `undefined`.
5. `Object.keys()`
console.log(Object.keys(obj).includes('name'));
console.log(Object.keys(obj).includes('gender'));
Pros:
- Returns an array of the object's own property names.
Cons:
- Inefficient for large objects because it creates an array of all keys.
6. `Object.hasOwn()`
console.log(Object.hasOwn(obj, 'name'));
console.log(Object.hasOwn(obj, 'gender'));
Pros:
- Modern alternative to `hasOwnProperty`, more readable and writable.
Cons:
- Not supported in older environments (introduced in ECMAScript 2022).
7. `Object.prototype.propertyIsEnumerable()`
console.log(obj.propertyIsEnumerable('name'));
console.log(obj.propertyIsEnumerable('toString'));
console.log(obj.propertyIsEnumerable('gender'));
Pros:
- Checks if a property is an own property and is enumerable (iterable).
Cons:
- Not very commonly used, so it might be less familiar.
8. Using `Map`
const map = new Map();
map.set('name', 'John');
console.log(map.has('name'));
console.log(map.has('age'));
Pros:
- Ideal for dynamic key-value collections.
Cons:
- Not suitable for simple objects or structured data like JSON.
9. Using `WeakMap`
const weakObj = {};
const weakMap = new WeakMap();
weakMap.set(weakObj, 'some value');
console.log(weakMap.has(weakObj));
const anotherObj = {};
console.log(weakMap.has(anotherObj));
Pros:
- Useful for memory-efficient key-value pairs where keys are objects.
Cons:
- Keys must be objects, and it's not enumerable or iterable.
10. `Reflect.has()`
console.log(Reflect.has(obj, 'name'));
console.log(Reflect.has(obj, 'gender'));
Pros:
- Similar to the `in` operator but more consistent as part of the Reflect API.
Cons:
- Less commonly used than the `in` operator.
11. Using Try-Catch (for special cases)
const objWithGetter = {
get name() {
throw new Error('Error accessing name');
},
age: 30
};
function hasProperty(obj, key) {
try {
return key in obj;
} catch (e) {
return false;
}
}
console.log(hasProperty(objWithGetter, 'name'));
console.log(hasProperty(objWithGetter, 'age'));
Pros:
- Handles cases where accessing properties might throw errors (e.g., getters).
Cons:
- More complex and typically not needed unless dealing with potential errors.
12. `Object.getOwnPropertyNames()`
console.log(Object.getOwnPropertyNames(obj).includes('name'));
console.log(Object.getOwnPropertyNames(obj).includes('gender'));
Pros:
- Returns an array of all own property names (including non-enumerable properties).
Cons:
- Inefficient for large objects because it creates an array of all property names.
13. `Object.getOwnPropertySymbols()`
const sym = Symbol('id');
const symObj = { [sym]: 'symbolic value' };
console.log(Object.getOwnPropertySymbols(symObj).includes(sym));
const anotherSym = Symbol('another');
console.log(Object.getOwnPropertySymbols(symObj).includes(anotherSym));
Pros:
- Allows checking for symbol-keyed properties.
Cons:
- Not useful for checking regular string-keyed properties.
14. `Object.entries()`
console.log(Object.entries(obj).some(([key]) => key === 'name'));
console.log(Object.entries(obj).some(([key]) => key === 'gender'));
Pros:
- Checks both keys and values, useful for more complex checks.
Cons:
- Inefficient for large objects because it creates an array of all entries.
15. `Object.fromEntries()`
const objArray = [['name', 'John'], ['age', 30]];
const newObj = Object.fromEntries(objArray);
console.log('name' in newObj);
console.log('gender' in newObj);
Pros:
- Useful for creating objects from key-value pairs.
Cons:
- Requires array input, not a direct check.