所以我试图对我的javascript代码进行分类。
我有一个名为node的类,它只包含一个整数,一个显示该整数的标签元素,以及一个用于递增整数的按钮元素。
当我通过代码调用incrementInteger
函数时,一切都按预期工作。但是当我尝试使用鼠标单击事件监听器来调用incrementInteger
函数时,事情就不起作用了。
这是我的代码:
$(document).ready(function() {
var firstNode = new Node();
firstNode.incrementInteger();
var secondNode = new Node();
});
function Node() {
this.integer = 0;
this.incrementInteger = function() {
this.integer++;
this.label.innerHTML = this.integer;
}
this.addButton = document.createElement("button");
this.addButton.addEventListener("mousedown", this.incrementInteger);
this.container = document.createElement("div");
this.label = document.createElement("div");
this.label.innerHTML = this.integer;
var bodyElement = document.getElementsByTagName("body")[0];
this.container.appendChild(this.label);
this.container.appendChild(this.addButton);
bodyElement.appendChild(this.container);
}
答案 0 :(得分:1)
this
函数中的 incrementInteger
不会引用对象上的属性。创建上下文参考:
var self = this;
this.integer = 0;
this.incrementInteger = function() {
self.integer++;
self.label.innerHTML = self.integer;
}
答案 1 :(得分:0)
您应该将this
绑定到incrementInteger
,如下所示:
this.incrementInteger = function() {
this.integer++;
this.label.innerHTML = this.integer;
}.bind(this);
答案 2 :(得分:0)
如果您的incrementInteger()
对于使用'Node'构造函数创建的每个'node'对象都相同,那么它应该是prototype
!否则(在普通的javascript中)你不会有共享方法(和属性)。
使用addEventListener
你几乎做对了,但你传递了对象的本地函数而不是对象本身(从而失去了对{{}的正确引用1}}如其他答案中所述)。
我的想法是this
可以将对象作为第二个参数,它将寻找一个名为handleEvent
的方法并调用它!
无需绑定addEventListener
;它将正确传递上下文:上下文是您刚刚设置为事件侦听器回调的对象。
这为我们提供了将(否则重复克隆的)this
函数移动到构造函数incrementInteger
的方法,包括prototype
函数。 NICE !
handleEvent
修改强>
或者(例如)你可以简单地写成:
function Node(){
this.integer = 0;
this.addButton = document.createElement('button');
this.addButton.addEventListener('mousedown', this);
this.container = document.createElement('div');
this.label = document.createElement('div');
this.label.innerHTML = this.integer;
this.container.appendChild(this.label);
this.container.appendChild(this.addButton);
document.getElementsByTagName('body')[0].appendChild(this.container);
}
Node.prototype={
incrementInteger: function(){
this.integer++;
this.label.innerHTML = this.integer;
},
handleEvent: function(){ // track event source-element to overload functionality.
this.incrementInteger();
}
};
// avoiding the html jquery script load line for this snippet
window.onload=function(){ // $(document).ready(function() {
var firstNode = new Node();
firstNode.incrementInteger();
var secondNode = new Node();
}; // });
在上面,您可以看到我们(仅在代码中)使用了标识符(window.Node = function(){
var d=document;
this.container = d.createElement('div');
(this.label = this.container.appendChild(d.createElement('div'))
).innerHTML = this.integer = 0;
(this.addButton = this.container.appendChild(d.createElement('button'))
).addEventListener('mousedown', this);
d.getElementsByTagName('body')[0].appendChild(this.container);
}).prototype={
incrementInteger: function(){
this.label.innerHTML = ++this.integer;
}
, handleEvent: function(){
this.incrementInteger();
}
};
window.onload=function(){
var firstNode = new Node();
firstNode.incrementInteger();
var secondNode = new Node();
};
一次,因此只有一个位置可以重命名您的标识符。
对象(由构造函数创建)共享的每个方法(或属性)都可以在Node
下轻松查看
除了ES6 Classes之外,这是你可以在纯javascript中实现的最接近你实现的目的:一个代码块,其中一个标识符描述 unique 和 shared 'class'的部分(因为'常见的'javascript没有类!)。
或者(例如)使用闭包将私有东西(共享)仅用于构造函数(第三部分):
(还将构造函数代码重新分解为2行,同时保留原始代码中的所有功能。)
prototype