14

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?

3
  • 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_Options Commented 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. Commented 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. Commented Nov 12, 2012 at 23:04

4 Answers 4

9

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
Sign up to request clarification or add additional context in comments.

1 Comment

This definitely seems like the cleanest solution for my question. This is exactly what I was looking for.
4

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

Noticed ;) One point though, I think it's appropriate to point out that this will make a shallow copy only. But that might actually be wanted.
This is a great answer to my initial question. If you care to edit it to account for differing default values, I would greatly appreciate it.
@sprawl .. What do you mean by different default values ??
This function does absolutely not work. It enumerates the given params argument, but when you omit a or b there null won't be used a default value, too.
@Sushanth-- Where you are settings it to null, what if you wanted to set it to a different value based off of an object of default values? For instance, you wanted this.a to be equal to, say, 10 if nothing is input, and you wanted this.b to be equal to 7, or something along those lines.
|
1

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

0

Extending answer by Bergi: var params = $.extend({}, defaults, custom);

We can now use Object.assign({}, defaults, custom) in ES6 without any library.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.