方法定义

方法定义是用于在对象初始化程序中定义函数属性的简写语法。它也可用于中。

试一试

语法

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" + 2]() {
    return 2;
  },
};

console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 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 语言规范
# sec-method-definitions

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅