原型功能链接到按钮不起作用

时间:2015-11-07 14:35:43

标签: javascript oop

我有一个类(我认为这是调用的)并在我的代码中创建了一个名为peter的对象。我现在想要升级Peter,如下所示:

// Define the class
function character(name, level){
   this.name = name;
   this.level = level;
}

// Create Peter at level 1
var peter = new character("Peter", 1);

// This will display the name of the character, level and a button to level him up
character.prototype.display = function() {
    document.getElementById("name").innerHTML += this.name;
    document.getElementById("level").innerHTML += this.level;

    // This line calls `levelup()` on load which is not what I want
    // and clicking the button no more calls `levelup`!
    document.getElementById("levelupbutton").onclick = this.levelup();

    // This line would call the function on click, but it looks like `this`
    // is not being passed down to the function `levelup` so I get NaN on
    // this.level down below?
    //document.getElementById("levelupbutton").onclick = this.levelup;
};


character.prototype.levelup = function() {
    alert("Level up in progress!");
    this.level++;
    alert(this.level);
}

peter.display();

jsfilldle

我可能错误地调用了该功能,而我似乎无法弄清楚如何正确地执行此功能。谁能给我一些指示?我是OOP的新手,所以如果解决方案涉及OOP,你能不能尽量解释一下呢?

2 个答案:

答案 0 :(得分:3)

您需要bind这个levelup而不是在线调用它来获得您想要的行为。 Updated your fiddle正确答案。

levelupbutton.onclick = this.levelup.bind(this);

function character(name, level){
  this.name = name;
  this.level = level;
}
var peter = new character("Peter", 1); // Instantiate new objects with 'new'
character.prototype.display = function(){
  document.getElementById("name").innerHTML += this.name;
  document.getElementById("level").innerHTML += this.level;
  document.getElementById("levelupbutton").onclick = this.levelup.bind(this);
};
character.prototype.levelup = function(){
  alert("Level up in progress!");
  this.level++;
  alert(this.level);
}
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>

答案 1 :(得分:2)

将处理函数附加到元素时,处理程序内部的值是对元素的引用。它与传递给处理程序的事件参数的e.target属性的值相同。

参考:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler

您可以使用Function.prototype.bind()方法创建一个新功能,将其this设置为提供的值。

只需附加click处理程序,如下所示:

document.getElementById("levelupbutton").addEventListener('click', 
    this.levelup.bind(this)
);

Why use addEventListener?

  

addEventListener是将事件监听器注册为的方式   在W3C DOM中指定..

小提琴:http://jsfiddle.net/abhitalks/sjfxorxz/6/

<强>段:

&#13;
&#13;
function character(name, level) {
    this.name = name;
    this.level = level;
}
character.prototype.levelup = function() {
    this.level++; 
    document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
    document.getElementById("name").innerHTML += this.name;
    document.getElementById("level").innerHTML += this.level;
    document.getElementById("levelupbutton").addEventListener('click', 
		this.levelup.bind(this)
	);
}

var peter = new character("Peter", 1);
peter.display();
&#13;
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
&#13;
&#13;
&#13;

或者,您也可以保存引用并在匿名函数调用中使用它而不是内联它。

例如:

character.prototype.display = function() {
    var self = this;
    document.getElementById("levelupbutton").addEventListener('click', 
        function () {
            self.levelup();
    });
}

小提琴2:http://jsfiddle.net/abhitalks/sjfxorxz/9/

代码段2:

&#13;
&#13;
function character(name, level) {
    this.name = name;
    this.level = level;
}
character.prototype.levelup = function() {
    this.level++; 
    document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
    var self = this;
    document.getElementById("name").innerHTML += this.name;
    document.getElementById("level").innerHTML += this.level;
    document.getElementById("levelupbutton").addEventListener('click', 
		function () {
        	self.levelup();
    });
}

var peter = new character("Peter", 1);
peter.display();
&#13;
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
&#13;
&#13;
&#13;