views:

35

answers:

3

What is the best way to go about creating javascript classes so that objects can be created by passing in object literals, and at the same time maintaining defaults set in the class.

var brett = new Person({
    name: 'Brett'
    ,age: 21
    //gender: 'male' //The default is female, so brett.gender will be female
});
+3  A: 

Possibly by defining your constructor function like so:

function Person(props) {
    this.name = props.name;
    this.age = props.age;
    this.gender = props.gender || 'female';
}

... although if you ever wanted to pass a false-ish gender (e.g. '', 0, false, null or undefined) the default value will still be used. If that's a problem, you could do something like:

function Person(props) {
    // expected properties
    this.name = props.name;
    this.age = props.age;

    // optional properties
    var defaults = {
        gender: 'female'
        // etc
    };
    for (var k in defaults) {
        this[k] = props.hasOwnProperty(k) ? props[k] : defaults[k];
    }
}
harto
+1  A: 

You can do a shallow clone:

function shallow_clone(target, source) {
    for (var i in source) {
        if (typeof target[i] == "undefined") {
            target[i] = source[i];
        }
     }
};

And then:

function Person(opts) {
    var defaults = { gender: 'male' }; 

    shallow_clone(this, opts);
    shallow_clone(this, defaults);
    ....
};

If you need deeper copies of your options, you can make a deep_clone() (which is more compicated, obviously).

pkh
+1  A: 

You could also use jQuery's $.extend()

Gary Green
Thanks! I didn't know this existed. I am using jquery anyway, so this will be very useful.
Brett