1

私は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) {

私は魔法のように働きます。HovewerArraysは、長さのプロパティだけではありません。String持っているので、それは広いアプローチではありません。

どうすれば防ぐことができますRangeErrorが、それでもチェックできlength propertyますか?

編集:NodeJSv0.8.12で例を実行しています

4

1 に答える 1

0

'a'[0][0][0][0][0][0][0]...それは無限に有効であり、すべての値は type であると考えてください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/

于 2013-01-22T16:05:34.690 に答える