JavaScript / jQuery中的这种设计模式是什么?

时间:2011-02-28 17:07:10

标签: javascript jquery design-patterns slickgrid

我正在查看SlickGrid的JavaScript源代码。

我注意到slick.grid.js具有以下结构:

(function($) {
    // Slick.Grid
    $.extend(true, window, {
        Slick: {
            Grid: SlickGrid
        }
    });

    var scrollbarDimensions; // shared across all grids on this page

    ////////////////////////////////////////////////////////////////////////////
    // SlickGrid class implementation (available as Slick.Grid)

    /**
     * @param {Node}           container   Container node to create the grid in.
     * @param {Array,Object}   data        An array of objects for databinding.
     * @param {Array}          columns     An array of column definitions.
     * @param {Object}         options     Grid options.
     **/
    function SlickGrid(container,data,columns,options) {
        /// <summary>
        /// Create and manage virtual grid in the specified $container,
        /// connecting it to the specified data source. Data is presented
        /// as a grid with the specified columns and data.length rows.
        /// Options alter behaviour of the grid.
        /// </summary>

        // settings
        var defaults = {
            ...
        };

        ...

        // private
        var $container;

        ...


        ////////////////////////////////////////////////////////////////////////
        // Initialization

        function init() {
            /// <summary>
            /// Initialize 'this' (self) instance of a SlickGrid.
            /// This function is called by the constructor.
            /// </summary>

            $container = $(container);

            ...
        }

        ////////////////////////////////////////////////////////////////////////
        // Private & Public Functions, Getters/Setters, Interactivity, etc.
        function measureScrollbar() {
            ...
        }

        ////////////////////////////////////////////////////////////////////////
        // Public API

        $.extend(this, {
            "slickGridVersion": "2.0a1",

            // Events
            "onScroll":                     new Slick.Event(),

            ...

            // Methods
            "registerPlugin":               registerPlugin,

            ...

        });

        init();
    }
}(jQuery));

为了简洁和清晰起见,省略了一些代码,但这应该给你一般的想法。

  1. 以下内容的目的是什么:(function($) { // code }(jQuery));这是我见过的模块模式吗?这是否意味着保持全局命名空间的清洁?

  2. $.extend()行是什么意思?:顶部$.extend(true, window, { // code });看起来与“命名空间”有关;什么是命名空间?看起来底部$.extend(this, { // code });用于暴露“公共”成员和功能?您将如何定义私有函数或变量?

  3. 如果您愿意,如何初始化多个“SlickGrids”?他们将分享多少以及他们将如何互动?请注意“构造函数”函数:function SlickGrid(...) { // code }

  4. 这种风格的编码有哪些书籍,链接和其他资源?谁发明了它?

  5. 谢谢! ♥

5 个答案:

答案 0 :(得分:9)

这是一个jQuery插件。

(function($) { // code }(jQuery));为您提供了一个新的函数范围,因此您的名称不会转储到全局范围内。将jQuery作为$传递,即使其他Javascript库使用$。

,也可以使用$简写

$.extend是一种将属性从一个对象复制到另一个对象的jQuery方法。第一个参数true意味着它应该是一个深而不是浅的副本。通过扩展window,可以创建新的全局属性,在本例中为Slick

底部的$.extend(this,...)位于大写函数SlickGrid中。 SlickGrid旨在用作构造函数,在这种情况下this将是新创建的对象,因此extend正在向对象添加属性。他们实际上是公共成员。在此代码示例中,measureScrollbar是私有的:它仅对此函数中定义的代码可见,而不是在其外部。

您可以使用以下命令创建多个网格:

var grid1 = new Slick.Grid(blah, blah);
var grid2 = new Slick.Grid(blah, blah);

在您展示的代码中,这两个实例将共享的唯一内容是scrollBarDimensions变量。

答案 1 :(得分:3)

(function($) { // code }(jQuery))

这是一个关闭。它基本上保持其内部的所有内容“//代码”免受外界的影响。你传递了jQuery和$,但是有更多知识的人必须解释为什么这是必要的。

$.extend()

这是一个jQuery函数,它将获取两个对象并将它们合并在一起。用第二个对象替换第一个对象“window”{Slick:{Grid:SlickGrid}}。这意味着如果有一个带有Grid的窗口对象:Null,它现在将等于Grid:SlickGrid。

将true添加为第一个参数意味着它也将替换嵌套对象:

var firstObj = { myObj:{
    first:this,
    second: {
        new: obj
    }
}}

$.extend(true, firstObj, {myObj:{second:{new:newer}}});

如果您使用大量对象来存储信息,这将非常有用。

不确定#3的含义,但请查看http://960.gs以获得良好的网格系统。

JavaScript Good Parts是一本很棒的书。 John Resig的Pro JavaScript也是一本很好的书,可以让你超越基础。

答案 2 :(得分:1)

简单地说,你的例子中的人只是编写了各种各样的jQuery插件...查看jquery.com的PLUGINS部分,以获取有关如何编写插件的源代码的更多参考。它们简单,直接且有趣,值得探索。

答案 3 :(得分:0)

1)加载JS文件时立即调用该函数。它接收jquery实例作为参数,并在内部以“$”形式提供。所有代码都封装在该函数中(除非您忘记前面的一个尚未声明的变量),否则不会污染全局命名空间。

2)第二个对象的所有属性都被复制到第一个对象,这里是“window”,它也是Web浏览器中的全局命名空间对象。因此,这段代码没有多大意义。它假装封装但反其道而行之。 $ .extend的第二次调用也没有多大意义。这没错,我只是认为代码“假装”。

4)我非常建议您查看Douglas Crockford在http://developer.yahoo.com/yui/theater/的视频 Crockford是一个JS神,非常有名(在严肃的JS程序员中) - 而且听起来非常有趣:)

答案 4 :(得分:0)

对于第一个问题,这个结构允许jQuery与可能使用$函数的其他库共存,但仍然使用$来引用代码块中的jQuery。

整个包被包装在一个函数调用中,$作为参数。运行此操作时唯一的“主要”活动是将jQuery作为参数调用该函数,这将引用已知的全局jQuery到本地参数$,它掩盖$可能具有的任何全局值。