最近我成了function.name
财产的忠实粉丝。
例如,我编写了一个扩展原型的函数。
它以...的方式运作。
Array.give(
function forEach() { ... }
);
..那会让你做..
['a', 'b', 'c'].forEach(function () { ... });
此代码适用于Chrome,Safari,Firefox和Opera,但不适用于IE。
在进行了一小部分挖掘之后,我意识到,对于给定函数,function.name
只是返回undefined
,就像返回其他所有内容一样"forEach"
。
有没有另一种方法可以在IE浏览器中获取该名称,或者我是否会对这个美妙的财产失去理智?
答案 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.name
为not 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);