Reputation: 1329
I'm intending to write a module that can be instantiated with default configuration and then overridden with custom configuration when initialized. The configuration object has nested objects, so I need to traverse over these nested objects if they are included in the custom configuration. I am attempting to do so by calling customize
recursively. This works for the first nested object but the traversal ends after that object. Why is this and what can I do to fully traverse an object containing nested objects?
function Config(options) {
function customize(conf) {
if (conf && conf.constructor === Object) {
for (var prop in conf) {
if(conf[prop].constructor === Object) {
return customize.call(this[prop], conf[prop]);
} else {
if (this.hasOwnProperty(prop)){
this[prop] = conf[prop];
}
}
}
} else {
console.error('The first argument must be an object.');
return;
}
}
//Default config values
this.foo = 'default';
this.bar = {
foo: 'default'
};
this.baz = {
foo: 'default'
};
//Overide default config with custom config
if (options && options.constructor === Object) {
customize.call(this, options);
}
}
function TestModule(){
this.init = function(options){
this.config = (options && options.constructor === Object) ? new Config(options) : new Config();
return this;
};
}
console.log(
new TestModule().init({
foo: 'custom',
bar: {foo: 'custom'},
baz: {foo: 'custom'}
}).config
);
//RESULT
// {
// foo: 'custom',
// bar: {foo: 'custom'},
// baz: {foo: 'default'}
// }
Upvotes: 0
Views: 68
Reputation: 1591
This line:
return customize.call(this[prop], conf[prop]);
occurs inside a for loop, so you are returning before each item has been iterated over. Your return statement should be outside the loop.
Upvotes: 2