Как я могу клонировать объект JavaScript, кроме одного ключа?

У меня есть плоский объект JS:

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

Я хочу клонировать объект, за исключением одного элемента:

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

Какой самый простой способ сделать это (предпочитая использовать es6/7, если это возможно)?

Ответ 1

Если вы используете Babel, вы можете использовать следующий синтаксис для копирования свойства b из x в переменную b, а затем скопировать остальную часть свойств в переменную y:

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

и он будет передан в:

"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"]);

Ответ 2

var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;

или если вы принимаете свойство undefined:

var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});

Ответ 3

Чтобы добавить к Илье Палкину ответ: вы даже можете динамически удалить ключи:

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

Демо в Babel REPL

Источник:

Ответ 4

Для тех, кто не может использовать ES6, вы можете использовать lodash или underscore.

_.omit(x, 'b')

Или ramda.

R.omit('b', x)

Ответ 5

Я использую этот однострочный синтаксис ES6,

const obj = {a: 1, b: 2, c: 3, d: 4};
const clone = (({b, c, ...others}) => ({...others}))(obj); // remove b and c
console.log(clone);

Ответ 6

Вы можете написать для него простую вспомогательную функцию. У Lodash есть аналогичная функция с тем же именем: omit

function omit(obj, omitKey) {
  return Object.keys(obj).reduce((result, key) => {
    if(key !== omitKey) {
       result[key] = obj[key];
    }
    return result;
  }, {});
}

omit({a: 1, b: 2, c: 3}, 'c')  // {a: 1, b: 2}

Также обратите внимание, что это быстрее, чем Object.assign и delete then: http://jsperf.com/omit-key

Ответ 7

Возможно, что-то вроде этого:

var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;

Это достаточно хорошо? Или невозможно c скопировать?

Ответ 8

Использование уничтожения объектов

const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}

Ответ 9

Привет, кажется, вы столкнулись с проблемами, когда пытаетесь скопировать объект и удалить свойство. Где-то вы должны назначить примитивные переменные, чтобы javascript сделал новое значение.

Простой трюк (может быть ужасным), я использовал это

var obj = {"key1":"value1","key2":"value2","key3":"value3"};

// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2

console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}

Ответ 10

Лодаш опустить

let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}

Ответ 11

Если вы имеете дело с огромной переменной, вы не хотите ее копировать, а затем удалять, поскольку это было бы неэффективно.

Простой для цикла с проверкой hasOwnProperty должен работать, и он гораздо более приспособлен к будущим потребностям:

for(var key in someObject) {
        if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
                copyOfObject[key] = someObject[key];
        }
}

Ответ 12

Вы также можете использовать оператор спреда, чтобы сделать это

const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }

Ответ 13

Я недавно сделал это очень простым способом:

const obj = {a: 1, b: 2, ..., z:26};

просто используя оператор распространения, чтобы отделить нежелательное свойство:

const {b, ...rest} = obj;

... и object.assign, чтобы принять только часть отдыха:

const newObj = Object.assign({}, {...rest});

Ответ 14

Как насчет этого? Я никогда не встречал этот шаблон, но я просто пытался исключить одно или несколько свойств без необходимости создания дополнительного объекта. Это, кажется, делает работу, но есть некоторые побочные эффекты, которые я не могу видеть. Наверняка не очень читабельно.

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

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

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

Ответ 15

Решения, описанные выше с использованием структурирования, страдают от того, что у вас есть используемая переменная, которая может вызвать жалобы от ESLint, если вы ее используете.

Итак, вот мои решения:

const src = { a: 1, b: 2 }
const result = Object.keys(src)
  .reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})

На большинстве платформ (кроме IE, если не используется Babel), вы также можете сделать:

const src = { a: 1, b: 2 }
const result = Object.fromEntries(
  Object.entries(src).filter(k => k !== 'b'))

Ответ 16

Я сделал это таким образом, как пример из моего редуктора Redux:

 const clone = { ...state };
 delete clone[action.id];
 return clone;

Другими словами:

const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey]           // or use clone.unwantedKey or any other applicable syntax
return clone                        // the original object without the unwanted key

Ответ 17

Здесь опция для пропуска динамических ключей, которая, я считаю, еще не упоминалась:

const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;

const { [removeMe]: removedKey, ...newObj } = obj;

removeMe называется псевдонимом removedKey и игнорируется. newObj становится { 2: 2, 3: 3, 4: 4 }. Обратите внимание, что удаленный ключ не существует, значение было не просто установлено в undefined.

Ответ 18

Это также должно сделать это, просто удалите этот ключ:

var copy = (obj, del)=>{
    delete obj[del];
    return obj;
}