Reputation: 465
I'm trying to allow for default settings to be overwritten by the init function but for some reason the it's only using the local settings can anyone please explain why and how I can fix this.
var obj = (function() {
var settings = {
height : 10,
width : 20
};
function init(settings) {
this.settings = settings
setObj()
}
function setObj() {
if (settings.height == 0) {
console.log('good height')
} else {
console.log('bad height')
}
}
return {
init : init,
}
})()
var settings = {
height : 0,
width : 20
};
obj.init(settings);
Upvotes: 2
Views: 92
Reputation: 7729
I am uncertain as to what you are trying to do, however your question is a great example to help people understand modules and the revealing module pattern.
At present when you execute the IIFE the only value it returns to your obj
variable/Module is an anonymous object with a method which is init
.
return { // <-- anonymous object returned with all its properties available!
init : init
}
So the methods bound to that returned object are now available to the module's namespace i.e. obj
. Everything else is private i.e. var settings (object), the setObj, (function object)
Think what might be confusing is this part:
function init(settings) {
this.settings = settings
setObj()
}
When you call init
this will add a new property to obj Module. That is because when you invoke:
obj.init(settings);
The this
keyword points to the returned object which was assigned to the obj namespace/Module.
To prove it after invoking the IFFE but before invoking init
on your Module, run:
console.dir(obj);
Calling console.dir(object) will log an interactive listing of an object's properties, like > a miniature version of the DOM tab
Essentially you'll get all the properties on obj. At this point it's only init.
So to reiterate, your init
will not overwrite the settings
variable, the one in the IIFE assigned to obj
, that one is inaccessible (unless you use a public method to update it). Your init
adds a property to the object returned by the IIFE.
I added a function to your Module called checkSettings
and changed your init
function. I created checkSettings
so you could see the settings
obj before you run init and after, essentially so you could see the changes first hand. And my init
just overwrites the properties if the names match.
var obj = (function() {
var settings = {
height : 10,
width : 20
};
function init(objProps) {
for (var p in objProps) {
if(settings.hasOwnProperty(p)) {
settings[p] = objProps[p];
}
}
setObj()
}
function checkSettings(){
console.log('The following properties and values are on settings object');
for(var p in settings) {
if(settings.hasOwnProperty(p)) {
console.log(p + ' ' + settings[p]);
}
}
}
function setObj() {
if (settings.height == 0) {
console.log('good height')
} else {
console.log('bad height')
}
}
return {
init : init,
checkSettings : checkSettings
}
})()
Hope this was helpful!
Upvotes: 0
Reputation: 117
The init function is a closure here, even after IIFE executes , init has reference to local variable. So first it checks whether height property of settings object is available locally and grabs the value. But when we use this keyword is used it refers to settings of init function which has the reference to global settings object. Please correct me if I am wrong.
var obj = (function() {
var settings = {
height : 10,
width : 20
};
function init(settings) {
this.settings = settings;
setObj();
}
function setObj() {
if (this.settings.height == 0) { // use this.settings here. The code works fine.
console.log('good height')
} else {
console.log('bad height')
}
}
return {
init : init,
}
})();
var settings = {
height : 0,
width : 20
};
obj.init(settings);
Upvotes: 0
Reputation: 805
instead of var use this.settings
var obj = (function() {
this.settings = {
height : 10,
width : 20
};
function init(settings) {
this.settings = settings
setObj()
}
function setObj() {
if (settings.height == 0) {
console.log('good height')
} else {
console.log('bad height')
}
}
return {
init : init,
}
})()
var settings = {
height : 0,
width : 20
};
obj.init(settings);
Upvotes: 1