JQuery和Underscore“每个”保证数组的顺序?

时间:2012-05-24 15:05:02

标签: javascript jquery each underscore.js

我读了Javascript:好的部分......

  

由于JavaScript的数组实际上是对象,因此for in语句可用于迭代数组的所有属性。不幸的是,因为不能保证房产的顺序......

据我所知,“每个”函数都基于for in,那么each函数是否形成JQuery,而Underscore库在迭代数组时保证顺序?我正试图避免令人讨厌的标准for

提前谢谢。

2 个答案:

答案 0 :(得分:16)

在迭代数组时,始终保证顺序。当你无法保证迭代(非数组)对象时。顺便说一下,数组仍然是对象。


对于对象,

each不超过for in,对于类似数组,for不超过var each = _.each = _.forEach = function (obj, iterator, context) { if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; } } else { for (var key in obj) { if (_.has(obj, key)) { if (iterator.call(context, obj[key], key, obj) === breaker) return; } } } }; 。框架确定作业的正确循环并应用相同的逻辑:数组迭代是有序的,而对象迭代则不是。

下划线的来源:

each: function (object, callback, args) {
    var name, i = 0,
        length = object.length,
        isObj = length === undefined || jQuery.isFunction(object);
    if (args) {
        if (isObj) {
            for (name in object) {
                if (callback.apply(object[name], args) === false) {
                    break;
                }
            }
        } else {
            for (; i < length;) {
                if (callback.apply(object[i++], args) === false) {
                    break;
                }
            }
        }
        // A special, fast, case for the most common use of each
    } else {
        if (isObj) {
            for (name in object) {
                if (callback.call(object[name], name, object[name]) === false) {
                    break;
                }
            }
        } else {
            for (; i < length;) {
                if (callback.call(object[i], i, object[i++]) === false) {
                    break;
                }
            }
        }
    }
    return object;
}

jQuery的来源:

{{1}}

答案 1 :(得分:3)

有两种方法可以循环遍历数组:数组的索引元素上的数字循环,或对象属性上的for in循环数组。

var a = ['a','b'];
a[3] = 'e';
a[2] = 'd';
a.foo = function() { };
for(key in a)
    console.log(key);

这会返回0 1 3 2 foo,因为这是属性定义的顺序(但是没有承诺您的浏览器甚至需要展示该行为)。

到目前为止,数值循环看起来更优越,但它们无法处理备用数组,即带有间隙的数组。 ES5 Array.forEach省略了未指定的值,而jQuery的$.each使用基于length属性的数字循环。

var a = [1,2];
a[1000000] = 4;
a[9000] = 3;
a.foo = function() {};

// outputs 0, 1, 9000, 1000000 -- note they are in order
a.forEach(function(elem, index){ console.log(index); })

// outputs 0, 1, 9000, 1000000 -- same as above
_.each(a, function(elem, index){ console.log(index); }) 

// outputs a million values and locks up  your browser for a while
$.each(a, function(index){ console.log(index); })

因此,forEach$.each都会按索引顺序返回您的值,但forEach和Underscore对于稀疏数组似乎更优越,因为它们忽略了没有赋值的索引它们。