功能:name

Function 实例的 name 数据属性指示创建函数时指定的函数名称,或者对于匿名创建的函数,它可以是 anonymous''(空字符串)。

¥The name data property of a Function instance indicates the function's name as specified when it was created, or it may be either anonymous or '' (an empty string) for functions created anonymously.

Try it

¥Value

一根绳子。

¥A string.

Property attributes of 功能:name
Writable no
Enumerable no
Configurable yes

注意:在 ES2015 之前的非标准实现中,configurable 属性也是 false

¥Note: In non-standard, pre-ES2015 implementations the configurable attribute was false as well.

描述

¥Description

函数的 name 属性可用于在调试工具或错误消息中标识该函数。它对语言本身没有语义意义。

¥The function's name property can be used to identify the function in debugging tools or error messages. It has no semantic significance to the language itself.

name 属性是只读的,不能通过赋值运算符更改:

¥The name property is read-only and cannot be changed by the assignment operator:

js
function someFunction() {}

someFunction.name = "otherFunction";
console.log(someFunction.name); // someFunction

要更改它,请使用 Object.defineProperty()

¥To change it, use Object.defineProperty().

name 属性通常是根据函数的定义方式推断出来的。在以下各节中,我们将描述推断它的各种方法。

¥The name property is typically inferred from how the function is defined. In the following sections, we will describe the various ways in which it can be inferred.

函数声明

¥Function declaration

name 属性返回函数声明的名称。

¥The name property returns the name of a function declaration.

js
function doSomething() {}
doSomething.name; // "doSomething"

默认导出的函数声明

¥Default-exported function declaration

export default 声明将函数导出为声明而不是表达式。如果是匿名声明,则名称为 "default"

¥An export default declaration exports the function as a declaration instead of an expression. If the declaration is anonymous, the name is "default".

js
// -- someModule.js --
export default function () {}

// -- main.js --
import someModule from "./someModule.js";

someModule.name; // "default"

函数构造函数

¥Function constructor

使用 Function() 构造函数创建的函数的名称为 "anonymous"。

¥Functions created with the Function() constructor have name "anonymous".

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

函数表达式

¥Function expression

如果函数表达式已命名,则该名称将用作 name 属性。

¥If the function expression is named, that name is used as the name property.

js
const someFunction = function someFunctionName() {};
someFunction.name; // "someFunctionName"

使用关键字 function 或箭头函数创建的匿名函数表达式将使用 ""(空字符串)作为其名称。

¥Anonymous function expressions created using the keyword function or arrow functions would have "" (an empty string) as their name.

js
(function () {}).name; // ""
(() => {}).name; // ""

然而,这种情况很少见 - 通常,为了在其他地方引用该表达式,函数表达式在创建时会附加到标识符(例如在变量声明中)。在这种情况下,可以推断出名称,如以下几小节所示。

¥However, such cases are rare — usually, in order to refer to the expression elsewhere, the function expression is attached to an identifier when it's created (such as in a variable declaration). In such cases, the name can be inferred, as the following few subsections demonstrate.

无法推断名称的一个实际情况是从另一个函数返回的函数:

¥One practical case where the name cannot be inferred is a function returned from another function:

js
function getFoo() {
  return () => {};
}
getFoo().name; // ""

变量声明和方法

¥Variable declaration and method

变量和方法可以从语法位置推断匿名函数的名称。

¥Variables and methods can infer the name of an anonymous function from its syntactic position.

js
const f = function () {};
const object = {
  someMethod: function () {},
};

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

这同样适用于赋值:

¥The same applies to assignment:

js
let f;
f = () => {};
f.name; // "f"

初始化器和默认值

¥Initializer and default value

destructuring默认参数类字段 等初始化程序(默认值)中的函数将继承绑定标识符的名称作为其 name

¥Functions in initializers (default values) of destructuring, default parameters, class fields, etc., will inherit the name of the bound identifier as their name.

js
const [f = () => {}] = [];
f.name; // "f"

const { someMethod: m = () => {} } = {};
m.name; // "m"

function foo(f = () => {}) {
  console.log(f.name);
}
foo(); // "f"

class Foo {
  static someMethod = () => {};
}
Foo.someMethod.name; // someMethod

速记法

¥Shorthand method

js
const o = {
  foo() {},
};
o.foo.name; // "foo";

绑定函数

¥Bound function

Function.prototype.bind() 生成一个函数,其名称为 "bound" 加函数名。

¥Function.prototype.bind() produces a function whose name is "bound " plus the function name.

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

获取器和获取器

¥Getter and setter

当使用 getset 访问器属性时,"get" 或 "set" 将出现在函数名称中。

¥When using get and set accessor properties, "get" or "set" will appear in the function name.

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

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

¥Class

类的名称遵循与函数声明和表达式相同的算法。

¥A class's name follows the same algorithm as function declarations and expressions.

js
class Foo {}
Foo.name; // "Foo"

警告:仅当函数没有自己的名为 name 的属性时,JavaScript 才会设置函数的 name 属性。但是,类的 静态成员 将被设置为类构造函数自己的属性,从而阻止应用内置的 name。参见下面的 一个例子

¥Warning: JavaScript will set the function's name property only if a function does not have an own property called name. However, classes' static members will be set as own properties of the class constructor function, and thus prevent the built-in name from being applied. See an example below.

符号作为函数名

¥Symbol as function name

如果 Symbol 用作函数名称并且符号有描述,则方法的名称是方括号中的描述。

¥If a Symbol is used a function name and the symbol has a description, the method's name is the description in square brackets.

js
const sym1 = Symbol("foo");
const sym2 = Symbol();

const o = {
  [sym1]() {},
  [sym2]() {},
};

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

私有属性

¥Private property

私有字段和私有方法的名称中包含哈希值 (#)。

¥Private fields and private methods have the hash (#) as part of their names.

js
class Foo {
  #field = () => {};
  #method() {}
  getNames() {
    console.log(this.#field.name);
    console.log(this.#method.name);
  }
}

new Foo().getNames();
// "#field"
// "#method"

示例

¥Examples

告诉对象的构造函数名称

¥Telling the constructor name of an object

你可以使用 obj.constructor.name 检查对象的 "class"。

¥You can use obj.constructor.name to check the "class" of an object.

js
function Foo() {} // Or: class Foo {}

const fooInstance = new Foo();
console.log(fooInstance.constructor.name); // "Foo"

但是,由于静态成员将成为类自己的属性,因此我们几乎无法获取具有静态方法属性 name() 的任何类的类名:

¥However, because static members will become own properties of the class, we can't obtain the class name for virtually any class with a static method property name():

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

使用 static name() 方法,Foo.name 不再保存实际的类名,而是保存对 name() 函数对象的引用。尝试通过 fooInstance.constructor.name 获取 fooInstance 的类根本不会给我们提供类名,而是给我们静态类方法的引用。示例:

¥With a static name() method Foo.name no longer holds the actual class name but a reference to the name() function object. Trying to obtain the class of fooInstance via fooInstance.constructor.name won't give us the class name at all, but instead a reference to the static class method. Example:

js
const fooInstance = new Foo();
console.log(fooInstance.constructor.name); // ƒ name() {}

由于静态字段的存在,name 也可能不是函数。

¥Due to the existence of static fields, name may not be a function either.

js
class Foo {
  static name = 123;
}
console.log(new Foo().constructor.name); // 123

如果一个类有一个名为 name 的静态属性,它也将变得可写。在没有自定义静态定义的情况下,内置定义是只读的:

¥If a class has a static property called name, it will also become writable. The built-in definition in the absence of a custom static definition is read-only:

js
Foo.name = "Hello";
console.log(Foo.name); // "Hello" if class Foo has a static "name" property, but "Foo" if not.

因此,你可能不会依赖内置的 name 属性来始终保存类的名称。

¥Therefore you may not rely on the built-in name property to always hold a class's name.

JavaScript 压缩器和压缩器

¥JavaScript compressors and minifiers

警告:将 name 属性与源代码转换一起使用时要小心,例如由 JavaScript 压缩器(压缩器)或混淆器执行的转换。这些工具通常用作 JavaScript 构建管道的一部分,以在将程序部署到生产之前减小程序的大小。此类转换通常会在构建时更改函数的名称。

¥Warning: Be careful when using the name property with source-code transformations, such as those carried out by JavaScript compressors (minifiers) or obfuscators. These tools are often used as part of a JavaScript build pipeline to reduce the size of a program prior to deploying it to production. Such transformations often change a function's name at build time.

源代码如:

¥Source code such as:

js
function Foo() {}
const foo = new Foo();

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

可以压缩为:

¥may be compressed to:

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

在未压缩版本中,程序运行到 truthy 分支并记录 "'foo' 是 '富' 的实例" - 而在压缩版本中,它的行为有所不同,并运行到 else 分支。如果你依赖 name 属性(如上面的示例所示),请确保你的构建管道不会更改函数名称,或者不要假设函数具有特定名称。

¥In the uncompressed version, the program runs into the truthy branch and logs "'foo' is an instance of 'Foo'" — whereas, in the compressed version it behaves differently, and runs into the else branch. If you rely on the name property, like in the example above, make sure your build pipeline doesn't change function names, or don't assume a function has a particular name.

规范

Specification
ECMAScript Language Specification
# sec-function-instances-name

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看