170

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

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

var oof = {}

我想将 x 和 y 值从 foo 转移到 oof。有没有办法使用 es6 解构语法来做到这一点?

也许是这样的:

oof{x,y} = foo
4

16 回答 16

162

虽然丑陋且有点重复,但您可以这样做

({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]);

尽管。

于 2016-11-16T05:18:21.963 回答
53

IMO这是完成您正在寻找的最简单的方法:

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

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

基本上,解构为变量,然后使用初始化程序简写来创建一个新对象。不需要Object.assign

无论如何,我认为这是最易读的方式。您可以据此选择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在我只需要几条离散数据的情况下,我经常使用它来处理请求。但是,我同意应该有一个单行来做到这一点。

编辑:PS - 我最近了解到您可以在第一步中使用超解构将嵌套值从复杂对象中提取出来!例如...

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

另外,您可以在创建新对象时使用扩展运算符而不是 Object.assign:

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 };
于 2017-06-23T18:04:00.290 回答
42

不,解构不支持简写形式的成员表达式,但当前仅支持普通属性名。esdiscuss上已经讨论过这样的问题,但没有任何提案会进入 ES6。

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

var foo = …,
    oof = {};
{
    let {x, y} = foo;
    Object.assign(oof, {x, y})
}
于 2015-04-14T07:30:39.450 回答
13

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

    var foo = {
      x: "bar",
      y: "baz"
    }
    
    var oof = { z: "z" }
    
    oof =  {...oof, ...foo }
    
    console.log(oof)

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

但是要使用此功能,您需要使用babelstage-2transform-object-rest-spread插件。这是一个关于 babel 的演示stage-2

于 2016-09-15T14:33:58.337 回答
9

BabelJS 插件

如果您使用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;
于 2018-02-05T07:40:58.483 回答
4

这是完全可能的。只是没有在一个声明中。

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

于 2018-02-17T23:40:14.227 回答
3

您可以像这样使用重组:

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)
于 2017-10-09T09:09:03.753 回答
2

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

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

const oof = Object.assign({}, () => ({ x, y } = foo));
于 2017-04-10T19:25:33.997 回答
2

您可以破坏直接分配给另一个对象属性的对象。

工作示例:

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

于 2019-07-03T13:36:02.510 回答
1

尝试

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

于 2018-07-07T01:56:03.310 回答
0

这是一种作弊,但你可以做这样的事情......

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' }
于 2017-04-05T20:08:41.247 回答
0

我想出了这个方法:

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你也可以同时重命名它们。

如果要将道具复制到现有对象上,只需设置destarg.

于 2017-01-31T19:57:52.167 回答
0

这是我能想到的最易读和最短的解决方案:

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

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

console.log(newProps);

它会输出{ isValidDate: 'yes' }

有朝一日能够说类似的话会很好,let newProps = ({ isValidDate } = props)但不幸的是它不是 ES6 支持的。

于 2017-11-09T17:33:35.370 回答
0

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

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

于 2018-09-07T12:09:45.307 回答
0

这适用于 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"}

于 2016-09-09T22:02:53.433 回答
0

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

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

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

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

JSON.stringify 的 MDN 文档

于 2019-10-29T08:53:12.367 回答