Javascript .call() 用法。一个工作案例,一个不是。有什么区别?
Javascript .call() usage. One working case, one not. What's the diff?
我对这些用例的区别感到困惑:
// CASE 1: Two separate attempts, neither work (see comments)
var circle = new google.maps.Circle({
// and then a bunch of properties, all work fine. Including this to show you
// where the variable I'm trying to use in call() came from
});
circle.initListeners = function(){
this.addListener('mouseover', function(){
// Works if circle is named explicitly in explodeView (see code below),
// doesn't work with .call(circle) here, this.setRadius() in explodeView
explodeView().call(circle);
// Both work fine
this.infoWindow.setPosition(this.getBounds().getNorthEast());
this.infoWindow.open(map);
// Works with circle.getCenter, not with .call(circle) and this
this.timer = setInterval(function(){
map.panTo(this.getCenter());
}, 1000).call(circle)
// Works with circle.setRadius, not with this.setRadius
function explodeView(){
var radiusExtender = ((300 - tweet.stats.reach) + 1) / 60;
radiusExtender > 1.15 ? this.setRadius(radiusExtender * radius) : this.setRadius(radius * 1.15);
}
});
});
将此与以下 .call()
的用法进行比较,我在调用没有 .call(map)
的函数时出现 "this does not have method ._togCircVis(...)"
错误后实现的:
// CASE 2: Works
// Call to function I added to circle prototype
map._togCircVis.call(map)
// Successfully receives map and executes correctly
google.maps.Map.prototype._togCircVis = function(){
this.circles.forEach(function(circle){
circle.getMap() != null ? circle.setMap(null) : circle.setMap(map);
})
}
当我尝试案例 1 中的代码时,我得到了与将 .call(map)
添加到案例 2 之前相同的 "this does not have method "
错误。当我尝试 .apply() 而不是 .apply() 时也是如此。 call()(一次万岁调试尝试)。我明白了为什么添加到案例 2 后它可以工作,因为它澄清了调用的函数,当我使用 this
时,我正在谈论 map
对象,而不是 window 对象用于变量赋值。但是,为什么它不适用于上述情况? MDN 文章帮助我开始使用 .call(map),但没有为我阐明其他用途。谢谢!
explodeView().call(circle);
在这里您正常调用 explodeView(没有调用)然后尝试调用 call
它返回的值 (undefined
)。相反,您应该写 explodeView.call( circle )
。你在这里有一个非常相似的问题:
setInterval(function(){
map.panTo(this.getCenter());
}, 1000).call(circle);
您正试图在一个非函数的对象上调用 call
。之前是undefined
,这次是数字(setInterval returns a number). You could use bind这样实现你想要的:
setInterval(function(){
map.panTo(this.getCenter());
}.bind(circle), 1000);
我对这些用例的区别感到困惑:
// CASE 1: Two separate attempts, neither work (see comments)
var circle = new google.maps.Circle({
// and then a bunch of properties, all work fine. Including this to show you
// where the variable I'm trying to use in call() came from
});
circle.initListeners = function(){
this.addListener('mouseover', function(){
// Works if circle is named explicitly in explodeView (see code below),
// doesn't work with .call(circle) here, this.setRadius() in explodeView
explodeView().call(circle);
// Both work fine
this.infoWindow.setPosition(this.getBounds().getNorthEast());
this.infoWindow.open(map);
// Works with circle.getCenter, not with .call(circle) and this
this.timer = setInterval(function(){
map.panTo(this.getCenter());
}, 1000).call(circle)
// Works with circle.setRadius, not with this.setRadius
function explodeView(){
var radiusExtender = ((300 - tweet.stats.reach) + 1) / 60;
radiusExtender > 1.15 ? this.setRadius(radiusExtender * radius) : this.setRadius(radius * 1.15);
}
});
});
将此与以下 .call()
的用法进行比较,我在调用没有 .call(map)
的函数时出现 "this does not have method ._togCircVis(...)"
错误后实现的:
// CASE 2: Works
// Call to function I added to circle prototype
map._togCircVis.call(map)
// Successfully receives map and executes correctly
google.maps.Map.prototype._togCircVis = function(){
this.circles.forEach(function(circle){
circle.getMap() != null ? circle.setMap(null) : circle.setMap(map);
})
}
当我尝试案例 1 中的代码时,我得到了与将 .call(map)
添加到案例 2 之前相同的 "this does not have method "
错误。当我尝试 .apply() 而不是 .apply() 时也是如此。 call()(一次万岁调试尝试)。我明白了为什么添加到案例 2 后它可以工作,因为它澄清了调用的函数,当我使用 this
时,我正在谈论 map
对象,而不是 window 对象用于变量赋值。但是,为什么它不适用于上述情况? MDN 文章帮助我开始使用 .call(map),但没有为我阐明其他用途。谢谢!
explodeView().call(circle);
在这里您正常调用 explodeView(没有调用)然后尝试调用 call
它返回的值 (undefined
)。相反,您应该写 explodeView.call( circle )
。你在这里有一个非常相似的问题:
setInterval(function(){
map.panTo(this.getCenter());
}, 1000).call(circle);
您正试图在一个非函数的对象上调用 call
。之前是undefined
,这次是数字(setInterval returns a number). You could use bind这样实现你想要的:
setInterval(function(){
map.panTo(this.getCenter());
}.bind(circle), 1000);