“在JavaScript初始化期间”;无法设置属性';x';“未定义”的定义;
当我移动鼠标时。控制台告诉我:无法设置未定义的属性“x”。。。为什么会这样?对象初始化是如何进行的“在JavaScript初始化期间”;无法设置属性';x';“未定义”的定义;,javascript,Javascript,当我移动鼠标时。控制台告诉我:无法设置未定义的属性“x”。。。为什么会这样?对象初始化是如何进行的 var kMapControl={ mousemovepos:{ x:0,, y:0 }, onmousemove:功能(ev){ ev=ev | |事件; //这里告诉我:this.mousemovepos.x不是未定义的 this.mousemovepos.x=ev.clientX; this.mousemovepos.y=ev.clientY; }, init:function(){ va
var kMapControl={
mousemovepos:{
x:0,,
y:0
},
onmousemove:功能(ev){
ev=ev | |事件;
//这里告诉我:this.mousemovepos.x不是未定义的
this.mousemovepos.x=ev.clientX;
this.mousemovepos.y=ev.clientY;
},
init:function(){
var div=document.getElementById(“div1”);
div.addEventListener(“mousemove”,this.onmousemove,false);
}
};
window.onload=函数(){
kMapControl.init();
};
这样分配事件侦听器时,您正在失去对象的上下文。基本上,onmousemove
中的新this
绑定到触发事件的元素(大部分时间)。解决这个问题有两种可能:
使用bind()
:
使用匿名函数和指向旧此的指针:
init : function(){
var div = document.getElementById("div1"),
that = this;
div.addEventListener("mousemove", function(ev){ that.onmousemove( ev ); }, false);
}
在事件内部,此
是事件的目标(此===ev.target
)。而且ev
没有mousemovepos
,因此这个.mousemovepos
是未定义的。而未定义
没有x
,因此错误。使用以下命令:
onmousemove : function (ev) {
ev = ev || event;
// here tell me:this.mousemovepos.x is not undefined
this.mousemovepos.x = ev.clientX;
this.mousemovepos.y = ev.clientY;
}.bind(this),
改变
mousemovepos : {
x:0,
y:0
},
到
我更喜欢后者——它比调用.bind
便宜,并且保留了这个在处理程序中引用元素而不是对象的语义。@Alnitak:真的吗?你能指出一个jsperf吗?(毫无疑问,这是我第一次听说它)@Amadan在内部,.bind
通过返回一个绑定到所传递参数的闭包来工作,然后使用function.prototype.apply
调用原始函数。在上创建自己的别名更简单。请参见@Alnitak,上面的代码还创建了许多闭包,最明显的是涉及该函数,但也涉及div。@RobG AFAIK上面的代码不会关闭div
,因为内部函数不使用它。事实上(我的意思是说)这里的代码也会在别名上创建闭包,但是我认为没有必要调用函数来实现这一点。IMHO,.bind
实际上只是在不控制被调用函数的词法范围的情况下才是更好的解决方案.bind
还会创建一个新的函数对象。您是对的。我该去睡觉了。显然已经过了我的就寝时间代码>仅对不支持W3C事件模型的浏览器是必需的。这样的浏览器不会有addEventListener,所以任务中没有太多要点。
onmousemove : function (ev) {
ev = ev || event;
// here tell me:this.mousemovepos.x is not undefined
this.mousemovepos.x = ev.clientX;
this.mousemovepos.y = ev.clientY;
}.bind(this),
mousemovepos : {
x:0,
y:0
},
this.mousemovepos : {
x:0,
y:0
},