[英]Javascript: initializing a variable once (like a static variable) in a recursive function
I have a recursive function, which returns the leaf nodes of a tree (which is in the form of nested objects):我有一个递归函数,它返回树的叶节点(以嵌套对象的形式):
var retrieve = function (a)
{
if (typeof retrieve.names == 'undefined') //would be true for the 1st pass only
retrieve.names = []
if (a.left != null)
retrieve (a.left)
if (a.right != null)
retrieve (a.right)
if (a.left == null && a.right == null)
retrieve.names.push(a)
return retrieve.names
}
The problem with this function is, it works perfectly fine for a single object (tree), but when another object is passed in the parameter, it simply appends the leaf nodes to the leaf nodes already obtained from the previous tree.这个函数的问题是,它对单个对象(树)工作得很好,但是当另一个对象传入参数时,它只是简单地将叶子节点附加到已经从前一棵树获得的叶子节点上。
For instance,例如,
// gets the leaf nodes of obj1 tree
obj1_leaves = retrieve(obj1)
// instead of only getting leaf nodes of obj2, it appends them to leaf nodes of obj1
obj2_leaves = retrieve(obj2)
Now the reason for this is typeof retrieve.names == 'undefined'
is true only for first time.现在的原因是
typeof retrieve.names == 'undefined'
仅在第一次为真。 Whenever this function is invoked again, the member names
of the retrieve
function (which can also be considered as an object) is already set/initialized.每当再次调用此函数时,
retrieve
函数的成员names
(也可以视为对象)已经设置/初始化。
Is there a way to set a variable (or member of an object) inside a recursive function for a given function call only, and then unset/set it again for another function call.有没有办法只为给定的函数调用在递归函数中设置变量(或对象的成员),然后为另一个函数调用再次取消设置/设置它。
You can use an inner function: 您可以使用内部函数:
function retrieve(a) {
var names = [];
function _retrieve(a) {
if (a.left != null)
_retrieve (a.left)
if (a.right != null)
_retrieve (a.right)
if (a.left == null && a.right == null)
names.push(a)
}
_retrieve(a);
return names;
}
The outer function initializes the empty array as a local variable. 外部函数将空数组初始化为局部变量。 The inner function does essentially the same work as your original function, but it references that local array.
内部函数与原始函数基本相同,但是它引用该本地数组。
Every time retrieve()
is called, a new local array is created and used to traverse the tree. 每次
retrieve()
,都会创建一个新的本地数组,并将其用于遍历树。
An alternative approach (to the one given by @Pointy, which I'm not going to repeat) is to use an optional parameter. 另一种方法(对于@Pointy给出的方法,我不再重复)是使用可选参数。 It is filled with the default value only on the "first", outermost call, and then passed through to each recursive invocation.
它仅在“第一个”最外层调用中填充默认值,然后传递给每个递归调用。
function retrieve(a, names) {
if (!names) names = [];
if (a.left != null)
retrieve(a.left, names);
if (a.right != null)
retrieve(a.right, names);
if (a.left == null && a.right == null)
names.push(a);
return names;
}
just do default value with equals sign, in the definition, that's only initialized if no parameter is provided.只需在定义中使用等号执行默认值,仅在未提供参数时才初始化。 Then in subsequent internal calls keep passing the same key:
然后在随后的内部调用中继续传递相同的密钥:
function something(a, b=[]){
// then just call 'something' passing b when recursing
// for example
something(a-1, b)
}
Since values are passed by reference for objects, same object will be shared across recursive calls由于对象的值是通过引用传递的,因此相同的对象将在递归调用之间共享
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.