我正在尝试使用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) {
我会神奇地工作。 Hovewer,不仅Arrays
有长度属性。 String
拥有它,所以这不是一个广泛的方法。
如何阻止RangeError
,但仍会检查length property
?
编辑:我在 NodeJS v0.8.12上运行示例
答案 0 :(得分:0)
请考虑'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);
...
}