Default value for object argument - javascript

I want to create a function with an object as parameter
The object can have for exemple three keys : x, y, z
All this keys must have default value assignment
I tried this :
function f({x:x, y:y, z: z} = {x:1,y:2,z:3}) {
return x + y + z;
}
But I have a problem
f() // return 6 => OK!
f({x: 2, y: 3, z: 4}) // return 9 => OK!
f({x: 2, y:3}) // return NaN (because z === undefined), I expect 8
How can I do this?

You can assign individual defaults when destructuring objects:
function f({ x = 1, y = 2, z = 3 } = {}) {
return x + y + z
}
console.log(f())
console.log(f({ x: 2, y: 3, z: 4 }))
console.log(f({ x: 2, y:3 }))
See the docs here, which describes array destructuring, but the same applies to objects.

What does destructuring mean? It’s a JavaScript expression that allows us to extract data from arrays, objects, maps and sets into their own variable. It allows us to extract properties from an object or items from an array, multiple at a time.
Short form: The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
Please have a look at this simple code example:
function yourFunction({
x = 1,
y = 2,
z = 3
} = {}) {
return x + y + z
}
out.innerHTML+="<br>" + yourFunction()
out.innerHTML+="<br>" + yourFunction({ x: 3, y: 3, z: 4 })
out.innerHTML+="<br>" + yourFunction({ x: 7, y: 1})
<p id="out">Results: </p>
Have a look at the docs: click

Related

Is is possible to select the value of a object in a array regardless of the object name? (reduce-method) (beginner) [duplicate]

This question already has answers here:
Get the value of an object with an unknown single key in JS
(2 answers)
Closed 1 year ago.
i am experimenting with the the reduce-method in javascript and was curious if its possible to write a more universal code?
function total(arr1) {
return arr1.reduce(function cb(sum, n) {return sum + n.x;}, 0);
};
console.log(total([{x: 1}, {x: 2}, {x: 3}]));
Output: 6
If if change one x to y:
function total(arr1) {
return arr1.reduce(function cb(sum, n) {return sum + n.x;}, 0);
};
console.log(total([{x: 1}, {y: 2}, {x: 3}]));
Output: NaN
My first question would be why? Why its not sum up the values of all object named x. So the Output should be: 4
My second and more important question: It is possible to write my function this way, that it will sum up the value of all objects in the array regardless of the Objectname? So that in my second function the Output will be always six, regardsless if input [{x: 1}, {y: 2}, {z: 3}]. Because its "annoying" that i have to "know" all the names of the object to sum it up, before i write the function and cant use it for any kind of array with this structure....
"Output: NaN My first question would be why?" Because 1 + undefined + 3 is NaN:
console.log(1 + undefined + 3)
You can return the first value of each object:
function total(arr1) {
return arr1.reduce((sum, n) => sum + Object.values(n)[0], 0);
};
console.log(total([{x: 1}, {y: 2}, {x: 3}]));
If an object can have multiple properties and you want the sum of all of them you can sum up all values:
function total(arr1) {
return arr1.reduce((sum, n) => sum + Object.values(n).reduce((sum, n) => sum + n), 0);
};
console.log(total([{x: 1}, {x: 5, y: 2}, {x: 3}]));

ES6 Destructing for objects

I am new to ES6 destructing. I have an object which contains another object. I want to store certain values from the nested object.
For example -
z = {g: 1, h: 2, i: {d1:5, d2:6, d3:7}}
When I do
let { g, i : {d1, d3}, ...less } = z
the less variable only stores h and not d2.
Is there a way to make it so it is
less = {h, i : {d2}}
No there is not. What you could do is
let { g, i: { d1, d3, ...less2 }, ...less } = z
let less = { ...less, i: less2 };
This extracts the remainder and merges them back together while preserving the shape.
No, unfortunately this is not possible.
You can however extract the missing values from i with a second rest spread:
let z = {g: 1, h: 2, i: {d1:5, d2:6, d3:7}};
let { g, i : {d1, d3, ...i_less}, ...rest_less } = z;
let less = { i: i_less, ...rest_less };
console.log(less)
This is my way, hope it could help.
let z = {
g: 1,
h: 2,
i: {
d1:5,
d2:6,
d3:7
}
}
let {g, i: {d1, d3, ...less1}, ...less2} = z
let less = {
i: less1,
...less2,
}
console.log(less); // output: {h: 2, i:{d2:6}}

Explanation of what is actually happening in ES6 Rest paramter

Please explain the following example.I am not able to understand what is actually happening here.Thank you in advance
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
Rest takes the 'rest' of the arguments and puts in them in an array which is assigned to a.
Your return statement turns into (1+2) * 3, which equals 9.
A simpler example:
[x, y, ...a] = [1, 2, 3, 4, 5, 6]
console.log(x)
// 1
console.log(y)
// 2
console.log(a)
// [ 3, 4, 5, 6 ]
If you think of arguments being passed as a simple array, then the following
function f(a,b,...c){...}
Can be converted to:
function f(args){
var a = args[0],
b = args[1],
c = args.slice(2);
//...
}
//function is getting defined here.
function f (x, y, ...a) {
return (x + y) * a.length
}
//function is getting called here.
f(1, 2, "hello", true, 7) === 9
When your function f is called, Inside the function f, your code takes x as 1, y as 2, and a as an array containing ["hello", true, 7]. So, array a has length 3.
Your result of the function is (1 + 2) * 3, which is 9.
So, your comparison of function result to 9, is true.

create object from variables with keys as same as variables names with ES6/7 [duplicate]

This question already has answers here:
One-liner to take some properties from object in ES 6
(12 answers)
Closed 7 years ago.
I want to create an object from multiple variables but i don't want to list these variables one by one:
let [x, y, z] = [1, 2, 3];
let obj = ??? // something shorter than {x: x, y: y, z: z};
obj.x === 1; // i want true here
obj.y === 2; // i want true here
obj.z === 3; // i want true here
Furthermore, i want to cut special values from one object and put them into another one with the same keys:
let obj1 = {
subobj1: {
x: 1,
y: 2,
z: 3
}
};
let obj2 = ??? // something shorter than {x: obj1.subobj1.x, y: obj1.subobj1.y,};
obj2.x === 1; // i want true here
obj2.y === 2; // i want true here
typeof obj2.z === "undefined"; // i want true here
How can i do these things with ES6/7?
For the first one, you can use this
let [x, y, z] = [1, 2, 3];
let obj = { x, y, z };
I don't think there is a shorter way to do the second assignment.

two javascript syntax problem

These days I am reading some javascript source codes,however I found some syntax that I can not understand.
1)the for-in loop
var c;
var obj={name:'test',age:33};
for(var e in c={},obj){
console.info(e+' = '+obj[e]);
}
2)The Conditional Operator (?:)
Generally,we use this operator this manner:
x > 0 ? x*y : -x*y
But I have seen some codes like this:
x > 0 ? (x*y,z=bar,..other expressoin) : (-x*y)
But it does not work if I change the comma to colon,it will throw a error.
In both cases, the comma operator [MDN] is used:
You can use the comma operator when you want to include multiple expressions in a location that requires a single expression. The most common usage of this operator is to supply multiple parameters in a for loop.
And the specification:
11.14 Comma Operator ( , )
Syntax
Expression :
AssignmentExpression
Expression , AssignmentExpression
(...)
Semantics
The production Expression : Expression , AssignmentExpression is evaluated as follows:
Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).
That just means that the result of the last expression is returned as result of the whole "list" of expressions.
In the examples you gave, it is used for its side effects [Wikipedia], namely evaluating every expression.
In general I'd say that this is not such a good style and, as you noticed, more difficult to understand.
for(var e in c={},obj)
is the same as
c = {};
for(var e in obj)
an does not seem to add any value. Even better would have been to just initialize c in the first line: var c = {};.
In case of the conditional operator: If x > 0 is true, then all the expressions are evaluated and the result of the last expression is returned. In this case, using a normal if statement would be better (easier to understand).
Here again, the comma operator and maybe even the conditional operator seems to be used solely because of their side effects: Normally the conditional operator is supposed to only return a value but not to execute arbitrary expressions (a single function call which returns a value might be an exception).
As the MDN documentation says, it is more commonly used in a for loop to initialize multiple variables:
for(var i = 0, l = array.length; i < l; i++)
In Javascript you can define variables like:
var obj1 = { a: 2, b: 4, c: 6};
var obj2 = { x: 1, y: 3, z: 5};
Or, you can comma-separate the declarations, like this:
var obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};
Now, a for in loop is normally something like:
for(var key in obj1) { console.log(key); }
But, if you comma-chain the part after 'in' it will allow it (just like when assigning), but will run the loop on the last object in the chain.
var key, obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};
// will output 'a', 'b' and 'c'
for(key in obj2, obj1) { console.log(key); }
// will output 'x', 'y' and 'z'
for(key in obj1, obj2) { console.log(key); }
This means you can assign values within the for in, and then do looping on another object.
var key, obj3; // obj3 === null
var obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};
// will output 'a', 'b' and 'c'
for(key in obj3 = { j: 9, k: 8, l: 7 }, obj1) { console.log(key); }
// obj 3 is now { j: 9, k: 8, l: 7 }
Okay, so now for the ternary operators. If the above makes sense, so should this.
Ternary operations are like if statements with a single line. You can't put semicolons in a line because then it becomes two or more lines. But putting () around comma-separated declarations then it is still considered one line.
So this is valid:
x > 0 ? a = 1 : a = 2;
And this is valid:
x > 0 ? (a = 1, b = 2) : (a = 2, b = 1);
But this is not, because the commas throw off the interpretation of the ternary:
x > 0 ? a = 1, b = 2 : a = 2, b = 1;
But I would not recommend setting values in a ternary, unless it looks something like:
a = x > 0 ? 1 : 2;
:)
The first? no idea. The second? It's just like your typical inline if except it executes multiple expressions rather than one
x > 0 ? (doThis(),doThat(),x=2) : (again(),another(),y=5);
Isn't the first one just an initializer?
var c;
var obj={name:'test',age:33};
for(var e in c=[], obj){
console.info(e + ' = ' + obj[e]);
c.push(e);
}
console.info(c);
Now, why you'd do it that way... I'm not sure.

Categories