IE中不支持function.name。

时间:2011-08-01 20:02:12

标签: javascript

最近我成了function.name财产的忠实粉丝。

例如,我编写了一个扩展原型的函数。

它以...的方式运作。

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

..那会让你做..

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

此代码适用于Chrome,Safari,Firefox和Opera,但不适用于IE。

在进行了一小部分挖掘之后,我意识到,对于给定函数,function.name只是返回undefined,就像返回其他所有内容一样"forEach"

有没有另一种方法可以在IE浏览器中获取该名称,或者我是否会对这个美妙的财产失去理智?

5 个答案:

答案 0 :(得分:31)

您可以使用Object.defineProperty在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;
        }
    });
}

答案 1 :(得分:21)

您可以通过调用function.toString [docs]来解析函数名称。 function.namenot a standard property

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

正如评论所说,这不一定是一种可靠的方式。 Imo传递一个对象会更容易阅读,你可以一次传递几个方法:

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

答案 2 :(得分:7)

我认为你的.give()解决方案有点......很难。出了什么问题:

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

但是,在提供自己的方法之前,你应该检查这种方法是否存在:

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

由于其他人将在这里被引导想知道function.name,有一种方法来获取名称(显然,它不适用于匿名函数):

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

答案 3 :(得分:0)

对于那些在同一条船上的人,请看看JamesMGreene的Function.name polyfill。这看起来是一个很好的解决方案。

答案 4 :(得分:0)

老问题,我不知道这是否适用于原生IE 7& 8浏览器(我使用的是开发人员工具模拟器),但我在构造函数中为函数提供了一个名称属性,用于在gag之前引入IE代码....

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);