3

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.

3 Answers 3

4

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

4 Comments

If the OP wants to keep the API, then jQuery is a good start but if the OP is prepared to change (simplify) the API a purpose built extend can be shorter, more efficient and more robust (e.g. the jQuery isPlainObject is pretty ordinary and not necessary, nor is isFunction or isArray).
What RobG said, the jQuery implementation seems like a quite a bit of code. I was wondering if there's any workarounds, or other ways to tackle this issue.
I'm trying to make an easy-to-use, independent code snippet that's basically just one function with a few methods inside. Kind of like a jQuery plugin, but without dependency on jQuery. I'd want to let the user define all the options in a single object for the sake of readable code, but I want to define default values for everything so the user doesn't need to change anything if he's happy with the default looks and functionality.
@user1463028: I was just referring to jQuery's as an example of a fairly thoroughly-done version that's survived a lot of use. The fundamental point is that it's just a recursive use of for..in. I've added a very basic one, but why not use something that's been thoroughly tested instead? Yes, it will take a bit more time to understand and unpick, but... :-) Best,
0

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.

Comments

0

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:

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.