为什么Array.prototype.map.call而不是Array.map.call

时间:2013-11-22 19:58:56

标签: javascript

我遇到了一些代码,其中的人使用Array.prototype.map.call代替Array.map.call

function getLinks() {
    var links = document.querySelectorAll('h3.r a');
    return Array.prototype.map.call(links, function(e) {
        return e.getAttribute('href');
    });
}

为什么不简单地拨打Array.map.call?我检查了Firefox控制台,ArrayArray.prototype都有地图功能。有区别吗?

5 个答案:

答案 0 :(得分:34)

这是因为document.querySelectorAll不返回Array个实例,而是返回NodeList的实例(或者至少不保证在所有浏览器上返回Array)。 NodeList已编入索引元素,但未包含Array原型中的所有方法。

这就是我们需要在返回的对象的上下文中从map的原型中调用Array方法的原因。

我认为您理解为:

var a = [], f = function() {};

表达式:

a.map(f);

相当于:

Array.prototype.map.call(a, f);

另见

答案 1 :(得分:9)

由于Array.map.call不起作用。 Array.map可以接受两个参数:数组和回调。 call运行一个函数,将this设置为您提供的对象。

因此,当您运行Array.prototype.map.call(somearray,function(){...});时,它几乎与您调用somearray.map(function(){...});相同。 Array.map只是一种实用工具方法Javascript 仅适用于Firefox (不使用它的另一个原因)必须让生活更轻松。 Array.map功能不是跨浏览器。

修改:他们必须使用Array.prototype.map.call(links,...);而非links.map(...);的原因是querySelectorAll没有返回正常数组,它返回一个NodeList没有map方法的{{1}}。

答案 2 :(得分:3)

好问题:

Array是一个用于创建数组的构造函数。


如果在浏览器控制台中键入数组,您将获得一个功能定义,如

function Array(){[native code]}

如果在浏览器控制台中键入Array.prototype,则会得到一个空数组,即 []  即一个数组对象。

考虑这段摘录

function a(){
console.log('hi');
function b(){console.log('b');}
function c(){console.log('c');}
return {b:b,c:c,d:this}
}


当您键入d = new a();时,然后d是具有两个属性(即b和c)的对象,您可以调用
{{1} } >> d.b() //logs b

但是你不能称之为>> d.c() //logs c //因为函数b和c不是a的属性。 />左,因为函数b和c在函数a中定义。类似地,函数映射在函数数组中定义。

因此,您不能调用a.b() or a.c(),但您必须获取Array的对象并在其上调用map函数。
Array.map()为我们提供了一个数组对象,因此他们正在使用Array.prototype

很抱歉很长的解释。希望它有益。:)

答案 3 :(得分:1)

他们可能已经避免使用Array.map,因为它在Chrome或IE中不存在。

答案 4 :(得分:1)

map意味着在数组实例上调用。因此,Array.prototype.map}在大多数浏览器中都不存在。