Is it possible to modify a function itself when its property function is called?

Basically I want to do this:

someFunction() // do something

someFunction.somePropertyFunction()

someFunction()  // Now someFunction is modified; it should now exhibit a different behaviour

Is this possible?

EDIT:

I'm not looking for what @Kolink was suggesting. Basically I want to augment a function's functionality by calling one of it's property function.

Specifically, I need to: 1. have access to the original function inside my property function (which is entirely doable using this), and 2. bind a new function to the original function's name (which I'm not sure if it's possible).

Just to be clear, I don't have access to the internal definition of the function that I want to augment. I want to attach a function to Function.prototype (so that it will be available as a property of the function that I want to augment), and then I will call func.augmentThis(), and then func should be augmented. But I'm not sure how, hence the question :P

Answers:

Answer

Easily. Here's an example:

var derp = 123;
someFunction = function() {alert(derp);};
someFunction.somePropertyFunction = function() {derp = 456;};

someFunction(); // alerts 123
someFunction.somePropertyFunction();
someFunction(); // alerts 456

Okay, that's an oversimplified example, but yeah, it's entirely possible.

Answer

If your question is whether a function attached as a property to another function has a way to access the function to which it is attached, the answer is no. After all, the same function could be attached to any number of functions of objects.

So one alternative is to explicitly refer to the "mother" function within the function that is attached to it and intended to change its behavior:

function f (n) {  alert (n + f.offset); }
f.offset = 0;
f.change_offset = function (i) { f.offset = i; };

f (1);                  //1
f.change_offset (100);
f (1);                  //101

Here, f is hard-wired into the definition of change_offset. If this bothers you, or you want something slightly more general, write a little routine to set a function as a property on another function, while binding its this to the function being attached to:

function set_func_as_func_prop ( propname, func_to_set, func_to_set_on ) {
    func_to_set_on[propname] = func_to_set.bind(func_to_set_on);
}

Now you can write the function more generally

function change_offset (i) {
    this.offset = i;
}

and set it on f or any other function.

set_func_as_func_prop ("change_offset", change_offset, f);
set_func_as_func_prop ("change_offset", change_offset, g);
Answer

Sort of:

function someFunction() {
    return realFunction.apply(this, arguments);
}

function someFunctionA(name) {
    return 'Hello, ' + name + '!';
}

function someFunctionB(name) {
    return 'Goodbye, ' + name + '...';
}

var realFunction = someFunctionA;

someFunction.somePropertyFunction = function () {
    realFunction = someFunctionB;
};
Answer

Sure it's possible. It's not recommended, but it's possible. For example:

function a() {
    alert("a");
}

function b() {
    alert("b");
}

function c() {
    return c.f.apply(this, arguments);
}

c.f = a;

c.toggle = function () {
    c.f = c.f === a ? b : a;
};

Now let's test it:

c();        // alerts "a"
c.toggle();
c();        // alerts "b"

See the demo: http://jsfiddle.net/LwKM3/

Answer

I want to attach a function to Function.prototype. Then I need to bind a new function to the original function's name (which I'm not sure if it's possible).

That indeed is impossible, you don't know what refers to the function. And you cannot change the internal representation of a function, which is immutable.

The only thing you can do is to create a new function and return that, to let the caller of your method use it somehow - specifically assigning it to the original variable:

somefunction = somefunction.augmentSomehow();

Your method for that will look like this:

Function.prototype.augmentSomehow = function() {
    var origFn = this;
    return function() {
        // in here, do something special
        // which might include invoking origFn() in a different way
    };
};
Answer

Not sure if this helps, but I would implement described problem in following way:

// defined by somebody else - unknown to developer
var someFunction = function() {
    alert("this is initial behavior");
}

someFunction(); // returns "this is initial behavior"

// defines parent object on which someFunction() is called
var parentObject = this; // returns window object (as called direclty in the
// browser)

// if you are calling someFunction from some object (object.someFunction())
// it would be:
// var parentObject = object;

// augumentThis definition
someFunction.augumentThis = function() {
    var newFunction = function() {
        alert("this is changed behavior");
    };
    parentObject.someFunction.somePropertyFunction = function() {
        parentObject.someFunction = newFunction;
        parentObject.someFunction();
    };
};

someFunction.augumentThis();            // change function behavior
someFunction();                         // "this is initial behavior"
someFunction.somePropertyFunction();    // "this is changed behavior"
someFunction();                         // "this is changed behavior"

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.