I'm trying to make a function that can be applied to a value returned from another function both within a function. Since that's probably a terrible explanation, here's a simplified sample:
function MainFnc() {
this.subFnc=function(a) {
return a*2
}
this.subFnc.subSubFnc=function(a) {
return this*a
}
}
This isn't my actual code - it'开发者_开发技巧s for a far better reason than multiplying numbers. This is just a simplified example of what I'm trying to achieve. My question is whether or not it's actually possible to go this deep, and if so how? The method I've portrayed in this sample code evidently does not work.
Thanks for any help.
Edit: Here's an example of it in use since not everyone understands clearly what I want to do with this:
anObject=new MainFnc;
alert(anObject.subFnc(2)); //returns 4
alert(anObject.subFnc(2).subSubFnc(2); //returns 8
This is not exactly what I'm doing, it's just easier to understand using simple multiplication.
This is about as close as you can get:
function foo(n){
this.value = n;
return this;
};
foo.prototype = {
valueOf : function(){
return this.value;
},
multiplyBy : function(n){
return new foo(this.value * n);
}
};
foo.prototype.toString = foo.prototype.valueOf;
var x = new foo(2);
var y = x.multiplyBy(2).multiplyBy(2).multiplyBy(2);
// y == 16
Update based on your comment:
MainFnc
is an object which is created in a variable (ieMainVar
). So if I wanted to tryMainVar.subFnc(2)
it'd return4
. If I wanted to tryMainVar.subFnc(2).subSubFnc(2)
, however, it'd return8
.
Right now, you're returning a number from your subFnc
, and so the expression MainVar.subFnc(2).subSubFnc(2)
breaks down like this:
- Look up the property
subFnc
onMainVar
; it returns a function reference. - Call the function with
this
=MainVar
; this returns the number2
. - Look up the property
subSubFnc
on the number2
; it returnsundefined
. - Call the function with
this
=2
; fails because you can't callundefined
as a function.
More: You must remember this
and Mythical Methods
To do what you're doing, you'd have to have subFnc
return an object with function properties. You could do it like this:
function MainFnc(val) {
this.value = val;
this.mult=function(a) {
return new MainFnc(this.value * a);
};
this.div=function(a) {
return new MainFnc(this.value / a);
};
this.get = function() {
return this.value;
};
}
...and then call it like this:
var MainVar = new MainFnc(3);
alert(MainVar.mult(3).mult(4).div(6).get()); // alerts "6" (3 * 3 * 4 / 6 = 6)
Live example
Note the get
function to return the underlying number. You might also add a toString
:
this.toString = function() {
return String(this.value);
};
But the above isn't taking advantage of prototypical inheritance at all (and it will be important to, if you're creating all of those objects; we need to keep them lightweight); you might consider:
function MainFnc(val) {
this.value = val;
}
MainFnc.prototype.mult = function(a) {
return new MainFnc(this.value * a);
};
MainFnc.prototype.div = function(a) {
return new MainFnc(this.value / a);
};
MainFnc.prototype.get = function() {
return this.value;
};
MainFnc.prototype.toString = function() {
return String(this.value);
};
Original Answer:
With that code, if you did this:
var f = new MainFnc();
alert(f.subFnc(3)); // alerts "6"
alert(f.subFnc.subSubFnc(3)); // NaN
...because this
inside subSubFnc
when called like that is subFnc
, and multipling a function reference tries to convert it to a number, which comes out NaN
, and so the result of the multiplication is NaN
.
Remember that in JavaScript, this
is defined entirely by how a function is called, not where the function is defined. When you call a function via dotted notation (a.b();
), the object you're looking up the property on becomes this
within the function call, and so with a.b.c();
, this
within c()
is b
, not a
. More: You must remember this
and Mythical Methods
精彩评论