Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归迭代器上的最大调用堆栈大小错误_Javascript - Fatal编程技术网

Javascript 递归迭代器上的最大调用堆栈大小错误

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

我正在用JavaScript进行实验,只是为了学习,我编写了一个forEach迭代器,它可以迭代嵌套数组或任何其他包含
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);
    ...
}