admin管理员组文章数量:1352152
Im wondering if someone might be able to help me with something that i think it fairly straight forward:
Essentially i want to extend the prototypes of all datatypes (including intrinsic types), to allow some kind of custom functions, consider:
var x = "some string";
var y = 101;
x = "some other value";
y++;
x.onChange();
y.onChange();
This is the basic idea im after, but really what i want is to actually have the onChange (in this example) to be different so a new function for the actual variable (rather than a stardard prototype extension), ie:
x.onChange = function() {
alert("x.onChange");
}
y.onChange = function() {
alert("y.onChange");
}
This doesnt seem to work but i must be missing something quite simple no? I mean surely i can extend all object and types and add on new functions... no?
Any help would be greatly appreciated!
Im wondering if someone might be able to help me with something that i think it fairly straight forward:
Essentially i want to extend the prototypes of all datatypes (including intrinsic types), to allow some kind of custom functions, consider:
var x = "some string";
var y = 101;
x = "some other value";
y++;
x.onChange();
y.onChange();
This is the basic idea im after, but really what i want is to actually have the onChange (in this example) to be different so a new function for the actual variable (rather than a stardard prototype extension), ie:
x.onChange = function() {
alert("x.onChange");
}
y.onChange = function() {
alert("y.onChange");
}
This doesnt seem to work but i must be missing something quite simple no? I mean surely i can extend all object and types and add on new functions... no?
Any help would be greatly appreciated!
Share Improve this question edited Jul 18, 2018 at 7:02 colxi 8,7503 gold badges47 silver badges44 bronze badges asked Feb 10, 2011 at 12:14 Ian HarriganIan Harrigan 8366 silver badges14 bronze badges3 Answers
Reset to default 8I might be tempted to approach this not by trying to add methods to existing types, but to create an object that can wrap a primative type. I would call this "observing" a value, and might implement it something like this:
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);
}
};
}
This can then be used to observe changes in any value (so long as that value is then changed only by methods on the observable class - a small detraction IMO).
Something like this would work with the above code:
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);
Live example here --> http://jsfiddle/MeAhz/
Extend the object prototype:
Object.prototype.foo = function() { alert('hello world'); };
var a = 1;
a.foo();
The standard DEPRECATED way : Object.observe()
The Object.observe() method was used for asynchronously observing the changes to an object. It provided a stream of changes in the order in which they occur. However, this API has been deprecated and removed from browsers.
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
But proxies arrived to the Standard (ES6) an Object.Observe became deprecated and, in consecuence, unsupported by the browsers.
Proxies are the new way to observe... but implement a generic observer requires a more plex implementation, in parsion with the way Object.observe used to provide us.
Observe value changes with third party libraries
You can find arround many implementations based in proxies. Some of them implement the Observer pattern, wich forces you to set or get the values using specific methods :
Observe : https://www.npmjs./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'
Other libraries instead, let you interact with your variables using a more natural way:
WatchJS : https://github./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'
My own apprach : deep-observer
All the implementaions have their own caveats, and none of them was working for my purposes, so i had to implement my own approach.
The result is a highly customizable Observer method with a really small footprint ( <100 bytes gziped)
Deep-observer : https://www.npmjs./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'
本文标签: javascriptHow to observe value changes in JS variablesStack Overflow
版权声明:本文标题:javascript - How to observe value changes in JS variables - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743891650a2557028.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论