I have the below code:
filtersManager = (function ($) {
var that = this;
function configure() {
// some work
return that;
};
function process() {
// some work
return that;
}
return {
// public functions
configure: configure,
process: process
};
}(jQuery));
but when it's called using the below it fails:
filtersManager.configure().process();
Error: Object doesn't support property or method 'process'
whereas the below works:
filtersManager.configure();
filtersManager.process();
I have the below code:
filtersManager = (function ($) {
var that = this;
function configure() {
// some work
return that;
};
function process() {
// some work
return that;
}
return {
// public functions
configure: configure,
process: process
};
}(jQuery));
but when it's called using the below it fails:
filtersManager.configure().process();
Error: Object doesn't support property or method 'process'
whereas the below works:
filtersManager.configure();
filtersManager.process();
Share
Improve this question
asked Feb 17, 2014 at 8:51
The LightThe Light
27k66 gold badges180 silver badges261 bronze badges
6
-
1
The IIFE has no context,
this
depends on how you call a function.this
inside each function is already the object. – elclanrs Commented Feb 17, 2014 at 8:54 - I tried with "this" and it worked but I'd like to avoid using "this" directly. In case, the method is also called from another private function within the class which changes the context. – The Light Commented Feb 17, 2014 at 8:55
-
}(jQuery));
is this correct closing isn't it should be})(jQuery);
this way. – Jai Commented Feb 17, 2014 at 8:57 - @Jai Yes but the former is the preferred. – Royi Namir Commented Feb 17, 2014 at 8:58
-
1
@Jai: It's valid, just semantics.
}(jQuery))
in fact makes more sense, as the function is being called and wrapped in parenthesis to force an expression. – elclanrs Commented Feb 17, 2014 at 8:59
4 Answers
Reset to default 15You are returning the wrong thing (this
in a plain function invocation is the global object). You want to return the object that you originally created, which I will call the interface.
filtersManager = (function ($) {
var interface = {
// public functions
configure: configure,
process: process
};
function configure() {
// some work
return interface;
};
function process() {
// some work
return interface;
}
return interface;
}(jQuery));
If you're wondering why I can reference the functions defined below, it's due to hoisting.
Immediate function is executed in global object (window
) context. Try something similar to this:
filtersManager = (function ($) {
var that = {};
that.configure = function() {
// some work
return that;
};
that.process = function() {
// some work
return that;
}
return that;
}(jQuery));
UPD. Based on ments
Constructor pattern seems to fit your need better:
var FiltersManager = (function($) {
function FiltersManager() {}
FiltersManager.prototype = {
configure: function() {
console.log('configure');
return this;
},
process: function() {
console.log('process');
return this;
}
}
return FiltersManager;
}(jQuery));
new FiltersManager().configure().process();
As to continue what others have said , I think you confused with the function constructor syntax which would work , similar to what you've said ;
var G=function g()
{
this.configure =function (){return this;}
this.process =function (){return this;}
};
var _= new G();
console.log(_.configure().process())
If you wanted to re-use the functions on other objects too, you could do it like this
filtersManager = function ($) {
function configure() {
// some work
return this;
};
function process() {
// some work
return this;
}
return {
// public functions
configure: configure,
process: process
};
}(jQuery);
(OTOH, if you wanted to create aliases to them, you would then have to bind them to the object)
Or if configure and process are quite short, simple functions :
filtersManager = (function ($) {
return {
// public functions
configure: function () {
// some work
return this;
},
process: function () {
// some work
return this;
}
};
}(jQuery));