Vic
Vic

Reputation: 8961

Extending a function

Let's say I have a function like this:

function foo(){
    var myValue = 5;
    var myOtherValue = 1;
    return {
        getValue: function(){
            return [myValue, myOtherValue];
        }
    }
}

Is there a way I can extend/overwrite this function somehow without touching the original function so that when I call getValue() I get [SOME OTHER VALUE I CHOOSE, myOtherValue]?

If not, can I do it at the instance level?

var myFoo = new foo();
myFoo.getValue = function(){
    return [0, myOtherValue]; // how to I access myOtherValue?
}

Upvotes: 0

Views: 104

Answers (8)

Ted Hopp
Ted Hopp

Reputation: 234795

You can't access a variable in a closure. However, you can define the new function to delegate to the original function to access it:

var myFoo = new foo();
myFoo.getValue = (function (original) {
    return function(){
        var val = original();
        val[0] = 0;
        return val;
    };
}(myFoo.getValue));

Here is a fiddle of this solution so you can try it out yourself: http://jsfiddle.net/6Ux92/1/

Upvotes: 1

Serge K.
Serge K.

Reputation: 5323

Try this :

function foo(){
    this.myValue = 5;
    var myOtherValue = 1;
    return {
        getValue: function(){
            return [this.myValue, myOtherValue];
        }
    }
}

var bar = new foo();
bar.myValue = "whatever";

Upvotes: 0

wharding28
wharding28

Reputation: 1349

If you don't want to modify foo, you can do this:

function foo(){
    var myValue = 5;
    var myOtherValue = 1;
    return {
        getValue: function(){
            return [myValue, myOtherValue];
        }
    }
}

var myFoo = new foo();
//move getValue to _getValue
myFoo._getValue = myFoo.getValue;

//do custom getValue
myFoo.getValue = function(){
    return [0, myFoo._getValue()[1]]; 
}

Upvotes: 3

ChenR
ChenR

Reputation: 161

you could wrap this function with a decorator function:

 var decorator = function() {
   var someNewValue = ...;
   var myOtherValue = foo().getValue()[1];
   return [someNewValue, myOtherValue];
} 

Upvotes: 0

squid314
squid314

Reputation: 1395

function foo() {
    .. original stuff ..
}


var hidden_foo = foo;
function decorator() {
    var internal = hidden_foo();

    // here is the proxy object
    return {
        getValue: function() {
            return [SOME OTHER VALUE I CHOOSE, internal.getValue()[1]];
        }
    }
}
// overwrite the original function with our decorated version
foo = decorator;

Upvotes: 1

qwertynl
qwertynl

Reputation: 3933

You can't.

myOtherValue is only defined in the scope of foo.


You could have to rewrite to something like this:

function foo(){
    var myValue = 5;

    return {
        myOtherValue: 1,
        getValue: function(){
            return [myValue, this.myOtherValue];
        }
    }
}

Then you could do:

var myFoo = new foo();
myFoo.getValue = function(){
    return [0, myFoo.myOtherValue]; 
}

Upvotes: 1

QBM5
QBM5

Reputation: 2788

function foo(){
    var myValue = 5;
    var myOtherValue = 1;
    return {
        getValue: function(){
            return [myValue, myOtherValue];
        }
    }
}

var myFoo = new foo();
var storeOriginal= myFoo.getValue;
myFoo.getValue = function(){
   //your code
   storeOriginal();
}

Upvotes: 1

Mr_Mig
Mr_Mig

Reputation: 783

You can do like this

function myFoo() {
    var vals = foo().getValue();
    return {
         getValue : function(){
             return [0, vals[1]]
         }
    }
} 

vals[1] is obviously myOtherValue

Upvotes: 0

Related Questions