Javascript 关于一种一次性自定义函数模式
考虑以下模式:Javascript 关于一种一次性自定义函数模式,javascript,closures,Javascript,Closures,考虑以下模式: function foo /* aka outer_foo */ () { // === stage 1 === // declaration and initialization of closure variables var ... <CLOSURE_VARS> ...; // initialization of CLOSURE_VARS // (possibly expensive and/or depending
function foo /* aka outer_foo */ () {
// === stage 1 ===
// declaration and initialization of closure variables
var ... <CLOSURE_VARS> ...;
// initialization of CLOSURE_VARS
// (possibly expensive and/or depending on values known only at run-time)
// === stage 2 ===
// one-time redefinition of foo
foo = function /* inner_foo */ ( arg0, ... ) {
var results;
// code computing value of results based on CLOSURE_VARS, arg0, ...
// foo is never modified here
return results;
};
// === stage 3 ===
// invocation of inner function and returning of result
return foo.apply( this, arguments );
}
在此变体中,最终分配给foo
的函数取决于运行时执行的一些测试
2这里很容易规定,
foo
不仅必须在outer\u foo中准确地重新定义一次,而且必须“决定性地”重新定义。当然,在foo
的最终设置中,任何对“决定论”的偏离(无论如何定义它)都只会增加代码运行时行为的复杂性。不幸的是,我不知道如何使这一规定准确无误,而不陷入律师们错综复杂的琐事中。我所能做的最好的事情就是加上一句含糊不清的话“越确定越好”,希望读者明白我的意思。然而,这一附加规定的唯一用途是排除反常但完全不现实的情况(例如,foo
的最终值取决于随机过程的结果),因此我省略了它。我可以想到另外两点,您应该注意:
- 性能。编译器就像你提到的人一样。他们中的一些人会对这种模式感到困惑,他们可能无法像使用不同的模式那样对其进行优化。这可能是个问题,也可能不是,但您应该确保对其进行测试
- 违约合同。你说你希望外施福最多被处决一次。情况可能并非如此!有人可能会将它传递给其他人,并将它的引用放在某个地方,以便在调用时不会无法访问它。当然,这不太可能,但根据您的需求,您可能希望防范它。
毕竟,这是一种破碎的设计,因为仅仅是一个别名(
)永远不会改变功能。确保所有消费者/用户都知道你在做什么,这样他们就不会被绊倒var f=foo;f()
function foo /* aka outer_foo */ () {
var inner_foo, ... <CLOSURE_VARS> ...;
if ( some_deterministic_test() ) {
inner_foo = function ( arg0, ... ) {
// etc.
}
}
else {
inner_foo = function ( arg0, ... ) {
// etc.
}
}
foo = inner_foo;
return foo.apply( this, arguments );
}