动态可观察对象
Dynamic observable object
我想要达到的目标:
var obj = new Dynamic({data:"something",data2:"something else"},function(val){
console.log('"'+val+'"');
});
console.log(obj.data,obj.data2);
obj.data = "this thing here";
console.log(obj.data,obj.data2);
控制台输出
"something" "something else"
"this thing here"
"something" "something else"
我当前的控制台输出
"something else" "something else"
"this thing here"
"this thing here" "this thing here"
我的 Dynamic
方法看起来像这样:
function Dynamic(obj,method){
var ret;
var Update = method;
if(obj instanceof Object){
ret = {};
for(var a in obj){
Object.defineProperty(ret,a,{
set: function(v){
inner = v;
Update.call(this,inner);
},
get: function(){
return inner;
}
});
ret[a] = (obj[a] instanceof Array||obj[a] instanceof Object)?Dynamic(obj[a],Update):obj[a];
}
}
return ret;
}
这个问题是,每个 属性 引用 inner
,而不是他们自己的内部版本
我试过了
Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {dadedadeda}
value:obj[a]});
但这不起作用,因为 this issue with get, set, and value 在我看来这是一个巨大的疏忽(如果我们确实想要一个值但又想拦截调用怎么办?)
我也试过了
Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {return this.inner;}
inner:obj[a]});
但这似乎是不会发生的事情,而且 this
无论如何都指代整个对象,th
当我思考这个问题时,我实际上找到了我的答案:JavaScript Closures
(谁会想到)
我的完整代码如下所示
function Observable(obj, method) {
function DefineDescriptor(object, key, method, value) {
var inner = value; // this is the private value of our property
var descriptor = {
set: function(v) {
inner = (v instanceof Object) ? Observable(v, method) : v; // every object added from this point will invoke the method defined
method.call(this, key, v);
},
get: function() {
return inner;
}
};
Object.defineProperty(object, key, descriptor);
}
var ret;
if (obj instanceof Object) {
ret = {};
for (var a in obj) {
DefineDescriptor(ret, a, method, (obj[a] instanceof Object) ? Observable(obj[a], method) : obj[a]);
}
}
return ret;
}
document.addEventListener("DOMContentLoaded", function(loadEvt) {
var B = Observable({
key: "value",
nested: {
key: 123,
str: "hey"
}
}, function(key, val) {
console.log(this, key, this[key], val);
});
});
我想要达到的目标:
var obj = new Dynamic({data:"something",data2:"something else"},function(val){
console.log('"'+val+'"');
});
console.log(obj.data,obj.data2);
obj.data = "this thing here";
console.log(obj.data,obj.data2);
控制台输出
"something" "something else"
"this thing here"
"something" "something else"
我当前的控制台输出
"something else" "something else"
"this thing here"
"this thing here" "this thing here"
我的 Dynamic
方法看起来像这样:
function Dynamic(obj,method){
var ret;
var Update = method;
if(obj instanceof Object){
ret = {};
for(var a in obj){
Object.defineProperty(ret,a,{
set: function(v){
inner = v;
Update.call(this,inner);
},
get: function(){
return inner;
}
});
ret[a] = (obj[a] instanceof Array||obj[a] instanceof Object)?Dynamic(obj[a],Update):obj[a];
}
}
return ret;
}
这个问题是,每个 属性 引用 inner
,而不是他们自己的内部版本
我试过了
Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {dadedadeda}
value:obj[a]});
但这不起作用,因为 this issue with get, set, and value 在我看来这是一个巨大的疏忽(如果我们确实想要一个值但又想拦截调用怎么办?)
我也试过了
Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {return this.inner;}
inner:obj[a]});
但这似乎是不会发生的事情,而且 this
无论如何都指代整个对象,th
当我思考这个问题时,我实际上找到了我的答案:JavaScript Closures
(谁会想到)
我的完整代码如下所示
function Observable(obj, method) {
function DefineDescriptor(object, key, method, value) {
var inner = value; // this is the private value of our property
var descriptor = {
set: function(v) {
inner = (v instanceof Object) ? Observable(v, method) : v; // every object added from this point will invoke the method defined
method.call(this, key, v);
},
get: function() {
return inner;
}
};
Object.defineProperty(object, key, descriptor);
}
var ret;
if (obj instanceof Object) {
ret = {};
for (var a in obj) {
DefineDescriptor(ret, a, method, (obj[a] instanceof Object) ? Observable(obj[a], method) : obj[a]);
}
}
return ret;
}
document.addEventListener("DOMContentLoaded", function(loadEvt) {
var B = Observable({
key: "value",
nested: {
key: 123,
str: "hey"
}
}, function(key, val) {
console.log(this, key, this[key], val);
});
});