我遇到了一些代码,其中的人使用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控制台,Array
和Array.prototype
都有地图功能。有区别吗?
答案 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
。 1>}在大多数浏览器中都不存在。