JavaScript调用-我可以直接访问对象属性
我试图理解使用JavaScript调用-我可以直接访问对象属性,javascript,scope,call,Javascript,Scope,Call,我试图理解使用call()的目的。我阅读了它的用途,并从中收集了示例,即: 我将从你问题的底部开始,询问为什么在代码中使用“call”: console.log([].map.call(document.querySelectorAll("span"), function(a){ return a.textContent; }).join("")); 所以,问题来了。这段代码真正想做的是在数组上使用map方法。但是,docum
call()
的目的。我阅读了它的用途,并从中收集了示例,即:
我将从你问题的底部开始,询问为什么在代码中使用“call”:
console.log([].map.call(document.querySelectorAll("span"),
function(a){
return a.textContent;
}).join(""));
所以,问题来了。这段代码真正想做的是在数组上使用map方法。但是,document.queryselectoral返回的是节点列表,而不是数组。这里最重要的是,NodeList上没有map函数。所以你会被困在经典的for循环中
然而,事实证明Array.map实际上适用于任何具有长度属性并支持数字索引的对象(例如,nodes[i]
)。但是,map的实现在内部专门使用this.length
因此,通过在此处使用call
,您可以借用Array.map的实现,向其传递一个this
引用,该引用实际上不是一个数组,但其工作方式与用于这些目的的数组非常相似
基本上,这是在呼吁:
document.querySelectorAll("span").map(
function(a){
return a.textContent;
}).join("");
除了返回实际上没有map方法,所以我们从数组中借用了一个。这通常被称为“duck类型”
动物的例子,就像任何有动物的例子一样,都是人为的。您在调用中传递i是因为您调用的函数(匿名函数)需要一个参数(请注意函数(i)
),因此您需要传递一个值。正如我所说,这是人为的,在现实生活中你不会这样做
因此,一般来说,调用最有用的方法是借用一种类型的方法在另一种类型上使用。我将从您问题的底部开始,询问为什么在代码中使用“调用”:
console.log([].map.call(document.querySelectorAll("span"),
function(a){
return a.textContent;
}).join(""));
所以,问题来了。这段代码真正想做的是在数组上使用map方法。但是,document.queryselectoral返回的是节点列表,而不是数组。这里最重要的是,NodeList上没有map函数。所以你会被困在经典的for循环中
然而,事实证明Array.map实际上适用于任何具有长度属性并支持数字索引的对象(例如,nodes[i]
)。但是,map的实现在内部专门使用this.length
因此,通过在此处使用call
,您可以借用Array.map的实现,向其传递一个this
引用,该引用实际上不是一个数组,但其工作方式与用于这些目的的数组非常相似
基本上,这是在呼吁:
document.querySelectorAll("span").map(
function(a){
return a.textContent;
}).join("");
除了返回实际上没有map方法,所以我们从数组中借用了一个。这通常被称为“duck类型”
动物的例子,就像任何有动物的例子一样,都是人为的。您在调用中传递i是因为您调用的函数(匿名函数)需要一个参数(请注意函数(i)
),因此您需要传递一个值。正如我所说,这是人为的,在现实生活中你不会这样做
因此,一般来说,调用最有用的方法是借用一种类型的方法在另一种类型上使用。
document.querySelectorAll(“span”)
返回节点列表而不是数组,因此如果尝试document.querySelectorAll(“span”).map(…)
您将得到一个关于未定义map
的错误(如果尝试.join,则相同)
这只是使用call
使其成为map
函数的数组
for(变量i=0;i
this
这里是动物数组。我猜您需要在这里调用,因为动物在其他方面超出了内部匿名函数的范围
实际上,这里的this
将引用索引i
处的动物数组中的对象。但是动物
并没有超出范围,只是做这个比较容易。物种
比动物[i]。物种
。他们本可以很容易地完成)(i)
和动物[i]。物种
而不是)。调用(…)
和这个。物种
i
参数,匿名函数将使用for循环的增量变量i
上次设置的任何值。因此,打印功能将记录相同的信息,而不是每个对象的信息document.querySelectorAll(“span”)
返回节点列表而不是数组,因此如果尝试document.querySelectorAll(“span”).map(…)
则会出现未定义map
的错误(如果尝试.join,则相同)
这只是使用call
使其成为map
函数的数组
for(变量i=0;i
this
这里是动物数组。我猜您需要在这里调用,因为动物在其他方面超出了内部匿名函数的范围
实际上,这里的this
将引用索引i
处的动物数组中的对象。但是动物
并没有超出范围,只是做这个比较容易。物种
比动物[i]。物种
。他们本可以很容易地完成)(i)
和动物[i]。物种
而不是)。调用(…)
和这个。物种
document.querySelectorAll("span").map(
function(a){
return a.textContent;
}).join("");
[].map.call(document.querySelectorAll("span"),
function(a){
return a.textContent;
}
)
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);
}
var animals = [
{ species: 'Lion', name: 'King' },
{ species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
})(i);
}
Array.prototype.map = function(fn) {
var copy = [];
for (var i = 0; i < this.length; i++) {
copy.push(fn(this[i]));
}
return copy;
};
var timesTwo = [1,2,3].map(function(n) {
return n * 2;
});
// timesTwo is [2,4,6];
var spanNodeList = document.querySelectorAll('span');
Array.prototype.map.call(spanNodeList, function(span) { /* ... */ });
// Or, as MDN's example, use an array instance as "[]"
[].map.call(spanNodeList, function(span) { /* ... */ });