MDN will be in maintenance mode on Friday September 22nd, starting at 10 AM Pacific / 5 PM UTC, for about 1 hour.

 

function.name 属性返回函数实例的名称。

Function.name 属性的属性特性:
writable false
enumerable false
configurable true

请注意,在非标准的ES2015之前的实现中,属性描述中 configurable 特性是  false 。

范例

函数声明的名称

 name 属性返回一个具名函数的名称。

function doSomething() { }

doSomething.name; 
// "doSomething" 

 

Function构造函数的名称

使用 new Function(...) 或 Function(...)语法创建的Function对象, 他们的名称是“anonymous”。

(new Function).name; 
// "anonymous"

推断函数名称

变量和方法可以从其句法位置推断匿名函数的名称(ECMAScript 2015 中新增):

var f = function() { };
var object = {
  someMethod: function() {}
};

console.log(f.name); 
// "f"
console.log(object.someMethod.name);
// "someMethod"

你可以在 函数表达式中指定函数的名称:

var object = {
  someMethod: function object_someMethod() {}
};

console.log(object.someMethod.name); // "object_someMethod"

try { object_someMethod } catch(e) { alert(e); }
// ReferenceError: object_someMethod is not defined

你不能改变一个函数的 name 属性的值, 因为该属性是只读的:

var object = {
  // someMethod 属性指向一个匿名函数
  someMethod: function() { }
};

object.someMethod.name = "otherMethod";
console.log(object.someMethod.name); // 仍旧是someMethod.

如果需要变更函数的name,可以通过 Object.defineProperty() 来修改。

简略方法的name

var o = {
  foo(){}
};
o.foo.name; // "foo";

绑定函数的name

Function.bind() 所创建的函数将会在函数的名称前加上"bound " 。

function foo() {}; 
foo.bind({}).name; // "bound foo"

getters和setters的函数name

当通过 get 和 set 访问器来存取属性时, "get" 或 "set" 会出现在函数名称前。

var o = { 
  get foo(){}, 
  set foo(x){} 
}; 

var descriptor = Object.getOwnPropertyDescriptor(o, "foo"); 
descriptor.get.name; // "get foo" 
descriptor.set.name; // "set foo";

类中的函数名称

你可以通过obj.constructor.name来获得对象的“类型” (请认真阅读下面的警告):

function Foo() {}  // ES2015 语法: class Foo {}

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // 输出 "Foo"

 

警告: 当一个函数没有自己的name属性时,JavaScript脚本解释器会使用内建的Function.name去设置函数的name属性(参见section 9.2.11 of the ECMAScript2015 Language Specification). 但是, ES2015规定由关键字static修饰的静态方法也会被认为是类的属性 (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).

因此我们不能得到任何有静态name()方法的类的类名:

class Foo {
  constructor() {}
  static name() {}
}

有关键字static修饰的name()方法Foo.name实际是指向name() 方法,不再指向真实的类名. 上面这ES2015中定义类的句法在Chrome和Firefox中的表现和下面这ES5的句法是一致的:

function Foo() {}
Object.defineProperty(Foo, 'name', { writable: true });
Foo.name = function() {};

试图通过fooInstance.constructor.name将无法获取实例fooInstance的类名,现在它只是指向一个静态方法。例如:

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs function name()

还有,有可能你确实在Chrome或Firefox中见过通过ES5句法来静态定义name的属性的情况,那是因为Foo.name在定义是是可写的,但注意默认的属性定义是只读的:

Foo.name = 'Hello';
console.log(Foo.name);
// 如果类型Foo具有静态属性name(),则输出 “Hello”,否则输出 “Foo” 

因此你不能依赖于内置的Function.name属性来获取类型名称。

Symbol作为函数名称

如果Symbol 被用于函数名称,并且这个symbol具有相应的描述符,在中括号内的方法的名称就是这个symbol的描述符。

var sym1 = Symbol("foo"); 
var sym2 = Symbol(); 
var o = { 
  [sym1]: function(){}, 
  [sym2]: function(){} 
}; 

o[sym1].name; // "[foo]"
o[sym2].name; // ""

JavaScript代码压缩的函数名称

警告:当使用源码转换,例如在使用JavaScript压缩(缩减)或混淆机制时Function.name的表现很不可靠。因为这些工具作为构建流程的一部分时,会在部署到生产环境前有意压缩源码。此类的转码机制经常会再会在构建时修改函数名。

例如下面的代码:

function Foo() {};
var foo = new Foo();

if (foo.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}

可能被压缩为:

function a() {};
var b = new a();
if (b.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}

在未压缩版本里, 这段程序的执行逻辑会进入逻辑是的分支里,进而打印出'foo' is an instance of 'Foo'。但是,在压缩版本里它的表现却完全不同,它进入了else分支。因此如果你像上面这样,使用了Function.name, 那要确认你的构建流程不会修改函数名,或者就不要假定某个特定的名字。

规范

规范 状态 注释
ECMAScript 2015 (6th Edition, ECMA-262)
name
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
name
Living Standard  

浏览器兼容性

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support 33.0 (Yes) (Yes) 12 (Yes) (Yes)
Configurable: true 43.0 ? 38 (38) ? ? ?
Inferred names on anonymous functions 51.0 ? 53 (53) ? ? ?
Feature Android Android Webview Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support (Yes) (Yes) (Yes) (Yes) 12 (Yes) (Yes) (Yes)
Configurable: true ? ? ? 38.0 (38) ? ? ? ?
Inferred names on anonymous functions 未实现 51.0 ? 53.0 (53) ? ? ? 51.0

文档标签和贡献者

 此页面的贡献者: inickel, minstrel1977, xgqfrms-GitHub, Marco_dev, teoli, ziyunfei
 最后编辑者: inickel,