In Douglas Crockford's book "Javascript: The Good Parts", he mentions Object Specifiers in passing values to a new object. Essentially, instead of passing parameters to a function in a certain order, he suggests passing an object with the parameters contained within, like so:
var myObject = someFunction({a: 1, b: 2, c: 3});
What isn't explained, however, is how to handle those parameters after they've been passed through. Instead of doing the following to set up default values:
function someFunction(params){
this.a = params.a || 0;
this.b = params.b || 0;
...
}
What's another way to handle a large amount of parameters without being as verbose?
EDIT: Looking at the answers below, the use of the for-in loop is a great option. What's another way to do it while setting different default values for each property? Is there a way to create an object with various default values and compare against that?
-
You could have a "standards"-object that you compare the input against in some sort of loop. The way jQuery-plugins usually handle this (this is using jQuery though) might be interesting as well: docs.jquery.com/Plugins/Authoring#Defaults_and_Optionsm90– m902012年11月12日 09:41:09 +00:00Commented Nov 12, 2012 at 9:41
-
Note that doing the parameters one by one lets you specify default values individually (the defaults object that m90 suggested also allows this), or otherwise take special action if certain parameters aren't supplied.nnnnnn– nnnnnn2012年11月12日 09:55:25 +00:00Commented Nov 12, 2012 at 9:55
-
m90 & nnnnnn: I've updated my question to account for differing default values if you care to illustrate an answer.opes– opes2012年11月12日 23:04:51 +00:00Commented Nov 12, 2012 at 23:04
4 Answers 4
Usually it is done using a defaults object, from which you copy properties if they are not existing in the params. That object might be private or available to the public for configuration.
var defaults = { a:null, b:1, ...};
function someFunction(params) {
for (var prop in defaults)
if (prop in params)
this[prop] = params[prop];
else
this[prop] = defaults[prop];
}
or
function someFunction(custom) {
var params = { a:null, b:1, ...};
for (var prop in custom)
params[prop] = custom[prop];
// now use params
}
Sometimes also the custom/params objects which is passed into the function is extended itself, but then in the docs it should be mentioned explicitly that the object can get modified:
var defaults = { a:null, b:1, ...};
function someFunction(params) {
// modifies params object!
for (var prop in defaults)
if (! (prop in params))
params[prop] = defaults[prop];
// now use params
}
If you are using a library with an extend function, you often can shorten this initialisation to
var params = $.extend({}, defaults, custom);
// create an empty object, copy the defaults, and overwrite with custom properties
1 Comment
How about using a for-in loop
function someFunction(params){
for(var key in params){
if( params.hasOwnProperty(key){
var def = null;
if(key == 'a' || key == 'b'){
def = 10;
}
if(key == 'c' || key == 'd'){
def = undefined;
}
this[key] = params[key] || def ;
}
}
}
6 Comments
params argument, but when you omit a or b there null won't be used a default value, too.Loop through the fields in the object passed as the parameter, creating each field as a field on the this object.
function someFunction(params){
for(x in params){
this[x] = params[x];
}
}
Working Example: http://jsfiddle.net/59kzD/
Comments
Extending answer by Bergi:
var params = $.extend({}, defaults, custom);
We can now use Object.assign({}, defaults, custom) in ES6 without any library.