Глобальная вар-подписка с Aurelia
У меня есть несколько глобальных переменных, инициализированных в теге script в 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 формы инициализации эквивалентны.
1 ответ
Я поиграл с твоим примером и выяснил, где что-то идет не так. Затем я провел небольшое исследование и узнал почему.
Итак, дело в том, что три способа определения глобальной переменной на самом деле не эквивалентны ( Разница между синтаксисами объявления переменных в Javascript (включая глобальные переменные)?). Ключевым моментом является то, что глобальная переменная объявлена с использованием var
не может быть удален из объекта окна. Это важно.
Видите ли, Аурелия не использует грязную проверку, если это вообще возможно. Когда ему говорят наблюдать свойство на объекте, оно обернет это свойство в SetterObserver
объект, который позволяет Aurelia знать, когда значение свойства изменяется. Это позволяет избежать грязной проверки без необходимости изменять способ установки значений свойств.
Итак, Aurelia заменяет созданное вами свойство оболочкой. Это делается с помощью Reflect.defineProperty
метод. Это встроенный API ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty). Но помните, что глобальные переменные нельзя удалить из объекта окна. Это также означает, что Reflect.defineProperty
не может переопределить свойство.
В конце концов это означает, что это ограничение собственных API браузера.
Единственное предостережение в том, что это применимо только в строгом режиме (в котором работает Аурелия). Я создал суть, которая показывает это здесь. Если вы удалите строку "использовать строгий", браузер позволяет вам делать все, что вы хотите, и он работает, но в строгом режиме он выдает ошибку.