方法定义

方法定义是用于在对象初始值设定项中定义函数属性的较短语法。也可用于 classes

¥Method definition is a shorter syntax for defining a function property in an object initializer. It can also be used in classes.

Try it

语法

¥Syntax

js
({
  property(parameters) {},
  *generator(parameters) {},
  async property(parameters) {},
  async *generator(parameters) {},

  // with computed keys
  [expression](parameters) {},
  *[expression](parameters) {},
  async [expression](parameters) {},
  async *[expression](parameters) {},
})

描述

¥Description

简写语法类似于 gettersetter 语法。

¥The shorthand syntax is similar to the getter and setter syntax.

给出以下代码:

¥Given the following code:

js
const obj = {
  foo: function () {
    // …
  },
  bar: function () {
    // …
  },
};

你现在可以将其缩短为:

¥You are now able to shorten this to:

js
const obj = {
  foo() {
    // …
  },
  bar() {
    // …
  },
};

使用此语法定义的属性是所创建对象的自己的属性,并且它们是可配置的、可枚举的和可写的,就像普通属性一样。

¥Properties defined using this syntax are own properties of the created object, and they are configurable, enumerable, and writable, just like normal properties.

function*async functionasync function* 属性都有各自的方法语法;请参阅下面的示例。

¥function*, async function, and async function* properties all have their respective method syntaxes; see examples below.

但是,请注意,方法语法并不等同于以函数为值的普通属性 - 存在语义差异。这使得对象字面量中定义的方法与 classes 中的方法更加一致。

¥However, note that the method syntax is not equivalent to a normal property with a function as its value — there are semantic differences. This makes methods defined in object literals more consistent with methods in classes.

方法定义不可构造

¥Method definitions are not constructable

方法不能是构造函数!如果你尝试实例化它们,它们将抛出 TypeError。另一方面,作为函数创建的属性可以用作构造函数。

¥Methods cannot be constructors! They will throw a TypeError if you try to instantiate them. On the other hand, a property created as a function can be used as a constructor.

js
const obj = {
  method() {},
};
new obj.method(); // TypeError: obj.method is not a constructor

在方法定义中使用 super

¥Using super in method definitions

只有定义为方法的函数才能访问 super 关键字。super.prop 在初始化该方法的对象的原型上查找属性。

¥Only functions defined as methods have access to the super keyword. super.prop looks up the property on the prototype of the object that the method was initialized on.

js
const obj = {
  __proto__: {
    prop: "foo",
  },
  notAMethod: function () {
    console.log(super.prop); // SyntaxError: 'super' keyword unexpected here
  },
};

示例

¥Examples

使用方法定义

¥Using method definitions

js
const obj = {
  a: "foo",
  b() {
    return this.a;
  },
};
console.log(obj.b()); // "foo"

类中的方法定义

¥Method definitions in classes

你可以使用完全相同的语法来定义类实例上可用的公共实例方法。在类中,方法之间不需要逗号分隔符。

¥You can use the exact same syntax to define public instance methods that are available on class instances. In classes, you don't need the comma separator between methods.

js
class ClassWithPublicInstanceMethod {
  publicMethod() {
    return "hello world";
  }
  secondPublicMethod() {
    return "goodbye world";
  }
}

const instance = new ClassWithPublicInstanceMethod();
console.log(instance.publicMethod()); // "hello world"

公共实例方法是在类的 prototype 属性上定义的,因此由该类的所有实例共享。它们是可写的、不可枚举的且可配置的。

¥Public instance methods are defined on the prototype property of the class and are thus shared by all instances of the class. They are writable, non-enumerable, and configurable.

在实例方法内部,thissuper 的工作方式与普通方法相同。通常,this 指的是实例本身。在子类中,super 允许你访问该方法所附加的对象的原型,从而允许你从超类调用方法。

¥Inside instance methods, this and super work like in normal methods. Usually, this refers to the instance itself. In subclasses, super lets you access the prototype of the object that the method is attached to, allowing you to call methods from the superclass.

js
class BaseClass {
  msg = "hello world";
  basePublicMethod() {
    return this.msg;
  }
}

class SubClass extends BaseClass {
  subPublicMethod() {
    return super.basePublicMethod();
  }
}

const instance = new SubClass();
console.log(instance.subPublicMethod()); // "hello world"

静态方法和私有方法使用类似的语法,在 static私有属性 页中进行了描述。

¥Static methods and private methods use similar syntaxes, which are described in the static and private properties pages.

计算属性名称

¥Computed property names

该方法语法还支持 计算属性名称

¥The method syntax also supports computed property names.

js
const bar = {
  foo0: function () {
    return 0;
  },
  foo1() {
    return 1;
  },
  ["foo" + 2]() {
    return 2;
  },
};

console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 2

生成器方法

¥Generator methods

请注意,生成器方法语法中的星号 (*) 必须位于生成器属性名称之前。(也就是说,* g(){} 可以工作,但 g *(){} 不行。)

¥Note that the asterisk (*) in the generator method syntax must be before the generator property name. (That is, * g(){} will work, but g *(){} will not.)

js
// Using a named property
const obj = {
  g: function* () {
    let index = 0;
    while (true) {
      yield index++;
    }
  },
};

// The same object using shorthand syntax
const obj2 = {
  *g() {
    let index = 0;
    while (true) {
      yield index++;
    }
  },
};

const it = obj2.g();
console.log(it.next().value); // 0
console.log(it.next().value); // 1

异步方法

¥Async methods

js
// Using a named property
const obj = {
  f: async function () {
    await somePromise;
  },
};

// The same object using shorthand syntax
const obj2 = {
  async f() {
    await somePromise;
  },
};

异步生成器方法

¥Async generator methods

js
// Using a named property
const obj = {
  f: async function* () {
    yield 1;
    yield 2;
    yield 3;
  },
};

// The same object using shorthand syntax
const obj2 = {
  async *f() {
    yield 1;
    yield 2;
    yield 3;
  },
};

规范

Specification
ECMAScript Language Specification
# sec-method-definitions

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看