function observe(target, listener){
			/*for(var i in target){
				addKey(i);
			}*/
			listener.addKey = addKey;
			listener.remove = function(){
				listener = null;
			};
			function addKey(key){
				var keyFlag = 'key' + key;
				if(this[keyFlag]){
					return;
				}else{
					this[keyFlag] = true;
				}
				var currentValue = target[key];
				var descriptor = Object.getOwnPropertyDescriptor(target, key);
				if(descriptor && descriptor.set){
					var previousSet = descriptor.set;
					var previousGet = descriptor.get;
					Object.defineProperty(target, key, {
						get: function(){
							return (currentValue = previousGet.call(this));
						},
						set: function(value){
							previousSet.call(this, value);
							if(currentValue !== value){
								currentValue = value;
								if(listener){
									queue(listener, this, key);
								}
							}
						}
					});
				}else{
					Object.defineProperty(target, key, {
						get: function(){
							return currentValue;
						},
						set: function(value){
							if(currentValue !== value){
								currentValue = value;
								if(listener){
									queue(listener, this, key);
								}
							}
						}
					});
				}
			}
		}
// this is much faster than polling
this is much faster than polling
this is much faster than polling
function observe(target, listener){
			listener.addKey = addKey;
			listener.remove = function(){
				listener = null;
			};
			function addKey(key){
				var keyFlag = 'key' + key;
				if(this[keyFlag]){
					return;
				}else{
					this[keyFlag] = true;
				}
				var currentValue = target[key];
				var descriptor = Object.getOwnPropertyDescriptor(target, key);
				if(descriptor && descriptor.set){
					var previousSet = descriptor.set;
					var previousGet = descriptor.get;
					Object.defineProperty(target, key, {
						get: function(){
							return (currentValue = previousGet.call(this));
						},
						set: function(value){
							previousSet.call(this, value);
							if(currentValue !== value){
								currentValue = value;
								if(listener){
									queue(listener, this, key);
								}
							}
						}
					});
				}else{
					Object.defineProperty(target, key, {
						get: function(){
							return currentValue;
						},
						set: function(value){
							if(currentValue !== value){
								currentValue = value;
								if(listener){
									queue(listener, this, key);
								}
							}
						}
					});
				}
			}
		}
function observe ( target , listener ) { listener . addKey = addKey ; listener . remove = function ( ) { listener = null ; } ; function addKey ( key ) { var keyFlag = 'key' + key ; if ( this [ keyFlag ] ) { return ; } else { this [ keyFlag ] = true ; } var currentValue = target [ key ] ; var descriptor = Object . getOwnPropertyDescriptor ( target , key ) ; if ( descriptor && descriptor . set ) { var previousSet = descriptor . set ; var previousGet = descriptor . get ; Object . defineProperty ( target , key , { get : function ( ) { return ( currentValue = previousGet . call ( this ) ) ; } , set : function ( value ) { previousSet . call ( this , value ) ; if ( currentValue !== value ) { currentValue = value ; if ( listener ) { queue ( listener , this , key ) ; } } } } ) ; } else { Object . defineProperty ( target , key , { get : function ( ) { return currentValue ; } , set : function ( value ) { if ( currentValue !== value ) { currentValue = value ; if ( listener ) { queue ( listener , this , key ) ; } } } } ) ; } } }
this is much faster than polling
this is much faster than polling
/*for(var i in target){
				addKey(i);
			}*/