我不确定如何将一些代码提取到需要访问变量的函数中。大多数语言都有相当明确的约定,但在Javascript中,一切似乎都有可能。
这里我正在使用变量stack
进行一些计算,我想将其提取到函数中。
function process() {
var stack = [];
while (work_to_do) {
var chunk = get_next_chunk();
stack.push(do_some_calculations(stack, chunk)); //
stack.push(do_more_fancy_calculations(stack, chunk)); // to extract
stack.push([ stack.pop(), stuff, stack.pop() ]); //
}
stack.push(do_some_calculations(stack, special_chunk));
stack.push(do_more_fancy_calculations(stack, special_chunk));
stack.push([ stack.pop(), 'stuff', stack.pop() ]);
}
现在我认为通常的方式(在Javascript中)将定义函数process()
内部的函数,以使其能够访问闭包变量stack
:
function process() {
var stack = [];
var do_calculations = function (chunk) {
stack.push(do_some_calculations(stack, chunk));
stack.push(do_more_fancy_calculations(stack, chunk));
stack.push([ stack.pop(), 'stuff', stack.pop() ]);
}
while (work_to_do) {
do_calculations(get_next_chunk());
}
do_calculations(special_chunk);
}
然而,(真实的)函数process()
已经非常混乱并且深度缩进,因此在顶层执行纯函数进行这些计算可能会更好。我可以将stack
作为参数传递:
function process() {
var stack = [];
while (work_to_do) {
do_calculations(stack, get_next_chunk());
}
do_calculations(stack, special_chunk);
}
function do_calculations (stack, chunk) {
stack.push(do_some_calculations(stack, chunk));
stack.push(do_more_fancy_calculations(stack, chunk));
stack.push([ stack.pop(), 'stuff', stack.pop() ]);
}
或者我可以将stack
视为某种类对象:
stack = {
data: [],
do_calculations: function (chunk) {
this.data.push(do_some_calculations(stack, chunk));
this.data.push(do_more_fancy_calculations(this.data, chunk));
this.data.push([ this.data.pop(), 'stuff', this.data.pop() ]);
}
};
function process() {
while (work_to_do) {
stack.do_calculations(get_next_chunk());
}
stack.do_calculations(special_chunk);
}
是否有最佳实践如何处理?
答案 0 :(得分:1)
这里没有绝对的最佳做法。这一切都取决于代码的情况。
如果函数自然不适合可以访问所需变量的闭包,那么在调用它时只需将变量作为参数传递给函数。
这是提供对特定变量的函数访问的通用方式(在Javascript和大多数其他语言中)。这里没什么棘手的。只是基本的编程。 Javascript的优点是,如果函数自然地位于另一个函数中,那么它自动可以访问父变量,因此有时您不必传递函数所需的一切,但如果该结构不自然,那么只需传递函数是它需要的参数。
并且,请记住,对象(包括Arrays)通过引用传递给函数,因此如果需要,函数可以修改原始函数。
此外,如果你有很多想要访问同一组数据的函数,那么有时将这些数据放入一个对象并使所有函数成为该对象上的方法是有意义的,这样他们就可以访问数据来自this
。
答案 1 :(得分:1)
没有明确的更好的选择。
如果你想让一个内部函数从外部获取一个变量,所以你不必将它作为参数传递,那么是的,根据定义,内部函数必须在外部词法中定义函数,以使它接近外部函数的变量。
就个人而言,即使结果是功能变长,我也没有看到这样做的问题。我觉得你的功能不是很混乱,而是深深地缩进了。#/ p>
当然,如果do_calculations
将在process
之外的任何其他环境中使用,则您需要在" top"级别,在这种情况下,您必须传入stack
。
使用对象的第三种方法在某种意义上与传递stack
实际上是相同的 - 除非您将其作为this
传递(或{{1}的属性而不是作为参数。对我来说,该代码看起来有点扭曲。
你的第二个代码片段对我来说似乎最干净。顺便说一句,很高兴看到有人担心这种详细的保理问题。
在这种情况下,有一种模式可能适合也可能不适合。考虑:
this
但这真的只是以一种略微不同的方式传递function make_calculator(stack) {
return function(chunk) {
stack.push(do_some_calculations(stack, chunk));
stack.push(do_more_fancy_calculations(stack, chunk));
stack.push([ stack.pop(), 'stuff', stack.pop() ]);
};
}
function process() {
var stack = [];
var do_calculations = make_calculator(stack);
while (work_to_do) {
do_calculations(get_next_chunk());
}
do_calculations(special_chunk);
}
。但是,它确实具有次要优势,您必须只将stack
传递一次stack
,然后对make_calculator
的单个调用不会混淆额外的do_calculations
stack
1}}参数。