Прослушивание изменений переменных в JavaScript

«Любой из метасимволов

!"#$%&'()*+,./:;<=>?@[\]^`{|}~

как буквальная часть имени, он должен быть экранирован с двумя обратными косыми чертами: \\.

Например , элемент с id = "foo.bar", может использовать селектор

$("#foo\\.bar")

"[источник: jquery doc ], а элемент с id =" foo [ bar] "(даже если он недействителен для W3C, но распознан JQuery), можно использовать селектор

$("#foo\\[bar\\]")

(Только один asnwer, как и многие другие, но все вместе:))

391
задан A-Sharabiani 8 February 2018 в 16:19
поделиться

4 ответа

Да, object.watch (хотя это нестандартно). Вот моя реализация , которая работает во всех основных браузерах.

190
ответ дан 29 August 2019 в 09:17
поделиться

Не напрямую: вам нужен парный геттер / сеттер с каким-то интерфейсом "addListener / removeListener" ... или плагин NPAPI (но это совсем другая история).

2
ответ дан 22 November 2019 в 23:22
поделиться

Нет.

Но, если это действительно так важно, у вас есть 2 варианта (первый проверяется, второй - нет):

Во-первых, используйте сеттеры и геттеры, например :

var myobj = {a : 1};

function create_gets_sets(obj) { // make this a framework/global function
    var proxy = {}
    for ( var i in obj ) {
        if (obj.hasOwnProperty(i)) {
            var k = i;
            proxy["set_"+i] = function (val) { this[k] = val; };
            proxy["get_"+i] = function ()    { return this[k]; };
        }
    }
    for (var i in proxy) {
        if (proxy.hasOwnProperty(i)) {
            obj[i] = proxy[i];
        }
    }
}

create_gets_sets(myobj);

тогда вы можете сделать что-то вроде:

function listen_to(obj, prop, handler) {
    var current_setter = obj["set_" + prop];
    var old_val = obj["get_" + prop]();
    obj["set_" + prop] = function(val) { current_setter.apply(obj, [old_val, val]); handler(val));
}

затем установить слушателя как:

listen_to(myobj, "a", function(oldval, newval) {
    alert("old : " + oldval + " new : " + newval);
}

Во-вторых, я действительно забыл, я отправлю, пока думаю об этом :)

EDIT: О, я помню: ) Вы можете навести часы на значение:

Учитывая myobj выше, с буквой «a» на нем:

function watch(obj, prop, handler) { // make this a framework/global function
    var currval = obj[prop];
    function callback() {
        if (obj[prop] != currval) {
            var temp = currval;
            currval = obj[prop];
            handler(temp, currval);
        }
    }
    return callback;
}

var myhandler = function (oldval, newval) {
    //do something
};

var intervalH = setInterval(watch(myobj, "a", myhandler), 100);

myobj.set_a(2);
33
ответ дан 22 November 2019 в 23:22
поделиться

Как ответ Люка Шафера ( примечание : это относится к его исходному сообщению; но весь смысл здесь остается в силе после редактирования), я бы также предложите пару методов Get / Set для доступа к вашему значению.

Однако я бы предложил некоторые изменения (и поэтому я публикую ...).

Проблема с этим кодом заключается в том, что поле a объекта myobj доступен напрямую, поэтому можно получить к нему доступ / изменить его значение без запуска слушателей:

var myobj = { a : 5, get_a : function() { return this.a;}, set_a : function(val) { this.a = val; }}
/* add listeners ... */
myobj.a = 10; // no listeners called!

Инкапсуляция

Итак, чтобы гарантировать, что слушатели действительно называется, мы должны были бы запретить этот прямой доступ к полю a . Как это сделать? Используйте закрытие !

var myobj = (function() { // Anonymous function to create scope.

    var a = 5;            // 'a' is local to this function
                          // and cannot be directly accessed from outside
                          // this anonymous function's scope

    return {
        get_a : function() { return a; },   // These functions are closures:
        set_a : function(val) { a = val; }  // they keep reference to
                                            // something ('a') that was on scope
                                            // where they were defined
    };
})();

Теперь вы можете использовать тот же метод для создания и добавления слушателей, как предложил Люк, но вы можете быть уверены, что невозможно прочитать или записать в , оставаясь незамеченным!

Добавление инкапсулированных полей программным способом

Все еще на пути Люка, я предлагаю простой способ добавить инкапсулированные поля полей и соответствующих методов получения / установки объектов с помощью простого вызова функции.

Обратите внимание, что это будет правильно работать только с типами значений . Чтобы это работало с ссылочными типами , должна быть реализована какая-то глубокая копия (см., Например, этот ).

function addProperty(obj, name, initial) {
    var field = initial;
    obj["get_" + name] = function() { return field; }
    obj["set_" + name] = function(val) { field = val; }
}

Это работает. так же, как и раньше: мы создаем локальную переменную для функции, а затем создаем замыкание.

Как это использовать? Просто:

var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);
7
ответ дан 22 November 2019 в 23:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: