Skip to content

前端最佳实践-判断对象是否存在某个属性

判断一个对象中是否存在某个属性,是我们在写代码时常见的场景,接下来会展示该场景的一些常见的错误写法,以及最佳实践。

第一种错误写法

直接判断属性是否有值。

javascript
var obj = {
  a: 1,
  b: undefined
};

function hasProperty(obj, key) {
  return obj[key] !== undefined;
}

console.log(hasProperty(obj, 'b')); // false

这种写法最明显的错误就是对象中恰好存在属性的值为 undefined。

第二种错误写法

通过 Object.keys() 方法获取对象中的属性数组,然后使用 includes 方法判断该属性是否存在。

javascript
var obj = {
  a: undefined
};

function hasProperty(obj, key) {
  return Object.keys(obj).includes(key);
}

console.log(hasProperty(obj, 'a')); // true

这种写法解决了第一种写法的错误,但当给对象添加不可遍历的属性时,这个写法就失效了。

javascript
var obj = {
  a: undefined
};

Object.defineProperty(obj, 'b', {
  enumerable: false,
  value: 2
});

function hasProperty(obj, key) {
  return Object.keys(obj).includes(key);
}

console.log(hasProperty(obj, 'b')); // false

第三种错误写法

使用 javascript 对象中提供的 hasOwnProperty 方法。

javascript
var obj = {
  a: undefined
};
Object.defineProperty(obj, 'b', {
  enumerable: false,
  value: 2
});

function hasProperty(obj, key) {
  return obj.hasOwnProperty(key);
}

console.log(hasProperty(obj, 'b')); // true

这种写法解决了上述两种写法的错误,但它仍旧不是最佳实践,它的错误是 hasOwnProperty 方法只能判断对象本身的属性,没法判断原型链上的属性。

javascript
console.log(hasProperty(obj, 'toString')); // false
console.log(obj.toString); // [Function: toString]

最佳实践

通过 in 关键字实现,既能判断不可遍历的属性,也能通过原型链去查找。

javascript
var obj = {
  a: undefined
};
Object.defineProperty(obj, 'b', {
  enumerable: false,
  value: 2
});

function hasProperty(obj, key) {
  return key in obj;
}

console.log(hasProperty(obj, 'b')); // true
console.log(hasProperty(obj, 'toString')); // true

另一种最佳实践

使用 javascript 的内置对象 Reflect 中的 has 方法,和 in 关键字的功能完全相同。

javascript
var obj = {
  a: undefined
};
Object.defineProperty(obj, 'b', {
  enumerable: false,
  value: 2
});

console.log(Reflect.has(obj, key))); // true
console.log(Reflect.has(obj, 'toString')); // true