Spread Syntax ES6 - javascript

Consider the following sample code
var x = ["a", "b", "c"];
var z = ["p", "q"];
var d = [...x, ...z];
var e = x.concat(z);
Here, the value of d and e are exactly same and is equal to ["a", "b", "c", "p", "q"], so,
What exactly is the difference between these two?
Which one is more efficient and why?
What exactly is the use of spread syntax?

In your example given, there is essentially no difference between the two
.concat is significantly more efficient: http://jsperf.com/spread-into-array-vs-concat because ... (spread) is merely syntax sugar on top of more fundamental underlying syntax that explicitly iterates over indexes to expand the array.
Spread allows sugared syntax on top of more clunky direct array manipulation
To expand on #3 above, your use of spread is a somewhat contrived example (albeit one that will likely appear in the wild frequently). Spread is useful when - for example - the entirety of an arguments list should be passed to .call in the function body.
function myFunc(){
otherFunc.call( myObj, ...args );
}
versus
function myFunc(){
otherFunc.call( myObj, args[0], args[1], args[2], args[3], args[4] );
}
This is another arbitrary example, but it's a little clearer why the spread operator will be nice to use in some otherwise verbose and clunky situations.
As #loganfsmyth points out:
Spread also works on arbitrary iterable objects which means it not only works on Arrays but also Map and Set among others.
This is a great point, and adds to the idea that - while not impossible to achieve in ES5 - the functionality introduced in the spread operator is one of the more useful items in the new syntax.
For the actual underlying syntax for the spread operator in this particular context (since ... can also be a "rest" parameter), see the specification. "more fundamental underlying syntax that explicitly iterates over indexes to expand the array" as I wrote above is enough to get the point across, but the actual definition uses GetValue and GetIterator for the variable that follows.

Taking the questions out of order, let's start with the fundamental question: What exactly is the use of spread syntax?
Spread syntax basically unpacks the elements of an iterable such as an array or object. Or, for the more detailed explanation from the MDN Web Docs on spread syntax:
Spread syntax allows an iterable such as an array expression or string
to be expanded in places where zero or more arguments (for function
calls) or elements (for array literals) are expected, or an object
expression to be expanded in places where zero or more key-value pairs
(for object literals) are expected.
Following are some simple examples of typical use cases for spread syntax and an example of the difference between spread syntax and rest parameters (they may look the same, but they perform nearly opposite functions).
Function call:
const multiArgs = (one, two) => {
console.log(one, two);
};
const args = [1, 2];
multiArgs(...args);
// 1 2
Array or string literal:
const arr1 = [2, 3];
const arr2 = [1, ...arr1, 4];
console.log(arr2);
// [1, 2, 3, 4]
const s = 'split';
console.log(...s);
// s p l i t
Object literal:
const obj1 = { 1: 'one' };
const obj2 = { 2: 'two' };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);
// { 1: 'one', 2: 'two' }
Rest parameter syntax is not the same as spread syntax:
Rest parameter syntax looks the same as spread syntax but actually represents an unknown number of function arguments as an array. So rather than "unpacking" the iterable, rest parameters actually package multiple arguments into an array.
const multiArgs = (...args) => {
console.log(args);
};
multiArgs('a', 'b', 'c');
// ['a', 'b', 'c']
Spread syntax performance / efficiency:
To address the question about efficiency compared to other methods, the only honest answer is that "it depends". Browsers change all the time and the context and data associated with a particular function create wildly different performance outcomes, so you can find all sorts of conflicting performance timings that suggest spread syntax is both amazingly faster and ridiculously slower than various array or object methods you might use to accomplish similar objectives. In the end, any situation where optimizations for speed are critical should be comparison tested rather than relying on generic timings of simplistic functions that ignore the specifics of your code and data.
Comparison to concat():
And finally a quick comment regarding the difference between spread syntax and concat() shown in the question code. The difference is that spread syntax can be used for a lot more than just concatenating arrays, but concat() works in older browsers like IE. In a situation where you are not concerned about compatibility with older browsers and micro optimizations for speed are unnecessary, then the choice between spread syntax and concat() is just a matter of what you find more readable: arr3 = arr1.concat(arr2) or arr3 = [...arr1, ...arr2].

The output of this example is the same, but it’s not the same behavior under the hood,
Consider ( check the browser's console ) :
var x = [], y = [];
x[1] = "a";
y[1] = "b";
var usingSpread = [...x, ...y];
var usingConcat = x.concat(y);
console.log(usingSpread); // [ undefined, "a", undefined, "b"]
console.log(usingConcat); // [ , "a", , "b"]
console.log(1 in usingSpread); // true
console.log(1 in usingConcat); // false
Array.prototype.concat will preserve the empty slots in the array while the Spread will replace them with undefined values.
Enter Symbol.iterator and Symbol.isConcatSpreadable :
The Spread Operator uses the ##iterator symbol to iterate through Arrays and Array-like Objects like :
Array.prototype
TypedArray.prototype
String.prototype
Map.prototype
Set.prototype
(that's why you can use for .. of on them )
We can override the default iterator symbol to see how the spread operator behaves :
var myIterable = ["a", "b", "c"];
var myIterable2 = ["d", "e", "f"];
myIterable[Symbol.iterator] = function*() {
yield 1;
yield 2;
yield 3;
};
console.log(myIterable[0], myIterable[1], myIterable[2]); // a b c
console.log([...myIterable]); // [1,2,3]
var result = [...myIterable, ...myIterable2];
console.log(result); // [1,2,3,"d","e","f"]
var result2 = myIterable.concat(myIterable2);
console.log(result2); // ["a", "b", "c", "d", "e", "f"]
On the other hand, ##isConcatSpreadable is
A Boolean valued property that if true indicates that an object should be flattened to its array elements by Array.prototype.concat.
If set to false, Array.concat will not flatten the array :
const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
let alphaNumeric = alpha.concat(numeric);
// console.log(alphaNumeric);
numeric[Symbol.isConcatSpreadable] = false;
alphaNumeric = alpha.concat(numeric);
// alphaNumeric = [...alpha, ...numeric];
// the above line will output : ["a","b","c",1,2,3]
console.log(JSON.stringify(alphaNumeric)); // ["a","b","c",[1,2,3]]
However, the spread behaves differently when it comes to Objects since they are not iterable
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
var objCopy = {...obj}; // copy
It copies own enumerable properties from a provided object onto a new object.
The spread operator is faster, check spread-into-array-vs-concat ( Since Chrome 67 at least )
And check how three dots changed javascript for some use cases, among them is the Destructuring assignment ( Array or Object ) :
const arr = [1, 2, 3, 4, 5, 6, 7];
const [first, , third, ...rest] = arr;
console.log({ first, third, rest });
and splitting a string to an array of characters :
console.log( [...'hello'] ) // [ "h", "e" , "l" , "l", "o" ]

There is no difference between these two in given example. For concatenation, we can use concat method over spread operator. However, use of spread operator is not limited to the concatenation of arrays.
The spread syntax allows an iterable such as an array expression or string to be expanded. It can be used in following scenarios.
Spread Operator with arrays
Concatenation of Arrays
String to Array
Array as Arguments to function.
Spread Operator with objects
Concatenation of Objects
To see how a demonstration of all these uses and to try your hands on code please follow below link (codepen.io)
ES6-Demonstration of Spread Operator
/**
* Example-1: Showing How Spread Operator can be used to concat two or more
arrays.
*/
const americas = ['South America', 'North America'];
const eurasia = ['Europe', 'Asia'];
const world = [...americas, ...eurasia];
/**
* Example-2: How Spread Operator can be used for string to array.
*/
const iLiveIn = 'Asia';
const iLiveIntoArray = [...iLiveIn];
/**
* Example-3: Using Spread Operator to pass arguments to function
*/
const numbers = [1,4,5];
const add = function(n1,n2,n3){
return n1 + n2 + n3;
};
const addition = add(numbers[0],numbers[1],numbers[2]);
const additionUsingSpread = add(...numbers);
/**
* Example-4: Spread Operator, can be used to concat the array
*/
const personalDetails = {
name: 'Ravi',
age: '28',
sex: 'male'
};
const professionalDetails = {
occupation: 'Software Engineer',
workExperience: '4 years'
};
const completeDetails = {...personalDetails, ...professionalDetails};

const colours = ['Blue','Red','Black']; // Simple array.
const my_colours = ['Blue','Red','Black','Yellow','Green'];
const favourite_colours = [...my_colours,'grey']; //[...] spread Operator access data in another array.

Spread syntax allows an iterable to be expanded in places where zero or more elements are expected. This high level explanation can be confusing, so a 'real-world' example of this is as follows:
Without the spread syntax you could update objects multiple times like so:
//If I needed to change the speed or damage at any time of a race car
const raceCar = {name: 'Ferrari 250 GT'};
const stats = {speed: 66, damage: 1, lap: 2};
raceCar['speed'] = stats.speed;
raceCar['damage'] = stats.damage;
Alternatively, a cleaner solution is to create a new object with the spread syntax:
//Creates a new object with priority from left to right
const lap1 = { ...raceCar, ...stats }
//Or a specific variable:
const enterPitStop = {...raceCar, speed: 0 }
In essence, rather than mutating the original object of raceCar, you will be creating a new immutable object.
It is also helpful when adding new values to arrays. With spread you can push/unshift multiple variables by copying the former array. Before spread, you would push like so:
var raceCars = ['Ferrari 250 GT', 'Le Mans Series', '24 Heures du Mans'];
//Sometimes, you will need to push multiple items to an array, which gets messy in large projects!
raceCars.push('Car 1');
raceCars.push('Car 2');
raceCars.push('Car 3');
Instead, you would copy the array and add it to a new variable or the same one for simplicity.
//Push values to array
raceCars = [...raceCars, 'Car 1', 'Car 2', 'Car 3'];
//This is dynamic! Add the values anywhere in the array:
//Adds the values at the front as opposed to the end
raceCars = ['Car 1', 'Car 2', 'Car 3', ...raceCars];
//Another dynamic examples of adding not in the front or back:
raceCars = ['Car 1', 'Car 2', ...raceCars, 'Car 3'];
I encourage you to view the more detailed documentation on the Mozilla Developer Website.

Context: You want to concatenate two arrays, in order to get a copy "by value" using the three dots spread syntax, but you are working with complex/nested arrays.
Finding: Take care that nested arrays are NOT passed by value, but by reference. In other words, only first level items are passed as a copy "by value". See the example:
sourceArray1 = [ 1, [2, 3] ] // Third element is a nested array
sourceArray2 = [ 4, 5 ]
targetArray = [ ...sourceArray1, ...sourceArray2]
console.log("Target array result:\n", JSON.stringify(targetArray), "\n\n") //it seems a copy, but...
console.log("Let's update the first source value:\n")
sourceArray1[0] = 10
console.log("Updated source array:\n", JSON.stringify(sourceArray1), "\n")
console.log("Target array is NOT updated, It keeps a copy by value: 1\n")
console.log(JSON.stringify(targetArray), "\n\n")
//But if you update a nested value, it has NOT been copied
console.log("Let's update a nested source value:\n")
sourceArray1[1][0] = 20
console.log("Updated source nested array:\n", JSON.stringify(sourceArray1), "\n")
console.log("Target array is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetArray)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level elements, but 'by reference' for nested/complex elements (This applies also for objects) so take care!\n")

Syntax
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
If you have any confusion then watch this video for more help Thanks.
https://youtu.be/U00S_b2Fv2E

Related

Spread Or Rest Operator in Array Push [duplicate]

What does the ... do in this React (using JSX) code and what is it called?
<Modal {...this.props} title='Modal heading' animation={false}>
That's property spread notation. It was added in ES2018 (spread for arrays/iterables was earlier, ES2015), but it's been supported in React projects for a long time via transpilation (as "JSX spread attributes" even though you could do it elsewhere, too, not just attributes).
{...this.props} spreads out the "own" enumerable properties in props as discrete properties on the Modal element you're creating. For instance, if this.props contained a: 1 and b: 2, then
<Modal {...this.props} title='Modal heading' animation={false}>
would be the same as
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>
But it's dynamic, so whatever "own" properties are in props are included.
Since children is an "own" property in props, spread will include it. So if the component where this appears had child elements, they'll be passed on to Modal. Putting child elements between the opening tag and closing tags is just syntactic sugar — the good kind — for putting a children property in the opening tag. Example:
class Example extends React.Component {
render() {
const { className, children } = this.props;
return (
<div className={className}>
{children}
</div>
);
}
}
ReactDOM.render(
[
<Example className="first">
<span>Child in first</span>
</Example>,
<Example className="second" children={<span>Child in second</span>} />
],
document.getElementById("root")
);
.first {
color: green;
}
.second {
color: blue;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Spread notation is handy not only for that use case, but for creating a new object with most (or all) of the properties of an existing object — which comes up a lot when you're updating state, since you can't modify state directly:
this.setState(prevState => {
return {foo: {...prevState.foo, a: "updated"}};
});
That replaces this.state.foo with a new object with all the same properties as foo except the a property, which becomes "updated":
const obj = {
foo: {
a: 1,
b: 2,
c: 3
}
};
console.log("original", obj.foo);
// Creates a NEW object and assigns it to `obj.foo`
obj.foo = {...obj.foo, a: "updated"};
console.log("updated", obj.foo);
.as-console-wrapper {
max-height: 100% !important;
}
... are called spread attributes which, as the name represents, it allows an expression to be expanded.
var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]
And in this case (I'm going to simplify it).
// Just assume we have an object like this:
var person= {
name: 'Alex',
age: 35
}
This:
<Modal {...person} title='Modal heading' animation={false} />
is equal to
<Modal name={person.name} age={person.age} title='Modal heading' animation={false} />
So in short, it's a neat short-cut, we can say.
The three dots represent the spread operator in ES6. It allows us to do quite a few things in JavaScript:
Concatenate arrays
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil'];
var racingGames = ['Need For Speed', 'Gran Turismo', 'Burnout'];
var games = [...shooterGames, ...racingGames];
console.log(games) // ['Call of Duty', 'Far Cry', 'Resident Evil', 'Need For Speed', 'Gran Turismo', 'Burnout']
Destructuring an array
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil'];
var [first, ...remaining] = shooterGames;
console.log(first); //Call of Duty
console.log(remaining); //['Far Cry', 'Resident Evil']
Combining two objects
var myCrush = {
firstname: 'Selena',
middlename: 'Marie'
};
var lastname = 'my last name';
var myWife = {
...myCrush,
lastname
}
console.log(myWife); // {firstname: 'Selena',
// middlename: 'Marie',
// lastname: 'my last name'}
There's another use for the three dots which is known as Rest Parameters and it makes it possible to take all of the arguments to a function in as one array.
Function arguments as array
function fun1(...params) {
}
... (three dots in JavaScript) is called the Spread Syntax or Spread Operator. This allows an iterable such as an array expression or string to be expanded or an object expression to be expanded wherever placed. This is not specific to React. It is a JavaScript operator.
All these answers here are helpful, but I want to list down the mostly used practical Use Cases of the Spread Syntax (Spread Operator).
1. Combine Arrays (Concatenate Arrays)
There are a variety of ways to combine arrays, but the spread operator allows you to place this at any place in an array. If you'd like to combine two arrays and place elements at any point within the array, you can do as follows:
var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];
// arr2 = ["one", "two", "three", "four", "five"]
2. Copying Arrays
When we wanted a copy of an array, we used to have the Array.prototype.slice() method. But, you can do the same with the spread operator.
var arr = [1,2,3];
var arr2 = [...arr];
// arr2 = [1,2,3]
3. Calling Functions without Apply
In ES5, to pass an array of two numbers to the doStuff() function, you often use the Function.prototype.apply() method as follows:
function doStuff (x, y, z) {}
var args = [0, 1, 2];
// Call the function, passing args
doStuff.apply(null, args);
However, by using the spread operator, you can pass an array into the function.
doStuff(...args);
4. Destructuring Arrays
You can use destructuring and the rest operator together to extract the information into variables as you'd like them:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }
5. Function Arguments as Rest Parameters
ES6 also has three dots (...) which indicates a rest parameter that collects all remaining arguments of a function into an array.
function f(a, b, ...args) {
console.log(args);
}
f(1, 2, 3, 4, 5); // [3, 4, 5]
6. Using Math Functions
Any function where spread is used as the argument can be used by functions that can accept any number of arguments.
let numbers = [9, 4, 7, 1];
Math.min(...numbers); // 1
7. Combining Two Objects
You can use the spread operator to combine two objects. This is an easy and cleaner way to do it.
var carType = {
model: 'Toyota',
yom: '1995'
};
var carFuel = 'Petrol';
var carData = {
...carType,
carFuel
}
console.log(carData);
// {
// model: 'Toyota',
// yom: '1995',
// carFuel = 'Petrol'
// }
8. Separate a String into Separate Characters
You can use the spread operator to spread a string into separate characters.
let chars = ['A', ...'BC', 'D'];
console.log(chars); // ["A", "B", "C", "D"]
You can think of more ways to use the Spread Operator. What I have listed here are the popular use cases of it.
The three dots in JavaScript are the spread / rest operator.
Spread operator
The spread syntax allows an expression to be expanded in places where multiple arguments are expected.
myFunction(...iterableObj);
[...iterableObj, 4, 5, 6]
[...Array(10)]
Rest parameters
The rest parameter syntax is used for functions with a variable number of arguments.
function(a, b, ...theArgs) {
// ...
}
The spread / rest operator for arrays was introduced in ES6. There's a State 2 proposal for object spread / rest properties.
TypeScript also supports the spread syntax and can transpile that into older versions of ECMAScript with minor issues.
This is a feature of ES6, which is used in React as well. Look at the below example:
function Sum(x, y, z) {
return x + y + z;
}
console.log(Sum(1, 2, 3)); // 6
This way is fine if we have a maximum of three parameters. But, what if we need to add, for example, 110 parameters. Should we define them all and add them one by one?
Of course there is an easier way to do, which is called spread.
Instead of passing all those parameters you write:
function (...numbers){}
We have no idea how many parameters we have, but we know there are heaps of those.
Based on ES6, we can rewrite the above function as below and use the spread and mapping between them to make it as easy as a piece of cake:
let Sum = (...numbers) => {
return numbers.reduce((prev, current) => prev + current);
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45
Kudos to Brandon Morelli. He explained perfectly here, but links may die so I am just pasting the content below:
The spread syntax is simply three dots: ...
It allows an iterable to expand in places where 0+ arguments are expected.
Definitions are tough without context. Let's explore some different use cases to help understand what this means.
Example 1 — Inserting Arrays
Take a look at the code below. In this code, we don’t use the spread syntax:
var mid = [3, 4];
var arr = [1, 2, mid, 5, 6];
console.log(arr);
Above, we’ve created an array named mid. We then create a second array which contains our mid array. Finally, we log out the result. What do you expect arr to print? Click run above to see what happens. Here is the output:
[1, 2, [3, 4], 5, 6]
Is that the result you expected?
By inserting the mid array into the arr array, we’ve ended up with an array within an array. That’s fine if that was the goal. But what if you want only a single array with the values of 1 through 6? To accomplish this, we can use the spread syntax! Remember, the spread syntax allows the elements of our array to expand.
Let’s look at the code below. Everything is the same — except we’re now using the spread syntax to insert the mid array into the arr array:
var mid = [3, 4];
var arr = [1, 2, ...mid, 5, 6];
console.log(arr);
And when you hit the run button, here’s the result:
[1, 2, 3, 4, 5, 6]
Awesome!
Remember the spread syntax definition you just read above? Here’s where it comes into play. As you can see, when we create the arr array and use the spread operator on the mid array, instead of just being inserted, the mid array expands. This expansion means that each and every element in the mid array is inserted into the arr array. Instead of nested arrays, the result is a single array of numbers ranging from 1 to 6.
Example 2 — Math
JavaScript has a built-in math object that allows us to do some fun math calculations. In this example we’ll be looking at Math.max(). If you’re unfamiliar, Math.max() returns the largest of zero or more numbers. Here are a few examples:
Math.max();
// -Infinity
Math.max(1, 2, 3);
// 3
Math.max(100, 3, 4);
// 100
As you can see, if you want to find the maximum value of multiple numbers, Math.max() requires multiple parameters. You unfortunately can’t simply use a single array as input. Before the spread syntax, the easiest way to use Math.max() on an array is to use .apply().
var arr = [2, 4, 8, 6, 0];
function max(arr) {
return Math.max.apply(null, arr);
}
console.log(max(arr));
It works, it’s just really annoying.
Now take a look at how we do the same exact thing with the spread syntax:
var arr = [2, 4, 8, 6, 0];
var max = Math.max(...arr);
console.log(max);
Instead of having to create a function and utilize the apply method to return the result of Math.max() , we only need two lines of code! The spread syntax expands our array elements and inputs each element in our array individually into the Math.max() method!
Example 3 — Copy an Array
In JavaScript, you can’t just copy an array by setting a new variable equal to already existing array. Consider the following code example:
var arr = ['a', 'b', 'c'];
var arr2 = arr;
console.log(arr2);
When you press run, you’ll get the following output:
['a', 'b', 'c']
Now, at first glance, it looks like it worked — it looks like we’ve copied the values of arr into arr2. But that’s not what has happened. You see, when working with objects in JavaScript (arrays are a type of object) we assign by reference, not by value. This means that arr2 has been assigned to the same reference as arr. In other words, anything we do to arr2 will also affect the original arr array (and vice versa). Take a look below:
var arr = ['a', 'b', 'c'];
var arr2 = arr;
arr2.push('d');
console.log(arr);
Above, we’ve pushed a new element d into arr2. Yet, when we log out the value of arr, you’ll see that the d value was also added to that array:
['a', 'b', 'c', 'd']
No need to fear though! We can use the spread operator!
Consider the code below. It’s almost the same as above. Instead though, we’ve used the spread operator within a pair of square brackets:
var arr = ['a', 'b', 'c'];
var arr2 = [...arr];
console.log(arr2);
Hit run, and you’ll see the expected output:
['a', 'b', 'c']
Above, the array values in arr expanded to become individual elements which were then assigned to arr2. We can now change the arr2 array as much as we’d like with no consequences on the original arr array:
var arr = ['a', 'b', 'c'];
var arr2 = [...arr];
arr2.push('d');
console.log(arr);
Again, the reason this works is because the value of arr is expanded to fill the brackets of our arr2 array definition. Thus, we are setting arr2 to equal the individual values of arr instead of the reference to arr like we did in the first example.
Bonus Example — String to Array
As a fun final example, you can use the spread syntax to convert a string into an array. Simply use the spread syntax within a pair of square brackets:
var str = "hello";
var chars = [...str];
console.log(chars);
For someone who wants to understand this simple and fast:
First of all, this is not a syntax only to React. This is syntax from ES6 called spread syntax which iterate (merge, add, etc.) the array and object. Read more about it here.
So to answer the question:
Let's imagine you have this tag:
<UserTag name="Supun" age="66" gender="male" />
And you do this:
const user = {
"name": "Joe",
"age": "50"
"test": "test-val"
};
<UserTag name="Supun" gender="male" {...user} age="66" />
Then the tag will be equal to this:
<UserTag name="Joe" gender="male" test="test-val" age="66" />
So when you used the spread syntax in a React tag, it took the tag's attribute as object attributes which merge (replace if it exists) with the given object user. Also, you might have noticed one thing that it only replaces before attribute, not after attributes. So in this example, age remains as it is.
It's just defining props in a different way in JSX for you!
It's using ... array and object operator in ES6 (object one not fully supported yet), so basically if you already define your props, you can pass it to your element this way.
So in your case, the code should be something like this:
function yourA() {
const props = {name='Alireza', age='35'};
<Modal {...props} title='Modal heading' animation={false} />
}
so the props you defined, now separated and can be reused if necessary.
It's equal to:
function yourA() {
<Modal name='Alireza' age='35' title='Modal heading' animation={false} />
}
These are the quotes from React team about spread operator in JSX:
JSX Spread Attributes
If you know all the properties that you want to place on a component
ahead of time, it is easy to use JSX:
var component = <Component foo={x} bar={y} />;
Mutating Props is Bad If you don't know which properties you want to set, you might be tempted to add them onto the object later:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
This is an anti-pattern because it means that we can't help you check
the right propTypes until way later. This means that your propTypes
errors end up with a cryptic stack trace.
The props should be considered immutable. Mutating the props object
somewhere else could cause unexpected consequences so ideally it would
be a frozen object at this point.
Spread Attributes Now you can use a new feature of JSX called spread attributes:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
The properties of the object that you pass in are copied onto the
component's props.
You can use this multiple times or combine it with other attributes.
The specification order is important. Later attributes override
previous ones.
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
What's with the weird ... notation? The ... operator (or spread operator) is already supported for arrays in ES6. There is also
an ECMAScript proposal for Object Rest and Spread Properties. We're
taking advantage of these supported and developing standards in order
to provide a cleaner syntax in JSX.
For those who come from the Python world, JSX Spread Attributes are equivalent to
Unpacking Argument Lists (the Python **-operator).
I'm aware this is a JSX question, but working with analogies sometimes helps to get it faster.
Three dots ... represent spread operators or rest parameters.
It allows an array expression or string or anything which can be iterating to be expanded in places where zero or more arguments for function calls or elements for array are expected.
Merge two arrays
var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1 = [...arr1, ...arr2];
console.log(arr1); //[1, 2, 3, 4, 5, 6]
Copying array:
var arr = [1, 2, 3];
var arr2 = [...arr];
console.log(arr); //[1, 2, 3]
Note: Spread syntax effectively goes one level deep while copying an
array. Therefore, it may be unsuitable for copying multidimensional
arrays as the following example shows (it's the same with
Object.assign() and spread syntax).
Add values of one array to other at specific index e.g 3:
var arr1 = [4, 5]
var arr2 = [1, 2, 3, ...arr1, 6]
console.log(arr2); // [1, 2, 3, 4, 5, 6]
When calling a constructor with new:
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
console.log(d);
Spread in object literals:
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
console.log(clonedObj); // {foo: "bar", x: 42}
var mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // {foo: "baz", x: 42, y: 13}
Note that the foo property of obj1 has been overwritten by the obj2 foo property.
As a rest parameter syntax which allows us to represent an indefinite number of arguments as an array:
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3)); //6
console.log(sum(1, 2, 3, 4)); //10
Note: The spread syntax (other than in the case of spread properties) can be applied only to iterable objects:
So the following will throw an error:
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
Reference1
Reference2
The ...(spread operator) is used in React to:
provide a neat way to pass props from parent to child components. E.g., given these props in a parent component,
this.props = {
username: "danM",
email: "dan#mail.com"
}
they could be passed in the following manner to the child,
<ChildComponent {...this.props} />
which is similar to this
<ChildComponent username={this.props.username} email={this.props.email} />
but way cleaner.
The three dots (...) are called the spread operator, and this is conceptually similar to the ES6 array spread operator, JSX
taking advantage of these supported and developing standards in order to provide a cleaner syntax in JSX
Spread properties in object initializers copies own enumerable
properties from a provided object onto the newly created object.
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
References:
Spread Properties
JSX In Depth
It is common practice to pass props around in a React application. In doing this we able to apply state changes to the child component regardless of whether it is Pure or Impure (stateless or stateful). There are times when the best approach, when passing in props, is to pass in singular properties or an entire object of properties. With the support for arrays in ES6 we were given the "..." notation and with this we are now able to achieve passing an entire object to a child.
The typical process of passing props to a child is noted with this syntax:
var component = <Component foo={x} bar={y} />;
This is fine to use when the number of props is minimal but becomes unmanageable when the prop numbers get too much higher. A problem with this method occurs when you do not know the properties needed within a child component and the typical JavaScript method is to simple set those properties and bind to the object later. This causes issues with propType checking and cryptic stack trace errors that are not helpful and cause delays in debugging. The following is an example of this practice, and what not to do:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;
This same result can be achieved but with more appropriate success by doing this:
var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?
But does not use JSX spread or JSX so to loop this back into the equation we can now do something like this:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
The properties included in "...props" are foo: x, bar: y. This can be combined with other attributes to override the properties of "...props" using this syntax:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
In addition we can copy other property objects onto each other or combine them in this manner:
var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';
Or merge two different objects like this (this is not yet available in all react versions):
var ab = { ...a, ...b }; // merge(a, b)
Another way of explaining this, according to Facebook's react/docs site is:
If you already have "props" as an object, and you want to pass it in JSX, you can use "..." as a SPREAD operator to pass the whole props object. The following two examples are equivalent:
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
Spread attributes can be useful when you are building generic containers. However, they can also make your code messy by making it easy to pass a lot of irrelevant props to components that don't care about them. This syntax should be used sparingly.
It is called spreads syntax in JavaScript.
It use for destructuring an array or object in JavaScript.
Example:
const objA = { a: 1, b: 2, c: 3 }
const objB = { ...objA, d: 1 }
/* Result of objB will be { a: 1, b: 2, c: 3, d: 1 } */
console.log(objB)
const objC = { ....objA, a: 3 }
/* result of objC will be { a: 3, b: 2, c: 3, d: 1 } */
console.log(objC)
You can do it same result with Object.assign() function in JavaScript.
Reference: Spread syntax
The spread operator (triple operator) introduced in ECMAScript 6 (ES6). ECMAScript (ES6) is a wrapper of JavaScript.
The spread operator enumerable properties in props.
this.props =
{
firstName: 'Dan',
lastName: 'Abramov',
city: 'New York',
country: 'USA'
}
<Modal {...this.props} title='Modal heading' animation={false}>
{...this.props} = { firstName: 'Dan',
lastName: 'Abramov',
city: 'New York',
country: 'USA' }
But the main feature spread operator is used for a reference type.
For example,
let person= {
name: 'Alex',
age: 35
}
person1 = person;
person1.name = "Raheel";
console.log( person.name); // Output: Raheel
This is called a reference type. One object affects other objects, because they are shareable in memory. If you are getting a value independently means spread memory and both use the spread operator.
let person= {
name: 'Alex',
age: 35
}
person2 = {...person};
person2.name = "Shahzad";
console.log(person.name); // Output: Alex
... 3 dots represent the spread operator in JS.
Without a spread operator.
let a = ['one','one','two','two'];
let unq = [new Set(a)];
console.log(a);
console.log(unq);
Output:
(4) ['one', 'one', 'two', 'two']
[Set(2)]
With spread operator.
let a = ['one','one','two','two'];
let unq = [...new Set(a)];
console.log(a);
console.log(unq);
Output:
(4) ['one', 'one', 'two', 'two']
(2) ['one', 'two']
Spread operator! As most ppl have already answered the question elegantly, I wanted to suggest a quick list of ways to use the spread operator:
The ... spread operator is useful for many different routine tasks in JavaScript, including the following:
Copying an array
Concatenating or combining arrays
Using Math functions
Using an array as arguments
Adding an item to a list
Adding to state in React
Combining objects
Converting NodeList to an array
Check out the article for more details. How to use the Spread Operator. I recommend getting used to it. There are so many cool ways you can use spread operators.
Those 3 dots ... is not React terms. Those are JavaScript ES6 spread operators. Which helps to create a new array without disturbing the original one to perform a deep copy. This can be used for objects also.
const arr1 = [1, 2, 3, 4, 5]
const arr2 = arr1 // [1, 2, 3, 4, 5]
/*
This is an example of a shallow copy.
Where the value of arr1 is copied to arr2
But now if you apply any method to
arr2 will affect the arr1 also.
*/
/*
This is an example of a deep copy.
Here the values of arr1 get copied but they
both are disconnected. Meaning if you
apply any method to arr3 it will not
affect the arr1.
*/
const arr3 = [...arr1] // [1, 2, 3, 4, 5]
<Modal {...{ title: "modal heading", animation: false, ...props} />
Much cleaner.
Those are called spreads. Just as the name implies, it means it's putting whatever the value of it in those array or objects.
Such as:
let a = [1, 2, 3];
let b = [...a, 4, 5, 6];
console.log(b);
> [1, 2, 3, 4, 5, 6]
The spread syntax allows an data structures like array and object to destructure
them for either to extract a value from them or to add a value to them.
e.g
const obj={name:"ram",age:10} const {name}=obj
from above example we can say that we destructured the obj and extracted name from that object.
similarly,
const newObj={...obj,address:"Nepal"}
from this example we added a new property to that object.
This is similar in case of array too.
The Spread operator lets you expand an iterable like an object, string, or array into its elements while the Rest operator does the inverse by reducing a set of elements into one array.

Javascript what is "...array"? [duplicate]

Consider the following sample code
var x = ["a", "b", "c"];
var z = ["p", "q"];
var d = [...x, ...z];
var e = x.concat(z);
Here, the value of d and e are exactly same and is equal to ["a", "b", "c", "p", "q"], so,
What exactly is the difference between these two?
Which one is more efficient and why?
What exactly is the use of spread syntax?
In your example given, there is essentially no difference between the two
.concat is significantly more efficient: http://jsperf.com/spread-into-array-vs-concat because ... (spread) is merely syntax sugar on top of more fundamental underlying syntax that explicitly iterates over indexes to expand the array.
Spread allows sugared syntax on top of more clunky direct array manipulation
To expand on #3 above, your use of spread is a somewhat contrived example (albeit one that will likely appear in the wild frequently). Spread is useful when - for example - the entirety of an arguments list should be passed to .call in the function body.
function myFunc(){
otherFunc.call( myObj, ...args );
}
versus
function myFunc(){
otherFunc.call( myObj, args[0], args[1], args[2], args[3], args[4] );
}
This is another arbitrary example, but it's a little clearer why the spread operator will be nice to use in some otherwise verbose and clunky situations.
As #loganfsmyth points out:
Spread also works on arbitrary iterable objects which means it not only works on Arrays but also Map and Set among others.
This is a great point, and adds to the idea that - while not impossible to achieve in ES5 - the functionality introduced in the spread operator is one of the more useful items in the new syntax.
For the actual underlying syntax for the spread operator in this particular context (since ... can also be a "rest" parameter), see the specification. "more fundamental underlying syntax that explicitly iterates over indexes to expand the array" as I wrote above is enough to get the point across, but the actual definition uses GetValue and GetIterator for the variable that follows.
Taking the questions out of order, let's start with the fundamental question: What exactly is the use of spread syntax?
Spread syntax basically unpacks the elements of an iterable such as an array or object. Or, for the more detailed explanation from the MDN Web Docs on spread syntax:
Spread syntax allows an iterable such as an array expression or string
to be expanded in places where zero or more arguments (for function
calls) or elements (for array literals) are expected, or an object
expression to be expanded in places where zero or more key-value pairs
(for object literals) are expected.
Following are some simple examples of typical use cases for spread syntax and an example of the difference between spread syntax and rest parameters (they may look the same, but they perform nearly opposite functions).
Function call:
const multiArgs = (one, two) => {
console.log(one, two);
};
const args = [1, 2];
multiArgs(...args);
// 1 2
Array or string literal:
const arr1 = [2, 3];
const arr2 = [1, ...arr1, 4];
console.log(arr2);
// [1, 2, 3, 4]
const s = 'split';
console.log(...s);
// s p l i t
Object literal:
const obj1 = { 1: 'one' };
const obj2 = { 2: 'two' };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);
// { 1: 'one', 2: 'two' }
Rest parameter syntax is not the same as spread syntax:
Rest parameter syntax looks the same as spread syntax but actually represents an unknown number of function arguments as an array. So rather than "unpacking" the iterable, rest parameters actually package multiple arguments into an array.
const multiArgs = (...args) => {
console.log(args);
};
multiArgs('a', 'b', 'c');
// ['a', 'b', 'c']
Spread syntax performance / efficiency:
To address the question about efficiency compared to other methods, the only honest answer is that "it depends". Browsers change all the time and the context and data associated with a particular function create wildly different performance outcomes, so you can find all sorts of conflicting performance timings that suggest spread syntax is both amazingly faster and ridiculously slower than various array or object methods you might use to accomplish similar objectives. In the end, any situation where optimizations for speed are critical should be comparison tested rather than relying on generic timings of simplistic functions that ignore the specifics of your code and data.
Comparison to concat():
And finally a quick comment regarding the difference between spread syntax and concat() shown in the question code. The difference is that spread syntax can be used for a lot more than just concatenating arrays, but concat() works in older browsers like IE. In a situation where you are not concerned about compatibility with older browsers and micro optimizations for speed are unnecessary, then the choice between spread syntax and concat() is just a matter of what you find more readable: arr3 = arr1.concat(arr2) or arr3 = [...arr1, ...arr2].
The output of this example is the same, but it’s not the same behavior under the hood,
Consider ( check the browser's console ) :
var x = [], y = [];
x[1] = "a";
y[1] = "b";
var usingSpread = [...x, ...y];
var usingConcat = x.concat(y);
console.log(usingSpread); // [ undefined, "a", undefined, "b"]
console.log(usingConcat); // [ , "a", , "b"]
console.log(1 in usingSpread); // true
console.log(1 in usingConcat); // false
Array.prototype.concat will preserve the empty slots in the array while the Spread will replace them with undefined values.
Enter Symbol.iterator and Symbol.isConcatSpreadable :
The Spread Operator uses the ##iterator symbol to iterate through Arrays and Array-like Objects like :
Array.prototype
TypedArray.prototype
String.prototype
Map.prototype
Set.prototype
(that's why you can use for .. of on them )
We can override the default iterator symbol to see how the spread operator behaves :
var myIterable = ["a", "b", "c"];
var myIterable2 = ["d", "e", "f"];
myIterable[Symbol.iterator] = function*() {
yield 1;
yield 2;
yield 3;
};
console.log(myIterable[0], myIterable[1], myIterable[2]); // a b c
console.log([...myIterable]); // [1,2,3]
var result = [...myIterable, ...myIterable2];
console.log(result); // [1,2,3,"d","e","f"]
var result2 = myIterable.concat(myIterable2);
console.log(result2); // ["a", "b", "c", "d", "e", "f"]
On the other hand, ##isConcatSpreadable is
A Boolean valued property that if true indicates that an object should be flattened to its array elements by Array.prototype.concat.
If set to false, Array.concat will not flatten the array :
const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
let alphaNumeric = alpha.concat(numeric);
// console.log(alphaNumeric);
numeric[Symbol.isConcatSpreadable] = false;
alphaNumeric = alpha.concat(numeric);
// alphaNumeric = [...alpha, ...numeric];
// the above line will output : ["a","b","c",1,2,3]
console.log(JSON.stringify(alphaNumeric)); // ["a","b","c",[1,2,3]]
However, the spread behaves differently when it comes to Objects since they are not iterable
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
var objCopy = {...obj}; // copy
It copies own enumerable properties from a provided object onto a new object.
The spread operator is faster, check spread-into-array-vs-concat ( Since Chrome 67 at least )
And check how three dots changed javascript for some use cases, among them is the Destructuring assignment ( Array or Object ) :
const arr = [1, 2, 3, 4, 5, 6, 7];
const [first, , third, ...rest] = arr;
console.log({ first, third, rest });
and splitting a string to an array of characters :
console.log( [...'hello'] ) // [ "h", "e" , "l" , "l", "o" ]
There is no difference between these two in given example. For concatenation, we can use concat method over spread operator. However, use of spread operator is not limited to the concatenation of arrays.
The spread syntax allows an iterable such as an array expression or string to be expanded. It can be used in following scenarios.
Spread Operator with arrays
Concatenation of Arrays
String to Array
Array as Arguments to function.
Spread Operator with objects
Concatenation of Objects
To see how a demonstration of all these uses and to try your hands on code please follow below link (codepen.io)
ES6-Demonstration of Spread Operator
/**
* Example-1: Showing How Spread Operator can be used to concat two or more
arrays.
*/
const americas = ['South America', 'North America'];
const eurasia = ['Europe', 'Asia'];
const world = [...americas, ...eurasia];
/**
* Example-2: How Spread Operator can be used for string to array.
*/
const iLiveIn = 'Asia';
const iLiveIntoArray = [...iLiveIn];
/**
* Example-3: Using Spread Operator to pass arguments to function
*/
const numbers = [1,4,5];
const add = function(n1,n2,n3){
return n1 + n2 + n3;
};
const addition = add(numbers[0],numbers[1],numbers[2]);
const additionUsingSpread = add(...numbers);
/**
* Example-4: Spread Operator, can be used to concat the array
*/
const personalDetails = {
name: 'Ravi',
age: '28',
sex: 'male'
};
const professionalDetails = {
occupation: 'Software Engineer',
workExperience: '4 years'
};
const completeDetails = {...personalDetails, ...professionalDetails};
const colours = ['Blue','Red','Black']; // Simple array.
const my_colours = ['Blue','Red','Black','Yellow','Green'];
const favourite_colours = [...my_colours,'grey']; //[...] spread Operator access data in another array.
Spread syntax allows an iterable to be expanded in places where zero or more elements are expected. This high level explanation can be confusing, so a 'real-world' example of this is as follows:
Without the spread syntax you could update objects multiple times like so:
//If I needed to change the speed or damage at any time of a race car
const raceCar = {name: 'Ferrari 250 GT'};
const stats = {speed: 66, damage: 1, lap: 2};
raceCar['speed'] = stats.speed;
raceCar['damage'] = stats.damage;
Alternatively, a cleaner solution is to create a new object with the spread syntax:
//Creates a new object with priority from left to right
const lap1 = { ...raceCar, ...stats }
//Or a specific variable:
const enterPitStop = {...raceCar, speed: 0 }
In essence, rather than mutating the original object of raceCar, you will be creating a new immutable object.
It is also helpful when adding new values to arrays. With spread you can push/unshift multiple variables by copying the former array. Before spread, you would push like so:
var raceCars = ['Ferrari 250 GT', 'Le Mans Series', '24 Heures du Mans'];
//Sometimes, you will need to push multiple items to an array, which gets messy in large projects!
raceCars.push('Car 1');
raceCars.push('Car 2');
raceCars.push('Car 3');
Instead, you would copy the array and add it to a new variable or the same one for simplicity.
//Push values to array
raceCars = [...raceCars, 'Car 1', 'Car 2', 'Car 3'];
//This is dynamic! Add the values anywhere in the array:
//Adds the values at the front as opposed to the end
raceCars = ['Car 1', 'Car 2', 'Car 3', ...raceCars];
//Another dynamic examples of adding not in the front or back:
raceCars = ['Car 1', 'Car 2', ...raceCars, 'Car 3'];
I encourage you to view the more detailed documentation on the Mozilla Developer Website.
Context: You want to concatenate two arrays, in order to get a copy "by value" using the three dots spread syntax, but you are working with complex/nested arrays.
Finding: Take care that nested arrays are NOT passed by value, but by reference. In other words, only first level items are passed as a copy "by value". See the example:
sourceArray1 = [ 1, [2, 3] ] // Third element is a nested array
sourceArray2 = [ 4, 5 ]
targetArray = [ ...sourceArray1, ...sourceArray2]
console.log("Target array result:\n", JSON.stringify(targetArray), "\n\n") //it seems a copy, but...
console.log("Let's update the first source value:\n")
sourceArray1[0] = 10
console.log("Updated source array:\n", JSON.stringify(sourceArray1), "\n")
console.log("Target array is NOT updated, It keeps a copy by value: 1\n")
console.log(JSON.stringify(targetArray), "\n\n")
//But if you update a nested value, it has NOT been copied
console.log("Let's update a nested source value:\n")
sourceArray1[1][0] = 20
console.log("Updated source nested array:\n", JSON.stringify(sourceArray1), "\n")
console.log("Target array is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetArray)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level elements, but 'by reference' for nested/complex elements (This applies also for objects) so take care!\n")
Syntax
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
If you have any confusion then watch this video for more help Thanks.
https://youtu.be/U00S_b2Fv2E

Create object from an array of objects [duplicate]

In Python one can pass the dict1 constructor a sequence of key-value pairs:
>>> dict([['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']])
{'age': 42, 'name': 'Bob', 'breakfast': 'eggs'}
I can't think of any way to do this sort of thing in JavaScript other than defining my own function for the purpose:
function pairs_to_object(pairs) {
var ret = {};
pairs.forEach(function (p) { ret[p[0]] = p[1]; });
return ret;
}
But I'm a JS noob... Is there anything built-in for this sort pairs-to-object conversion?
1 For the purposes of this question, I'm treating Python dicts as Python's counterpart of JS objects, although, of course the similarity is limited only to the fact that they are both key-value collections.
Object.fromEntries does the job. It was added to the language with EcmaScript2019.
If you don't have support for that function, you could define it yourself with the following ES2015 code:
Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
A nice thing is that this method does the opposite of Object.entries (ES2017), so now you can go back and forth between the object and array representation:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const obj = Object.fromEntries(arr);
console.log(obj);
// ... and back:
const arr2 = Object.entries(obj);
console.log(arr2); // copy of the original array (omitting duplicate keys)
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6 Map
There is an alternative to plain objects for key/value pairs: Map.
Its constructor accepts the array-of-pairs format:
// Demo:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const mp = new Map(arr);
// Get one particular value:
console.log(mp.get('age'));
// Get all the keys:
console.log(...mp.keys());
// Get all the values:
console.log(...mp.values());
// Get all the key/value pairs:
console.log(...mp.entries());
If you really need a plain object, then this is not useful, but a Map might present a viable alternative.
You can use the reduce function
x = [[1,2],[3,4],[5,6]];
o = x.reduce(function(prev,curr){prev[curr[0]]=curr[1];return prev;},{})
o is now the equivalent of {1:2, 3:4, 5:6}
If your input array is sparse, you'll want to add a if(curr!=undefined) test on the assignment, but make sure you still return "prev".
If your tuples are something more complex than simple [key,value], you can simply change the way "prev" is assigned to. Eg: prev["key-"+curr[0].toString()]=curr[1]*2;
At the time of writing (2013) JavaScript objects / dictionaries / associative arrays don't have such a constructor natively.
As you said yourself, you can of course build your own function using for instance a functional approach using the reduce function as explained in one of the other answers. A classic for or newer forEach loop would also work, of course. But there isn't anything built-in.
Edit: It's 2019 and now we have Object.fromEntries, which will give you what you need.
Lodash's fromPairs function will do this:
const _ = require('lodash')
const kvPairs = [['a', 1], ['b', 2]]
_.fromPairs(kvPairs)
// => { a: 1, b: 2 }
Object.fromEntries()
There is a method on the Object object called Object.fromEntries(iterable). The iterator object from the iterable object has to produce an array with 2 elements. The first (index 0) array element will be the object key and the second the value.
MDN describes this very accurately:
The Object.fromEntries() method takes a list of key-value pairs and
returns a new object whose properties are given by those entries. The
iterable argument is expected to be an object that implements an
##iterator method, that returns an iterator object, that produces a
two element array-like object, whose first element is a value that
will be used as a property key, and whose second element is the value
to associate with that property key.
How to use:
You don't even need to know the specifics of an iterable object in order to use the Object.fromEntries() method. You can always use the method on the following objects:
2 Dimensional arrays where the inner/nested arrays have 2 elements
Maps
Here is an example:
// map example:
const map = new Map([ ['hi', 'there'], ['foo', 2] ]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // { hi: "there", foo: 2 }
// array example:
const array = [ ['0', '00'], ['1', '11'], ['2', '22'] ];
const objFromArray = Object.fromEntries(array);
console.log(objFromArray); // { 0: "00", 1: "11", 2: "22" }
Caveat, browser compatibility!
At the time of this writing (december 2019) this method is relatively new and not implemented by all browsers. In order to use this method and to ensure that you JS code will run in all browsers you might have to transpile your code to a earlier version of JS.
Javascript does not have a native function for converting an array into an object in the way you have described. But, this is because there is no need for it. You have already included in the question an example solution, where you define the function yourself, but that really isn't necessary. As long as you can be sure that the input array is correct, you could even do the conversion with a simple for loop, like so:
var input = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
var output = {};
for(i in input) output[input[i][0]] = input[i][1];
Which is just about the most basic code imaginable.
Of course, (as mamapitufo points out) it is generally a bad idea to actually use for..in to iterate over an array, because that will also return non-indexes as values of i. Still, the point is that this kind of operation is too simple, and too rarely needed, to justify having a native function.
The python dict is a structure which is not needed in javascript, because the two languages have different approaches to typing, and to design in general, and so what is useful to one is not useful to another. While you could work on using the same methods and structures that you used in python, it might be a better idea to think about how to take advantage of javascript's different way of doing things - maybe you will find that you don't need a dict after all.
const sampleArr = ['foo', 'bar', 'baz', 42];
const _chunk = (arr, chunkSize, chunks = []) => {
while (arr.length) {
chunks = [...chunks, arr.splice(0, chunkSize)];
}
return chunks;
}; //splice array to chunks
const arr = _chunk(sampleArr, 2);
const entries = new Map([...arr]);
const obj = Object.fromEntries(entries);
console.log(obj)
// expected output: Object { foo: "bar", baz: 42 }

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.
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:
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):
Think of the code as being
const words = {0:'oops', 1:'gasp', 2:'shout', 3:'sun', length:4};
let { length } = words;
console.log(length);
Which it essentially is (nevermind all the other stuff arrays come with)
Does it make sense now?
If you add a property inside the { and } that belongs to the Array, it's value is copied.
Here we check for the property constructor. Will log constructor function to console.
IF you add a property not belongs to an array, will return undefined
Another Example
const words = ['oops', 'gasp', 'shout', 'sun'];
let { constructor } = words;
console.log(constructor);
We are testing for something will return undefined
const words = ['oops', 'gasp', 'shout', 'sun'];
let { something } = words;
console.log(something);

What is the use case for Javascript's (ES6) Array.of()?

I came across the new Array.of() method that's been finalized in ES6, and I was wondering when one might use:
var a = Array.of('foo', 'bar');
over:
var b = ['foo', 'bar'],
c = new Array('foo', 'bar');
instantiating an Array with a number creates an array with that many slots.
new Array(2);
> [undefined x 2]
instantiating using Array.of creates an array with those elements.
Array.of(2)
> [2]
The point of Array.of is to solve the issue where you want to pass a type around that gets constructed later, which in the special case of array is problematic when it receives a single argument. For instance:
function build(myItem, arg){
return new myItem(arg);
}
Which would give:
console.log(build(Array, 2));
> [undefined x 2]
// ??? Can't pass the literal definition:
//console.log(build([, 1))
console.log(build(Array.of, 2));
> [2]
Or to use even more of ES6 as an example:
var params = [2,3];
console.log(new Array(...params));
// [2,3]
console.log(new Array.of(...params));
// [2,3]
params = [2];
console.log(new Array(...params));
// [undefined x2]
console.log(new Array.of(...params));
// [2]
Array.of consistently does what you expect.
I googled it for you, and the first result had a great example:
Array.of(...items)
If you want to turn several values into an array, you should always
use an array literal, especially since the array constructor doesn’t
work properly if there is a single value that is a number (more information on this quirk):
new Array(3, 11, 8)
// => [ 3, 11, 8 ]
new Array(3)
// => [ , , ,]
new Array(3.1)
// => RangeError: Invalid array length
But how are you supposed to turn values into an instance of a
sub-constructor of Array then? This is where Array.of() helps
(remember that sub-constructors of Array inherit all of Array’s
methods, including of()).
class MyArray extends Array {
...
}
console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true
console.log(MyArray.of(3).length === 1); // true
It's also worth noting that Array.of() also preserves Array's API compatibility with TypedArray. With TypedArray (Int32Array, UInt32Array, etc.), of() is very useful. From MDN:
Uint8Array.of(1); // Uint8Array [ 1 ]
Int8Array.of("1", "2", "3"); // Int8Array [ 1, 2, 3 ]
Float32Array.of(1, 2, 3); // Float32Array [ 1, 2, 3 ]
Int16Array.of(undefined); // IntArray [ 0 ]
It basically fixes the Array constructor, which has a special case when you pass it a single number.
From the original proposal:
Array.of provides a constructor that, unlike Array, does not have
the special case for new Array(42), which presets length (and
hints to implementations to preallocate) but leaves holes in [0, length).
The use-case is when you can't write a literal, because you are passing a function-that-constructs as a funarg, and the eventual
caller may pass only one number arg, or several args.
It also does help with subclassing, where it can be used as the "literal form" for instances of your array subclass.
Array.of([elem1], [elem2], ...)
returns elem1, elem2, etc. in an array.
equivalent to :
Array.of = function() {
return [].slice.call( arguments );
};
example:
Array.of("red", "green", "blue")
[ 'red', 'green', 'blue' ]
When you need a constructor function (e.g. to pass it to another function) for arrays, this method is useful. That method lets you avoid a potential pitfall of the Array constructor function: If it has several arguments, it behaves like an array literal. If it has a single argument, it creates an empty array of the given length.
new Array(3, 4, 5)
[ 3, 4, 5 ]
new Array(3)
[]
Here is a link to six new array methods added in ECMAScript for futher refernce.

Categories

Resources