In attempting to keep with the DRY principle, I decided to revise a function’s prototype in an effort to reduce the number of function.call() calls.
Following is a snippet of what I currently have and further clarification as to what I am attempting to do.
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
}
}());
I realize this looks very much like I am attempting to mimic the functionality of jQuery. While intentional, this is not meant to act as a replacement but rather a better personal understanding of JavaScript.
That said, what I would like to do is remove the need to invoke exe() via exe.call(this[, fnc]); in order for the context of this to be what I want. I believe I can do this through function binding (.bind()), though perhaps not the way I would like to. I understand it is possible to instead do something like:
com.domain.$.prototype.exe = function(){}
and call it like:
function addClass(c){this.exe(function(){});}
In doing so, however, I lose the private visibility of exe() provided by the closure in my original code. I would like to keep that in tact, if possible.
My question, then, is whether or not it is possible to bind exe() within my original code in such a way that I can reduce the redundant use of exe.call(this, possess the correct context for this within exe(), and maintain the private visibility within the closure?
If this seems a poor implementation of what I am trying to accomplish, I am more than happy to consider other options.
Thank you in advance.
No, you can’t, since at the moment you define
exe(), the instance you want to callexe()on does not exist yet.In fact, if you are going to make several calls to
com.domain.$, you will useexe()with different instances and therefore it does not make sense to bindexe()to a specific instance.If you wanted to do that, you’d have to define all these methods inside the constructor and you would loose all the advantages of prototypes:
I would suggest, if you don’t want to use
.call, to just modifyexe()so that it accepts an array of elements as argument and passthis.elementsto it from the prototype functions. I don’t see whyexe()needs to usethisat all. It’s merely a helper which passes each element of an array to a given function and by making it more general, it is easier to reuse.For example: