方法定义

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 2015 年 9 月以来,该特性已在各大浏览器中可用。

方法定义是一种在对象初始化器中定义函数属性的更短的语法。它也可以用于中。

试一试

const obj = {
  foo() {
    return "bar";
  },
};

console.log(obj.foo());
// Expected output: "bar"

语法

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

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

描述

这种简写语法类似于gettersetter语法。

给定以下代码

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

你现在可以将其缩短为

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

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

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

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

方法定义不可构造

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

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

在方法定义中使用 super

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

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

示例

使用方法定义

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

类中的方法定义

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

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

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

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

在实例方法内部,thissuper像普通方法一样工作。通常,this指向实例本身。在子类中,super允许你访问方法所附加的对象的原型,从而可以调用超类中的方法。

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私有元素页面中描述。

计算属性名

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

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

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

生成器方法

请注意,生成器方法语法中的星号 (*) 必须在生成器属性名*之前*。(也就是说,* g(){}会起作用,但g *(){}不会。)

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

异步方法

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

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

异步生成器方法

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;
  },
};

规范

规范
ECMAScript® 2026 语言规范
# sec-method-definitions

浏览器兼容性

另见