Javascript getter / setter作用域访问

时间:2019-09-07 23:06:51

标签: javascript properties getter-setter

我正在尝试使用具有经典原型继承的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.currentcounter.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在哪里存储其值?

1 个答案:

答案 0 :(得分:1)

您的代码调用Object.assign()时,它将传入一个具有current的getter和setter的对象。因此,Object.assign()流程本身将在将属性值复制到新对象时调用该getter以获取属性“ current”的值。因此,Counter对象最终没有获得getter和setter的 ,这解释了您的结果。它的“ counter”属性只是一个简单的属性,带有构造函数代码运行时本地counter变量的值的副本。

Object.assign()只是复制属性值,就像访问其他任何代码一样访问它们。

请注意,如果您根本不调用Object.assign(),而只是返回要传递给它的对象,则将获得一个工作对象,其行为与预期的一样