【问题标题】:How to create a javascript library using a closure如何使用闭包创建 javascript 库
【发布时间】:2012-09-16 14:17:17
【问题描述】:

我已经编写了一些 javascript,我将它们封装在一个闭包中,以便我可以在其他地方使用它。我想这样做类似于 jQuery 所做的那样。我希望能够将一个 id 传递给我的闭包并在其上调用一些函数,同时设置一些选项。类似这样:

<script type="text/javascript">
    _snr("#canvas").draw({
        imageSrc : someImage.png
    });
</script>

我已经阅读了很多关于如何使用闭包来做到这一点的不同帖子,但我仍在为这个概念而苦苦挣扎。这是我离开的地方:

_snr = {};
(function (_snr) {

    function merge(root){
        for ( var i = 1; i < arguments.length; i++ )
            for ( var key in arguments[i] )
                root[key] = arguments[i][key];
        return root;
    }

    _snr.draw = function (options) {

        var defaults = {
            canvasId : 'canvas',
            imageSrc : 'images/someimage.png'
        }

        var options = merge(defaults, options)

        return this.each(function() {
            //More functions here
        });
    };

    _snr.erase = function () {};

})(_snr);

当我尝试像上面的第一个代码部分那样调用绘图函数时,我收到以下错误,“_snr 不是函数”。我哪里错了?

编辑 这是我最终做的:

function _snr(id) {

    // About object is returned if there is no 'id' parameter
    var about = {
        Version: 0.2,
        Author: "ferics2",
        Created: "Summer 2011",
        Updated: "3 September 2012"
    };

    if (id) {

        if (window === this) {
            return new _snr(id);
        }

        this.e = document.getElementById(id);
        return this;
    } else {
        // No 'id' parameter was given, return the 'about' object
        return about;
    }
};

_snr.prototype = (function(){

    var merge = function(root) {
        for ( var i = 1; i < arguments.length; i++) {
            for ( var key in arguments[i] ) {
                root[key] = arguments[i][key];
            }
        }
        return root;
    };

    return {
        draw: function(options) {

            var defaults = {
                canvasId : 'canvas',
                imageSrc : 'images/someimage.png'
            };

            options = merge(defaults, options);

            return this;
        },

        erase: function() {
            return this;
        }
    };
})();

我现在可以打电话了:

<script type="text/javascript">
    _snr("#canvas").draw({
        imageSrc : someImage.png
    });
</script>

【问题讨论】:

    标签: javascript oop closures


    【解决方案1】:

    这里有一个 snr 对象,它具有擦除和绘制方法。您打算做的是编写一个 _snr 函数,该函数将获取一个 id 并返回一个包装器对象。返回的对象应该有擦除和绘制方法。所以你可以做 var returnedObject = _snr("my_id"); 返回对象.draw("image.png");

    【讨论】:

      【解决方案2】:

      你在第一行就错了_snr = {}

      应该是

      _snr = function(){
          selector = arguments[0]||false;
          //snr init on dom object code
          return _snrChild;
      }
      

      我在手机上,但当我在电脑上时,我可能会修复整个代码 c:

      【讨论】:

        【解决方案3】:

        当您执行 _snr('#canvas') 时,这是一个函数调用,这就是您收到该错误的原因。 _snr 是一个附加了一些方法的对象,例如draw()erase()。 jQuery 能够将参数传递给 $ 的原因是因为它们将 $ 作为函数对象返回,这就是我们能够将各种选择器作为参数传递给它的原因。

        【讨论】:

          【解决方案4】:

          因为您将 _snr 声明为对象而不是函数。函数可以具有属性和方法,因此有多种方法可以实现您想要的,例如其中一种是...

          _snr = function(tag) {
          this.tag = tag;
          }
          
          _snr.foo = function() {
          //Code goes here
          }
          

          您还可以将外部上下文传递到闭包中,以隐藏您的变量以免意外污染全局命名空间,就像...

          (function(global) {
          var _snr = function(tag) {
          this.tag = tag;
          }
          
          _snr.foo = function() {
          //Code goes here
          }
          
          //export the function to the window context:
          global._snr = _snr;
          })(window);
          
          window._snr('#tag').foo('wat');
          

          编码愉快。

          【讨论】:

          • 那么有没有办法结合上面的两个解决方案,所以我仍然可以隐藏我的变量,但调用 _snr('#tag').foo('wat');而不是 window._snr....?
          【解决方案5】:

          因为您的 _snr 是一个对象,而不是一个函数。你必须这样称呼它:

          _snr.draw({
              canvasId: '#canvas',
              imageSrc: 'someImage.png'
          });
          

          【讨论】:

            猜你喜欢
            • 2020-06-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-19
            • 1970-01-01
            • 2018-12-23
            相关资源
            最近更新 更多