試一試
const obj = {
log: ["a", "b", "c"],
get latest() {
return this.log[this.log.length - 1];
},
};
console.log(obj.latest);
// Expected output: "c"
語法
{ get prop() { /* … */ } }
{ get [expression]() { /* … */ } }
還有一些額外的語法限制
- getter 必須恰好有零個引數。
引數
描述
有時,希望允許訪問返回動態計算值的屬性,或者你可能希望反映內部變數的狀態,而無需顯式方法呼叫。在 JavaScript 中,這可以透過使用 getter 來實現。
物件屬性要麼是資料屬性,要麼是訪問器屬性,但不能同時是兩者。有關更多資訊,請參閱Object.defineProperty()。getter 語法允許你在物件初始化器中指定 getter 函式。
const obj = {
get prop() {
// getter, the code executed when reading obj.prop
return someValue;
},
};
使用此語法定義的屬性是建立物件的自身屬性,並且它們是可配置和可列舉的。
示例
在物件初始化器中為新物件定義 getter
這將為物件 obj 建立一個偽屬性 latest,它將返回 log 中的最後一個數組項。
const obj = {
log: ["example", "test"],
get latest() {
return this.log.at(-1);
},
};
console.log(obj.latest); // "test"
請注意,嘗試為 latest 賦值不會改變它。
在類中使用 getter
你可以使用完全相同的語法來定義在類例項上可用的公共例項 getter。在類中,方法之間不需要逗號分隔符。
class ClassWithGetSet {
#msg = "hello world";
get msg() {
return this.#msg;
}
set msg(x) {
this.#msg = `hello ${x}`;
}
}
const instance = new ClassWithGetSet();
console.log(instance.msg); // "hello world"
instance.msg = "cake";
console.log(instance.msg); // "hello cake"
getter 屬性定義在類的 prototype 屬性上,因此由類的所有例項共享。與物件字面量中的 getter 屬性不同,類中的 getter 屬性不可列舉。
使用 delete 運算子刪除 getter
如果你想移除 getter,你可以直接delete 它
delete obj.latest;
使用 defineProperty 在現有物件上定義 getter
要隨時向現有物件追加 getter,請使用Object.defineProperty()。
const o = { a: 0 };
Object.defineProperty(o, "b", {
get() {
return this.a + 1;
},
});
console.log(o.b); // Runs the getter, which yields a + 1 (which is 1)
使用計算屬性名
const expr = "foo";
const obj = {
get [expr]() {
return "bar";
},
};
console.log(obj.foo); // "bar"
定義靜態 getter
class MyConstants {
static get foo() {
return "foo";
}
}
console.log(MyConstants.foo); // 'foo'
MyConstants.foo = "bar";
console.log(MyConstants.foo); // 'foo', a static getter's value cannot be changed
智慧/自重寫/惰性 getter
getter 為你提供了一種 定義 物件屬性的方法,但它們直到屬性被訪問時才 計算 屬性的值。getter 將計算值的成本推遲到需要該值時。如果從未需要它,你就不必為此付出成本。
一種額外的最佳化技術,用於惰性化或延遲屬性值的計算並將其快取以供以後訪問,是 智慧(或 記憶化)getter。值在第一次呼叫 getter 時計算,然後快取起來,以便後續訪問返回快取值而不重新計算。這在以下情況下很有用:
- 如果屬性值的計算成本很高(佔用大量 RAM 或 CPU 時間,生成工作執行緒,檢索遠端檔案等)。
- 如果現在不需要該值。它將在以後使用,或者在某些情況下,根本不使用。
- 如果它被使用,它將被多次訪問,並且不需要重新計算該值將永遠不會改變或不應重新計算。
注意:這意味著你不應該為預期會更改其值的屬性編寫惰性 getter,因為如果 getter 是惰性的,那麼它將不會重新計算該值。
請注意,getter 本身並不是“惰性”或“記憶化”的;如果你希望有這種行為,則必須實現此技術。
在以下示例中,物件有一個 getter 作為其自身屬性。獲取屬性時,該屬性從物件中移除並重新新增,但這次隱式地作為資料屬性。最後,返回該值。
const obj = {
get notifier() {
delete this.notifier;
this.notifier = document.getElementById("bookmarked-notification-anchor");
return this.notifier;
},
};
get 與 defineProperty
雖然使用 get 關鍵字和 Object.defineProperty() 具有相似的結果,但在 classes 上使用時,兩者之間存在細微差別。
使用 get 時,屬性將定義在例項的原型上,而使用 Object.defineProperty() 時,屬性將定義在應用它的例項上。
class Example {
get hello() {
return "world";
}
}
const obj = new Example();
console.log(obj.hello);
// "world"
console.log(Object.getOwnPropertyDescriptor(obj, "hello"));
// undefined
console.log(
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), "hello"),
);
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-method-definitions |
瀏覽器相容性
載入中…
另見
- 使用物件指南
- 函式
setObject.defineProperty()- 物件初始化器
class- 屬性訪問器
- 不相容的 ES5 更改:字面量 getter 和 setter 函式現在必須恰好有零個或一個引數,作者 Jeff Walden (2010)
- 更多 SpiderMonkey 更改:用於建立 getter 和 setter 的古老、深奧、極少使用的語法正在被移除,作者 Jeff Walden (2010)