pro-collection / interview-question

目标:收集全网经典面试问题
639 stars 42 forks source link

判断一个对象是否为空,包含了其原型链上是否有自定义数据或者方法。 该如何判定?【热度: 546】 #791

Open yanlele opened 3 months ago

yanlele commented 3 months ago

关键词:原型链相关知识

要判断一个对象是否为空,并且考虑到对象自身及其原型链上是否有自定义数据或方法,您可以使用以下的 JavaScript 函数来实现:

function isObjectEmpty(obj) {
  // 首先获取对象自身的属性
  const ownProperties = Object.getOwnPropertyNames(obj);

  // 遍历自身属性
  for (const property of ownProperties) {
    const descriptor = Object.getOwnPropertyDescriptor(obj, property);
    // 如果属性是数据属性并且有值,或者是方法(可调用函数),则对象不为空
    if (
      (descriptor.value && descriptor.value !== null && descriptor.value !== undefined) ||
      typeof descriptor.value === "function"
    ) {
      return false;
    }
  }

  // 获取对象的原型
  const prototype = Object.getPrototypeOf(obj);

  // 如果有原型并且原型不是 `Object.prototype`(避免误判普通对象的默认方法)
  while (prototype && prototype !== Object.prototype) {
    const prototypeProperties = Object.getOwnPropertyNames(prototype);

    // 遍历原型的属性
    for (const property of prototypeProperties) {
      const descriptor = Object.getOwnPropertyDescriptor(prototype, property);
      // 如果原型上的属性是数据属性并且有值,或者是方法(可调用函数),则对象不为空
      if (
        (descriptor.value && descriptor.value !== null && descriptor.value !== undefined) ||
        typeof descriptor.value === "function"
      ) {
        return false;
      }
    }

    // 继续沿着原型链向上查找
    prototype = Object.getPrototypeOf(prototype);
  }

  // 如果以上检查都没有找到非空属性或方法,则对象为空
  return true;
}

可以使用这个函数来判断对象是否为空,例如:

function MyClass() {}

MyClass.prototype.myMethod = function () {};

const instance = new MyClass();

console.log(isObjectEmpty(instance));
whynyist commented 2 months ago

function isObjectEmpty(obj) { return Reflect.ownKeys(obj).length === 0 }