這是今年百度公司暑期實習生招聘web前端開發工程師面試的面試官問本人的一道面試題。
問題:javascript如何監控變數呢?
答:__defineGetter__ 和 __defineSetter__這兩個方法每次get和set的時候都會執行。不過並不是所有瀏覽器都支援。在Firefox下,我們可以通過object.watch(prop, handler)來實現。而在IE下,可以通過Object.defineProperty來實現。具體代碼如下:
1 /* 2 * object.watch polyfill 3 * 4 * 2012-04-03 5 * 6 * By Eli Grey, http://eligrey.com 7 * Public Domain. 8 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 9 */10 11 // object.watch12 if (!Object.prototype.watch) {13 Object.defineProperty(Object.prototype, "watch", {14 enumerable: false15 , configurable: true16 , writable: false17 , value: function (prop, handler) {18 var19 oldval = this[prop]20 , newval = oldval21 , getter = function () {22 return newval;23 }24 , setter = function (val) {25 oldval = newval;26 return newval = handler.call(this, prop, oldval, val);27 }28 ;29 30 if (delete this[prop]) { // can't watch constants31 Object.defineProperty(this, prop, {32 get: getter33 , set: setter34 , enumerable: true35 , configurable: true36 });37 }38 }39 });40 }41 42 // object.unwatch43 if (!Object.prototype.unwatch) {44 Object.defineProperty(Object.prototype, "unwatch", {45 enumerable: false46 , configurable: true47 , writable: false48 , value: function (prop) {49 var val = this[prop];50 delete this[prop]; // remove accessors51 this[prop] = val;52 }53 });54 }
以上代碼可在IE8+, Safari, Chrome, Firefox, Opera下順利執行。
PS. 看來這個在代碼測試時很有用,開發中還不可以用呀!如果你想在各種瀏覽器中都使用的話,請看:https://github.com/melanke/Watch.JS
參考資料:
http://www.cnblogs.com/McJeremy/archive/2010/06/18/1760385.html
https://gist.github.com/384583
http://stackoverflow.com/questions/1269633/watch-for-object-properties-changes-in-javascript?rq=1
http://www.w3resource.com/javascript/object-property-method/object-watch.php
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/watch
http://www.htmlv5.net/forum.php?mod=viewthread&tid=122&extra=page%3D1
http://www.htmlv5.net/forum.php?mod=viewthread&tid=122&page=1