gpt4 book ai didi

javascript - 使用 Aurelia 进行全局变量订阅

转载 作者:行者123 更新时间:2023-11-30 07:57:11 25 4
gpt4 key购买 nike

我在 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 种初始化形式是等价的。

最佳答案

我试过你的例子并弄清楚哪里出了问题。然后我做了一些研究并了解了原因

所以,问题是您定义全局变量的三种方式实际上等同(Difference between variable declaration syntaxes in Javascript (including global variables)?)。关键是不能从窗口对象中删除使用 var 声明的全局变量。这很重要。

你看,Aurelia 尽可能不使用脏检查。当它被告知要观察对象的属性时,它将将该属性包装在 SetterObserver 对象中,该对象允许 Aurelia 知道属性值何时发生更改。这避免了脏检查,而无需更改设置属性值的方式。

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

归根结底,这是浏览器自身API的限制。

需要注意的是,这仅适用于严格模式(Aurelia 在其中运行)。我创建了一个显示此 here 的要点.如果你删除“use strict”这一行,浏览器可以让你做任何你想做的事情并且它可以工作,但在严格模式下它会抛出一个错误。

关于javascript - 使用 Aurelia 进行全局变量订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com