[英]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.