user1463028
user1463028

Reputation: 73

Replacing object's properties with properties from another object in JavaScript, without libraries

I've been using jQuery.extend to replace default properties like this

var Car = function(options){
    var defaultOptions = {
        color: "hotpink",
        seats: {
            material: "fur",
            color: "black",
            count: 4
        },
        wheels: 4
    }
    this.options = $.extend(true,{},defaultOptions,options); 
}

var myCar = new Car({
    color: "blue",
    seats: {
        count: 2,
        material: "leather"
    }
});

alert(myCar.options.color); // "blue"
alert(myCar.options.seats.color); // "black"
alert(myCar.options.seats.count); // 2

While it works great, I'd like to know the best way to achieve similar results without any libraries. I just want to define some default settings in a function and replace them with settings from arguments, would be an overkill to include a library every time I do that.

Upvotes: 3

Views: 6144

Answers (3)

vee
vee

Reputation: 4765

In ES6 it was introduced spread operator.

var Car = function(options){
    var defaultOptions = {
        color: "hotpink",
        seats: {
            material: "fur",
            color: "black",
            count: 4
        },
        wheels: 4
    }
    this.options = {...defaultOptions, ...this.options};
}

var myCar = new Car({
    color: "blue",
    seats: {
        count: 2,
        material: "leather"
    }
});

References:

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075457

Basically it's just a recursive use of for..in. You can see the full source of jQuery's implementation in the source code (the line number on that will rot over time, but it's likely to remain in core.js).

Here's a very basic off-the-cuff:

function deepCopy(src, dest) {
    var name,
        value,
        isArray,
        toString = Object.prototype.toString;

    // If no `dest`, create one
    if (!dest) {
        isArray = toString.call(src) === "[object Array]";
        if (isArray) {
            dest = [];
            dest.length = src.length;
        }
        else { // You could have lots of checks here for other types of objects
            dest = {};
        }
    }

    // Loop through the props
    for (name in src) {
        // If you don't want to copy inherited properties, add a `hasOwnProperty` check here
        // In our case, we only do that for arrays, but it depends on your needs
        if (!isArray || src.hasOwnProperty(name)) {
            value = src[name];
            if (typeof value === "object") {
                // Recurse
                value = deepCopy(value);
            }
            dest[name] = value;
        }
    }

    return dest;
}

Upvotes: 4

jasonjifly
jasonjifly

Reputation: 347

You can emulate jQuery's api "extend", just like upstairs said. I think there's no better way to manage to do this. So, I think jQuery's api is appropriate.

Upvotes: 0

Related Questions