Sha*_*aoz 18 javascript object-literal
我正在尝试使用this关键字调用我创建的对象文字中的函数.但是错误显示说this.doTheMove()不是功能:
window.onload = function(){
var animBtn = document.getElementById('startAnim');
animBtn.addEventListener('click', Animation.init, false);
}
var Animation = {
init: function(){
this.doTheMove(); // I'm calling the function here, but it gives an error.
},
doTheMove: function(){
alert('Animation!');
}
}
Run Code Online (Sandbox Code Playgroud)
为什么会出错?
Ray*_*nos 16
对正在发生的事情的解释.Pointy的答案很好,但我想更一般地解释它.this可以在这里找到一个非常好的研究
事件处理程序只是一个回调.你传递一个函数和一个事件来监听.它所做的一切就是调用该函数.
Animation.init只是该函数的一个getter.可以这样想:
var callback = Animation.init
animBtn.addEventListener('click', callback, false);
...
// internal browser event handler
handler() {
// internal handler does stuff
...
// Oh click event happened. Let's call that callback
callback();
}
Run Code Online (Sandbox Code Playgroud)
所以你所做的就是传入
var callback = function(){
this.doTheMove(); // I'm calling the function here, but it gives an error.
}
Run Code Online (Sandbox Code Playgroud)
默认情况下在javascript中this === window.如果没有设置为某个东西,这将引用全局对象.净效应是window.doTheMove被称为.而且这个功能不存在.
在这种情况下,由于callback事件处理程序会动态this调用node.doTheMove该对象,因此该对象指向触发该事件的DOM对象,因此您的调用仍然不存在.
你想要做的是用动画引用它.
var callback = function() {
Animation.init();
}
Run Code Online (Sandbox Code Playgroud)
这是一个函数的执行,并执行init上Animation.当你在像这样的对象上执行它时,就像this === Animation你期望的那样在内部执行它.
总结一下.这里的问题是它Animation.init只是对函数的引用.它没有像Pointy提到的任何其他信息.
Poi*_*nty 10
你必须改变你设置的方式:
window.onload = function(){
var animBtn = document.getElementById('startAnim');
animBtn.addEventListener('click', function() { Animation.init(); }, false);
}
Run Code Online (Sandbox Code Playgroud)
在JavaScript中,函数碰巧被定义为对象文字的一部分的事实实际上并不是非常重要(事实上,如果有的话).引用Animation.init 确实可以让你找到合适的函数,但问题是当稍后调用函数时(响应实际的"点击"),浏览器会调用函数但不知道对象"动画"应该是该this参考.同样,函数被声明为对象的一部分这一事实在这里根本不重要.因此,如果您想this成为您自己选择的特定内容,那么您必须确保在您控制的代码中明确设置它.上面的解决方案是关于最简单的方法:它使用匿名函数处理"click"事件,除了通过"Animation"通过显式引用调用"init"函数之外什么都不做.这将确保this在"init"运行时引用"Animation"对象.
另一种方法是使用某些浏览器和框架支持的".bind()"工具:
window.onload = function(){
var animBtn = document.getElementById('startAnim');
animBtn.addEventListener('click', Animation.init.bind(Animation); }, false);
}
Run Code Online (Sandbox Code Playgroud)
净效果几乎完全相同:对".bind()"的调用返回一个函数,该函数调用它所调用的函数(即"Animation"对象中的"init"函数),并且它的第一个参数作为this引用("context"对象).这与我们从第一个例子得到的相同,或者无论如何都是有效的.
| 归档时间: |
|
| 查看次数: |
14449 次 |
| 最近记录: |