如何删除JavaScript对象中未定义或空的所有属性?

(这个问题与数组的问题类似)


当前回答

我在我的项目中有同样的场景,并使用以下方法实现。

它适用于所有数据类型,上面提到的一些数据类型不适用于日期和空数组。

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) { Object.keys(obj).forEach(key => { if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) { delete obj[key]; } else if (obj[key] && typeof obj[key] === 'object') { this.removeEmptyKeysFromObject(obj[key]); } else if (obj[key] == null || obj[key] === '') { delete obj[key]; } if (obj[key] && typeof obj[key] === 'object' && Object.keys(obj[key]).length === 0 && Object.prototype.toString.call(obj[key]) !== '[object Date]') { delete obj[key]; } }); return obj; }

将任何对象传递给该函数

其他回答

这可以使用递归来解决。JavaScript对象可以是一个数组,也可以有一个包含空值的数组作为值。

function removeNullValues(obj) {
  // Check weather obj is an array
  if (Array.isArray(obj)) {
    // Creating copy of obj so that index is maintained after splice
    obj.slice(0).forEach((val) => {
      if (val === null) {
        obj.splice(obj.indexOf(val), 1);
      } else if (typeof val === 'object') {
        // Check if array has an object
        removeNullValues(val);
      }
    });
  } else if (typeof obj === 'object') {
    // Check for object
    Object.keys(obj).forEach((key) => {
      if (obj[key] === null) {
        delete obj[key];
      } else if (typeof obj[key] === 'object') {
        removeNullValues(obj[key]);
      }
    });
  }
  return obj;
}

为了进行深度搜索,我使用了下面的代码,也许它对任何研究这个问题的人都有用(它不适用于循环依赖关系):

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

您可能正在寻找delete关键字。

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;

如果你想要4行纯ES7解决方案:

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

或者如果你喜欢更易读的版本:

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

这将保留布尔值,也将清理数组。它还通过返回一个清理过的副本来保存原始对象。

这是一个递归的ES6实现,它也可以清理属性的属性。它是一个副作用自由函数,意味着它不修改对象,因此必须使用返回对象。

function removeUndefinedProperties(obj) {
  return Object.keys(obj || {})
    .reduce((acc, key) => {
      const value = obj[key];
      switch (typeof value) {
        case 'object': {
          const cleanValue = removeUndefinedProperties(value); // recurse
          if (!Object.keys(cleanValue).length) {
            return { ...acc };
          }
          return { ...acc, [key]: cleanValue };
        }
        case 'undefined':
          return { ...acc };
        default:
          return { ...acc, [key]: value };
      }
    }, {});
}

在TypeScript中,使用unknown输入它,例如:

function removeUndefinedProperties(obj: unknown): unknown {
  return Object.keys(obj ?? {})
    .reduce((acc, key) => {
      const value = obj[key];
      switch (typeof value) {
        case 'object': {
          const cleanValue = removeUndefinedProperties(value); // recurse
          if (!Object.keys(cleanValue).length) {
            return { ...acc };
          }
          return { ...acc, [key]: cleanValue };
        }
        case 'undefined':
          return { ...acc };
        default:
          return { ...acc, [key]: value };
      }
    }, {});
}