Object.hasOwn的用法及应用业务场景

440 阅读2分钟

这篇笔记主要记录

  1. Object.hasOwn的用法,为什么推荐用Object.hasOwn
  2. Object.hasOwn使用的业务场景
Object.hasOwn的用法,为什么推荐用Object.hasOwn

Object.prototype.hasOwnProperty, Object.hasOwn, 都是判断一个对象是不是有某个属性; 看下vue3源码,位于packages/shared/src/general.ts

const hasOwnProperty = Object.prototype.hasOwnProperty
export const hasOwn = (
  val: object,
  key: string | symbol,
): key is keyof typeof val => hasOwnProperty.call(val, key)

2个疑问

  1. 为什么不用Object.hasOwnProperty
  2. 为什么不用Object.hasOwn
为什么不用Object.hasOwnProperty

因为Object.hasOwnProperty, 对象可以重新定义hasOwnProperty,如果重新定义了,就会导致检测结果不正确,只要重新定义,就会返回false, 而Object.prototype.hasOwnPrototype,不会被覆盖

const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: "Here be dragons",
};

foo.hasOwnProperty("bar"); // re-implementation always returns false

为什么不用Object.hasOwn

Object.hasOwn不会被覆盖,而且相比Object.hasOwnProperty还有一个特点,用Object.create(null)也可以检测Object.hasOwn(), 是ES2022(ES13)的语法

const foo = Object.create(null);
foo.prop = "exists";
if (Object.hasOwn(foo, "prop")) {
  console.log(foo.prop); // true - works irrespective of how the object is created.
}

// `null` 原型对象(null-prototype objects)不继承自 `Object.prototype`,因此无法访问 `hasOwnProperty()` 方法。
const foo = Object.create(null);
foo.prop = "exists";
foo.hasOwnProperty("prop"); // Uncaught TypeError: foo.hasOwnProperty is not a function

那Vue3的源码为什么不用Object.hasOwn, 要用Object.hasOwnProperty呢?看下兼容性对比

hasOwnProperty兼容性截图, 兼容PC版Chrome1及以后

image.png

hasOwn兼容性截图, 兼容PC版Chrome93以后

image.png

我感觉应该是考虑兼容性问题,所以Vue3没有用Object.hasOwn

Object.hasOwn 应用场景

应用场景1: 假设后端返回对象数组,判断对象数组里是不是, 某一条数据有某个key,来增加逻辑判断。

// Example array of objects
const objectsArray = [
  { id: 1, name: 'Object 1' },
  { id: 2, materials: ['wood', 'metal'] },
  { id: 3, description: 'Some description' },
];

// Check if any object has the key 'materials'
const hasMaterials = objectsArray.some(obj => Object.hasOwn(obj, 'materials'));

console.log(hasMaterials); // Output: true

应用场景2: 不同界面请求同一个接口,有的操作传参需要单独加一个参数,而另外一些操作就不要这个参数, 可以判断, 如果不需要,就删除这个参数,不污染数据

let obj = { a: 10 };

if (true) {
  obj.c = 100; // Add property 'c' if the condition is true
} else {
  // Use Object.hasOwn() to check if 'obj' has the property 'c'
  if (Object.hasOwn(obj, 'c')) {
    delete obj.c; // Delete property 'c' if it exists
  }
}

console.log(obj);