Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

ecmascript 6 - JavaScript object destructuring and aliasing

Is there a way to destructure an object in JavaScript and alias the local destructured object?

Something like:

const env = {ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z} = process.env;

...and have env become a local constant containing those selected environment variables. (I'm aware that my example doesn't work with babel)

{
  ENV_VAR_X: "s867c7dsj4lal7", 
  ENV_VAR_Y: "hd73m20s-a=snf77f", 
  ENV_VAR_Z: "production"
}

Is there a way to achieve this aliasing?

On a side note, I'm using babel as my transpiler, then running the script with node so that I can leverage more ECMAScript 6 functionality.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

According to my reading of the spec, this should be parseable, but it doesn't mean what you think. It would be parsed from right-to-left as

const env = ({ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z} = process.env);

where the production

({ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z} = process.env)

is defined, like all other assignments, as evaluating to the RHS, which is process.env.

Therefore, your code is equivalent to

const {ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z} = process.env;
const env = process.env;

It's quite easy to validate this:

const foo = {a: 1, b: 2};
const bar = {a} = foo;

results in a new constant a being declared with the value 1, as you would expect. However, the value of bar is not an "alias to the deconstructed object", which would be {a: 1}; it's the same as foo, which is {a: 1, b: 2}. bar === foo.


What you are trying to do has been discussed many times here on SO and also in the ES discuss group. The bottom line is that there is no way to do this. All you can do is:

const {ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z} = process.env;
const env = {ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z};

In other words, there is no way to "deconstruct from an object into an object", or "pick from an object into an object". You can only deconstruct from an object into variables.

You could fall back to the old-fashioned way:

const env = {ENV_VAR_X: process.env.ENV_VAR_X, ...

which I know is horrible.

You could use the pick function from underscore or write your own, but that requires you to say

const env = _.pick(process.env, 'ENV_VAR_X', "ENV_VAR_Y', 'ENV_VAR_Z');

which is only slightly less horrible.

We have "rest properties" and "spread properties" proposed for ES7, but they do not seem to help us here.


What we need is a new syntax for picking properties into another object. There have been various proposals made for this, none of which has gained much traction. One is the "extended dot notation", which allows a curly-bracketed construct to be put after a dot. In your case, you would write

const env = process.env.{ENV_VAR_X, ENV_VAR_Y, ENV_VAR_Z};
                       ^^

You can find out more about this proposal here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...