McKayla
McKayla

Reputation: 6949

function.name not supported in IE.

Lately I've become a huge fan of the function.name property.

For example, I've written a function for extending prototypes.

It works in the way of..

Array.give(
    function forEach() { ... }
);

..which would then let you do..

['a', 'b', 'c'].forEach(function () { ... });

This code works great in Chrome, Safari, Firefox, and Opera, but not in IE.

After just a small bit of digging, I realized that to the give function, function.name was just returning undefined, where as in everything else it returned "forEach".

Is there an alternative way to get the name in IE, or should I just fall out of love with this wonderful property?

Upvotes: 16

Views: 14874

Answers (5)

user2782001
user2782001

Reputation: 3488

Old question, and I don't know if this works on a native IE 7 & 8 browser (I'm using the developer tools emulator), but I've given functions a name property on the constructor for gag inducing IE code before....

function sayMyName(func){
    var name=func.name || func.constructor.name
    alert(name);

}

var ieGivesMeNightTerrors=function(){
    //there there, these ugly workarounds aren't your fault
};
ieGivesMeNightTerrors.constructor.name=ieGivesMeNightTerrors;
sayMyName(myFunc);

Upvotes: 0

Jürg Lehni
Jürg Lehni

Reputation: 1826

You can use Object.defineProperty to add support for it on IE9+

// Fix Function#name on browsers that do not support it (IE):
if (!(function f() {}).name) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var name = (this.toString().match(/^function\s*([^\s(]+)/) || [])[1];
            // For better performance only parse once, and then cache the
            // result through a new accessor for repeated access.
            Object.defineProperty(this, 'name', { value: name });
            return name;
        }
    });
}

Upvotes: 32

bencergazda
bencergazda

Reputation: 670

For those, who are in the same boat, have a look at JamesMGreene's Function.name polyfill. This looks to be a good solution.

Upvotes: 0

Felix Kling
Felix Kling

Reputation: 816404

You might be able to parse the function name from calling function.toString [docs]. function.name is not a standard property.

var name = func.toString().match(/^function\s*([^\s(]+)/)[1];

As the comments also say, this is not necessarily a reliable way. Imo passing an object would be easier to read and you could pass several methods at once:

Array.give({
    forEach: function() { ... },
    somethingElse: function() {...}
});

Upvotes: 22

James
James

Reputation: 111900

I think your .give() solution is a little..verbose. What's wrong with:

Array.prototype.forEach = function () { ... };

?

Really, though, you should check for such a method's existence before supplying your own:

Array.prototype.forEach = Array.prototype.forEach || function () { ... };

Since others will be led here wondering about function.name, there is a way to grab the name (obviously, it doesn't work on anonymous functions):

function getFnName(fn) {
    return (fn.toString().match(/function (.+?)\(/)||[,''])[1];
}

Upvotes: 7

Related Questions