Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Проверка значения переменной при её изменении (https://javascript.ru/forum/dom-window/69969-proverka-znacheniya-peremennojj-pri-ejo-izmenenii.html)

dexforint 31.07.2017 18:07

Проверка значения переменной при её изменении
 
Допустим у нас есть переменная x со значением 3 (var x = 3; ), и нам нужно сделать чтобы, когда её значение изменится на 5 (x = 5; ), выводилось сообщение (console.log("x == 5")) . Я пытался реализовать, но я встрял:
---------------------------------------------------------------------
var x = 3;
Object.defineProperty(window, "x", {
get : function(){
return this.x;
},
set : function(value){
this.x = value;
if (this.x == 5) {
console.log("x == 5");
}
}
});
x = 5;
----------------------------------------------------------------------
В итоге выводится ошибка. Как бы данную затею реализовать?

destus 31.07.2017 18:44

var x = 3;
Object.defineProperty(window, "x", {
get : function(){
return this._x;
},
set : function(value){
this._x = value;
if (value == 5) {
console.log("x == 5");
}
}
});
x = 5;

рони 31.07.2017 20:19

destus,
ваш вариант точно рабочий? у меня с var или let не работает.

j0hnik 31.07.2017 20:33

почему нельзя так сделать
var x = 3;
		{// это функция в которой что-то делается
			x = 5;
			xxx();
		}
		function xxx(){
			if(x == 5) console.log("x == 5");
		}

destus 01.08.2017 06:54

рони,
А поподробней? Браузер / ошибка/ гифка?

рони 01.08.2017 09:05

destus,
windows 10
Цитата:

TypeError: can't redefine non-configurable property "x"
-- Mozilla Firefox
Цитата:

Uncaught TypeError: Cannot redefine property: x
at Function.defineProperty (<anonymous>)
-- Google Chrome
создал страницу для теста
<!DOCTYPE html>

<html>
<head>

  <script>
var x = 3;
Object.defineProperty(window, "x", {
get : function(){
return this._x;
},
set : function(value){
this._x = value;
if (value == 5) {
console.log("x == 5");
}
}
});
x = 5;

  </script>
</head>

<body>


</body>
</html>

запускаю в браузерах, ошибки выдаёт.
вчера эти же ошибки были тут пост 2, на форуме, сегодня их нет, когда запускаешь код.

Rise 01.08.2017 12:03

destus, рони,
Выходит глобальные переменные в глобальном eval становятся configurable :)
var x = 3;
alert(delete x);

destus 01.08.2017 13:21

Rise,
рони,
похоже на то...

рони 01.08.2017 14:56

Rise,
destus,
не понимаю чем var x = 3;(не рабочий вариант) отличается от x = 3; (рабочий)
так и так оба варианта глобальны, в данном случае, но второй работает, а первый нет?

destus 01.08.2017 16:48

рони,
Когда объявляем через var, создается свойство объекта window, с десриптором {..., configurable: false, ...}
<script>
var x = 3;
const descriptor = Object.getOwnPropertyDescriptor(window, 'x');
alert(descriptor.configurable);
</script>

, а если без var, то с true
<script>
x = 3;
const descriptor = Object.getOwnPropertyDescriptor(window, 'x');
alert(descriptor.configurable);
</script>

И именно поэтому генерируется ошибка в первом случае, когда мы пытаемся переопределить дескриптор этого свойства (добавляя геттер / сеттер).

Можно было бы определить переменную через var, получить дескриптор, добавить геттер / сеттер, и удалить свойство из объекта window, но т.к. ссылка на переменную создается в VariableEnvironment, то delete window.x всегда будет возвращать false.

Rise,
Цитата:

Выходит глобальные переменные в глобальном eval становятся configurable
Нашел это в спецификации
2. If code is eval code, then let configurableBindings be true else let configurableBindings be false.
...
[[Configurable]]: configurableBindings


Часовой пояс GMT +3, время: 19:13.