Как наблюдать изменения значений в переменных JS - PullRequest
2 голосов
/ 10 февраля 2011

Мне интересно, может ли кто-нибудь помочь мне с чем-то, что, на мой взгляд, довольно прямолинейно:

По сути, я хочу расширить прототипы всех типов данных (включая внутренние типы), чтобы разрешить какие-топользовательские функции, рассмотрим:

var x = "some string";
var y = 101;

x = "some other value";
y++;

x.onChange();
y.onChange();

Это основная идея, которую я хочу, но на самом деле я хочу, чтобы onChange (в этом примере) был другим, поэтому новая функция для фактической переменной (а не стандартное расширение прототипа), то есть:

x.onChange = function() {
    alert("x.onChange");
}

y.onChange = function() {
    alert("y.onChange");
}

Кажется, это не работает, но я должен упустить что-то довольно простое, нет?Я имею в виду, конечно, я могу расширить все объекты и типы и добавить новые функции ... нет?

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

5 голосов
/ 10 февраля 2011

Я мог бы испытать желание приблизиться к этому не пытаясь добавить методы к существующим типам, но создать объект, который может обернуть примитивный тип. Я бы назвал это «наблюдением» значения и мог бы реализовать его примерно так:

function observable(v){
    this.value = v;

    this.valueChangedCallback = null;

    this.setValue = function(v){
        if(this.value != v){
            this.value = v;
            this.raiseChangedEvent(v);
        }
    };

    this.getValue = function(){
        return this.value;
    };

    this.onChange = function(callback){
        this.valueChangedCallback = callback;
    };

    this.raiseChangedEvent = function(v){
        if(this.valueChangedCallback){
             this.valueChangedCallback(v);
        }   
    };
}

Затем его можно использовать для наблюдения за изменениями в любом значении (при условии, что это значение затем изменяется только с помощью методов в наблюдаемом классе - небольшое отвлечение IMO).

Примерно так будет работать с кодом выше:

var obs = new observable(123);
obs.onChange(function(v){
         alert("value changed to: " + v);
     });

// the onChange callback would be called after something like obs.setValue(456);

Живой пример здесь -> http://jsfiddle.net/MeAhz/

0 голосов
/ 18 июля 2018

Стандартный способ УСТАРЕЛО: Object.observe ()

Метод Object.observe () был , используемый для асинхронного наблюдения за изменениями объекта.Это обеспечило поток изменений в порядке, в котором они происходят.Однако этот API устарел и удален из браузеров.

let myObservdObject = Object.observe( { a : 'foo' }, e=>console.log('change!', e) );
myObservdObject.a = 'bee';
// callback gets executed
// and prints 'changed! in console, with the change event data

Но прокси-серверы прибыли в Стандарт (ES6), объект.Observe устарел и, как следствие, не поддерживается браузерами.

Прокси - это новый способ наблюдения ... но реализация универсального наблюдателя требует более сложной реализации по сравнению со способом, который нам предоставлял Object.observe.


Наблюдениеизменения значений в сторонних библиотеках

Вы можете найти множество реализаций, основанных на прокси.Некоторые из них реализуют шаблон Observer, который заставляет вас устанавливать или получать значения, используя определенные методы:

Наблюдать : https://www.npmjs.com/package/observe

// define your object
var object = {a:'bee'};
// generate an observer
var observer = observe(object);
// declare the onchange event handler
observer.on( 'change', change=> console.log(change) );
// ready!
// set the value of 'a' and see how the callback is executed...
observer.set('a', 'foo')   
// get the new value
observer.get('a')   // returns 'foo'

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

WatchJS : https://github.com/melanke/Watch.JS/

// define your object
var object = {a:'bee'};
// generate an observer and declare de hadler
watch(object , "a" , e=>console.log(e) );
// ready!
// set the value of 'a' and see how the callback is executed...
object.a = 'foo';   
// get the new value
object.a  // returns 'foo'

Мой собственный apprach: deep-observer

Все реализации имеют свои собственные предостережения, и ни одна из них не работала для моих целей, поэтому мне пришлось реализовать свой собственный подход.

В результате получился высоко настраиваемый метод Observer сочень маленькая занимаемая площадь (<100 байт в сжатом виде) </p>

Глубокий наблюдатель : https://www.npmjs.com/package/deep-observer

// create an observable object
const myObserved = new Observer( { a : 'bee' } , e=>console.log(e) ),
// perform a modification
myObserved.a = 'foo'; 
// console  : { action:'update', oldValue:'bee', object:{a:'foo'}, name:'a' }
myObserved.a;  // returns 'foo'
0 голосов
/ 10 февраля 2011

Расширение прототипа объекта:

Object.prototype.foo = function() { alert('hello world'); };
var a = 1;
a.foo();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...