方法定义
方法定义是用于在对象初始化程序中定义函数属性的简写语法。它也可用于类中。
试一试
语法
js
({
property(parameters) {},
*generator(parameters) {},
async property(parameters) {},
async *generator(parameters) {},
// with computed keys
[expression](parameters) {},
*[expression](parameters) {},
async [expression](parameters) {},
async *[expression](parameters) {},
})
描述
给定以下代码
js
const obj = {
foo: function () {
// …
},
bar: function () {
// …
},
};
您现在可以将其缩短为
js
const obj = {
foo() {
// …
},
bar() {
// …
},
};
使用此语法定义的属性是创建的对象的自身属性,并且它们是可配置的、可枚举的和可写的,就像普通属性一样。
function*
、async function
和async 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
属性上,因此由类的所有实例共享。它们是可写的、不可枚举的和可配置的。
在实例方法内部,this
和super
的工作方式与普通方法相同。通常,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"
计算出的属性名称
方法语法也支持计算出的属性名称。
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 表格仅在浏览器中加载