【问题标题】:Calling a function from another function within the same prototype and context of this在 this 的相同原型和上下文中从另一个函数调用一个函数
【发布时间】:2012-08-25 02:02:04
【问题描述】:

为了保持 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(),这样我可以减少exe.call(this 的冗余使用,在@ 中拥有this 的正确上下文987654332@,并在关闭内保持私有可见性?

如果这似乎无法实现我想要完成的目标,我非常乐意考虑其他选择。

提前谢谢你。

【问题讨论】:

    标签: javascript bind prototype


    【解决方案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 $;
    }());
    

    【讨论】:

    • 感谢您的回复,菲利克斯。正如您所注意到的,出于显而易见的原因,我想将功能排除在构造函数的定义之外。正如您还提到的,我可以将this.elements 传递给exe(),我确实考虑过这一点,但我希望避免重复使用exe(this.elements, ... 并保持脚本文件更小。
    • 有些事情是不可能的 :) 你应该专注于可读性和可维护性,并使用代码压缩器来减小文件大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    相关资源
    最近更新 更多