Array.prototype.map.bind可以与对象一起使用吗?

时间:2014-10-13 08:08:28

标签: javascript

我喜欢Array.prototype.map方法,前段时间我遇到了一个我没想到的用途。

    var xargByID = { a: 1, b: 2 };

    Array.prototype.map.bind(xargByID)(function (xarg) {

    });

我不知道Array.prototype.map内部如何工作所以我不得不问,它可靠吗?它可能会随着时间而破碎吗?

3 个答案:

答案 0 :(得分:2)

它根本行不通。您只能在具有以0开头的数字属性且具有相应长度属性的对象上调用Array.map。所以只有这样才能起作用:

var xargByID = {0: 'first', 1: 'second', 2: 'third', length: 3};

Array.prototype.map.bind(xargByID)(function (xarg) {
    console.log(xarg);
});

这是因为.map()内部做了类似下面的模拟:

function simulateMap(callback, thisArg) {
    var ret = [], length = this.length, that = thisArg || this;
    for (var i = 0; i < length; i++) {
        ret.push(callback.call(that, this[i], i, this));
    }
    return ret;
}

.forEach().some()相同,等等。

编辑但是,如果你对.map()这么多,你可以这样做:

var xargByID = { a: 1, b: 2, c: 3};

Object.getOwnPropertyNames(xargByID).map(function(xarg, i, arr) {
    console.log(xarg, arr[i]);
});

答案 1 :(得分:1)

首先,.bind绝对不是编写示例的最佳方式,更好的是Array.prototype.map.call(xargByID, function (xarg) {

只要对象是类似数组,它就会工作:它有一个length属性,它是一个整数&gt; = 0,你要迭代的元素是整数&gt; =的属性0和&lt;长度。这不是黑客,而是设计; Array.prototype.map可用于非Array个对象,只要它们具有Array之类的形式。

在您的示例中,它不起作用,因为属性不在数字索引处且没有length属性。但是,如果xArgByID是这样的话,它会起作用:{0: 'a', 1: 'b', length: 2}

答案 2 :(得分:-1)

我知道这并不能回答您问题的可靠性方面,但是如果您可以访问lodash之类的库,那么您可以使用其map function来迭代对象。 可靠。

  

_。map(collection,[iteratee = _。identity])

     

通过遍历iteratee运行集合中的每个元素来创建值数组。使用三个参数调用iteratee:   (value,index | key,collection)。

根据您的具体要求,您可能还需要考虑_.forOwn()_.forIn()_.forEach()方法。它们还迭代Object中的属性。

编辑:根据下面的cortopy评论,我已经更新了这个答案,以便对lodash 4.x准确无误。 (之前的答案对于lodash 3.x来说是准确的)

相关问题