递归迭代器上的最大调用堆栈大小错误
Maximum call stack size error on recursive iterator
我正在用JavaScript做实验,只是为了学习目的,我正在编写一个forEach迭代器,它可以遍历嵌套数组或任何其他包含length property
的可迭代对象。
这是我写的:
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]);
}
}
};
如果我传递一个嵌套数组,我得到RangeError: Maximum call stack size exceeded
:
forEach(['a', 'b', ['c', 'd']], function(x) {
console.log(x);
}, { deep: true });
但这似乎只发生如果我检查长度属性在obj[x]
如果我替换:
if(!isEmpty(obj[x]) && options.deep === true) {
为:if((obj[x] instanceof Array) && options.deep === true) {
我将神奇地工作。然而,并非只有Arrays
具有长度属性。String
有它,所以这不是一个广泛的方法。
如何防止RangeError
,但仍然检查length property
?
我运行这个示例 NodeJS v0.8.12
考虑'a'[0][0][0][0][0][0][0]...
是无限有效的,并且每个值都是string
类型。如果类型是string
,那么不应该递归地迭代它。还要注意,function
对象有一个length
属性,而function
参数可以是对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);
...
}
演示:http://jsfiddle.net/bjpx5/
相关文章:
- 是什么让一个“;Uncaught RangeError:超过了最大调用堆栈大小“;错误(Chrome,在其他浏览器中显示
- 超过了async.detect最大调用堆栈大小
- 如何远程检查JavaScript应用程序的函数调用堆栈
- 超过了最大调用堆栈大小,循环无限
- 超过了最大调用堆栈大小.递归标签
- 日志:未捕获的范围错误:超过了最大调用堆栈大小
- 未捕获的范围错误:setTimeout()超过了最大调用堆栈大小
- JavaFX+WebView/Javascript:setTimeOut不起作用调用堆栈来自Java
- JavaScript继承:未捕获的范围错误:超过了最大调用堆栈大小
- 使用$cookies和$stateChangeStart检查sessionID是否超过了最大调用堆栈
- jQuery捕获"RangeError:超过了最大调用堆栈大小“;
- 设置这个.RangeError:超过了最大调用堆栈大小
- 收到“范围错误: 超出最大调用堆栈大小”错误
- 递归 - 测试最大堆栈大小时,调用堆栈无法弹出
- 轮询 ajax 函数超出调用堆栈
- Chrome RangeError:使用jQuery$.map时超过了最大调用堆栈大小
- 要求JS 2.1.9引起“;最大调用堆栈"使用Grunt时出错
- Chrome/jQuery未捕获范围错误:超过了最大调用堆栈大小(函数循环)
- 超过了最大调用堆栈大小-没有明显的递归
- 警告:字体加载过程中出错:轨道上的PDFJS超过了最大调用堆栈大小错误