本主在练习编写一个简单的js组件时,遇到一个小问题,苦思冥想不得其解,折腾来折腾去才明白原因只是一个误解,记录下来,提醒自己。(调试技术好烂啊!!!基础不牢坑死人!!!)
下面附上源码。是一个简单的小组件,在输入框输入文本后会显示输入了多少个字符。
(function(window) {
var Input = function(id) {
this.DOMCollection=(function() {
var obj = {};
obj.input = $(id);
obj.showBox = $('<span></span>');
obj.input.after(obj.showBox);
return obj;
}());
this.init(id);
};
Input.prototype = (function() {
function bindEvents() {
var that = this;
that.input.keyup(function() {
render.call(that);//that引用的是obj对象。this以及this.DOMCollecton只是中间变量名。(这是误区的所在)
});
}
function render() {
this.showBox.html(this.input.val().length);
}
return {
init: function() {
bindEvents.call(this.DOMCollection);//this.DOMCollection引用的是obj对象。
},
destory: function() {
//
}
}
}());
var test = new Input('#test');
//当尝试修改DOMcollection来破坏组件的功能,没想到完全没作用。组件运行良好。
test.DOMCollection=null;
var test2 = new Input('#test2');
原因在于:将null赋值给test.DOMCollection只是解除了对obj对象的引用。所以并没有修改obj对象自身,并不会破坏组件。除非test.DOMColletion.input=null这种直接通过引用访问对象的属性值并更改值的方式。(前者解除对象的引用,后者更改对象的值)
附:上面的方式把DOMCollection暴露给全局,还是可能被重写。可以把DOM对象的创建也放在prototype对象的某一私有方法内来隐藏。