Javascript 递归迭代器上的最大调用堆栈大小错误
我正在用JavaScript进行实验,只是为了学习,我编写了一个forEach迭代器,它可以迭代嵌套数组或任何其他包含Javascript 递归迭代器上的最大调用堆栈大小错误,javascript,Javascript,我正在用JavaScript进行实验,只是为了学习,我编写了一个forEach迭代器,它可以迭代嵌套数组或任何其他包含length属性的iterable对象 这是我写的: var forEach = function(obj, callback, options) { var options = options || {}; var context = options.context || this; if(!isEmpty(obj)) { // isEmpty funct
length属性的iterable对象
这是我写的:
var forEach = function(obj, callback, options) {
var options = options || {};
var context = options.context || this;
if(!isEmpty(obj)) { // isEmpty function just evaluates `return !(!!obj.length);`
for(var x = 0; x < obj.length; x++) {
if(!isEmpty(obj[x]) && options.deep === true) {
forEach.call(context, obj[x], callback, options);
continue;
}
callback.call(context, obj[x]);
}
}
};
但只有在检查obj[x]
如果我替换:
if(!isEmpty(obj[x]) && options.deep === true) {
用于:
我会神奇地工作。Hovewer,不仅数组
具有长度属性<代码>字符串
必须这样做,因此这不是一个广泛的方法
如何防止范围错误
,但仍要检查长度属性
编辑:我正在NodeJS v0.8.12上运行这个示例考虑
'a'[0][0][0][0][0][0]…
是无限有效的,每个值都是字符串类型。如果类型为string
,则不应递归迭代它。还请注意,function
对象具有length
属性,function
参数可以是函数本身的自引用。这将导致另一个无限递归。我认为用不同的方式处理不同的类型可能会更有意义,而不是试图开发一个包罗万象的函数
您还可以使用maxLevel
属性来限制递归的深度,默认值为10
。这样,无限递归应该不容易实现
forEach(['a', 'b', ['c', 'd']], function(x) {
console.log(x);
}, { deep: true, maxLevel: 10 });
var forEach = function(obj, callback, options, level) {
var options = options || {};
var context = options.context || this;
if (!level) level = 1;
if (!options.maxLevel) options.maxLevel = 10;
if (level > options.maxLevel) return;
...
forEach.call(context, obj[x], callback, options, level + 1);
...
}
演示:考虑'a'[0][0][0][0][0][0]…
是无限有效的,并且每个值都是字符串类型。如果类型是string
,那么您不应该递归迭代它。@mellamokb是的,我想这更有意义:)@mellamokb请将您的建议作为答案发布,以便我可以接受
if((obj[x] instanceof Array) && options.deep === true) {
forEach(['a', 'b', ['c', 'd']], function(x) {
console.log(x);
}, { deep: true, maxLevel: 10 });
var forEach = function(obj, callback, options, level) {
var options = options || {};
var context = options.context || this;
if (!level) level = 1;
if (!options.maxLevel) options.maxLevel = 10;
if (level > options.maxLevel) return;
...
forEach.call(context, obj[x], callback, options, level + 1);
...
}