Это классический камень преткновения в 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 в закрытии функции. Чтобы исправить ваш код таким образом, я бы просто собрал все привязки событий в одном месте, а не каскадировал их, удалив ссылки «this» из обоих «displaydown ()» и «displaymove ()»:
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) Используйте функцию curry для привязки области во время определения. Я поднял метод bind () из библиотеки Prototype, чтобы проиллюстрировать:
// 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.