試一試
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 |
瀏覽器相容性
載入中…