Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者。
话说这个KVO是Object-C中提供的一种机制,估计在ios开发中会比较常见,你可以到苹果官方网站上看看关于它的一些介绍。
在谷歌地图API中已用Javascript对该机制有了很好的实现,本着学习研究的心态,特研究了一下谷歌地图的部分源码。
下面是它的部分源码分享(这是一个基类,你应该通过继承它来使用)
function MVCObject(){} MVCObject.prototype = { /** * MVCObject 获取值 * * @param {String} str * @return {*} */ get : function(key) { var _accessor = getAccessors(this)[key]; if (_accessor) { var _targetKey = _accessor.targetKey, _target = _accessor.target, _getterName = "get" + _firstUpper(_targetKey); return _target[_getterName] ? _target[_getterName]() : _target.get(_targetKey); } else { return this[key]; } }, /** * MVCObject 设置值 * * @param {String} str * @param {*} value */ set : function(key, value) { var _accessors = getAccessors(this); if (_accessors.hasOwnProperty(key)) { var _accessor = _accessors[key], _targetKey = _accessor.targetKey, _target = _accessor.target, _setterName = "set" + _firstUpper(_targetKey); if (_target[_setterName]){ _target[_setterName](value); }else{ _target.set(_targetKey, value); } } else { this[key] = value; triggerChanged(this, key); } }, /** * 通知所有观察者此属性有所改变。这会通知绑定到对象属性的对象以及绑定到的对象。 * * @param {String} key */ notify : function(key) { var _accessors = getAccessors(this); if(_accessors.hasOwnProperty(key)){ var _accessor = _accessors[key]; _accessor.target.notify(_accessor.targetKey); }else{ triggerChanged(this, key); } }, /** * 设置键值对集合 * * @param {Object|undefined} keyValues * @return {None} */ setValues : function(keyValues) { for (var key in keyValues) { var _value = keyValues[key], _setterName = "set" + _firstUpper(key); this[_setterName] ? this[_setterName](_value) : this.set(key, _value); } }, /** * 将视图绑定到模型 * * @param {String} key * @param {MVCObject} target * @param {String} targetKey * @param {Boolean} noNotify */ bindTo : function(key, target, targetKey, noNotify) { var targetKey = targetKey || key, _self = this, eventName = targetKey.toLowerCase() + "_changed", handler = function() { triggerChanged(_self, key); }; _self.unbind(key); //绑定外部监听器 getBindings(_self)[key] = Event.addListener(target, eventName,handler); setAccessor(_self, key, target, targetKey, noNotify); }, /** * 删除绑定。取消绑定会将未绑定属性设置为当前值。将不会通知该对象,因为值尚未更改。 * * @param {String} key */ unbind : function(key) { var _listener = getBindings(this)[key]; if (_listener) { delete getBindings(this)[key]; //移除外部绑定的监听器 Event.removeListener(_listener); var _value = this.get(key); delete getAccessors(this)[key]; this[key] = _value; } }, /** * 删除所有绑定 */ unbindAll : function() { var _keys = []; var _listeners = getBindings(this); for (var key in _listeners) { _keys.push(key); } if(_keys){ var _self = this; for (var i = 0, len = _keys.length; i < len; ++i){ (function() { return _self.unbind.apply(_self || this, arguments); })(_keys[i], i); } } }, changed : function(key){} }; // -- 下面是一些全局的函数方法 -- MVCObject.prototype.setOptions = MVCObject.prototype.setValues; function triggerChanged(mvcObj, key) { var _change = key + "_changed"; if (mvcObj[_change]){ mvcObj[_change](); }else{ mvcObj['changed'](key); } //触发外部绑定的监听器 Event.trigger(mvcObj, key.toLowerCase() + "_changed");//触发事件 } var _firstUpperList = {}; /** * 将给定的字符串首字母转为大写 * * @param {String} str * @return {String} str */ function _firstUpper(str) { return _firstUpperList[str] || (_firstUpperList[str] = str.substr(0, 1).toUpperCase() + str.substr(1)); } function setAccessor(mvcObject, key, target, targetKey, noNotify) { getAccessors(mvcObject)[key] = { 'target': target, 'targetKey': targetKey }; noNotify || triggerChanged(mvcObject, key); } function getAccessors(mvcObject) { if (!mvcObject._accessors) mvcObject._accessors = {}; return mvcObject._accessors; } function getBindings(mvcObject) { if (!mvcObject._bindings) mvcObject._bindings = {}; return mvcObject._bindings; }
博主,你的源代码是怎么分析出来的?最近对google map api v3 很感兴趣,但是代码都混淆过了,你是怎么弄到的?
用的最笨的办法~~
什么办法啊,能透露了吗?
楼主是硬拼的吗?比较费劲,有工具没?