试一试
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) {},
})
描述
给定以下代码
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".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 |
浏览器兼容性
加载中…