【问题标题】:function.name not supported in IE.IE 不支持 function.name。
【发布时间】:2011-10-17 17:46:34
【问题描述】:

最近我成为了function.name 属性的忠实粉丝。

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

它的工作原理是……

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

..这会让你做..

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

此代码在 Chrome、Safari、Firefox 和 Opera 中运行良好,但在 IE 中不适用。

经过一点点挖掘,我意识到对于 give 函数,function.name 只是返回 undefined,而在其他所有内容中它都返回 "forEach"

是否有其他方法可以在 IE 中获取名称,或者我应该对这个美妙的属性失去兴趣?

【问题讨论】:

  • 什么是.give()?你在哪里使用function.name
  • 如果没关系那你为什么要用它作为样本呢? (@patrick 我猜也一样,但我对实现很感兴趣。另外,我很确定 function.name 根本没有必要)
  • @Tomalak 显示function.name 的用例。我如何在内部使用function.name 几乎无关紧要。如果您只是对它的代码感兴趣,我很乐意将其提供给您,但我认为当人们在 cmets 中提问时,它是为了帮助提供答案,所以如果我可以阻止人们提供通过不回答他们的问题来回答无关紧要的答案,那么我会的。不,没有必要,只是非常方便。
  • @tylermwashburn 我认为不要把每一条评论都看在表面上是件好事。特别是如果它是来自高级用户的看似毫无意义的 cmets。 a) 你可能没有你想的那么清楚。 b) 编程至少与 “我为什么要这样做”“我怎样才能这样做” 相同。 c) 提出问题时,说明您的意图是您工作的一部分。完全拒绝表明自己的意图是粗鲁的(至少我是这么认为的)。

标签: javascript


【解决方案1】:

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

【讨论】:

  • 我已更改正则表达式以在所有这些情况下都能正常工作:function() {}、function () {}、function test() {}、function test () {}
  • 如果函数名包含 unicode 字符,您可能想要使用 \S* 而不是 \w*
  • @alex 我不知道函数名称可以有 unicode 名称。你确定是这样吗?
  • 函数名是一个标识符,标识符符合7.6 ES5规范,其中包括unicode。另外,jquery 有 '$' 作为函数名,\w 也不会匹配它。
  • @JohnArcher 我已经调整了代码以适应这种情况。感谢您指出!
【解决方案2】:

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

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

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

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

【讨论】:

  • 我强烈建议不要解析函数的toString() 方法的输出来获取名称。没有任何保证。
  • @Tim:这就是我说可能的原因;)但无论如何,specification 说:返回了函数的依赖于实现的表示。此表示具有 FunctionDeclaration 的语法。请特别注意,在表示 String 中使用和放置空格、行终止符和分号是依赖于实现的。 因此,至少根据规范,toString 方法将函数声明作为字符串返回,这意味着是一些的保证。我猜空格可以处理...
  • 我认为从 IE 的 toString 表示中可靠地解析 func 名称并不难。空格不能是函数标签的一部分。
  • @ricosrealm:我更新了表达式以忽略空白字符。
  • @TimDown 为什么它不起作用?如果在function( 之间找不到名称,则可以假定名称为"",这与支持Function.name 的系统中(function() {}).name 的结果相同.似乎这可以在 100% 的时间内工作(尽管对于大型功能可能会很慢)。是否存在Function.toString() 的结果不包含"function ...()" 的系统?
【解决方案3】:

我认为您的.give() 解决方案有点……冗长。有什么问题:

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

?

实际上,您应该在提供自己的方法之前检查是否存在这样的方法:

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

由于其他人会被带到这里想知道function.name,所以有一种方法可以获取名称(显然,它不适用于匿名函数):

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

【讨论】:

  • Array.prototype.forEach || ( Array.prototype.forEach = function () { ... } );
  • 这实际上与实际问题无关。 -1
  • 我从来没有问过任何关于扩展原型的问题。这只是 function.name 如何有用的一个例子。而已。整个事情中唯一的问题是询问您可以在 IE 中使用的替代方案,这意味着您的答案应该已经涵盖了。如果我想覆盖本地人,我会的,因为那是我自己的编码风格。你没有理由反对。
  • @tylerwashburn,我只是想帮忙。把你的愤慨带到别处。
  • Tyler,我想有一种方法可以在不谈论您的 Object.prototype.give 增强的情况下提出这个问题,而只需坚持 Fn.name 部分。你有它来了。 (而且你甚至知道并说“继续,向我开枪”......)我认为你不能指望开发人员不会用这样的东西向你开枪。 :)
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    老问题,我不知道这是否适用于本机 IE 7 和 8 浏览器(我正在使用开发人员工具模拟器),但我在构造函数上为函数提供了一个名称属性,用于诱导 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);
    

    【讨论】:

    • "sayMyName"...大声笑
    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 2021-12-07
    • 2012-04-03
    相关资源
    最近更新 更多