试一试
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 |
浏览器兼容性
加载中…
另见
- 使用对象指南
- 函数
set
Object.defineProperty()
- 对象初始化器
class
- 属性访问器
- 不兼容的 ES5 更改:字面量 getter 和 setter 函数现在必须恰好有零个或一个参数,作者 Jeff Walden (2010)
- 更多 SpiderMonkey 更改:用于创建 getter 和 setter 的古老、深奥、极少使用的语法正在被移除,作者 Jeff Walden (2010)