jfriend00
jfriend00

Reputation: 707318

Any way to get the currently executing function object in javascript?

Is there any way to refer to the function object that you're currently executing in? If it's not a method of any object or not called with .call() or .apply(), the this pointer is likely just window, not the function object.

I often use a design pattern like this for global variables that I want scoped to a particular function as this keeps them out of the top level namespace:

function generateRandom() {
    if (!generateRandom.prevNums) {    
        generateRandom.prevNums = {};    // generateRandom.prevNums is a global variable
    }
    var random;
    do {
        random = Math.floor((Math.random() * (99999999 - 10000000 + 1)) + 10000000);
    } while (generateRandom.prevNums[random])
    generateRandom.prevNums[random] = true;
    return(random.toString());
}

But, I'd rather not have to spell out the function name every time I want to use a variable scoped to that object. If the name of the function ever changes, there are then a lot of places to change the name.

Is there any way to get the currently executing function object?

Upvotes: 2

Views: 1918

Answers (3)

Steve
Steve

Reputation: 31642

Well, you could use arguments.callee()...

https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee

From MDN:

Description

callee is a property of the arguments object. It can be used to refer to the currently executing function inside the function body of that function. This is for example useful when you don't know the name of this function, which is for example the case with anonymous functions.

Note: You should avoid using arguments.callee() and just give every function (expression) a name.

BUT...

What you really want are Javascript Prototypes.

function RandomSomethingGenerator()
{
   this.prevNums = {};
}

RandomSomethingGenerator.prototype.generate = function() { 
    var random;
    do {
        random = Math.floor((Math.random() * (99999999 - 10000000 + 1)) + 10000000);
    } while (this.prevNums[random])
    this.prevNums[random] = true;
    return(random.toString());
};

Why do I say this?

1.) You're dirtying the global space with all those functions.

2.) Even if you like Jani's suggestion, and you want a "static" function like you have now, my suggestion would be the same, but with a twist: Create your global function, and wrap an instance of an object (built from a prototype) inside the closure and make the call to it (so, basically, make yourself a singleton).

As in this (adapted from Jani's answer):

var randomSomething = (function() {
    var randomSomethingGenerator = new RandomSomethingGenerator();

    return function() {
        randomSomethingGenerator.generate();
    };
})();

Upvotes: 2

a paid nerd
a paid nerd

Reputation: 31512

You want arguments.callee. From MDN - callee:

callee is a property of the arguments object. It can be used to refer to the currently executing function inside the function body of that function. This is for example useful when you don't know the name of this function, which is for example the case with anonymous functions.

For example:

> foo = function() { console.log(arguments.callee); };
> bar = function() { foo() };
> bar();
function () { console.log(arguments.callee) }

However, I think this is being deprecated. The above link says, "The 5th edition of ECMAScript forbids use of arguments.callee() in strict mode."

Upvotes: 1

Jani Hartikainen
Jani Hartikainen

Reputation: 43243

I don't think there's any way to do exactly what you ask, but you could use a closure for your function-local static variables instead.

You can easily achieve this using an IIFE:

var generateRandom = (function() {
    //any function's static variables go here
    var prevNums = {};

    return function() {
        //function code goes here
        var random;
        do {
            random = Math....
        }

        prevNums[random] = true; 

        return random.toString();
    };
})();

Upvotes: 1

Related Questions