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

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


当前回答

我们可以使用JSON。stringify和JSON。解析以从对象中删除空白属性。

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });

其他回答

ES10 - ES2019和

一个简单的一行程序(返回一个新对象)。

let o = Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));

和上面一样,只是写成函数形式。

function removeEmpty(obj) {
  return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
}

此函数使用递归从嵌套对象中删除项。

function removeEmpty(obj) {
  return Object.fromEntries(
    Object.entries(obj)
      .filter(([_, v]) => v != null)
      .map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v])
  );
}

ES6 / ES2015和

简单的一行代码。警告:这将改变给定的对象,而不是返回一个新的对象。

Object.keys(obj).forEach((k) => obj[k] == null && delete obj[k]);

单个声明(不改变给定对象)。

let o = Object.keys(obj)
  .filter((k) => obj[k] != null)
  .reduce((a, k) => ({ ...a, [k]: obj[k] }), {});

和上面一样,只是写成函数形式。

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
}

此函数使用递归从嵌套对象中删除项。

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce(
      (acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeEmpty(v) : v }),
      {}
    );
}

与上面的函数相同,但以命令式(非函数式)风格编写。

function removeEmpty(obj) {
  const newObj = {};
  Object.entries(obj).forEach(([k, v]) => {
    if (v === Object(v)) {
      newObj[k] = removeEmpty(v);
    } else if (v != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

ES5 / ES2009例子

在过去,事情要啰嗦得多。

这是一个以函数式风格编写的非递归版本。

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = obj[k];
      return acc;
    }, {});
}

这是一个以命令式风格编写的非递归版本。

function removeEmpty(obj) {
  const newObj = {};
  Object.keys(obj).forEach(function (k) {
    if (obj[k] && typeof obj[k] === "object") {
      newObj[k] = removeEmpty(obj[k]);
    } else if (obj[k] != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

还有一个函数式的递归版本。

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = typeof obj[k] === "object" ? removeEmpty(obj[k]) : obj[k];
      return acc;
    }, {});
}

reduce helper可以做到这一点(不需要类型检查)-

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

这可以使用递归来解决。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;
}

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

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

您可以使用json在一行中进行递归删除。Stringify的replacer参数

const removeEmptyValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)

用法:

removeEmptyValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

正如Emmanuel的评论中提到的,只有当数据结构只包含可以放入JSON格式的数据类型(字符串、数字、列表等)时,这种技术才有效。

(此答案已更新为使用新的Nullish Coalescing运算符。根据浏览器的支持需要,你可能想要使用这个函数代替:(k,v) => v!=零?V:未定义)