我有一个平面JS对象:

{a: 1, b: 2, c: 3, ..., z:26}

我想克隆对象除了一个元素:

{a: 1, c: 3, ..., z:26}

最简单的方法是什么(如果可能的话,更倾向于使用es6/7)?


当前回答

我有一个对象:带有一些键的选项

  let options = {       
        userDn: 'somePropertyValue',
        username: 'someValue',
        userSearchBase: 'someValue',
        usernameAttribute: 'uid',
        userPassword: 'someValue'
    }

我想记录所有对象excelp userPassword属性,因为我在测试一些东西,我正在使用这段代码:

console.log(Object.keys(options).map(x => x + ': ' + (x === "userPassword" ? '---' : options[x])));

如果你想让它动态,只要做一个函数,而不是显式地放置userPassword,你可以放置你想要排除的属性的值

其他回答

JavaScript中有一个析构赋值语法可以使用

let obj = {a: 1, b: 2, c: 3, z:26};
let {b, ...rest} = obj;

// skips the "Unused variable" warning
let {b: _, ...rest} = obj;

// removes property based on the dynamic key
const dynamicKey = "b";
let {[dynamicKey]: _, ...rest} = obj;

现代浏览器已经开箱即用地支持它。 参见:JavaScript操作符:解构赋值:对象中的Rest

对于旧的浏览器版本,有一个选项可以使用Babel来支持解构赋值。它将被翻译成:

"use strict";

function _objectWithoutProperties(obj, keys) {
  var target = {};
  for (var i in obj) {
    if (keys.indexOf(i) >= 0) continue;
    if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
    target[i] = obj[i];
  }
  return target;
}

var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;

var y = _objectWithoutProperties(x, ["b"]);

你可以使用lodash库来实现这个目的(如果你需要在一个项目中使用大量的数组/对象数组/对象)。

使用lodash deepclone函数你可以做:

const _obj = _.cloneDeep(obj);
delete _obj.key;

首先将整个对象克隆为新的对象,然后从克隆对象中删除所需的键,这样原始的键就不会受到影响。

使用lodash清洁和快速,有了这个解决方案,您可以删除多个键,也不改变原始对象。这在不同的情况下具有更强的可扩展性和可用性:

import * as _ from 'lodash';

function cloneAndRemove(
    removeTheseKeys: string[],
    cloneObject: any,
): object | never {
    const temp = _.cloneDeep(cloneObject);
    removeTheseKeys.forEach((key) => {
        delete temp[key];
    });

    return temp;
}

export { cloneAndRemove };

补充一下Ilya Palkin的回答:你甚至可以动态删除键:

const x = {a: 1, b: 2, c: 3, z:26};

const objectWithoutKey = (object, key) => {
  const {[key]: deletedKey, ...otherKeys} = object;
  return otherKeys;
}

console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};

演示在巴别塔REPL

来源:

https://twitter.com/ydkjs/status/699845396084846592

这个呢? 我从来没有发现这种模式周围,但我只是试图排除一个或多个属性,而不需要创建一个额外的对象。这似乎是做的工作,但有一些副作用,我不能看到。当然不是很好读。

const postData = {
   token: 'secret-token',
   publicKey: 'public is safe',
   somethingElse: true,
};

const a = {
   ...(({token, ...rest} = postData) => (rest))(),
}

/**
a: {
   publicKey: 'public is safe',
   somethingElse: true,
}
*/