1

我正在尝试编写一个跨浏览器foreach方法/函数。应该可以使用数组或对象的真实值或属性的副本或副本来迭代(就像 PHP 一样foreach ($array as &$item))。

forEach 和 map 方法都不是跨浏览器兼容的,所以我需要 for 循环。

这个主题JavaScript for...in vs for警告我不要使用for... in循环数组,但是当我使用以下代码进行测试时:

var arr = [];
arr[3] = "foo";
arr[0] = "bar";
arr["baz"] = "baz";

for (var i in arr) {
    alert(i);
}

我得到结果 3、0 和 baz(这是正确的)。这似乎也适用于索引数组(0、1、2)。然而Object.prototype.toString.call(arr) === "[object Array]"返回真。

那么创建一个 foreach 方法的最佳跨浏览器方法是什么,该方法将迭代数组值和对象属性,理想情况下提供使用数组/对象的实际值/属性的选项?

4

5 回答 5

1

只需检查hasOwnProperty何时使用for..in即可解决最危险的问题:

for (var name in buz) {
    if (buz.hasOwnProperty(name)) {
        // do stuff
    }
}
于 2013-04-29T20:20:26.130 回答
0

这应该适用于数组和对象,属性检查不是必需的,它们只是为了演示目的。

function forEach(object, callBack) {
    var tObject = Object.prototype.toString.call(object),
        i,
        l;

    if (tObject !== "[object Array]" && tObject !== "[object Object]") {
        throw new TypeError("'object' must be an array or object");
    }

    if (Object.prototype.toString.call(callBack) !== "[object Function]") {
        throw new TypeError("'callBack' must be a function");
    }

    if (tObject === "[object Array]") {
        i = 0;
        l = object.length;

        while (i < l) {
            callBack(object[i], i);

            i += 1;
        }

        return;
    }

    for (i in object) {
        if (object.hasOwnProperty(i)) {
            callBack(object[i], i);
        }
    }

    return;
}

var test1 = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
var test2 = {
    "a": 10,
    "b": 11,
    "c": 12,
    "d": 13,
    "e": 14,
    "f": 15,
    "g": 16,
    "h": 17,
    "i": 18
};

forEach(test1, function (element, index) {
    console.log(index, element);
});

forEach(test2, function (element, index) {
    console.log(index, element);
});

jsfiddle 上

我还为您设置了性能测试以查看jsperf

于 2013-04-29T20:24:25.657 回答
0
var arr = [];
arr[3] = "foo";
arr[0] = "bar";
arr["baz"] = "baz";

for (var i in arr) {
    alert(arr[i]);
}

干杯!

于 2013-04-29T20:21:47.500 回答
0

您可能对像underscore.js这样的实用程序库感兴趣。它提供了许多有用的实用功能,例如eachmap。如果可用,它将使用本机实现,否则将回退到其自己的自定义实现。生产版本的库也相对较小,只有 4kb。

但是,如果您真的有动力自己做这件事,那么underscore.js 源代码至少可以准确地说明这是如何完成的。他们每个人都在顶部附近。该行以'var each = _.each = ...'开头

您可以放心,代码质量很高,因为它可能已经过多次审查和优化。

于 2013-04-29T20:22:04.743 回答
-1
for (var i in arr) {
    if (arr.hasOwnProperty(i)) {
        alert(i + '--->' + arr[i]);
    }
}
于 2013-04-29T20:23:14.593 回答