search

Home  >  Q&A  >  body text

javascript - 如何给js的对象动态增加key?

我有这样一段代码

_.each(course, function(value, key) {
  course[key+"test"] = value + 1;
});

这段代码在chrome下,是ok的。但是ie8下会报内存溢出。如果去掉test,就好了。

_.each(course, function(value, key) {
  course[key] = value + 1;
});

求大神指点一下。谢谢了。

阿神阿神2901 days ago471

reply all(2)I'll reply

  • 大家讲道理

    大家讲道理2017-04-10 14:52:08

    不知道LZ的_.each是什么,很有可能是因为foreach循环会动态查询course的所有键值,由于键值不断增多,造成了死循环,造成内存溢出。

    比如course是{a:1},死循环过程就是这样:

    course["atest"] = 2;
    course["atesttest"] = 3;
    course["atesttesttest"] = 4;
    course["atesttesttesttest"] = 5;
    // ...
    

    ECMAScript的标准里面未定义for-in遍历顺序,新增键是否被遍历完全依赖于UA,无法强制保证新增的键会/不会被遍历到。

    The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.

    underscore避免这个死循环的方法是首先用一个数组缓存当前的keys(ECMAScript 5里面有Object.keys,fallback方法则是for in循环),然后循环keys数组,这样在遍历过程中增加的key不会被遍历到。

    function getKeys(obj) {
        if(Object.keys) {
            return Object.keys(obj) ;
        }
        var keys = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    var course = {a: 1},
        courseKeys = getKeys(course);
    for( var i = 0 ; i < courseKeys.length; i++ ) {
        course[courseKeys[i]+"test"] = i ;
    }
    

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 14:52:08

    换一种写法

    javascriptvar tmpCourse = {};
    _.each(course, function(value, key) {
      tmpCourse[key] = value;
      tmpCourse[key+"test"] = value + 1;
    });
    course = tmpCourse;
    

    reply
    0
  • Cancelreply