【发布时间】:2019-09-07 23:06:51
【问题描述】:
我正在尝试使用带有经典原型继承的 JS,而不是新的 ES6 类模型,主要是为了能够访问闭包范围。
在下面的示例中,我想通过new 运算符创建的this 对象暴露在函数Counter 中声明的变量current。
function Counter(start, stop) {
var current = start;
function inc() { if (current < stop) return current++ }
function getCurrent() { return current }
Object.assign(this, { inc, getCurrent,
get current() { return current }, set current(value) { current = value }
})
}
counter = new Counter(0, 3)
while ((v = counter.inc()) !== undefined)
console.log(counter.getCurrent(), counter.current)
我希望得到以下输出:
1 1
2 2
3 3
因为counter.current 和counter.getCurrent() 应该都返回相同的结果。但相反,我收到了
1 0
2 0
3 0
如果我用下面的代码替换 Object.assign(...),它会按预期工作。
Object.assign(inc, getCurrent })
Object.defineProperty(Counter.prototype, 'current',
{ get: () => { return current }, set: (value) => { current = value }
我可以使用这个模型,(并且目前正在使用),但我想使用前者,因为它更简单且不那么冗长。这里似乎有2个不同的范围。
我使用节点 10、Chrome 73 和 Firefox 68 进行了测试,并收到了相同的结果。
我在这里缺少什么?
在上面的例子中,我尽量做到简洁。但为了更准确和更好地说明这一点,请进行更完整的测试,并附上一些我尝试过的评论。
在这里,我将变量 current 重命名为 _current 以避免与 current 属性混淆,但这不应该是强制性的。
function Counter(start, stop) {
var _current = start;
function inc() { if (_current < stop) return _current++ }
function getCurrent() { return _current }
// Object.assign(this.constructor.prototype,
// Object.assign(this.__proto__,
// Object.assign(Counter.prototype, {
Object.assign(this, {inc, getCurrent,
get current() { return _current }, set current(value) { _current = value }
// get current() { return current } // supposed to be read-only, but not
})
// This works as expected
// Object.defineProperty(Counter.prototype, 'current',
// { get: () => { return _current }, set: (value) => { _current = value } })
}
counter = new Counter(0, 3)
while ((v = counter.inc()) !== undefined) {
console.log(counter.getCurrent(), counter.current)
counter.current -= 0.5
}
上面代码的输出是:
1 0
2 -0.5
3 -1
counter.current -= 0.5 在哪里存储它的值?
【问题讨论】:
-
Object.assign不会复制 getter,它会评估它们。只需return来自Counter的对象文字。或者拨打Object.definePropertythis。 -
我不能返回对象字面量,因为那样的话,我会失去 this 的类型 Counter()。而且我相信以前的 getter/setter 问题没有我的问题的答案。为什么输出不一样?第二个属性
counter.current -= 0.5将值存储在哪里? -
你所说的“这个类型”是什么意思?反正你也不打算使用原型。
-
关于您编辑的问题,
counter.current是一个简单的数据属性。您拨打的Object.assign(…)与this.inc = inc; this.getCurrent = getCurrent; this.current = _current; // 0的结果完全相同。-= 0.5赋值简单地将新数字存储在counter对象上。inc和getCurrent仍然是内部_current变量的闭包。 -
我的意思是
get current() { … }, set current(…) { … },但是是的。当然这是一个普通的对象,但没关系,它具有您想要的所有功能。你为什么关心对象的类型,你需要它做什么?
标签: javascript properties getter-setter