繁体   English   中英

Aurelia的全球var订阅

[英]Global var subscription with Aurelia

我在HTML的脚本标签中初始化了一些全局变量:

<script>
  count = 0;
  window.count2 = 0;
  var count3 = 0;
</script>

app.js ,我订阅以观察其更改:

let subscription = bindingEngine.propertyObserver(window, 'count')
  .subscribe((newValue, oldValue) => console.log('Global count: ', newValue, oldValue));

let subscription2 = bindingEngine.propertyObserver(window, 'count2')
  .subscribe((newValue, oldValue) => console.log('window.count2: ', newValue, oldValue));

let subscription3 = bindingEngine.propertyObserver(window, 'count3')
  .subscribe((newValue, oldValue) => console.log('Global count3: ', newValue, oldValue));  

然后我像这样更改值:

change() {
    count++;
    count2++;
    count3++;
}

在控制台中仅观察count && count2

Global count:  1 0
window.count2:  1 0

这是GistRun

问题:为什么无法观察到count3 我认为3种初始化形式是等效的。

我以您的示例为例,弄清楚哪里出了问题。 然后,我做了一些研究,并了解了原因

因此,事实是,定义全局变量的三种方式实际上并不等效( Javascript中的变量声明语法(包括全局变量)之间的区别? )。 关键是不能使用window删除使用var声明的全局变量。 这个很重要。

您会看到,Aurelia完全不使用脏检查。 当被告知要观察对象的属性时,它将将该属性包装在SetterObserver对象中,该对象使Aurelia知道何时更改属性值。 这样可以避免脏检查,而无需更改设置属性值的方式。

因此,Aurelia用包装器替换了您创建的属性。 它通过使用Reflect.defineProperty方法来实现。 这是内置的API( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty )。 但是请记住,不能从window对象中删除全局变量。 这也意味着Reflect.defineProperty无法重新定义该属性。

最后,这意味着它是浏览器自己的API的限制。

一个警告是,这仅适用于严格模式(Aurelia在其中运行)。 我创建了一个要点, 在此处显示了这一点 如果删除“使用严格”行,浏览器将允许您执行所需的任何操作,并且可以运行,但是在严格模式下会引发错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM