referencing desired objects in namespaced functions
I'm having trouble referencing the desired object whe开发者_如何学编程n I've namespaced functions.
No problems here:
obj.test = function() {
// this == obj
}
But I'm getting tripped up when I namespace:
obj.namespace.test = function() {
// this == namespace
}
In the latter example, I know this
references namespace
, but I want to reference obj
. How can I do it?
Others have made some good suggestions.
I just wanted to add you can also make namespace a function that will return an object with a variable pointing to the obj and whatever member functions you want.
Example:
// Note that "namespace" is a reserved word in JS for some reason,
// so you can't use it as a variable/function/etc name.
var myNamespace = function myNamespace(){
var that = this;
var test = function test(){
//in here use this.that to point to obj
alert(this.that.name);
};
return {that: that, test: test};
};
// Then create the obj:
var obj = { name: "Mr. Ahb Jeckt", myNamespace: myNamespace};
// Then you can just call the "namespace" and member function like this:
obj.myNamespace().test();
//Or, "initialize" the namespace and call it like so:
obj.myNamespace = obj.myNamespace();
obj.myNamespace.test();
obj.name = "Mrs Ahb Jeckt";
obj.myNamespace.test();
This way there are no hard-coded references to obj in the "namespace" itself, and I think it's pretty clean.
This also works if obj is a "class"; just make obj a constructor instead of an object literal:
// Then create the obj:
var obj = function (name){
this.name = name || "unnamed";
this.myNamespace = myNamespace;
// Initialize the namespace, we can leave this out and just reference
// obj.myNamespace() each time as well
this.myNamespace = this.myNamespace();
};
// Then you can just call the "namespace" and member function like this:
var myObj = new obj("Mr Ahb Jeckt");
myObj.myNamespace.test();
var myObj2 = new obj("Mrs Ahb Jeckt");
myObj2.myNamespace.test();
There is no simple answer, but you have a few options:
obj.namespace.test = function () {
return (function () {
// this == obj
}).apply(obj, Array.prototype.slice.call(arguments));
};
This returns a function that is bound to obj
. Unfortunately, if obj
is reassigned, this will not work, because it's a live reference. This is more robust:
obj.namespace.test = (function (obj) {
return function () {
return (function () {
// this == obj
}).apply(obj, Array.prototype.slice.call(arguments));
};
}(obj));
As you can see, neither of these is very clean. You might ask yourself why you depend on this
to begin with. Using a normal reference to obj
is obviously the most straightforward approach.
精彩评论