(function (window, undefined) { function aspect (type) { return function (target, methodName, advice) { var exist = target[methodName], dispatcher; if (!exist || exist.target != target) { dispatcher = target[methodName] = function () { // before methods var beforeArr = dispatcher.before; var args = arguments, next; for (var l = beforeArr.length; l--;) { next = beforeArr[l].advice.apply(this, args); if (next === false) { return false; } args = next || args; } // target method var rs = dispatcher.method.apply(this, args); // after methods var afterArr = dispatcher.after; for (var i = 0, ii = afterArr.length; i < ii; i++) { next = afterArr[i].advice.call(this, rs, args); if (rs === false) { return false; } args = next || args; } return rs; }; dispatcher.before = []; dispatcher.after = []; if (exist) { dispatcher.method = exist; } dispatcher.target = target; } var aspectArr = (dispatcher || exist)[type]; var obj = { advice: advice, _index: aspectArr.length, remove: function () { aspectArr.splice(this._index, 1); } }; aspectArr.push(obj); return obj; }; } BI.aspect = { before: aspect("before"), after: aspect("after") }; return BI.aspect; })(window);