IE中不支持function.name.

McK*_*yla 15 javascript

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

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

它的工作方式..

Array.give(
    function forEach() { ... }
);
Run Code Online (Sandbox Code Playgroud)

..然后会让你做..

['a', 'b', 'c'].forEach(function () { ... });
Run Code Online (Sandbox Code Playgroud)

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

在进行了一小部分挖掘之后,我意识到对于give函数来说,function.name只是返回undefined,就像返回的其他东西一样"forEach".

有没有另一种方法可以在IE中获得该名称,或者我是否会对这个美妙的财产失去爱意?

Jür*_*hni 32

您可以使用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;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • @JohnArcher我调整了代码以适应这种情况.谢谢你指出来! (3认同)
  • 如果函数名称具有unicode字符,则可能需要使用\ S*而不是\ w* (2认同)
  • function name是一个Identifier,标识符符合7.6 ES5规范,包括unicode.另外,jquery有'$'作为函数名,而\ w也不匹配它. (2认同)

Fel*_*ing 21

您可以通过调用function.toString [docs]来解析函数名称.function.name不是一个标准特性.

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

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

Array.give({
    forEach: function() { ... },
    somethingElse: function() {...}
});
Run Code Online (Sandbox Code Playgroud)

  • @Tim:这就是为什么我说*可能*;)但是无论如何,[规范](http://ecma262-5.com/ELS5_HTML.htm#Section_15.3.4.2)说:*依赖于实现的表示函数返回.此表示具有FunctionDeclaration的语法.请特别注意,表示字符串中的空格,行终止符和分号的使用和放置是依赖于实现的.*所以至少每个规范的`toString`方法返回一个函数声明为字符串,这意味着有*some*保证.白色空间可以照顾我猜... (2认同)
  • 我认为从IE的toString表示中可靠地解析func名称并不困难.空格不能是功能标签的一部分. (2认同)

Jam*_*mes 7

我认为你的.give()解决方案有点......很难.有什么不对:

Array.prototype.forEach = function () { ... };
Run Code Online (Sandbox Code Playgroud)

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

Array.prototype.forEach = Array.prototype.forEach || function () { ... };
Run Code Online (Sandbox Code Playgroud)

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

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

  • @tylerwashburn,我只想帮忙.把你的愤慨放在别处. (4认同)
  • Tyler,我想有一种方法可以在不讨论你的`Object.prototype.give`扩充的情况下提出这个问题而只是坚持使用`Fn.name`部分.你有点过来了.(你甚至知道它并且说"继续拍摄我"......)我认为你不能指望开发者不要用这样的东西来拍摄你.:) (3认同)
  • `Array.prototype.forEach || (Array.prototype.forEach = function(){...});` (2认同)
  • 这实际上与实际问题无关.-1 (2认同)