在Javascript中从对象中删除空白属性

515

如何在JavaScript对象中删除所有值为undefinednull的属性?

(该问题类似于此问题针对数组的解决方案)


27
强烈建议大家忽略排名靠前的版本,转而使用ES6/ES7版本,链接在这里:https://dev59.com/JnVC5IYBdhLWcg3wdw65#38340730 - Evan Carroll
5
ES6中不改变对象的一行代码也在这里:https://dev59.com/JnVC5IYBdhLWcg3wdw65#57625661 - chickens
ES6 -> JSON.parse(JSON.stringify(obj)) 的意思是将一个对象进行深拷贝。 - STEEL
2
小心!这两个都不能用于数组。 - Martin D
请查看链接,您不仅可以清除null或undefined,甚至可以定义自定义值以删除。 https://dev59.com/JnVC5IYBdhLWcg3wdw65#71968391 - ABHIJEET KHIRE
显示剩余3条评论
55个回答

4
一个reduce辅助函数可以解决这个问题(不需要类型检查)-
const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

4
为了跟随Ben的答案并使用lodash的_.pickBy解决这个问题,你也可以在姊妹库Underscore.js_.pick中解决这个问题。
var obj = {name: 'John', age: null};

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

查看:JSFiddle示例


1
这会返回一个空数组,而且你把 obj 的名字改成了 object。 - Stephen DuMont
谢谢Stephen!现在怎么样?我已经更新了我的答案,包括一个JSFiddle链接。 - Alex Johnson
尝试使用 _.omit(obj, _.isEmpty); 这更具概念纯粹性,将包括空字符串。 - Stephen DuMont

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;
}

这将保留布尔值并且会清空数组。同时,它通过返回一个清理过的副本来保留原始对象。

3
您可以使用类似以下代码的forEach...扩展语法来实现:

let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};

Object.keys(obj).forEach(val => {
  const newVal = obj[val];
  cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});

console.info(cleanObj);


3

使用 Lodash:

_.omitBy({a: 1, b: null}, (v) => !v)

这将同时删除0或空字符串'',更好的做法是: _.omitBy({a: 1, b: null, c: undefined, d: 0, e: ''}, (v) => typeof v !== undefined && typeof v !== 'null') - bukso

3

递归删除null、undefined、空对象和空数组,返回副本(ES6版本)


export function skipEmpties(dirty) {
    let item;
    if (Array.isArray(dirty)) {
        item = dirty.map(x => skipEmpties(x)).filter(value => value !== undefined);
        return item.length ? item : undefined;
    } else if (dirty && typeof dirty === 'object') {
        item = {};
        Object.keys(dirty).forEach(key => {
            const value = skipEmpties(dirty[key]);
            if (value !== undefined) {
                item[key] = value;
            }
        });
        return Object.keys(item).length ? item : undefined;
    } else {
        return dirty === null ? undefined : dirty;
    }
}

3

如果您不想在原地进行更改,而是返回一个已删除null/undefined的克隆副本,则可以使用ES6 reduce函数。

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

2

这里是在不改变对象且只使用ES6中的reduce函数来从对象中移除nulls的一种可行方法:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

“巨魔评论” 关于这个函数式模式有两件事情:在 stripNulls 函数中,它使用了累加器函数作用域之外的引用;并且它还通过在累加器函数内部进行过滤来混淆关注点。(例如 Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});是的,它会对过滤后的项进行两次循环,但实际的性能损失可以忽略不计。 - Jason Cust

2
如果您使用eslint并且希望避免触发no-param-reassign规则,可以使用Object.assign与.reduce和计算属性名称结合使用,以获得相当优雅的ES6解决方案:
const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

2
如果有人需要使用lodash进行深度搜索并从对象中删除undefined值,则以下是我使用的代码。很容易将其修改为删除所有空值(null/undefined)。请保留HTML标签。
function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接