Yes. You can use "defaults" in destructuring as well:
(function test({a = "foo", b = "bar"} = {}) {
console.log(a + " " + b);
})();
This is not restricted to function parameters, but works in every destructuring expression.
Answer from Bergi on Stack Overflowjavascript - ES6 Object Destructuring Default Parameters - Stack Overflow
Workaround for missing ES6 feature: default values for function parameters (combined with object destructuring)
ecmascript 6 - Javascript Object destructuring and default parameters combined - Stack Overflow
javascript - ES6 destructuring object assignment function parameter default value - Stack Overflow
That syntax indeed uses Object Destructuring in order to extract default values from the parameter object. There are some examples in the Mozilla documentation that helps us understand the trick, check this out:
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
A possible disadvantage of your example is that the createUser method ignores all other values of the parameter object and always returns an object that contains only age and name. If you want to make this more flexible, we could use Object.assign() like this:
const createUser = (o) => Object.assign({ age: 1, name: 'Anonymous' }, o);
In this case, the user created will be an object that merges the parameter object with the default values. Note now that the default values are in the method body. With this method we can create users that contain other properties, example:
const superman = createUser({ name: 'Superman', type: 'superhero' });
console.log(superman);
// output: {age: 1, name: "Superman", type: "Superhero"}
Your code is using both Object Destructuring and default function props.
const createUser = ({
age = 1,
name = 'Anonymous',
}) => ({
age,
name,
});
Here function createUser is accepting single argument of type Object. Function is returing same object, if you have both object properties defined in your argument, then it will return your passed object. Otherwise it will replace it with default values, which are 1 and Anonymous respectively.
You can further read about it here:
https://wesbos.com/destructuring-renaming/
https://wesbos.com/destructuring-default-values/
If you use it, and call the function with no parameters, it works:
function drawES6Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
console.log(size, cords, radius);
// do some chart drawing
}
drawES6Chart();
Run code snippetEdit code snippet Hide Results Copy to answer Expand
if not, an error is thrown:
TypeError: can't convert undefined to object
function drawES6Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25}) {
console.log(size, cords, radius);
// do some chart drawing
}
drawES6Chart();
Run code snippetEdit code snippet Hide Results Copy to answer Expand
The destructuring with defaults only does its thing when you pass an object which doesn't have the respective properties. The = {} default for the whole parameter allows to not pass an (empty) object at all.
It makes drawES6Chart() equivalent to drawES6Chart({}).
I'm trying to understand this pattern
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters#destructured_parameter_with_default_value_assignment
function preFilledArray([x = 1, y = 2] = []) {
return x + y;
}
preFilledArray(); // 3
preFilledArray([]); // 3
preFilledArray([2]); // 4
preFilledArray([2, 3]); // 5I'm not sure if its possible to be understood logically based on development principles, or if its something you must learn by heart
I've been asking AI, looking in the docs and reviewing some example, but the more I read the less I understand this, I can't grasp a pinch of logic.
From what I read, theoretically this structure follows two sections:
-
Destructuring with default:
[x = 1, y = 2] = arr -
Parameter defaults
function fn(param = defaultValue
Theoretically param equals arr. So [] is the defaultValue But the reality is that [x = 1, y = 2] is both the defaultValue and the param
So I'm trying to grasp why is not somthing like:
function preFilledArray([x = 1, y = 2] = arr)
Or simply something like:
function preFilledArray([x = 1, y = 2])
I have a hunch that I will probably need to end learning this by heart, but I have a hope someone will give me a different perspective I haven't been looking at.
=== Conclusion
Thanks everyone for the ideas. I think I've got to a conclusion to simplify this in my mind. I'm copy/pasting from a comment below:
The idea follows this kind of weird structure:
fn ([ x=a, y=b, ... , n=i ] = [])
-
If the function receives undefined, default it to empty array
-
If the first parameter of the array is undefined, then default it to the first default value
-
If the n parameter of the array is undefined, then default it to the n default value.
Arguments vs. Parameters
For this question, it's important to distinguish between arguments and parameters. Arguments are what is passed to the function when it's invoked, without consideration for how the function destructures or sets defaults to those values. So when you call getConfig() with no arguments, and log arguments.length, it should be 0, regardless of how getConfig destructures or sets defaults.
Parameters on the other hand are the variables in the function definition, that it uses. They can be assigned defaults or they can be derived from a destructured argument.
It's a little unclear what you're looking for, whether it's an object that reflects the parameters that the function uses or whether it's an object that reflects the values passed to the function (including destructured undefined variables). I'll go over both cases.
Parameters
To reconstitute the parameters, a rather clunky way is to use the destructured variables into a new object:
import {defaultOptions} from "../defaults.js"
export function getConfig({
width = defaultOptions.width,
height = defaultOptions.height,
fontsize = defaultOptions.fontsize
} = {}) {
// just assign them to parameters
var parameters = { width, height, fontsize };
console.log(parameters);
}
Alternatively, if defaultOptions represents all of and only the parameters passed to the function (i.e. it only has width, height, fontsize), you can assign them with spread syntax:
import {defaultOptions} from "../defaults.js"
export function getConfig(options = {}) {
var calculatedParameters = { ...defaultOptions, ...options };
var { width, height, fontsize } = calculatedParameters;
console.log(calculatedParameters);
}
Values passed to the function (including destructured undefined variables)
To reconstitute the values passed, you can destructure the argument and then assign it again to a variable. This variable is nearly identical to the argument itself. In the below example calculatedArguments is almost identical to options, except now it will have properties for width, height, and fontsize, even if they represent undefined values:
import {defaultOptions} from "../defaults.js"
export function getConfig(options = {}) {
var { width, height, fontsize } = options;
var calculatedArguments = { width, height, fontsize };
console.log(calculatedArguments);
// can also assign width, height, fontsize with default values
({
width = defaultOptions.width,
height = defaultOptions.height,
fontsize = defaultOptions.fontSize
} = options);
}
let defaults = {
width: 300,
height: 500,
symbsize: 25,
margin: {
top: 10,
bottom: 10
}
}
class Config {
constructor({
width = defaults.width,
height = defaults.height,
symbsize = defaults.symbsize,
margin = defaults.margin
} = defaults) {
this.width = width
this.height = height
this.symbsize = symbsize
this.margin = margin
}
getConfig() {
return {
width: this.width,
height: this.height,
symbsize: this.symbsize,
margin: this.margin
}
}
}
const config = new Config({height: 1})
console.log(config.getConfig());
using class should do the work, or i prefer using it