我会将我以前的js代码移到更多的OOP风格。这是代码。
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function test() {
}
test.prototype = {
init: function () {
addEvent(document, 'mousedown', this.displaydown);
},
displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";
addEvent(document, 'mousemove', this.displaymove);
},
displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}
var test0 = new test();
test0.init()
使用
进行mousedown后无法添加mousemove事件addEvent(document, 'mousemove', this.displaymove);
但是如果我像
那样写内联样式addEvent(document, 'mousemove', function(e){
document.getElementById('mydiv').innerHTML = "move";
});
没关系。它看起来2个代码做同样的事情。为什么会有区别?谢谢!
编辑
经过2个晚上的斗争,我终于解决了这个问题。感谢johnvey的启发。
错误发生在此关键字上。在对象的情况下,这指的是窗口而不是对象本身。解决方案是我在开始时定义了全局参数 me(me = this)。现在没关系。
答案 0 :(得分:2)
这是一个经典的Javascript绊脚石块,与“this”键在闭包中的作用方式有关。举例说明:
redPrinter = function() {
this.X = 'red';
return function() {
return this.X;
}
}
main = function() {
this.X = 'blue';
var myRedPrinter = new redPrinter();
alert("Red printer returned: " + myRedPrinter());
}
main();
此代码将打印出来:
Red printer returned: blue
因为行中的'this'范围:
return this.X
实际上是在调用时绑定到main()对象。
通常有两种解决方法:
1)避免在函数闭包中使用'this'关键字。要以这种方式修复代码,我只需在一个地方收集所有事件绑定而不是级联它们,从而从'displaydown()'和'displaymove()'中删除'this'引用:
test.prototype = {
init: function () {
addEvent(document, 'mousedown', this.displaydown);
addEvent(document, 'mousemove', this.displaymove);
},
displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";
},
displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}
OR
2)使用函数currying在定义时绑定范围。我已经从Prototype库中解除了bind()方法来说明:
// declare the global bind() method for all functions
Function.prototype.bind = function(obj) {
var method = this,
temp = function() {
return method.apply(obj, arguments);
};
return temp;
}
test.prototype = {
init: function () {
addEvent(document, 'mousedown', this.displaydown);
},
displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";
// note that we bind the method object here
addEvent(document, 'mousemove', this.displaymove.bind(this));
},
displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}
这里的重要变化是:
this.displaymove.bind(this)
基本上说,“当你调用displaymove()时,将关键字'this'重新调整到原始范围上下文而不是当前的Event对象。