2012-08-24 221 views
0

的相同原型和上下文中为了保持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.call(this[, fnc]);调用exe(),以使this的上下文成为我想要的。我相信我可以通过函数绑定(.bind())来做到这一点,但可能不是我想要的方式。我的理解是可能的,而不是像做:

com.domain.$.prototype.exe = function(){} 

,并调用它像:

function addClass(c){this.exe(function(){});} 

这样做,但我失去的exe()经闭在我原来提供的私有可见码。如果可能的话,我希望保持这一点。

我的问题,那么,它是否有可能以这样的方式,我可以减少重复使用的exe.call(this,具备内exe()this正确的上下文我的原代码中绑定exe(),并保持私人闭幕内的知名度?

如果这似乎是我尝试完成的一个糟糕的实现,我很乐意考虑其他选项。

预先感谢您。

回答

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 $; 
}()); 
+0

感谢您的答复,菲利克斯。如你所注意到的,我想保留功能超出构造函数的定义,原因很明显。你也注意到,我可以将'this.elements'传递给'exe()',我确实考虑过这个,但我希望避免重复使用'exe(this.elements,...'并保持脚本文件变小 – AustinP

+0

有些事情是不可能的:)你应该关注可读性和可维护性,并使用代码缩减器来减小文件大小。 –