除了一个键外,如何克隆JavaScript对象?
我有一个平面JS对象:除了一个键外,如何克隆JavaScript对象?,javascript,ecmascript-6,ecmascript-harmony,ecmascript-2016,Javascript,Ecmascript 6,Ecmascript Harmony,Ecmascript 2016,我有一个平面JS对象: {a: 1, b: 2, c: 3, ..., z:26} 我要克隆除一个元素之外的对象: {a: 1, c: 3, ..., z:26} 最简单的方法是什么(如果可能,更喜欢使用es6/7)?可能是这样的: var copy = Object.assign({}, {a: 1, b: 2, c: 3}) delete copy.c; 这够好吗?或者c不能被复制 var clone = Object.assign({}, {a: 1, b: 2, c: 3}); d
{a: 1, b: 2, c: 3, ..., z:26}
我要克隆除一个元素之外的对象:
{a: 1, c: 3, ..., z:26}
最简单的方法是什么(如果可能,更喜欢使用es6/7)?可能是这样的:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
这够好吗?或者c
不能被复制
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
或者,如果您接受未定义的属性:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
您可以为它编写一个简单的助手函数。Lodash具有相同名称的类似功能: 另外,请注意,它比Object.assign和delete then快:如果使用,则可以使用以下语法将属性b从x复制到变量b,然后将其余属性复制到变量y中: 并分为:
要补充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};
资料来源:
lodash
或下划线
_.omit(x, 'b')
或ramda
R.omit('b', x)
如果您处理的是一个巨大的变量,您不希望复制它然后删除它,因为这样做效率很低 带有hasOwnProperty检查的简单for循环应该可以工作,并且它更适合未来的需要:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
洛达斯
当您尝试复制对象然后删除属性时,似乎遇到了引用问题。在某些地方,您必须分配基本变量,以便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"}
您也可以使用spread运算符来执行此操作
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
下一个班轮我用这个
constobj={a:1,b:2,c:3,d:4}
const clone=({b,c,…o})=>o(obj)//删除b和c
console.log(clone)
我最近用了一种非常简单的方法:
const obj = {a: 1, b: 2, ..., z:26};
只需使用spread运算符来分离不需要的属性:
const {b, ...rest} = obj;
…和object.assign仅获取“剩余”部分:
const newObj = Object.assign({}, {...rest});
这个怎么样?
我从未发现这种模式,但我只是试图排除一个或多个属性,而不需要创建额外的对象。这似乎起到了作用,但有些副作用我看不出来。当然,它的可读性不是很强
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
使用对象分解
const-omit=(prop,{[prop]:,…rest})=>rest;
常量obj={a:1,b:2,c:3};
const objwithout a=省略('a',obj);
console.log(objWithoutA);//{b:2,c:3}
我是这样完成的,作为我的Redux reducer的一个例子:
const clone={…state};
删除克隆[action.id];
返回克隆;
换言之:
const clone={…originalObject}//注意:原始对象未更改
删除clone[unwantedKey]//或使用clone.unwantedKey或任何其他适用语法
返回克隆//没有不需要的键的原始对象
上述使用结构化的解决方案确实存在一个问题,即您使用了一个变量,如果您使用该变量,可能会引起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'))
这里有一个我认为还没有提到的省略动态键的选项:
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}
。请注意,删除的键不存在,该值不只是设置为未定义
如何:
let clone = Object.assign({}, value);
delete clone.unwantedKey;
我有一个
对象
,我想在使用它的方法后删除它。这就是我的工作
/*样本数据*/
让项目=[
{
姓名:'约翰',
文件:{
set:async(item)=>{/*…设置远程服务器上的文档*/}
}
},{
姓名:'玛丽',
文件:{
set:async(item)=>{/*…设置远程服务器上的文档*/}
}
},{
名字:“杰克”,
文件:{
set:async(item)=>{/*…设置远程服务器上的文档*/}
}
}
]
/*映射到承诺*/
const promises=items.map(({doc,…item})=>doc.set(item));
//已使用的单据和已使用的“剩余”项目:)
祝你好运:)这是我的两分钱,在打字稿上,从@Paul的答案中略作衍生,使用reduce代替 我有一个对象名为:带有一些键的选项
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,您可以放置要排除的属性的值我不知道您到底想用它做什么,所以我不确定这是否适用于您,但我只是做了以下操作,它适用于我的用例:
const newObj={…obj[key]:未定义}
如果使用,则可以使用其和函数对对象进行深度克隆,并省略不必要的字段
var object = {a: 1, b: 2, c: 3, y:25, z:26};
R.clone(R.omit(["z", "y"], object));
使用loadash deepclone功能,您可以执行以下操作:
const _obj = _.cloneDeep(obj);
delete _obj.key;
首先将整个对象克隆到新对象中,然后从克隆的对象中删除所需的键,这样原始对象就不会受到影响。如果使用typescript,delete关键字解决方案将抛出编译错误,因为它破坏了实例化对象的约定。ES6 spread运算符解决方案(
const{x,…keys}=object
)可能会抛出错误,具体取决于您在项目中使用的linting配置,因为未使用x
变量。所以我提出了这个解决方案:
const cloneObject = Object.entries(originalObject)
.filter(entry => entry[0] !== 'keyToRemove')
.reduce((acc, keyValueTuple) => ({ ...acc, [keyValueTuple[0]]: keyValueTuple[1] }), {});
它使用方法(获取原始对象的键/值对数组)与数组方法和的组合来解决该问题。它看起来很冗长,但我认为拥有一行可链接的解决方案是很好的。如果你为未使用的变量筛选代码,这将导致“未使用的变量'b.”警告。如果你有
let x=[{a:1,b:2,c:3,z:26},{a:5,b:6,c:7,z:455}],语法会是什么样子
@RossAllen在v3.15.0中添加了一个选项(2017年2月3日)
function objectWithoutKey(object: object, keys: string[]) {
return keys.reduce((previousValue, currentValue) => {
// @ts-ignore
const {[currentValue]: undefined, ...clean} = previousValue;
return clean
}, object)
}
// usage
console.log(objectWithoutKey({a: 1, b: 2, c: 3}, ['a', 'b']))
let options = {
userDn: 'somePropertyValue',
username: 'someValue',
userSearchBase: 'someValue',
usernameAttribute: 'uid',
userPassword: 'someValue'
}
console.log(Object.keys(options).map(x => x + ': ' + (x === "userPassword" ? '---' : options[x])));
var object = {a: 1, b: 2, c: 3, y:25, z:26};
R.clone(R.omit(["z", "y"], object));
const _obj = _.cloneDeep(obj);
delete _obj.key;
const cloneObject = Object.entries(originalObject)
.filter(entry => entry[0] !== 'keyToRemove')
.reduce((acc, keyValueTuple) => ({ ...acc, [keyValueTuple[0]]: keyValueTuple[1] }), {});