Created
August 16, 2016 02:02
-
-
Save xeaone/9c0a37a880dcdb17fa9d523b8b496eb4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var object = { | |
hello: 'blue', | |
app: { | |
env: { | |
port: 7777, | |
la: 1 | |
} | |
}, | |
more: 'stuff' | |
}; | |
var model = ObserveObject(object, function(type, path, value) { | |
console.log(type); | |
console.log(path); | |
console.log(value); | |
}); | |
//model.app.env.port = 8888; | |
//console.log('echo: ' + model.hello); | |
console.log(model); | |
function ObserveObject(object, callback, path, referenceObject) { | |
path = path || ''; | |
referenceObject = referenceObject || object; | |
object = clone(object); | |
for (var key in object) { | |
if (object.hasOwnProperty(key)) { | |
var keyClone = clone(key); | |
var pathCloneVariable = clone(path === '' ? key : path + '.' + key); | |
var pathCloneObject = clone(path === '' ? key : path + '.' + key); | |
if (isObject(object[key])) { | |
object[key] = ObserveObject(object[key], callback, pathCloneObject, referenceObject); | |
} else { | |
Object.defineProperty(object, keyClone, { | |
enumerable: true, | |
get: function(oldValue) { | |
oldValue = getByPath(referenceObject, pathCloneVariable); | |
callback('get', pathCloneVariable, oldValue); | |
return oldValue; | |
}, | |
set: function(newValue) { | |
referenceObject = setByPath(referenceObject, pathCloneVariable, newValue); | |
callback('set', pathCloneVariable, newValue); | |
} | |
}); | |
} | |
} | |
} | |
return object; | |
} | |
function getByPath(object, path) { | |
var keys = path.split('.'); | |
for (var i = 0; i < keys.length; i++) { | |
object = object[keys[i]]; | |
if (object === undefined) return undefined; | |
} | |
return object; | |
} | |
function setByPath(object, path, value) { | |
if (typeof path === 'string') path = path.split('.'); | |
if (path.length > 1) { | |
var e = path.shift(); | |
object[e] = Object.prototype.toString.call(object[e]) === '[object Object]' ? object[e] : {}; | |
setByPath(object[e], path, value); | |
} else { | |
object[path[0]] = value; | |
} | |
return object; | |
} | |
function clone (item) { | |
return JSON.parse(JSON.stringify({ value: item })).value; | |
} | |
function isObject(value) { | |
if (value === null || value === undefined) return false; | |
else return value.constructor === Object; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment