是否有可能解构到一个现有的对象上? (Javascript ES6)

例如,如果我有两个对象:

var foo = {
x: "bar",
y: "baz"
}

还有

var oof = {}

我想把 x 和 y 值从 foo 传递到 oof。有没有使用 es6解构语法实现这一点的方法?

比如:

oof{x,y} = foo
86063 次浏览

不,解构不支持以简写形式显示的成员表达式,当前只支持普通属性名。有 一直在谈判关于这样的讨论,但没有建议将进入 ES6。

然而,你也许可以使用 Object.assign-如果你不需要所有自己的属性,你仍然可以这样做

var foo = …,
oof = {};
{
let {x, y} = foo;
Object.assign(oof, {x, y})
}

这个工作在 chrome 53.0.2785.89中

    let foo = {
x: "bar",
y: "baz"
};
    

let oof = {x, y} = foo;
    

console.log(`oof: ${JSON.stringify(oof)}`);
    

//prints oof: { "x": "bar", "y": "baz"}

除了 Object.assign之外,还有 对象扩展语法对象扩展语法,它是 ECMAScript 的第二阶段提案。

    var foo = {
x: "bar",
y: "baz"
}
    

var oof = { z: "z" }
    

oof =  {...oof, ...foo }
    

console.log(oof)


/* result
{
"x": "bar",
"y": "baz",
"z": "z"
}
*/

但是要使用这个功能,你需要使用 stage-2transform-object-rest-spread插件的巴贝尔

虽然丑陋和有点重复,你可以做

({x: oof.x, y: oof.y} = foo);

它将读取 foo对象的两个值,并将它们写入 oof对象上各自的位置。

我个人还是更喜欢读书

oof.x = foo.x;
oof.y = foo.y;

或者

['x', 'y'].forEach(prop => oof[prop] = foo[prop]);

不过。

我想出了这个方法:

exports.pick = function pick(src, props, dest={}) {
return Object.keys(props).reduce((d,p) => {
if(typeof props[p] === 'string') {
d[props[p]] = src[p];
} else if(props[p]) {
d[p] = src[p];
}
return d;
},dest);
};

你可以这样使用:

let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'});
let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});

也就是说,您可以选择您想要输出的属性并将它们放入一个新对象中。与 _.pick不同,您还可以同时重命名它们。

如果您想要将道具复制到一个现有的对象上,只需设置 dest参数。

这是一种欺骗,但你可以做这样的事情..。

const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};


const partialObject = (({ hello, your }) => {
return { hello, your };
})(originalObject);


console.log(partialObject); // ​​​​​{ hello: 'nurse', your: 'mom' }​​​​​

实际上,我认为你很少会想要使用它。下面的内容更加清晰,但是没有那么有趣。

const partialObject = {
hello: originalObject.hello,
your: originalObject.your,
};

另一条完全不同的路线,包括捣鼓原型(现在要小心了... ...) :

if (!Object.prototype.pluck) {
Object.prototype.pluck = function(...props) {
return props.reduce((destObj, prop) => {
destObj[prop] = this[prop];


return destObj;
}, {});
}
}


const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};


const partialObject2 = originalObject.pluck('hello', 'your');


console.log(partialObject2); // { hello: 'nurse', your: 'mom' }

您可以在箭头函数中返回非结构化对象,并使用 Object.sign ()将其分配给变量。

const foo = {
x: "bar",
y: "baz"
}


const oof = Object.assign({}, () => ({ x, y } = foo));

我的天,这是最简单的方法来完成你所寻找的:

let { prop1, prop2, prop3 } = someObject;
let data = { prop1, prop2, prop3 };


// data === { prop1: someObject.prop1, ... }

基本上,将结构解构为变量,然后使用初始化器的简写来创建一个新对象

不管怎样,我认为这是最可读的方法。你可以从 someObject中精确选择你想要的道具。如果你有一个现有的对象,你只是想合并道具,这样做:

let { prop1, prop2, prop3 } = someObject;
let data = Object.assign(otherObject, { prop1, prop2, prop3 });
// Makes a new copy, or...
Object.assign(otherObject, { prop1, prop2, prop3 });
// Merges into otherObject

另一种可以说更简洁的写法是:

let { prop1, prop2, prop3 } = someObject;
let newObject = { prop1, prop2, prop3 };


// Merges your selected props into otherObject
Object.assign(otherObject, newObject);

我经常用它来处理 POST请求,因为我只需要一些离散的数据。但是,我同意应该有一个这样做的一行。

编辑: 附言 我最近了解到,您可以在第一步中使用超重构来从复杂对象中提取嵌套值!比如说..。

let { prop1,
prop2: { somethingDeeper },
prop3: {
nested1: {
nested2
}
} = someObject;
let data = { prop1, somethingDeeper, nested2 };

另外,在创建新对象时,您可以使用传播操作符而不是 Object.sign:

const { prop1, prop2, prop3 } = someObject;
let finalObject = {...otherObject, prop1, prop2, prop3 };

或者..。

const { prop1, prop2, prop3 } = someObject;
const intermediateObject = { prop1, prop2, prop3 };
const finalObject = {...otherObject, ...intermediateObject };

你可以像这样使用重组:

const foo = {x:"a", y:"b"};
const {...oof} = foo; // {x:"a", y:"b"}

如果 oof 具有值,则合并两个对象:

const foo = {x:"a", y:"b"};
let oof = {z:"c"}
oof = Object.assign({}, oof, foo)

这是我能想到的最简洁易读的解决方案:

let props = {
isValidDate: 'yes',
badProp: 'no!',
};


let { isValidDate } = props;
let newProps = { isValidDate };


console.log(newProps);

它将输出 { isValidDate: 'yes' }

如果有一天能够说像 let newProps = ({ isValidDate } = props)这样的东西就好了,但不幸的是它不是 ES6支持的东西。

BabelJS 插件

如果你正在使用 翻译: 奇芳,你现在可以激活我的插件 babel-plugin-transform-object-from-destructuring(安装和使用见 npm 软件包)。

我在这个线程中描述过同样的问题,对我来说,从解构表达式创建一个对象是非常累人的,特别是当您必须重命名、添加或删除一个属性时。有了这个插件,维护这样的场景变得更加容易。

对象示例

let myObject = {
test1: "stringTest1",
test2: "stringTest2",
test3: "stringTest3"
};
let { test1, test3 } = myObject,
myTest = { test1, test3 };

可以这样写:

let myTest = { test1, test3 } = myObject;

数组示例

let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
myTest = [ test1, test3 ];

可以这样写:

let myTest = [ test1, , test3 ] = myArray;

完全有可能,只是不是一句话。

var foo = {
x: "bar",
y: "baz"
};
var oof = {};
({x: oof.x, y: oof.y} = foo); // {x: "bar", y: "baz"}

(请注意语句前后的括号。) 但请记住,清晰度比代码高尔夫球更重要:)。

资料来源: http://exploringjs.com/es6/ch_destructuring.html#sec_assignment-targets

    var a = {a1:1, a2: 2, a3: 3};
var b = {b1:1, b2: 2, b3: 3};
    

const newVar = (() => ({a1, a2, b1, b2})).bind({...a, ...b});
const val = newVar();
console.log({...val});
// print: Object { a1: 1, a2: 2, b1: 1, b2: 2 }

或者

    console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});

这不是一个美丽的方式,也不是我推荐的方式,但它是可能的这种方式,只是为了知识。

   const myObject = {
name: 'foo',
surname: 'bar',
year: 2018
};


const newObject = ['name', 'surname'].reduce(
(prev, curr) => (prev[curr] = myObject[curr], prev),
{},
);


console.log(JSON.stringify(newObject)); // {"name":"foo","surname":"bar"}

可以销毁直接分配给另一个对象属性的对象。

实例:

let user = {};
[user.name, user.username] = "Stack Overflow".split(' ');
document.write(`
1st attr: ${user.name} <br />
2nd attr: ${user.username}`);

您可以使用与您想要捕获的对象属性名称相同的变量进行析构,这样您就不需要:

let user = { name: 'Mike' }
let { name: name } = user;

这样使用:

let user = { name: 'Mike' }
let { name } = user;

同样,如果对象结构具有相同的属性名,则可以将新值设置为对象结构。

看看这个实际的例子:

// The object to be destructed
let options = {
title: "Menu",
width: 100,
height: 200
};


// Destructing
let {width: w, height: h, title} = options;


// Feedback
document.write(title + "<br />");  // Menu
document.write(w + "<br />");      // 100
document.write(h);                 // 200

您可以使用 JSON 类方法来实现它,如下所示

const foo = {
x: "bar",
y: "baz"
};


const oof = JSON.parse(JSON.stringify(foo, ['x','y']));
// output -> {x: "bar", y: "baz"}

将需要添加到结果对象中作为第二个参数的属性以数组格式传递给 stringify函数。

MDN Doc for JSON.stringify