【问题标题】:too much recursion过多的递归
【发布时间】:2010-05-29 16:10:56
【问题描述】:

在这个递归函数中,我想替换(嵌套)对象中的一个值。

var testobj = {
    'user': {
        'name': 'Mario',
        'password': 'itseme'
    }
};

updateObject('emesti', 'password', testobj)

function updateObject(_value, _property, _object) {
    for(var property in _object) {
        if(property == _property) {
            _object[property] = _value;
        }
        else if(objectSize(_object) > 0) {
            updateObject(_value, _property, _object[property]);
        }
    }

    return _object
};

function objectSize(_object) {
    var size = 0, key;
    for (key in _object) {
        if (_object.hasOwnProperty(key)) size++;
    }
    return size;
};

运行后,firefox 会在 else if(objectSize(_object) > 0) { 行抛出异常“递归过多”。

编辑: 如果我设置

function updateObject(_value, _property, _object) {
    for(var property in _object) {
        if(property == _property) {
            _object[property] = _value;
        }
        else if(_object[property].hasOwnProperty(_property)) {
            updateObject(_value, _property, _object[property]);
        }
    }

    return _object
};

它有效,但它只搜索一个级别。如果我在嵌套对象中有一个嵌套对象,它就不会工作。

还有什么想法吗?

编辑: 此问题出现在 Firefox 3.6 中。它在 Chrome 中工作。

【问题讨论】:

  • 天哪。你混合了_property 和property?亲爱的上帝,请重命名它们。
  • :rolleyes: .. 哦,老论坛时代...

标签: javascript recursion


【解决方案1】:

我不是 100% 熟悉如何用 Javascript 做事,但基本上你想要这样的东西:

var testobj = {
    'user': {
        'name': 'Mario',
        'password': 'itseme',
        'bleh': {
            'password': 'something'
        }
    }
};

function updateObject(_value, _property, _object) {
    for(var property in _object) {
        if(property == _property) {
            _object[property] = _value;
        }
        else if(explorable(_object[property])) {
            updateObject(_value, _property, _object[property]);
        }
    }

    return _object
};

function explorable(_object) {
    return typeof(_object) != "string";
};

updateObject('emesti', 'password', testobj);
document.writeln(testobj.user.password);      // "emesti"
document.writeln(testobj.user.bleh.password); // "emesti"

目前,任何不是字符串的都是explorable。这可能适用于所有情况,也可能不适用于所有情况,因此您可能希望更好地定义explorable。

另请注意,递归现在会更新 ALL 匹配属性。

【讨论】:

  • 我已经看了大约半个小时了 :-D 非常感谢,但遗憾的是这不是“最终”解决方案。
  • @Dänu:检查最新版本。
  • 我试试看。顺便说一句,我试过了: else if(objectSize(_object[property]) > 0 && property != 0) { 也可以。好吧,我试试你的,看起来更干净
  • 顺便说一句,javascript 类型(由 typeof() 返回)是“字符串”、“数字”和“布尔”。至少,这些是我测试过的,我想至少也应该有一个用于数组。
  • ok javascript 类型:字符串、数字、布尔值、对象、函数、null 和未定义。哦,真是个骗子
【解决方案2】:

if(objectSize(_object) > 0) { 不应该是if(objectSize(_object[property]) > 0) {吗?

【讨论】:

    【解决方案3】:

    您没有在 updateObject 内的 for 循环中使用 .hasOwnProperty()。能否找到某种本质上“无限”深度的内置属性?

    【讨论】:

    • 嘿,马特,我认为对象不能有任何其他属性,而不是您设置的属性。否则我们不能将它们用作关联数组...
    • 噢嗬嗬,@Dänu,但是一个对象绝对可以有其他属性,继承自它的原型。这就是 hasOwnProperty 函数存在的原因!
    【解决方案4】:

    这是一个想法:

    function updateObject(_value, _property, _object) {
        function u(v, p, o) {
          if (o === _object) return;
          if (o.hasOwnProperty(p))
            o[p] = v;
          else {
            for (var prop in o)
              if (o.hasOwnProperty(prop))
                u(v, p, o[prop]);
          }
        }
        u(_value, _property, _object);
        return _object
    };
    

    这增加了一个测试,以确保您不会从原始对象重新开始。

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 2015-08-07
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多