Reputation: 952
First of all, I'm attempting to use faux namespaces in my JavaScript program like so:
// Ish.Com namespace declaration
var Ish = Ish || {};
Ish.Com = Ish.Com || {};
// begin Ish.Com.View namespace
Ish.Com.View = new function() {
var privateVariable;
this.publicFunction = function() {
this.publicFunction2()
};
this.publicFunction2 = function() { ... };
};
I'm not crazy about using this
to call other functions, but up to recently, it has worked. However, I've added event listeners to some elements, and they interpret this
to be the target object.
I know I can use the full namespace instead of this
to call functions inside of my listeners (Ish.Com.View.publicFunction2()
), but the listeners often call one function, which calls another, and another. I'd need to use the entire namespace in nearly every function call.
How can I get namespaces to work nicely with Event Listeners? I'd also be interested in a better way of implementing namespaces, since using this.publicFunction2()
is clunky.
I'm very interested in best-practices, and learning how to write a well architected application in JavaScript. However, frameworks are out of the question until I gain a more thorough understanding of JavaScript.
Upvotes: 2
Views: 1177
Reputation: 21
This is caused by variable context and closure. "this" always refers to the current object. The event function is an object itself and "this" refers to that object. If you need to refer to the parent object you can use bind as described previously or you set the parent "this" to a variable and use that in your event function.
// Ish.Com namespace declaration
var Ish = Ish || {};
Ish.Com = Ish.Com || {};
// begin Ish.Com.View namespace
Ish.Com.View = new function() {
var privateVariable, thisObj=this;
this.publicFunction = function() {
thisObj.publicFunction2()
};
this.publicFunction2 = function() { ... };
};
Upvotes: 0
Reputation: 1287
I don't know if i have understood completely your question. Would this suit your needs ?
var obj = new function() {
var scope = this;
this.fun1 = function() {
return scope.fun2();
}
this.fun2 = function() {
//do sth
}
};
Upvotes: 0
Reputation: 413916
Seems like I've been answering every question this morning the same way :-)
You can use ".bind()":
var eventHandler = yourObject.someFunction.bind(yourObject);
That'll guarantee that this
will refer to "yourObject" whenever the "eventHandler" is called by anything.
The "bind()" function is there on the Function.prototype object in newer browsers. The Mozilla docs include a solid implementation of "bind()" you can use to patch older browsers.
What "bind()" does is return you a new function that explicitly arranges for this
to be bound as you stipulate. You can also pass arguments to be passed in, if you like. An alternative to using "bind()" is to wrap the function call in your own anonymous function:
var eventHandler = function() { yourObject.someFunction(); };
Upvotes: 4