如何观察JS变量中的值变化

时间:2011-02-10 12:14:56

标签: javascript observable watch

我想知道是否有人可以帮助我做一些我认为相当直接的事情:

基本上我想扩展所有数据类型的原型(包括内部类型),以允许某种自定义函数,考虑:

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

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

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

这是我之后的基本想法,但我真正想要的是实际上让onChange(在这个例子中)与实际变量(而不是标准原型扩展)的新函数不同,即:< / p>

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

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

这似乎不起作用,但我必须遗漏一些非常简单的事情吗?我的意思是我可以扩展所有对象和类型并添加新功能......不是吗?

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:5)

我可能不想尝试将方法添加到现有类型,而是创建一个可以包装主要类型的对象。我会称之为“观察”一个值,并且可能会实现这样的:

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);

这里的实例 - &gt; http://jsfiddle.net/MeAhz/

答案 1 :(得分:0)

扩展对象原型:

Object.prototype.foo = function() { alert('hello world'); };
var a = 1;
a.foo();

答案 2 :(得分:0)

不推荐使用的标准方法: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),因此对象(Object.Observe)被弃用,因此浏览器不支持。

代理是观察的新方法...但是与Object.observe用于提供给我们的方法相比,实现通用观察器需要更复杂的实现。


通过第三方库观察价值的变化

您可以找到许多基于代理的实现。 其中一些实现观察者模式,迫使您使用特定方法设置或获取值:

观察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'

我自己的方法:深入观察者

所有实现都有自己的警告,并且没有一个适合我的目的,因此我不得不实现自己的方法。

结果是高度可定制的Observer方法,占用空间非常小(压缩了<100字节)

深入观察者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'