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
221 views
in Technique[技术] by (71.8m points)

javascript - how does destructuring array get length property

I came across this destructuring expression in an article.

const words = ['oops', 'gasp', 'shout', 'sun'];
let { length } = words;
console.log(length); // 4

How does length get the value of 4? I know .length is a property of the array, but how does this syntax work? It seems to be doing let length = words.length; and in fact in babel does output it as such. But my question is what is the logic behind it? What is confusing me is the mix of an array of values and the the use of {length}.

I have read MDN 's description but can't see this example explained.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Intro

I had the same question so I read the docs and it finally clicked for me that the variable (length) is just being assigned the Object’s value at the key with the same name as the variable (words[length]).

That may not make sense, so I’m going to start by explaining this type of destructuring in 2 steps and then show how it applies in this situation.

I’ll then provide one last (cool) example which confused me initially and led me to research this topic. It’s also the exact problem described in a duplicate question.


Destructuring

This syntax is called Object Destructuring (MDN):

let a, b;

({a, b} = {a: 1, b: 2});
a; // 1
b; // 2


({b, a} = {c: 3, b: 2, d: 4, a: 1});
a; // 1
b; // 2

Same result – order doesn't matter!

The variables on the left (a & b) are assigned to the value of their corresponding key's value on the Object (right).


const obj = {a: 1, b: 2};
let {a, b} = obj;

a; // 1
b; // 2

We can store the object on the right into a variable (obj in this case) and then use the same syntax (without parens).


Applied to your Example (Array)

Finally, let's show the words array as an Object (arrays are just Objects under the hood).

Here's what you'll see if you type ['oops', 'gasp', 'shout', 'sun'] into Chrome's console:

chrome console output

const words = {0: 'oops', 1: 'gasp', 2: 'shout', 3: 'sun', length: 4};
let { length } = words;
console.log(length); // 4

Just like above, it's going to set the length variable (left) to the value of the corresponding key in the words Object/array (right). words[length] has a value of 4 so the length variable (left) now has a value of 4 as well.


Example Where Destructuring is Useful

From Wes Bos's Blog:

Given a person Object, how do you create global variables referring to its properties?

const person = {
  first: 'Wes',
  last: 'Bos',
  country: 'Canada',
  city: 'Hamilton',
  twitter: '@wesbos'
};

Old School:

const first = person.first;
const last = person.last;

The power of destructuring!

const { first, last } = person;

BONUS: Cool Usage w/ Arrow Functions (MDN)

Challenge: return new array with the lengths of the respective elements in the input array.

This example is shown as a way to use arrow functions. All three solutions solve the problem, they’re just showing the evolution to finally arrive at a simple one-liner.

var materials = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

materials.map(function(material) { 
  return material.length; 
}); // [8, 6, 7, 9]

materials.map((material) => {
  return material.length;
}); // [8, 6, 7, 9]

materials.map(({length}) => length); // [8, 6, 7, 9]

On each iteration of the input array passed to map, we are setting the {length} parameter to the current element of materials that is passed in as an argument:

{length} = 'Hydrogen';

This sets the length variable to the length property of the current string element (more on that below) and then simply returns the value of length to the map function which eventually returns a new array with all of the elements from the original array's lengths as its elements.

Supplement: String (primitive) vs. Array (Object)

"strings" are "primitives", not objects, so they don't have properties BUT when you try to call a property such as .length on a string, the primitive is coerced (changed) into a String Object.

Here's what a String Object looks like in the Chrome console. Notice how it's practically the same as the Array Object. String (function) is a constructor, so calling new will create a new Object constructed from that function with String (Object) as its prototype (which is what __proto__ refers to):

new String in Chrome console


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

...