javascript - 用于处理私有(private)函数的 jQuery 插件设计模式(常见做法?)

标签 javascript jquery design-patterns plugins

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.


3年前关闭。







Improve this question




我开发 jQuery 插件已经有一段时间了,我想我现在知道如何设计一个很好的插件了。一个问题一直困扰着我,那就是如何以一种强大而优雅的方式处理私有(private)函数。

我的插件通常看起来像这样:

(function($) {

  $.fn.myplugin = function(...) {
    ...
    // some shared functionality, for example:
    this.css('background-color', 'green');
    ...
  };
  $.fn.mypluginAnotherPublicMethod = function(...) {
    ...
    // some shared functionality, for example:
    this.css('background-color', 'red');
    ...
  };

}(jQuery));

现在我的问题是:如何巧妙地干掉共享功能?一个明显的解决方案是将它放在插件命名空间内的一个函数中:
var fill = function($obj, color) {
  $obj.css('background-color', color);
};

尽管此解决方案有效且命名空间很好,但我真的不喜欢它。原因很简单:我必须将 jQuery 对象传递给它。 IE。我必须这样调用它:fill(this, 'red'); ,而我想这样调用它:this.fill('red');
当然,我们可以通过简单地输入 fill 来实现这个结果。进入 jQuery.fn .但这感觉非常不舒服。想象一下,有十个基于这种方法开发的插件,每个插件将其中五个“私有(private)”函数放入 jQuery 函数命名空间。它最终陷入了巨大的困惑。我们可以通过在每个函数前面加上它们所属插件的名称来缓解,但这并不能真正使它更具吸引力。这些函数应该是插件私有(private)的,所以我们根本不想将它们暴露给外界(至少不直接暴露)。

所以我的问题是:你们中是否有人对如何两全其美提出建议。那是;插件代码能够以类似于 this.fill('red') 的方式调用“私有(private)”插件函数(或 this.myplugin.fill('red') 甚至 this.myplugin().fill('red') 等),同时防止 jQuery 函数命名空间污染。当然它应该是轻量级的,因为这些私有(private)函数可能会被非常频繁地调用。

更新 : 谢谢你的建议。

我特别喜欢 David 定义一个包含“私有(private)”函数并包装 jQuery 对象的对象类型的想法。唯一的问题是它仍然不允许我链接“私有(private)”和“公共(public)”功能。这是想要 this.fill('red') 这样的语法的重要原因首先。

我最终得到了一个我认为不是非常优雅的解决方案,但对“两全其美”的事业具有吸引力:
$.fn.chain = function(func) {
    return func.apply(this, Array.prototype.slice.call(arguments, 1));
};

它允许以下构造:
this.
    find('.acertainclass').
    chain(fill, 'red').
    click(function() {
        alert("I'm red");
    });

我在其他地方交叉发布了我的问题,其中也收集了一些有趣的回答:
  • http://forum.jquery.com/topic/jquery-plugin-design-pattern-common-practice-for-dealing-with-private-functions
  • http://groups.google.com/group/jquery-en/browse_thread/thread/fa8ccef21ccc589a
  • 最佳答案

    一件事先 : 如果你想调用 this.fill('red');在哪里 这个是 jQuery 的一个实例,你必须扩展 jQuery 原型(prototype)并制作 fill() “上市”。 jQuery 提供了使用所谓的“插件”扩展其原型(prototype)的指南,可以使用 $.fn.fill 添加。 , 与 jQuery.prototype.fill 相同.

    在 jQuery 回调中,这个通常是对 HTML 元素的引用,并且您不能向这些元素添加原型(prototype)(目前)。这就是 jQuery 包装元素并返回可以轻松扩展的 jQuery 实例的原因之一。

    使用 (function(){})();语法,您可以即时创建和执行“私有(private)”javascript,完成后一切都会消失。使用这种技术,您可以创建自己的类似 jQuery 的语法,将 jQuery 包装到您自己的私有(private)可链接对象中。

    (function(){
        var P = function(elem) {
            return new Private(elem);
        };
        var Private = function(elem) {
            this.elem = jQuery(elem);
        }
        Private.prototype = {
            elem: null,
            fill: function(col) {
                this.elem.css('background',col);
                return this;
            },
            color: function(col) {
                this.elem.css('color', col);
                return this;
            }
        }
    
        $.fn.myplugin = function() {
            P(this).fill('red');
        };
        $.fn.myotherplugin = function() {
            P(this).fill('yellow').color('green');
        };
    
    })();
    
    $('.foo').myplugin();
    $('.bar').myotherplugin();
    
    console.log(typeof P === 'undefined') // should print 'true'
    

    这样,P 代表您自己的“私有(private)”功能工具箱。除非您将它们附加到某个地方,否则它们在代码或 jQuery 命名空间中的其他任何地方都不会可用。您可以在 Private 对象中添加任意数量的方法,只要您返回 这个 ,您也可以像我在示例中所做的那样链接它们 jQuery 样式。

    关于javascript - 用于处理私有(private)函数的 jQuery 插件设计模式(常见做法?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2061501/

    相关文章:

    java - Java 中的工厂模式示例

    javascript - 具有 flowtype 的 PhpStorm 无法识别 React.Node

    javascript - 在 d3 图表列下对齐表格列

    Javascript - 如何在 iframe 中取消 YouTube 视频静音

    jquery - 在 jQuery 中,如何删除所有出现的 CSS 类,并将它一次添加到标记的父级的父级的特定兄弟级?

    c# - 使用接口(interface) - 设计模式方面

    javascript - 如果缺少脚本则跳过函数

    javascript - 在下拉列表 1 中选择某项后启用第二个下拉列表

    jquery - jquery如何捕获动态生成按钮的点击事件

    Javascript 模块模式 : When to go private with methods? Getters/setters?改进空间?