我有以下对象:
const action = {id: 100, name: 'Andres', age: 27, type: 'CREATE_USER'}
我想将一些属性复制到另一个对象中。在最新版本的Chrome中,我可以这样做:
const newUser = {id, name, age} = action;
newUser
对象包含:
{id: 100, name: 'Andres', age: 27}
这在浏览器中运行良好。但是,使用我编译的JS代码它并不起作用。我明白了:
error ReferenceError: id is not defined
如果我删除id
,我会使用不同的密钥获得相同的消息,依此类推。
我的设置:
"webpack": "2.1.0-beta.21"
"webpack-dev-server": "2.1.0-beta.0"
对于巴别塔:
"babel-core": "6.x",
"babel-eslint": "6.x",
"babel-loader": "6.x",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "6.x",
"babel-polyfill": "^6.8.0",
"babel-preset-es2015": "6.x",
"babel-preset-es2015-native-modules": "^6.6.0",
"babel-preset-react": "6.x",
"babel-preset-stage-0": "6.x",
Babel或Webpack是否缺少我想要的东西来完成我想要的东西?
答案 0 :(得分:6)
这里的问题是你一次尝试声明并分配给变量,而在严格模式语义下这是不允许的,这是由Babel强制执行的。因此,您的代码段比您预期的更多:
const newUser = {id, name, age} = action;
作为evaluating the destructuring expression的一部分,将对id
,name
,age
,不存在的引用执行分配,这些引用应该引发ReferenceError
根据{{3}}的异常。更具体地说,底部有一个说明:
当在严格模式代码中发生赋值时,如果在第一个算法的步骤1.f中的 lref 或第二个算法的步骤7中它是一个运行时错误,则它是一个不可解析的引用。如果是,则抛出 ReferenceError 异常。
您可以尝试在控制台中运行此代码段来证明:
// Will work
(function () {
a = 5;
})();
// Won't work
(function () {
'use strict';
b = 5;
})()

为了让Babel以我认为你想要的方式工作,你必须放弃ES2015预设并手动包含所有插件,选择退出the specification。简而言之,您将自己打开一罐PITA。
正确的做法是声明您要绑定到的属性的所有变量:
'use strict';
let a, b, c;
({fee: a, fii: b, foo: c} = {fee: 1, fii: 2, foo: 3});
console.log(a, b, c);

不幸的是,这仍然无法满足您的需求。解构表达式的结果是一个赋值表达式,其中返回的值将是赋值(析构)的值,因此您的newUser
实际上不会像预期的那样成为新对象:
const action = {id: 100, name: 'Andres', age: 27, type: 'CREATE_USER'}
const newUser = {id, name, age} = action;
console.log(newUser === action);

这使我们得到以下解决方案。它可能不那么简洁,但它清楚地概述了正在进行的工作:
const action = {id: 100, name: 'Andres', age: 27, type: 'CREATE_USER'}
const {id, name, age} = action;
const newUser = {id, name, age};

答案 1 :(得分:1)
const action = {id: 100, name: 'Andres', age: 27, type: 'CREATE_USER'}
const newUser = {id, name, age} = action;
newUser对象包含:
{id: 100, name: 'Andres', age: 27}
不,它没有。它仍包含type
属性。原因是第二个语句被解析为:
const newUser = ({id, name, age} = action);
换句话说,newUser
被分配给评估作业声明的结果 ({id, name, age}) = action
。赋值语句的计算结果为其右侧。在这种情况下,它因此评估为action
。总的来说,您的赋值语句完全等同于以下两个赋值:
({id, name, age} = action);
const newUser = action;
这几乎肯定不是你想要的。 id
等将被隐式声明为全局变量,或者更可能导致ReferenceError
。 newUser
将与action
相同。
您要做的是解构为另一个对象,而不是变量。 ES6中没有这样的功能。已经有一些讨论和建议,例如“选择”功能,但TC39上的权力似乎是决定性的不感兴趣。暂时,写下
const {id, name, age} = action;
const newUser = {id, name, age};
如果您可以访问传播属性功能,并且知道除了 type
之外的所有,那么您可以写:
const {type, ...newUser} = actions;
但这对于“挑选”来说并不是一个很好的通用解决方案。