Reputation: 786
I need a function that its parameter is an object, and if I leave it empty it will load default values.
something like:
function loadMap(args) { //args is an object and its optional
//this is what I want to do, test args and load defauts if necesary
/*
pseudocode:
if args.latitude is not set then
give it a default value
if args.longitude is not set then
give it a default value
end pseudocode */
alert("Latitude is "+args.latitude );
alert("Longitude is "+args.longitude );
}
//outputs the default values
loadMap();
//outputs custom values
loadMap({latitude: "x.xxxx", longitude: "-x.xxxx"});
//and should work too and output one default and one custom value
loadMap({latitude: "x.xxxx"});
I found this solution in this question (Is there a better way to do optional function parameters in Javascript?) but it requires jQuery: http://jsfiddle.net/xy84kwdv/
It's ALMOST what I want but I don't want to depend on a jquery function.
Upvotes: 11
Views: 24137
Reputation: 31
Ran into this problem because I wanted a default configuration object with many properties. So, destructuring in the function argument was out of the question.
Spread syntax does have some caveats. But it's unlikely complex objects that cause issues are going to be passed as optional arguments.
let defaultArgs = { lat: 'x.xxxx', lng: 'x.xxxx' };
function loadMap(args) {
let { lat,lng } = { ...defaultArgs, ...args };
console.log(`Lat: ${lat} Lng: ${lng}`)
}
loadMap();
loadMap({ lat: 1.2345 });
loadMap({ lat: 1.2345, lng: 1.2345 });
Console Logs:
Lat: x.xxxx Lng: x.xxxx
Lat: 1.2345 Lng: x.xxxx
Lat: 1.2345 Lng: 1.2345
Upvotes: 1
Reputation: 1434
Uses "??" instead of "||" or you may have errors in undefined or false variables
function loadMap(args) {
args = args ?? {};
args.latitude = args.latitude ?? "X.XXX";
args.longitude = args.longitude ?? "Y.YYY";
alert(args.latitude);
alert(args.longitude);
};
loadMap({latitude:"custom_latitude"});
Upvotes: 1
Reputation: 41
Fisher's answer should be the accepted answer. Also, if you want to rename any of the destructured variables while still maintaining default values, you can do like so:
function findByCoordinates({coordinates: cords = {x: 0, y: 0}} = {}) {
console.log(cords);
// Some calculation...
}
Upvotes: 0
Reputation: 379
Surely this question is over 3 years old now(2018-03-02). I searched about this topic but most of the questions I got and the answers ranked top are seemed like to be outdated, like this, this, this, or this.
Currently, lots of browsers support ES6/ECMAScript 2015(the 6th Edition of ECMAScript). For compatibility, you can use WebpackJs(or another packer) and BabelJs(or another compiler) to compile and pack your ES6 codes to ES5. And the ES6-version answer for this question may be Object Destructuring.
function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
console.log(size, cords, radius);
// do some chart drawing
}
drawES2015Chart({cords: {x: 18, y: 30}, radius: 30});
function fn(requiredArg, {optionalArg = 'Default Value', a = 1, b ={some: 'object'}} = {}){
// Do with destructured values: requiredArg, optionalArg, a, and b.
console.log(requiredArg, optionalArg, a, b);
}
so for your question, it will be:
function loadMap({latitude = "x.xxxx", longitude = "-x.xxxx"} = {}) {
console.log('latitude is:', latitude, 'and longitude is:', longitude);
console.log(`latitude is: ${latitude}, and longitude is: ${longitude}`);
}
// Call the function.
loadMap({latitude: "1.2345", longitude: "-6.7890"});
Upvotes: 35
Reputation: 66324
Overkill, introduce full blown Object cloning (ECMAScript 5.1)
function cloneOwnProperties(A, B, overwrite) { // this is shallow
var i, p;
if (!(A instanceof Object)) {
if (undefined === A) A = {};
else throw new TypeError('cloneOwnProperties called on non-object');
}
if (!B) B = {};
p = Object.getOwnPropertyNames(A);
for (i = 0; i < p.length; ++i)
if (overwrite || !(p[i] in B))
Object.defineProperty(B, p[i], Object.getOwnPropertyDescriptor(A, p[i]));
return B;
}
// and for completeness
function cloneObject(obj_in, clone_seal, clone_frozen) {
var obj_out;
if (!(obj_in instanceof Object))
throw new TypeError('cloneObject called on non-object');
obj_out = Object.create(Object.getPrototypeOf(obj_in));
cloneOwnProperties(obj_in, obj_out, true);
if (clone_seal && Object.isSealed(obj_in)) Object.seal(obj_out);
if (clone_frozen && Object.isFrozen(obj_in)) Object.freeze(obj_out);
return obj_out;
}
// back on topic
Now you can use it to set some defaults
function foo(bar) {
bar = cloneOwnProperties(bar, {
fizz: true,
buzz: false
}, true);
return bar;
}
foo({buzz: 'user_value'}); // {fizz: true, buzz: "user_value"}
Upvotes: -1
Reputation: 780889
This makes the argument object optional, as well as making individual properties optional:
var defaults = { latitude: x, longitude: y };
function loadMap(args) {
args = args || {};
for (var key in defaults) {
if (!(key in args)) {
args[key] = default[key];
}
}
...
}
Upvotes: 4
Reputation:
How to overload functions in javascript? Check out the second answer to the OP. It offers an alternative to using jQ.
Note: Kim's code will result in a logical error if args passes but evaluates to true. A better fix: optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
Upvotes: 0
Reputation: 18869
Are you looking for something like:
function loadMap(args) {
args = args || {};
args.latitude = args.latitude || "X.XXX";
args.longitude = args.longitude || "Y.YYY";
alert(args.latitude);
alert(args.longitude);
};
loadMap({latitude:"custom_latitude"});
Upvotes: 9