Skip to content

Instantly share code, notes, and snippets.

@mkdizajn
Forked from rwaldron/complex-observe.js
Created July 26, 2014 06:24
Show Gist options
  • Save mkdizajn/2528e2e72d697d72f7f0 to your computer and use it in GitHub Desktop.
Save mkdizajn/2528e2e72d697d72f7f0 to your computer and use it in GitHub Desktop.
function log( change ) {
// Note that |change.object| is actually a reference to the
// target object.
if ( change.type === "read" ) {
console.log( "What was accessed? ", change.name );
console.log( "What value was given? ", change.oldValue );
}
else {
// Only access properties when the event is not "read",
// Otherwise it will result in an infinite access loop
console.log( "What Changed? ", change.name );
console.log( "How did it change? ", change.type );
console.log( "What was the old value? ", change.oldValue );
console.log( "What is the present value? ", change.object[ change.name ] );
}
}
(function( exports ) {
var priv = new WeakMap();
function User( name ) {
this.name = name;
// Store some sensitive tracking information out of reach
priv.set( this, {
login: Date.now(),
lastSeen: Date.now()
});
// Create an accessor set that will act as an intermediary
// for updating sensitive data bound to this instance
Object.defineProperties( this, {
seen: {
set: function( val ) {
var notifier = Object.getNotifier( this ),
p = priv.get( this );
// The program must trigger an "updated" notification
// manually, since Object.observe will not notify
// for accessors
notifier.notify({
type: "updated",
name: "seen",
oldValue: p.lastSeen
});
// Update and store the sensitive data
p.lastSeen = val;
priv.set( this, p );
},
get: function() {
var notifier = Object.getNotifier( this ),
p = priv.get( this );
// A program can also notify for custom behaviours;
// in this case, theprogram will notify any time
// the property is read.
// WARNING!!!!
// This will fire _every_ _time_ _any_ code
// accesses the .seen property
notifier.notify({
type: "read",
name: "seen",
oldValue: p.lastSeen
});
return p.lastSeen;
}
}
});
// Make all instances of User observable
Object.observe( this, function( changes ) {
console.log( "Observed..." );
changes.forEach( log );
});
}
exports.User = User;
}( this ));
var user = new User("Rick");
console.log( user.seen );
/*
Observed...
What was accessed? seen
What value was given? 1345831387279
*/
user.seen = Date.now();
/*
Observed...
What Changed? seen
How did it change? updated
What was the old value? 1345831387279
What is the present value? 1345831401342
Observed...
// This is triggered by the log() function
// when it displays the present value, in a new turn
What was accessed? seen
What value was given? 1345831401342
*/
console.log( user.seen );
/*
Observed...
What was accessed? seen
What value was given? 1345831401342
*/
user.seen = Date.now();
/*
Observed...
What Changed? seen
How did it change? updated
What was the old value? 1345831401342
What is the present value? 1345831474108
Observed...
// This is triggered by the log() function
// when it displays the present value, in a new turn
What was accessed? seen
What value was given? 1345831474108
*/
Object.freeze( user );
/*
Observed...
What Changed? name
How did it change? reconfigured
What was the old value? Rick
What is the present value? Rick
*/
user.seen = Date.now();
/*
TypeError when trying to call the notifier.
Once an object is frozen, Object.getNotifier()
returns null;
*/
user = new User("Rick");
user.name = "Rose";
user.name = "Alli";
user.name = "Taco";
/*
Observed...
What Changed? name
How did it change? updated
What was the old value? Rick
What is the present value? Taco
What Changed? name
How did it change? updated
What was the old value? Rose
What is the present value? Taco
What Changed? name
How did it change? updated
What was the old value? Alli
What is the present value? Taco
*/
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ].forEach(function( n ) {
user.name = n;
});
/*
Observed...
What Changed? name
How did it change? updated
What was the old value? 10
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 0
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 1
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 2
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 3
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 4
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 5
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 6
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 7
What is the present value? 9
What Changed? name
How did it change? updated
What was the old value? 8
What is the present value? 9
*/
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ].forEach(function( n ) {
if ( n % 3 === 0 ) {
console.log( "Force delivery @", n );
Object.deliverChangeRecords(log);
}
user.name = n;
});
/*
Force delivery @ 0
Observed...
What Changed? name
How did it change? updated
What was the old value? 9
What is the present value? 2
What Changed? name
How did it change? updated
What was the old value? 0
What is the present value? 2
What Changed? name
How did it change? updated
What was the old value? 1
What is the present value? 2
Force delivery @ 3
Observed...
What Changed? name
How did it change? updated
What was the old value? 2
What is the present value? 5
What Changed? name
How did it change? updated
What was the old value? 3
What is the present value? 5
What Changed? name
How did it change? updated
What was the old value? 4
What is the present value? 5
Force delivery @ 6
Observed...
What Changed? name
How did it change? updated
What was the old value? 5
What is the present value? 8
What Changed? name
How did it change? updated
What was the old value? 6
What is the present value? 8
What Changed? name
How did it change? updated
What was the old value? 7
What is the present value? 8
Force delivery @ 9
Observed...
What Changed? name
How did it change? updated
What was the old value? 8
What is the present value? 9
*/
function log( change ) {
// Note that |change.object| is actually a reference to the
// target object.
console.log( "What Changed? ", change.name );
console.log( "How did it change? ", change.type );
console.log( "What is the present value? ", change.object[ change.name ] );
}
var o = {};
// Specify |o| as an observable object
Object.observe(o, function( changes ) {
changes.forEach( log );
});
o.who = "Rick";
/*
What Changed? who
How did it change? new
What is the present value? Rick
*/
o.who = "Rose";
/*
What Changed? who
How did it change? updated
What is the present value? Rose
*/
delete o.who;
/*
What Changed? who
How did it change? deleted
What is the present value? undefined
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment