我有一个Javascript对象像:

var my_object = { a:undefined, b:2, c:4, d:undefined };

如何删除所有未定义的属性?False属性应该保留。


当前回答

我能够在深层对象中做到这一点,其中包括数组,只有一个lodash函数,transform。

注意,双重不相等(!= null)是有意的,因为它也将匹配undefined, typeof 'object'检查也是如此,因为它将匹配object和array。

这只用于不包含类的普通数据对象。

const cloneDeepSanitized = (obj) =>
  Array.isArray(obj)
    ? obj.filter((entry) => entry != null).map(cloneDeepSanitized)
    : transform(
        obj,
        (result, val, key) => {
          if (val != null) {
            result[key] =
              typeof val === 'object' ? cloneDeepSanitized(val) : val;
          }
        },
        {},
      );

其他回答

你可以使用lodash来删除null和未定义的对象,但你应该知道你需要使用什么lodash方法,许多开发人员使用isNil来删除null和未定义的对象,但这个函数不删除空对象(' ')

你可以使用isEmpty来删除Null, Undefined和

import pickBy from 'lodash/fp/pickBy'
import negate from 'lodash/negate';
import isEmpty from 'lodash/isEmpty';

const omitNullish = pickBy(negate(isEmpty));

      addressObject = {
      "a": null,
      "c": undefined,
      "d": "",
      "e": "test1",
      "f": "test2
    }

 const notNullObjects = omitNullish(addressObject);
 
 console.log(notNullObjects); 

你将拥有这个对象:{ “e”:“test1”, “f”:“test2 }

如果你想移除所有假值,那么最紧凑的方法是:

对于Lodash 4。X及以后:

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

对于遗留的Lodash 3.x:

_.pick(obj, _.identity);

_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

你可以简单地用_连接_.省略()。isUndefined和_。isNull组合,并获得懒惰求值的结果。

Demo

var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();

2016年3月14日更新:

正如dylants在评论部分中提到的,您应该使用_.omitBy()函数,因为它使用谓词而不是属性。对于lodash 4.0.0及以上版本,您应该使用此选项。

DEMO

var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();

2016年6月1日更新:

正如Max Truxa所评论的,lodash已经提供了一个替代的_。isNil,检查null和undefined:

var result = _.omitBy(my_object, _.isNil);

使用纯JavaScript:(尽管Object。entries是ES7, Object。assign是ES6;但是等效的ES5使用Object。键也应该是可行的);还要注意v != null检查null和undefined;

> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: 0.3, s: "", t: false };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => Object.assign(acc, {[k]: v}), {})
{ b: 2, c: 0, f: 0.3, s: '', t: false }

编辑:下面是ES5对象的版本。但一般来说,在Node v8中使用ES7是非常令人愉快的;-)

> Object.keys(d)
    .filter(function(k) { return d[k] != null; })
    .reduce(function(acc, k) { acc[k] = d[k]; return acc; }, {});
{ b: 2, c: 0, f: 0.3, s: '', t: false }

2017年10月更新:在v8节点(从v8.3左右开始)现在它有对象扩展结构:

> var d = { a:undefined, b:2, c:0, d:undefined,
    e: null, f: -0.0, s: "", t: false, inf: +Infinity, nan: NaN };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => ({...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

或只在一个减法之内:

> Object.entries(d)
   .reduce((acc, [k, v]) => (v==null ? acc : {...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

更新:有人要递归吗?也不是很难,只需要额外检查isObject,并递归调用自己:

> function isObject(o) {
    return Object.prototype.toString.call(o) === "[object Object]"; }
undefined
> function dropNullUndefined(d) {
    return Object.entries(d)
      .reduce((acc, [k, v]) => (
        v == null ? acc :
         {...acc, [k]: (isObject(v) ? dropNullUndefined(v) : v) }
      ), {});
  }
> dropNullUndefined({a: 3, b:null})
{ a: 3 }
> dropNullUndefined({a: 3, b:null, c: { d: 0, e: undefined }})
{ a: 3, c: { d: 0 } }

我的结论:如果纯Javascript可以做到,我会避免任何第三方库依赖:

默认情况下,pickBy使用identity:

_.pickBy({ a: null, b: 1, c: undefined, d: false });