之前的這篇文章
[其實那個監聽方式有個大bug,當不停的update 監聽物件以後就會導致記憶體洩漏。因為每次在呼叫get的時候都會生成乙個新的proxy,後來才知道是多傻。
經過我一天時間的思考,用了乙個遞迴的方法去解決巢狀物件的監聽問題。
下面是**:
//傳遞兩個引數,乙個是object, 乙個是proxy的handler
//如果是不是巢狀的object,直接加上proxy返回,如果是巢狀的object,那麼進入addsubproxy進行遞迴。
function todeepproxy(object, handler)
}object = new proxy(object, handler)
}//是不是乙個pure object,意思就是object裡面沒有再巢狀object了
function ispureobject(object) else }}
return
true;}}
這個函式的關鍵點就在於,你是從巢狀物件的第乙個屬性進行判斷加proxy還是從巢狀物件的最末端先進行判斷加proxy, 此函式是後者。
前者我也除錯過,行不通,就不贅述了。而且前者向後遞迴有個問題,在初始化的時候會觸發不必要的get/set 指令。
乙個有趣的事情是,在js中array也是object, 所以這個方法也是可以監聽array的, 衍生開去,這個方法可以監聽整個json資料結構。
但是這個函式有個缺點,就是會直接汙染 需要監聽的target, 如果你不想target被汙染,那麼這個方法就不可行了。
下面是用法:
//這是乙個巢狀了物件和陣列的物件
letobject = }},
class: 5,
arr: [1, 2, ],
age:
}//這是乙個巢狀了物件和陣列的陣列
let objectarr = [, arr1:[1,2]}, 2, 3, 4, 5, 6]
//這是proxy的handler
let handler = ,
set(target, property, value)
}//變成監聽物件
object = todeepproxy(object, handler);
objectarr = todeepproxy(objectarr, handler);
//進行一系列操作
console.time('pro')
objectarr.length
objectarr[3];
objectarr[2]=10
objectarr[0].name.first = 'ss'
objectarr[0].arr1[0]
object.name.first.second.third = 'yyyyy'
object.class = 6;
object.name.first.four
object.arr[2].arr1
object.age.age1 = 20;
console.timeend('pro')
下面是結果:
可以看到,每次操作,不管物件,巢狀物件,陣列,巢狀陣列都有被呼叫到,而且在3ms左右完成,沒有記憶體洩漏的問題。
接下來封裝一下,用兩種方法封裝,一種是類,一種是函式
類:
class watch ;
this.eventupdated = new customevent('updated', customeventdata);
this.eventread = new customevent('read', customeventdata);
this.eventchanged = new customevent('changed', customeventdata);
this.targetobj = obj;
}createproxy() ,
set(target, property, value)
}return todeepproxy(_this.targetobj, handler);
function todeepproxy(object, handler)
}object = new proxy(object, handler)
}function ispureobject(object) else }}
return
true;}}
}on(eventstr, callback) );
} else );}}
}}
用法:
let obj1 =
let obj2 =
let watcher = new watch(obj1);
let watcher2 = new watch(obj2);
obj1 = watcher.createproxy();
obj2 = watcher2.createproxy();
watcher.on('read, updated', function
() );
watcher2.on('read, updated', function
() );
obj1.name
obj2.class
這是用了addeventlistener來監聽物件的變化,但是問題是要呼叫全域性變數document
下面用函式的方法:
function watchout(obj, opts) ,
set(target, property, value)
}return todeepproxy(obj, handler);
function todeepproxy(object, handler)
}object = new proxy(object, handler)
}function ispureobject(object) else }}
return
true;}}
}
呼叫方法:},,
read(target, property) ,
beforeupdated(target, property, value) ,
beforechanged(target, property, value) ,
updated(target, property, value) ,
changed(target, property, value)
});obj3.name.second
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
經過我的測試發現,如果用上面的方法對乙個巢狀對像進行todeepproxy以後,如果對此proxy進行賦值,而且這個值是個物件時,那麼還是不能對賦的新值進行監聽,因為我們沒有在handler的set裡面對新值進行**。
所以我們改下handler。
let handler = ,
set(target, property, value)
return result;}}
用golang寫乙個proxy
我複雜的網路環境中,proxy是個很有用的工具,我們可以通過proxy 幫我們完成網路流量的 這個proxy得先能接收請求,所以這裡先啟動乙個tcp的監聽,獲取請求 func s server start glog.infof proxy listen in s,waiting for connec...
用python寫乙個restful API
coding utf 8 package.module python實現的圖書的乙個restful api.restful api 一般模式 get select 從伺服器取出資源 一項或多項 post create 在伺服器新建乙個資源。put update 在伺服器更新資源 客戶端提供改變後的完...
用python寫乙個蛇形矩陣
蛇形矩陣,如 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4從右上角大回環,其實挺簡單,思路想明白了就順了。這樣的矩陣可以看做二維陣列,python對陣列的寫法很麻煩,用numpy生成就簡單多了 myarray np.zeros n,n dtype np.int16 有...