javascript - 如何使用对象方法定义而不进入无限循环

标签 javascript object initializer

On MDN有一个示例显示在对象初始化中使用 get 和 set:

var o = {
  property: function ([parameters]) {},
  get property() {},
  set property(value) {}
};

没有任何示例显示如何使用该结构,我总是进入无限循环,例如:

var o = {
  property: function (test) {return "test"},
  get property() {return this.property;},
  set property(value) {this.property = value;}
};

当我尝试访问名为 property 的对象属性时,无限循环开始,我认为这是因为 get 在尝试读取它获取的属性时也会触发自身。

console.log(o.property); // infinite loop occurs

所以我假设我做错了,但在这种情况下,该网页上的示例不是很清楚。我找到的临时解决方案是将值保存在类似的属性中(例如_property),但我不想这样做并保持对象、getter 和 setter 的属性名称完整。

这可能吗?如果可以,如何正确执行?

最佳答案

A property of an object can also refer to a function or a getter or setter method.

有点令人困惑,但请注意OR。这里的意思是,您可以拥有引用函数的对象的属性,或者可以拥有引用 getter/setter 的对象的属性。

Getter/setter 只是尊重特定签名的函数,并且充当具有附加功能的属性,可以在设置/获取这些属性时注册这些附加功能。

通常,这些仅用于计算值,这些值基于对象的其他状态属性。

但是,在某些情况下,您确实可以使用它们来添加一些功能/预先计算,例如设置值时。

您可以通过多种方式做到这一点,但如果您仍然需要一个与对象上的所有其他属性不同的 getter/setter 名称。

例如,有这样的东西

var o = {
  prop: 0.6
}

如果您想添加诸如访问类似百分比值之类的内容,您可以执行以下操作:

var o = {
  prop: 0.6,
  get propPerc() { return this.prop * 100; },
  set propPerc(val) { this.prop = this.val / 100; }
}

但是,如果您想简单地增强 Prop 的设置/获取(例如确保始终有一个数值),您需要执行以下操作:

var o = {
  _prop: 0.6,
  get prop() { return this._prop || 0; },
  set prop(val) { this._prop = this.val || 0; }
}

您需要为属性指定一个与 get/set 属性不同的名称。不幸的是,对于外部来说,这两个属性都是可见的,因此,如果您使用这种方法,则按照约定不要直接使用 _prop,因为 JS 本身没有私有(private)属性。

但是,您可以使用符号模拟类似私有(private)属性的内容,例如:

var propSymbol = Symbol('prop');

var o = {
  get prop() { return this[propSymbol] || 0; },
  set prop(val) { this[propSymbol] = this.val || 0; }
}
o[propSymbol] = 0.6; // can only do it here, assuming this piece of code is not accessible to outside and propSymbol is just a local variable.

希望这有帮助。

关于javascript - 如何使用对象方法定义而不进入无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43840825/

相关文章:

python - 如何检查python对象列表中是否存在值

javascript - 替换为 javascript 中的 regExp

javascript - 如何为基于 youtube.com/embed URL 的链接添加类?

javascript - Jquery attr 不工作 Internet Explorer

javascript - 降级 angular 2 指令或至少能够在 angular js 中使用它

javascript - .fill() 相当于对象

javascript - 如何仅更改对象的一个​​属性

ios - 在 Swift 中继承 MKCircle

java - Android 上的 TextToSpeech 初始化——如果失败怎么办?

objective-c - Objective-C 中的静态初始值设定项