get
get
语法将对象属性绑定到一个函数,该函数将在查找该属性时被调用。它也可用于类。
试一试
语法
{ 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()
会产生类似的结果,但在类
上使用时,两者之间存在细微差别。
使用 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 语言规范 # sec-method-definitions |
浏览器兼容性
BCD 表格仅在浏览器中加载
另请参阅
- 使用对象 指南
- 函数
set
Object.defineProperty()
- 对象初始化器
class
- 属性访问器
- 不兼容的 ES5 更改:字面量 getter 和 setter 函数现在必须正好有零个或一个参数 作者:Jeff Walden (2010)
- 更多 SpiderMonkey 更改:用于创建 getter 和 setter 的古老、深奥、很少使用的语法正在被删除 作者:Jeff Walden (2010)