Javascript: 在递归函数中初始化一个变量一次(如静态变量)
Javascript: initializing a variable once (like a static variable) in a recursive function
我有一个递归函数,returns一棵树的叶子节点(以嵌套对象的形式):
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
}
这个函数的问题是,它对单个对象(树)工作得很好,但是当另一个对象传入参数时,它只是简单地将叶节点追加到已经从前一棵树获得的叶节点上.
例如,
// 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)
现在的原因是 typeof retrieve.names == 'undefined'
仅第一次为真。每当再次调用这个函数时,retrieve
函数(也可以认为是一个对象)的成员names
已经是set/initialized。
有没有办法在递归函数内设置一个变量(或对象的成员)仅用于给定的函数调用,然后 unset/set 再次设置它用于另一个函数调用。
您可以使用内部函数:
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;
}
外层函数将空数组初始化为局部变量。内部函数与原始函数的工作基本相同,但它引用了该本地数组。
每次调用retrieve()
,都会创建一个新的本地数组,用于遍历树。
另一种方法(@Pointy 给出的方法,我不打算重复)是使用可选参数。它仅在 "first" 最外层调用时填充默认值,然后传递给每个递归调用。
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;
}
就是用等号做默认值,在定义中,只有在没有提供参数的情况下才初始化。然后在随后的内部调用中继续传递相同的密钥:
function something(a, b=[]){
// then just call 'something' passing b when recursing
// for example
something(a-1, b)
}
由于对象的值是通过引用传递的,因此同一对象将在递归调用之间共享
我有一个递归函数,returns一棵树的叶子节点(以嵌套对象的形式):
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
}
这个函数的问题是,它对单个对象(树)工作得很好,但是当另一个对象传入参数时,它只是简单地将叶节点追加到已经从前一棵树获得的叶节点上.
例如,
// 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)
现在的原因是 typeof retrieve.names == 'undefined'
仅第一次为真。每当再次调用这个函数时,retrieve
函数(也可以认为是一个对象)的成员names
已经是set/initialized。
有没有办法在递归函数内设置一个变量(或对象的成员)仅用于给定的函数调用,然后 unset/set 再次设置它用于另一个函数调用。
您可以使用内部函数:
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;
}
外层函数将空数组初始化为局部变量。内部函数与原始函数的工作基本相同,但它引用了该本地数组。
每次调用retrieve()
,都会创建一个新的本地数组,用于遍历树。
另一种方法(@Pointy 给出的方法,我不打算重复)是使用可选参数。它仅在 "first" 最外层调用时填充默认值,然后传递给每个递归调用。
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;
}
就是用等号做默认值,在定义中,只有在没有提供参数的情况下才初始化。然后在随后的内部调用中继续传递相同的密钥:
function something(a, b=[]){
// then just call 'something' passing b when recursing
// for example
something(a-1, b)
}
由于对象的值是通过引用传递的,因此同一对象将在递归调用之间共享