正如已经提到的,唯一有助于实现更改/更改封闭函数/方法的控制流的目标的模式(因此,一个人不拥有他们的代码库。)是函数组合。
它也被指出,有不同的实现方法。
OP 的更改示例将使用Function.before
. 由于bind
JavaScript
已经 具有标准化
的 .
Function.prototype
_ _
_
before
after
around
afterThrowing
afterFinally
... 尽可能贴近 OP 的示例:
var
obj = {
foo: function() {
console.log('foo');
},
bah: function() {
console.log('bah');
}
};
function fn1() {
//foo();
console.log('fn1');
}
function fn2() {
//bah();
console.log('fn2');
}
function main() {
//fn1.add(obj.foo); // <= Should add function foo to fn1
//fn2.add(obj.bah); // <= Should add function bah to fn2
window.fn1 = window.fn1.before(obj.foo);
window.fn2 = window.fn2.before(obj.bah);
fn1(); // Should output: foo and then fn1
fn2(); // should output: bah and then fn2
//obj.foo = obj.foo.after(f1);
//obj.bah = obj.bah.after(f2);
}
main();
...实施Function.prototype.before
:
(function (Function) {
var
isFunction = function (type) {
return (
(typeof type == "function")
&& (typeof type.call == "function")
&& (typeof type.apply == "function")
);
},
getSanitizedTarget = function (target) {
//return (target == null) ? null : target;
return ((target != null) && target) || null;
};
Function.prototype.before = function (handler, target) { // before
target = getSanitizedTarget(target);
var proceed = this ;
return (isFunction(handler) && isFunction(proceed) && function () {
var args = arguments;
//handler.apply(target, args);
handler.call(target, args);
return proceed.apply(target, args);
}) || proceed;
};
}(Function));
考虑到OP的回答......
答:是的,没错……
...对于这个问题...
问:......我是否理解正确,您将决定是否调用foo
派生obj.foo
或bah
/取决于分别obj.bah
在其中实现的逻辑?fn1
fn2
...我以前的方法从 更改Function.before
为Function.around
。
然而,我个人对这个解决方案并不满意,因为这两种方法都是全局提供的fn1
,fn2
现在需要提前预测修改,在我看来这不是一个干净的方法。
然而,下一个示例接近 OP 正在寻找的内容:
var
obj = {
foo: function() {
console.log('foo');
},
bah: function() {
console.log('bah');
}
};
// - both next function's arguments-signatures
// do already anticipate the modification.
// - this is considered to be a dirty approach,
// please check your architecture or your
// concept of control flow.
function fn1(foo, fn1, args) {
foo(); // does not necessarily need to be called.
console.log('fn1');
}
function fn2(bah, fn2, args) {
bah(); // does not necessarily need to be called.
console.log('fn2');
}
function main() {
//fn1.add(obj.foo); // <= Should add function foo to fn1
//fn2.add(obj.bah); // <= Should add function bah to fn2
window.fn1 = obj.foo.around(window.fn1);
window.fn2 = obj.bah.around(window.fn2);
fn1(); // Should output: foo and then fn1
fn2(); // should output: bah and then fn2
}
main();
...实施Function.prototype.around
:
(function (Function) {
var
isFunction = function (type) {
return (
(typeof type == "function")
&& (typeof type.call == "function")
&& (typeof type.apply == "function")
);
},
getSanitizedTarget = function (target) {
//return (target == null) ? null : target;
return ((target != null) && target) || null;
};
Function.prototype.around = function (handler, target) { // around
target = getSanitizedTarget(target);
var proceed = this ;
return (isFunction(handler) && isFunction(proceed) && function () {
return handler.call(target, proceed, handler, arguments);
}) || proceed;
};
}(Function));