我正在尝试使用具有经典原型继承的JS,而不是新的ES6类模型,主要是为了能够访问闭包作用域。
在下面的示例中,我想公开由@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
}
运算符创建的,通过函数current
通过Counter
对象在函数this
中声明的变量new
。
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
在哪里存储其值?
答案 0 :(得分:1)
您的代码调用Object.assign()
时,它将传入一个具有current
的getter和setter的对象。因此,Object.assign()
流程本身将在将属性值复制到新对象时调用该getter以获取属性“ current”的值。因此,Counter对象最终没有获得getter和setter的 ,这解释了您的结果。它的“ counter”属性只是一个简单的属性,带有构造函数代码运行时本地counter
变量的值的副本。
Object.assign()
只是复制属性值,就像访问其他任何代码一样访问它们。
请注意,如果您根本不调用Object.assign()
,而只是返回要传递给它的对象,则将获得一个工作对象,其行为与预期的一样