Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Several demos and usages for ES6 destructuring. Runnable demos and slides about the same topic: http://git.mikaelb.net/presentations/bartjs/destructuring
// === Arrays
var [a, b] = [1, 2];
console.log(a, b);
//=> 1 2
// Use from functions, only select from pattern
var foo = () => [1, 2, 3];
var [a, b] = foo();
console.log(a, b);
// => 1 2
// Omit certain values
var [a, , b] = [1, 2, 3];
console.log(a, b);
// => 1 3
// Combine with spread/rest operator (accumulates the rest of the values)
var [a, ...b] = [1, 2, 3];
console.log(a, b);
// => 1 [ 2, 3 ]
// Fail-safe.
var [, , , a, b] = [1, 2, 3];
console.log(a, b);
// => undefined undefined
// Swap variables easily without temp
var a = 1, b = 2;
[b, a] = [a, b];
console.log(a, b);
// => 2 1
// Advance deep arrays
var [a, [b, [c, d]]] = [1, [2, [[[3, 4], 5], 6]]];
console.log("a:", a, "b:", b, "c:", c, "d:", d);
// => a: 1 b: 2 c: [ [ 3, 4 ], 5 ] d: 6
// === Objects
var {user: x} = {user: 5};
console.log(x);
// => 5
// Fail-safe
var {user: x} = {user2: 5};
console.log(x);
// => undefined
// More values
var {prop: x, prop2: y} = {prop: 5, prop2: 10};
console.log(x, y);
// => 5 10
// Short-hand syntax
var { prop, prop2} = {prop: 5, prop2: 10};
console.log(prop, prop2);
// => 5 10
// Equal to:
var { prop: prop, prop2: prop2} = {prop: 5, prop2: 10};
console.log(prop, prop2);
// => 5 10
// === Potential grammar hiccups
// Oops: This doesn't work:
var a, b;
{ a, b } = {a: 1, b: 2};
// But this does work
var a, b;
({ a, b } = {a: 1, b: 2});
console.log(a, b);
// => 1 2
// This due to the grammar in JS.
// Starting with { implies a block scope, not an object literal.
// () converts to an expression.
// From Harmony Wiki:
// Note that object literals cannot appear in
// statement positions, so a plain object
// destructuring assignment statement
// { x } = y must be parenthesized either
// as ({ x } = y) or ({ x }) = y.
// === Combined destructuring of objects and arrays
// Combine objects and arrays
var {prop: x, prop2: [, y]} = {prop: 5, prop2: [10, 100]};
console.log(x, y);
// => 5 100
// === Nested object destructuring
// Deep objects
var {
prop: x,
prop2: {
prop2: {
nested: [ , , b]
}
}
} = { prop: "Hello", prop2: { prop2: { nested: ["a", "b", "c"]}}};
console.log(x, b);
// => Hello c
// === Combining all to make fun happen
// All well and good, can we do more? Yes!
// Using as method parameters
var foo = function ({prop: x}) {
console.log(x);
};
foo({invalid: 1});
foo({prop: 1});
// => undefined
// => 1
// === Nested advanced examples
// Can also use with the advanced example
var foo = function ({
prop: x,
prop2: {
prop2: {
nested: b
}
}
}) {
console.log(x, ...b);
};
foo({ prop: "Hello", prop2: { prop2: { nested: ["a", "b", "c"]}}});
// => Hello a b c
// === In combination with other ES2015 features.
// Computed property names
const name = 'fieldName';
const computedObject = { [name]: name }; // (where object is { 'fieldName': 'fieldName' })
const { [name]: nameValue } = computedObject;
console.log(nameValue)
// => fieldName
// === Rest and defaults
var ajax = function ({ url = "localhost", port: p = 80}, ...data) {
console.log("Url:", url, "Port:", p, "Rest:", data);
};
ajax({ url: "someHost" }, "additional", "data", "hello");
// => Url: someHost Port: 80 Rest: [ 'additional', 'data', 'hello' ]
ajax({ }, "additional", "data", "hello");
// => Url: localhost Port: 80 Rest: [ 'additional', 'data', 'hello' ]
ajax({ });
// => Url: localhost Port: 80 Rest: []
// Doesn't work due to trying to destructure undefined
ajax();
// => Uncaught TypeError: Cannot match against 'undefined' or 'null'
// To fix this we need to have default value for parameter in function
// Note: See the `= {}` at the end, saying default empty object if the first argument is undefined.
var ajax = ({ url: url = "localhost", port: p = 80} = {}) => {
console.log("Url:", url, "Port:", p);
};
// Now this works.
ajax();
// => Url: localhost Port: 80
ajax({ });
// => Url: localhost Port: 80
ajax({ port: 8080 });
// => Url: localhost Port: 8080
ajax({ url: "someHost", port: 8080 });
// => Url: someHost Port: 8080
// === Similar to _.pluck
var users = [
{ user: "Name1" },
{ user: "Name2" },
{ user: "Name2" },
{ user: "Name3" }
];
var names = users.map( ({ user }) => user );
console.log(names);
// => [ 'Name1', 'Name2', 'Name2', 'Name3' ]
// === Usage in for..of loops
var users = [
{ user: "Name1" },
{ user: "Name2", age: 2 },
{ user: "Name2" },
{ user: "Name3", age: 4 }
];
for (let { user, age = "DEFAULT AGE" } of users) {
console.log(user, age);
}
// => Name1 DEFAULT AGE
// => Name2 2
// => Name2 DEFAULT AGE
// => Name3 4
@weslleyaraujo

This comment has been minimized.

Show comment
Hide comment
@weslleyaraujo

weslleyaraujo Oct 9, 2015

awesome examples!
really useful feature...

awesome examples!
really useful feature...

@cvasani

This comment has been minimized.

Show comment
Hide comment
@cvasani

cvasani Dec 29, 2015

Thanks ..

cvasani commented Dec 29, 2015

Thanks ..

@AshCoolman

This comment has been minimized.

Show comment
Hide comment
@AshCoolman

AshCoolman Dec 31, 2015

Nice.

That js grammar issue is easy to explain with arrow functions:

var getUtils = () => {Math, window, document} // err...what? ok.
var getUtils = () => ({Math, window, document}) // oh, I get you

Nice.

That js grammar issue is easy to explain with arrow functions:

var getUtils = () => {Math, window, document} // err...what? ok.
var getUtils = () => ({Math, window, document}) // oh, I get you
@shuaibird

This comment has been minimized.

Show comment
Hide comment
@shuaibird

shuaibird Apr 3, 2016

awesome.
Thx

awesome.
Thx

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Apr 6, 2016

Here are slides with runnable demos and edit features from the talk where these examples originated: http://git.mikaelb.net/presentations/bartjs/destructuring

Owner

mikaelbr commented Apr 6, 2016

Here are slides with runnable demos and edit features from the talk where these examples originated: http://git.mikaelb.net/presentations/bartjs/destructuring

@gilesbradshaw

This comment has been minimized.

Show comment
Hide comment
@gilesbradshaw

gilesbradshaw Jun 21, 2016

How about

const name = "fieldName"
const {[name]: nameValue} = {fieldName: 'value'}

console.log(nameValue)
// => value

gilesbradshaw commented Jun 21, 2016

How about

const name = "fieldName"
const {[name]: nameValue} = {fieldName: 'value'}

console.log(nameValue)
// => value
@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Jul 8, 2016

@gilesbradshaw Ah, a combination of variable property name and destructuring. I like that. Never thought of combining it. Adding it now ๐Ÿ‘

Owner

mikaelbr commented Jul 8, 2016

@gilesbradshaw Ah, a combination of variable property name and destructuring. I like that. Never thought of combining it. Adding it now ๐Ÿ‘

@gilesbradshaw

This comment has been minimized.

Show comment
Hide comment
@gilesbradshaw

gilesbradshaw Jul 8, 2016

glad you like it :)

glad you like it :)

@brunolemos

This comment has been minimized.

Show comment
Hide comment
@brunolemos

brunolemos Sep 14, 2016

Manual pull request: Use Arrow Function Shorthand:

-var foo = () => {
-  return [1, 2, 3];
-};
+var foo = () => [1, 2, 3];

Manual pull request: Use Arrow Function Shorthand:

-var foo = () => {
-  return [1, 2, 3];
-};
+var foo = () => [1, 2, 3];
@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Sep 15, 2016

Updated. Didn't really have to be a fat arrow in that case, but just as well. ๐Ÿ‘

Owner

mikaelbr commented Sep 15, 2016

Updated. Didn't really have to be a fat arrow in that case, but just as well. ๐Ÿ‘

@sabithpocker

This comment has been minimized.

Show comment
Hide comment
@sabithpocker

sabithpocker Sep 22, 2016

Good read. :)

[
  { firstName: "Paul", lastName: "Nicklen", age: 48, profession: "Photography"},
  { firstName: "Steve", lastName: "McCurry", age: 66, profession: "Photography"},
  { firstName: "Frans", lastName: "Lanting", age: 65, profession: "Photography"},
  { firstName: "Jimmy", lastName: "Chinn", age: 42, profession: "Photography"}
].map(({firstName, lastName, age}) => ({name:firstName + lastName, age}));

sabithpocker commented Sep 22, 2016

Good read. :)

[
  { firstName: "Paul", lastName: "Nicklen", age: 48, profession: "Photography"},
  { firstName: "Steve", lastName: "McCurry", age: 66, profession: "Photography"},
  { firstName: "Frans", lastName: "Lanting", age: 65, profession: "Photography"},
  { firstName: "Jimmy", lastName: "Chinn", age: 42, profession: "Photography"}
].map(({firstName, lastName, age}) => ({name:firstName + lastName, age}));
@jstewart8053

This comment has been minimized.

Show comment
Hide comment
@jstewart8053

jstewart8053 Oct 10, 2016

Super Helpful! Thanks!

Super Helpful! Thanks!

@xgqfrms-GitHub

This comment has been minimized.

Show comment
Hide comment

great work!

@iczechowski

This comment has been minimized.

Show comment
Hide comment
@iczechowski

iczechowski Nov 3, 2016

You may also want to demonstrate destructuring with default function parameters.

var ajax = ({ url: url = "localhost", port: p = 80} = {}) => {
  console.log("Url:", url, "Port:", p);
}; 

ajax();
//  => Url: localhost Port: 80
 
ajax({ port: 8080 });
//  => Url: localhost Port: 8080

ajax({ url: "someHost", port: 8080 });
//  => Url: someHost Port: 8080

You may also want to demonstrate destructuring with default function parameters.

var ajax = ({ url: url = "localhost", port: p = 80} = {}) => {
  console.log("Url:", url, "Port:", p);
}; 

ajax();
//  => Url: localhost Port: 80
 
ajax({ port: 8080 });
//  => Url: localhost Port: 8080

ajax({ url: "someHost", port: 8080 });
//  => Url: someHost Port: 8080
@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Nov 8, 2016

@iczechowski I updated the destructure function parameter section now to be more clear. Thanks!

Owner

mikaelbr commented Nov 8, 2016

@iczechowski I updated the destructure function parameter section now to be more clear. Thanks!

@ariel2023

This comment has been minimized.

Show comment
Hide comment
@ariel2023

ariel2023 Nov 18, 2016

Hi @mikaelbr can I ask something?
I tried example
var {prop: x, prop2: [, y]} = {prop: 5, prop2: [10, 100]};
and when I print prop2 I get 10 instead of 100. Can you explain me why ? It shouldn't be [100] (an array containing number 100)? Since we ignore the 1st number.

Thank you in advance

Hi @mikaelbr can I ask something?
I tried example
var {prop: x, prop2: [, y]} = {prop: 5, prop2: [10, 100]};
and when I print prop2 I get 10 instead of 100. Can you explain me why ? It shouldn't be [100] (an array containing number 100)? Since we ignore the 1st number.

Thank you in advance

@ariel2023

This comment has been minimized.

Show comment
Hide comment
@ariel2023

ariel2023 Nov 18, 2016

Additionally in the last example
[for ({ user, age = "DEFAULT AGE" } of users) console.log(user, age)];
I don't understand why we need the brackets [].

I tried it without brackets and works fine

Additionally in the last example
[for ({ user, age = "DEFAULT AGE" } of users) console.log(user, age)];
I don't understand why we need the brackets [].

I tried it without brackets and works fine

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Nov 25, 2016

Hi @ariel2023. Sorry for the late response, but I don't get notifications from gists. I don't understand what you mean about the first example you get:

var { prop: x, prop2: [, y] } = { prop: 5, prop2: [10, 100] };

Here you do "name prop x" and "name the second element of prop2 y", and if you try that in e.g. Chrome you do in fact get x = 5 and y = 100 as expected. Try running

var { prop: x, prop2: [, y] } = { prop: 5, prop2: [10, 100]};
console.log({ x, y });
//=> Result: Object {x: 5, y: 100}

As for the second example, this can probably removed. The example was written at a time where list comprehensions still was thought to be included in the new standard. Now we know it wasn't and is probably not getting included anytime soon. We have other patterns, such as map, reduce etc which can achieve much of the same, depending on usage.

So writing the example using those constructs instead we could do:

var users = [
  { user: "Name1" },
  { user: "Name2", age: 2 },
  { user: "Name2" },
  { user: "Name3", age: 4 }
];
users.forEach(({ user, age = "DEFAULT AGE" }) => console.log(user, age));

As a sidenote: It works when you remove the [] more as a happy accident, because that is valid syntax for a for..of loop.

for ({ user, age = "DEFAULT AGE" } of users) console.log(user, age);

becomes

for ({ user, age = "DEFAULT AGE" } of users) {
  console.log(user, age);
}

Which is destructuring user, age from users each iteration and printing that. Please note, though, this wouldn't work in strict mode. As we are not declaring our variables before using them in the destructuring. For it to be valid we would have to do something like:

for (let { user, age = "DEFAULT AGE" } of users) {
  console.log(user, age);
}
Owner

mikaelbr commented Nov 25, 2016

Hi @ariel2023. Sorry for the late response, but I don't get notifications from gists. I don't understand what you mean about the first example you get:

var { prop: x, prop2: [, y] } = { prop: 5, prop2: [10, 100] };

Here you do "name prop x" and "name the second element of prop2 y", and if you try that in e.g. Chrome you do in fact get x = 5 and y = 100 as expected. Try running

var { prop: x, prop2: [, y] } = { prop: 5, prop2: [10, 100]};
console.log({ x, y });
//=> Result: Object {x: 5, y: 100}

As for the second example, this can probably removed. The example was written at a time where list comprehensions still was thought to be included in the new standard. Now we know it wasn't and is probably not getting included anytime soon. We have other patterns, such as map, reduce etc which can achieve much of the same, depending on usage.

So writing the example using those constructs instead we could do:

var users = [
  { user: "Name1" },
  { user: "Name2", age: 2 },
  { user: "Name2" },
  { user: "Name3", age: 4 }
];
users.forEach(({ user, age = "DEFAULT AGE" }) => console.log(user, age));

As a sidenote: It works when you remove the [] more as a happy accident, because that is valid syntax for a for..of loop.

for ({ user, age = "DEFAULT AGE" } of users) console.log(user, age);

becomes

for ({ user, age = "DEFAULT AGE" } of users) {
  console.log(user, age);
}

Which is destructuring user, age from users each iteration and printing that. Please note, though, this wouldn't work in strict mode. As we are not declaring our variables before using them in the destructuring. For it to be valid we would have to do something like:

for (let { user, age = "DEFAULT AGE" } of users) {
  console.log(user, age);
}
@reoxb

This comment has been minimized.

Show comment
Hide comment
@reoxb

reoxb Mar 25, 2017

I did something like this,

let str = "hello";
const toCapital = ([a, ...b]) => [a.toUpperCase(), ...b].join('');
console.log(toCapital(str)); // Hello

and it works!

reoxb commented Mar 25, 2017

I did something like this,

let str = "hello";
const toCapital = ([a, ...b]) => [a.toUpperCase(), ...b].join('');
console.log(toCapital(str)); // Hello

and it works!

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Apr 4, 2017

@reoxb In JavaScript, you can iterate strings, as it is a sequence of characters. See for instance:

console.log("Hello"[0]); //=> 'H' 

Also you can get the iterator from a string, as you can with an array:

"Hello"[Symbol.iterator] // Returns the iterator.

e.g.

for (let l of "hello")
  console.log(l);
Owner

mikaelbr commented Apr 4, 2017

@reoxb In JavaScript, you can iterate strings, as it is a sequence of characters. See for instance:

console.log("Hello"[0]); //=> 'H' 

Also you can get the iterator from a string, as you can with an array:

"Hello"[Symbol.iterator] // Returns the iterator.

e.g.

for (let l of "hello")
  console.log(l);
@asicfr

This comment has been minimized.

Show comment
Hide comment
@asicfr

asicfr Apr 6, 2017

Dummy question
With default, we can avoid "TypeError: Cannot read property" on undefined value, it's great !!
But how to deal with null ?
With ajax function line 178 we have :
ajax(); // is's ok for undefined => Url: localhost Port: 80
ajax(null); // but not for null => error

asicfr commented Apr 6, 2017

Dummy question
With default, we can avoid "TypeError: Cannot read property" on undefined value, it's great !!
But how to deal with null ?
With ajax function line 178 we have :
ajax(); // is's ok for undefined => Url: localhost Port: 80
ajax(null); // but not for null => error

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Apr 7, 2017

@asicfr I'm afraid you can't by using default parameter. Technically, null is a value as it is defined. IMO, you don't really have to use null in JavaScript.


Now you could always write a decorator for a function to convert null to register as undefined, but I wouldn't necessarily say it's a good idea:

function undefinedNull (fn) {
  return function (...args) {
    return fn(...args.map(v => v == null ? void 0 : v));
  };
}
let add = undefinedNull(function (a = 5, b = 3) {
  return a + b;
});
add(); //=> 8
add(undefined, null); //=> 8
add(null, null); //=> 8
add(2, 2); //=> 4

I'd say avoiding null should be preferred.

Owner

mikaelbr commented Apr 7, 2017

@asicfr I'm afraid you can't by using default parameter. Technically, null is a value as it is defined. IMO, you don't really have to use null in JavaScript.


Now you could always write a decorator for a function to convert null to register as undefined, but I wouldn't necessarily say it's a good idea:

function undefinedNull (fn) {
  return function (...args) {
    return fn(...args.map(v => v == null ? void 0 : v));
  };
}
let add = undefinedNull(function (a = 5, b = 3) {
  return a + b;
});
add(); //=> 8
add(undefined, null); //=> 8
add(null, null); //=> 8
add(2, 2); //=> 4

I'd say avoiding null should be preferred.

@asicfr

This comment has been minimized.

Show comment
Hide comment
@asicfr

asicfr Apr 7, 2017

yes, i think you're right.
thanks

asicfr commented Apr 7, 2017

yes, i think you're right.
thanks

@reqshark

This comment has been minimized.

Show comment
Hide comment
@reqshark

reqshark Aug 5, 2017

wow nice gist!

IMO, you don't really have to use null in JavaScript

I would compare null in javascript to the human appendix. Basically either develops a rare cancer or more commonly an acute appendicitis, both of which can be cured by general surgery. anyway, yea avoid it, null is useless.

reqshark commented Aug 5, 2017

wow nice gist!

IMO, you don't really have to use null in JavaScript

I would compare null in javascript to the human appendix. Basically either develops a rare cancer or more commonly an acute appendicitis, both of which can be cured by general surgery. anyway, yea avoid it, null is useless.

@CanRau

This comment has been minimized.

Show comment
Hide comment
@CanRau

CanRau Aug 19, 2017

thanks for sharing :D wasn't sure about nested destructuring..now I know ๐Ÿ‘

CanRau commented Aug 19, 2017

thanks for sharing :D wasn't sure about nested destructuring..now I know ๐Ÿ‘

@reski78

This comment has been minimized.

Show comment
Hide comment
@reski78

reski78 Aug 24, 2017

Please note, that now you can use variable as key:

{
  const key = 'user';
  const { [key]: x } = { user: 5 };

  console.log(x);
  // 5
}

reski78 commented Aug 24, 2017

Please note, that now you can use variable as key:

{
  const key = 'user';
  const { [key]: x } = { user: 5 };

  console.log(x);
  // 5
}
@Jivvie

This comment has been minimized.

Show comment
Hide comment
@Jivvie

Jivvie Dec 11, 2017

Thank you

Jivvie commented Dec 11, 2017

Thank you

@gitasong

This comment has been minimized.

Show comment
Hide comment
@gitasong

gitasong Jan 29, 2018

How would you use array destructuring in a for-of loop? I keep seeing syntax like this, but don't understand it:

it('in for-of loop', () => {
    for (var [a, b] of [[0, 1, 2]]) {}
    expect([a, b]).toEqual([1, 2])
  })

(Ignore the test suite syntax. How do I rewrite the for line to get for (var [a, b] of [[0, 1, 2]]) to equal [1, 2]?)

How would you use array destructuring in a for-of loop? I keep seeing syntax like this, but don't understand it:

it('in for-of loop', () => {
    for (var [a, b] of [[0, 1, 2]]) {}
    expect([a, b]).toEqual([1, 2])
  })

(Ignore the test suite syntax. How do I rewrite the for line to get for (var [a, b] of [[0, 1, 2]]) to equal [1, 2]?)

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Feb 5, 2018

@gitasong There are a couple of non-destructuring grammar rules in play in your example, I'm just going to explain some of them to avoid potential misunderstandings for other potential readers.

When we iterate and use var to declare, it's hoisted to the top of the scope and the value of the last item in the list we iterate over is accessible. So if we did:

for (var a of [1, 2, 3]) {}
console.log(a); // Output: 3

As this is essentially the same as:

var a;
a = 1;
a = 2;
a = 3;
console.log(a); // Output: 3

This would not be the case if we used let or const:

for (let z of [1, 2, 3]) {}
console.log(z); // z is not defined

This explains why we can use a and b in your example even though it's outside the body of the for-of loop. Looking at the assignment/destructuring part, there are 2 parts to this: the destructuring in assignment part of the loop, and the destructuring of values it self.

for (var [a, b] of [[0, 1, 2]])

Says for each iteration, take the current item (in this case it's only one item, [0, 1, 2]) and destructure to a and b. If the list had additional values, it would be re-assigned accordingly. If we were to write the iteration as 1 by 1 imperative statements we would write:

// instead of something like
for (var [a, b] of [[0, 1, 2], [3, 4, 5]]) console.log(a, b);

// it would be
var a, b;
[a, b] = [0, 1, 2];
console.log(a, b); // 0 1

[a, b] = [3, 4, 5];
console.log(a, b); // 3 4

From this, we can also see that the destructuring part of it is a normal array destructuring. And seeing the gist above, we can omit values in destructuring by not having an identifier.

Meaning, we can ignore the first value in the array (the 0) and only select 1 and 2:

var a, b;
[   , a, b] = [0, 1, 2];
// ^--- note the comma. Ignoring the first item

console.log(a, b); // Output: 1 2

This was a very long winded and maybe too detailed explanation, but I hope it gives somewhat more insight. The short version is that you can ignore elements in destructuring by using no identifiers, and making your test pass by doing:

it('in for-of loop', () => {
  for (var [, a, b] of [[0, 1, 2]]) {}
  expect([a, b]).toEqual([1, 2]);
});

Hope this helps.

Owner

mikaelbr commented Feb 5, 2018

@gitasong There are a couple of non-destructuring grammar rules in play in your example, I'm just going to explain some of them to avoid potential misunderstandings for other potential readers.

When we iterate and use var to declare, it's hoisted to the top of the scope and the value of the last item in the list we iterate over is accessible. So if we did:

for (var a of [1, 2, 3]) {}
console.log(a); // Output: 3

As this is essentially the same as:

var a;
a = 1;
a = 2;
a = 3;
console.log(a); // Output: 3

This would not be the case if we used let or const:

for (let z of [1, 2, 3]) {}
console.log(z); // z is not defined

This explains why we can use a and b in your example even though it's outside the body of the for-of loop. Looking at the assignment/destructuring part, there are 2 parts to this: the destructuring in assignment part of the loop, and the destructuring of values it self.

for (var [a, b] of [[0, 1, 2]])

Says for each iteration, take the current item (in this case it's only one item, [0, 1, 2]) and destructure to a and b. If the list had additional values, it would be re-assigned accordingly. If we were to write the iteration as 1 by 1 imperative statements we would write:

// instead of something like
for (var [a, b] of [[0, 1, 2], [3, 4, 5]]) console.log(a, b);

// it would be
var a, b;
[a, b] = [0, 1, 2];
console.log(a, b); // 0 1

[a, b] = [3, 4, 5];
console.log(a, b); // 3 4

From this, we can also see that the destructuring part of it is a normal array destructuring. And seeing the gist above, we can omit values in destructuring by not having an identifier.

Meaning, we can ignore the first value in the array (the 0) and only select 1 and 2:

var a, b;
[   , a, b] = [0, 1, 2];
// ^--- note the comma. Ignoring the first item

console.log(a, b); // Output: 1 2

This was a very long winded and maybe too detailed explanation, but I hope it gives somewhat more insight. The short version is that you can ignore elements in destructuring by using no identifiers, and making your test pass by doing:

it('in for-of loop', () => {
  for (var [, a, b] of [[0, 1, 2]]) {}
  expect([a, b]).toEqual([1, 2]);
});

Hope this helps.

@leodutra

This comment has been minimized.

Show comment
Hide comment
@leodutra

leodutra Feb 19, 2018

This is handy when you want to destructure and redefine. Hat-trick!

function foo(param) {
    const arg = {a, b} = param
    console.log(a, b)
    console.log(arg)
}
foo({a:1, b:2})

leodutra commented Feb 19, 2018

This is handy when you want to destructure and redefine. Hat-trick!

function foo(param) {
    const arg = {a, b} = param
    console.log(a, b)
    console.log(arg)
}
foo({a:1, b:2})
@KangYoosam

This comment has been minimized.

Show comment
Hide comment

+1

@mqliutie

This comment has been minimized.

Show comment
Hide comment
@mqliutie

mqliutie Apr 18, 2018

can I set {a,b,c} to one object using pure JavaScript?

like

const {a,b,c} as params = obj; or const {a,b,c} : params = obj;

// in store.js

// long time you mustn't remember how many variables there
const obj = {a:1,b:2,c:3,d:4,e:5,f:6};

// in component

const {a,b,c} = obj;
getSomething({a,b,c});
// I know this way can do it . but long time you mustn't remember how many variables in obj
//const {d,e,f,...params} = obj;
// some day you add `y` to obj in the store and it will be in params if you don't update your component.
// getSomething(params);

can I set {a,b,c} to one object using pure JavaScript?

like

const {a,b,c} as params = obj; or const {a,b,c} : params = obj;

// in store.js

// long time you mustn't remember how many variables there
const obj = {a:1,b:2,c:3,d:4,e:5,f:6};

// in component

const {a,b,c} = obj;
getSomething({a,b,c});
// I know this way can do it . but long time you mustn't remember how many variables in obj
//const {d,e,f,...params} = obj;
// some day you add `y` to obj in the store and it will be in params if you don't update your component.
// getSomething(params);

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr Apr 23, 2018

@mqliutie I'm not entirely sure if I understand the question. Are you talking about constructing objects after destructuring it? Could you maybe show a more concise example?

Owner

mikaelbr commented Apr 23, 2018

@mqliutie I'm not entirely sure if I understand the question. Are you talking about constructing objects after destructuring it? Could you maybe show a more concise example?

@evandrix

This comment has been minimized.

Show comment
Hide comment
@evandrix

evandrix Apr 27, 2018

how about:

const data = {
  valid: true,
  products: [{
    item: 'Awesome shoe',
    price: 19.99,
    inStore: ['Regent Street', 'Oxford Street', 'Harrods']
  }, {
    item: 'Fave shirt',
    price: 12.99,
    inStore: ['Regent Street']
  }]
};
const { products: [ { item, inStore: [, , x] } ]} = data;
console.log(item + " is in " + x);

why is the output "Awesome shoe is in Harrods", and not "Fav shirt is in undefined" ?

evandrix commented Apr 27, 2018

how about:

const data = {
  valid: true,
  products: [{
    item: 'Awesome shoe',
    price: 19.99,
    inStore: ['Regent Street', 'Oxford Street', 'Harrods']
  }, {
    item: 'Fave shirt',
    price: 12.99,
    inStore: ['Regent Street']
  }]
};
const { products: [ { item, inStore: [, , x] } ]} = data;
console.log(item + " is in " + x);

why is the output "Awesome shoe is in Harrods", and not "Fav shirt is in undefined" ?

@mikaelbr

This comment has been minimized.

Show comment
Hide comment
@mikaelbr

mikaelbr May 14, 2018

@evandrix If I understand the question correctly, the key here is the destructuring of arrays. Let's simplify the code to see only the relevant parts:

const data = [{
  item: 'Awesome shoe',
  price: 19.99,
  inStore: ['Regent Street', 'Oxford Street', 'Harrods']
}, {
  item: 'Fave shirt',
  price: 12.99,
  inStore: ['Regent Street']
}];
const [ { item, inStore: [, , x] } ] = data;
console.log(item + " is in " + x);

Which would result in the same. We can reduce the structure further if we just focus on the item and not the inStore property:

const data = [{
  item: 'Awesome shoe'
}, {
  item: 'Fave shirt'
}];
const [ { item } ] = data;
console.log(item); //=> Awesome shoe

And that again is pretty much the same as:

const data = [1, 2];
const [ item ] = data;
console.log(item); //=> 1

And hopefully it's easier to see what is going on. We're destructuring an array and fetching the first element and ignore all other in the array. As if we did const [ item, ].

Owner

mikaelbr commented May 14, 2018

@evandrix If I understand the question correctly, the key here is the destructuring of arrays. Let's simplify the code to see only the relevant parts:

const data = [{
  item: 'Awesome shoe',
  price: 19.99,
  inStore: ['Regent Street', 'Oxford Street', 'Harrods']
}, {
  item: 'Fave shirt',
  price: 12.99,
  inStore: ['Regent Street']
}];
const [ { item, inStore: [, , x] } ] = data;
console.log(item + " is in " + x);

Which would result in the same. We can reduce the structure further if we just focus on the item and not the inStore property:

const data = [{
  item: 'Awesome shoe'
}, {
  item: 'Fave shirt'
}];
const [ { item } ] = data;
console.log(item); //=> Awesome shoe

And that again is pretty much the same as:

const data = [1, 2];
const [ item ] = data;
console.log(item); //=> 1

And hopefully it's easier to see what is going on. We're destructuring an array and fetching the first element and ignore all other in the array. As if we did const [ item, ].

@AkshayIyer12

This comment has been minimized.

Show comment
Hide comment
@AkshayIyer12

AkshayIyer12 Jun 28, 2018

Thanks! I'm using it production now. ๐Ÿ‘

Thanks! I'm using it production now. ๐Ÿ‘

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment