get

get 语法将对象属性绑定到一个函数,该函数将在查找该属性时被调用。它也可用于

试一试

语法

js
{ get prop() { /* … */ } }
{ get [expression]() { /* … */ } }

还有一些额外的语法限制

  • getter 必须正好有零个参数。

参数

prop

要绑定到给定函数的属性的名称。与对象初始化程序中的其他属性一样,它可以是字符串字面量、数字字面量或标识符。

表达式

您还可以使用表达式作为计算属性名称来绑定到给定函数。

描述

有时,希望允许访问返回动态计算值的属性,或者可能希望反映内部变量的状态,而无需使用显式方法调用。在 JavaScript 中,这可以通过使用getter来实现。

对象属性要么是数据属性,要么是访问器属性,但它不能同时是两者。阅读Object.defineProperty()以获取更多信息。getter 语法允许您在对象初始化程序中指定 getter 函数。

js
const obj = {
  get prop() {
    // getter, the code executed when reading obj.prop
    return someValue;
  },
};

使用此语法定义的属性是创建的对象的自身属性,并且它们是可配置的和可枚举的。

示例

在对象初始化程序中为新对象定义 getter

这将为对象 obj 创建一个伪属性 latest,它将返回 log 中的最后一个数组项。

js
const obj = {
  log: ["example", "test"],
  get latest() {
    return this.log.at(-1);
  },
};
console.log(obj.latest); // "test"

请注意,尝试为 latest 赋值不会更改它。

在类中使用 getter

您可以使用完全相同的语法来定义在类实例上可用的公共实例 getter。在类中,您不需要方法之间的逗号分隔符。

js
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 属性不可枚举。

静态 getter 和私有 getter 使用类似的语法,这些语法在static私有属性 页面中进行了描述。

使用 delete 运算符删除 getter

如果要删除 getter,只需delete 它即可

js
delete obj.latest;

使用 defineProperty 为现有对象定义 getter

要以后在任何时间将 getter 附加到现有对象,请使用Object.defineProperty()

js
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)

使用计算属性名称

js
const expr = "foo";

const obj = {
  get [expr]() {
    return "bar";
  },
};

console.log(obj.foo); // "bar"

定义静态 getter

js
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 作为其自身属性。在获取属性时,属性将从对象中删除并重新添加,但这次隐式地作为数据属性。最后,该值被返回。

js
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() 时,属性将定义在其应用到的实例上。

js
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 表格仅在浏览器中加载

另请参阅