为了保持DRY原则,我决定修改函数的原型,以减少function.call()调用的次数。
以下是我目前所拥有的内容片段,并进一步澄清我正在尝试做什么。
com.domain.$ = function(s){
if(!this){return new com.domain.$(s);}
this.selector = s;
this.elements = document.querySelectorAll(s);
}
com.domain.$.prototype = (function(){
function exe(f){
var e = this.elements,
el = e.length;
for(var i=0; i<el; i++){
f(e[i]);
}
}
function addClass(c){exe.call(this,function(el){el.classList.add(c);});}
function removeClass(c){exe.call(this,function(el){el.classList.remove(c);});}
function toggleClass(c){exe.call(this,function(el){el.classList.toggle(c);});}
return {
addClass:addClass,
removeClass:removeClass,
toggleClass:toggleClass
}
}());
我意识到这看起来非常像我试图模仿jQuery的功能。虽然是故意的,但这并不意味着可以作为替代品,而是更好地理解JavaScript。
那就是说,我想要做的就是不再需要通过exe()
调用exe.call(this[, fnc]);
,以便this
的上下文成为我想要的。我相信我可以通过函数绑定(.bind()
)来做到这一点,尽管可能不是我想要的方式。我知道有可能做类似的事情:
com.domain.$.prototype.exe = function(){}
并称之为:
function addClass(c){this.exe(function(){});}
然而,在这样做的过程中,我失去了原始代码中闭包提供的exe()
的隐私可见性。如果可能的话,我想保持这一点。
我的问题是,是否可以在我的原始代码中绑定exe()
,以便减少exe.call(this
的冗余使用,拥有this
的正确上下文在exe()
中{1}},并在闭包内保持私密可见性?
如果这似乎是我想要实现的不好的实现,我非常乐意考虑其他选择。
提前谢谢。
答案 0 :(得分:1)
不,您不能,因为目前您定义exe()
,您要调用exe()
的实例尚不存在。
事实上,如果您要对com.domain.$
进行多次调用,则会将exe()
用于不同的实例,因此将exe()
绑定到具体的实例。
如果你想这样做,你必须在构造函数中定义所有这些方法,你将失去原型的所有优点:
(function() {
function exe(f){
// ...
}
com.domain.$ = function(s){
// ...
var exe_ = exe.bind(this);
this.addClass = function(c) {
exe_(function(el){el.classList.add(c);});
};
// ...
};
}());
如果您不想使用.call
,我建议您只修改exe()
,使其接受一个元素数组作为参数,并将this.elements
传递给它原型功能。我不明白为什么exe()
需要使用this
。它只是一个帮助器,它将数组的每个元素传递给给定的函数,并使其更通用,更容易重用。
例如:
var com.domain.$ = (function(o) {
function exe(arr, f){
var el = e.length;
for(var i=0; i<el; i++){
f(arr[i]);
}
}
var $ = function(s){
// ...
}
$.prototype.addClass = function(c){
exe(this.elements, function(el){
el.classList.add(c);
});
};
// ...
return $;
}());