10

我正在查看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. 有哪些关于这种风格编码的书籍、链接和其他资源?谁发明的?

谢谢!♥</p>

4

5 回答 5

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变量。

于 2011-02-28T17:14:26.037 回答
3
(function($) { // code }(jQuery))

这是一个关闭。它基本上使“//代码”内部的所有内容免受外部事物的影响。你传入 jQuery 和 $,但有更多知识的人将不得不解释为什么这是必要的。

$.extend()

这是一个 jQuery 函数,它将获取两个对象并将它们合并在一起。用第二个对象 {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 the Good Parts 是一本很棒的书。John Resig 的 Pro JavaScript 也是一本让您超越基础知识的好书。

于 2011-02-28T17:15:36.753 回答
1

简而言之,您示例中的人只是编写了各种 jQuery 插件...查看 jquery.com 的 PLUGINS 部分,以获取有关如何编写插件的资源的更多参考。它们简单、直接且探索起来很有趣。

于 2011-02-28T17:15:30.807 回答
0

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

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

于 2011-02-28T17:15:00.753 回答
0

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

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

4) 我非常强烈建议您查看来自http://developer.yahoo.com/yui/theater/的 Douglas Crockford 的视频 Crockford 是一位 JS 大神,非常有名(在严肃的 JS 程序员中)——此外还非常有趣听:)

于 2011-02-28T17:13:08.537 回答