【问题标题】:How to create multiple instances of IIFE Javascript module?如何创建 IIFE Javascript 模块的多个实例?
【发布时间】:2016-01-13 20:00:30
【问题描述】:

我正在处理一个巨大的 JavaScript 代码库,我正在尝试重新组织它。我不是真正的专家,我刚开始研究良好的 javascript 编码实践。所以,我想做的一件事是将所有代码划分为模块。在这种特殊情况下,我正在尝试创建一个可以帮助我优化视频嵌入的模块。我想向模块传递一个 id 并从中接收一些 html 代码或图像。

我没有把整个代码放在这里,但是对于示例来说已经足够了:

var videoIframe = (function($) {
    'use strict';
     var id,

    setVideoId = function(videoId) {
        id = videoId;
        console.log(id);
    },
    getVideoThumbnail = function(videoId) {
        setVideoId(videoId);

    },
    test = function() {
        console.log(id)
    },
    getVideoEmbedCode = function() {

    };

    return {
       test: test,
       getVideoThumbnail: getVideoThumbnail
    };
})(jQuery);

在另一个模块中,我将它分配给两个变量:

    var video1 = videoIframe;
    var video2 = videoIframe;

    video1.getVideoThumbnail(123);
    video2.getVideoThumbnail(456);

    video1.test();
    video2.test();

当然,我没有得到我期望的结果。在第二次getVideoThumbnail 调用之后,它总是打印456

做一些研究后,我了解到我正在创建一个单例、一个实例,并且我只是在该实例中更改值。我想我的模块需要一个构造函数,但我不确定如何结合 IIFE 模式来创建它。这是正确的方法吗?

【问题讨论】:

    标签: iife javascript


    【解决方案1】:

    这是正确的方法吗?

    没有。 IIFE 适用于您只想做一次的事情。

    如果你想多次做某事,那么使用一个常规函数并多次调用它。

    var videoIframe = (function($) {
    
        function videoIframe() {
            'use strict';
            var id,
    
                setVideoId = function(videoId) {
                    id = videoId;
                    console.log(id);
                },
                getVideoThumbnail = function(videoId) {
                    setVideoId(videoId);
    
                },
                test = function() {
                    console.log(id)
                },
                getVideoEmbedCode = function() {
    
                };
    
            return {
                test: test,
                getVideoThumbnail: getVideoThumbnail
            };
        }
    
        return videoIframe;
    })(jQuery);
    
    var video1 = videoIframe();
    var video2 = videoIframe();
    
    video1.getVideoThumbnail(123);
    video2.getVideoThumbnail(456);
    
    video1.test();
    video2.test();
    

    【讨论】:

    • 那你为什么还在你的例子中保留 IIFE?
    • @Carlo — 因为还有一些事情需要做一次(即使$ 变量可用)。需要重复调​​用的代码被移到自己的函数中,并从 IIFE 中返回。
    【解决方案2】:

    问题是您在分配给videoIframe 变量时正在初始化对象:

    var videoIframe = (function($) {
      // ...
    })(jQuery);
    

    你可以试试:

    var videoIframe = (function($) {
      // ...
    });
    
    var video1 = videoIframe(jQuery);
    var video2 = videoIframe(jQuery);
    

    【讨论】:

      【解决方案3】:

      只需将 videoIframe 保留为返回 IIFE 的函数,而不是重复使用单例。我保留了 IIFE,因此 id 和内部函数继续被封装,因此如果它们不在返回的接口对象中,则无法访问它们。如果您打算创建大量此类,则仅使用构造函数和原型可能更有效,因此不会为每个实例重新创建内部函数。

      var videoIframe = function() {
          'use strict';
          return (function() {
              var id,
                  setVideoId = function(videoId) {
                      id = videoId;
                      console.log(id);
                  },
                  getVideoThumbnail = function(videoId) {
                      setVideoId(videoId);
      
                  },
                  test = function() {
                      console.log(id)
                  },
                  getVideoEmbedCode = function() {
      
                  };          
              return {
                 test: test,
                 getVideoThumbnail: getVideoThumbnail
              };
          }());
      };
      

      【讨论】:

        【解决方案4】:

        我做了一些小的修改。希望对你有帮助

            var videoIframe = (function($) {
            'use strict';
             var id;
        
            function _setVideoId(videoId) {
                id = videoId;
                alert(id);
            };
            function _getVideoThumbnail(videoId) {
                _setVideoId(videoId);
        
            };
            function _test(){
                console.log(id)
            }
            function _getVideoEmbedCode() {
        
            };
        
            return {
               test: _test,
               getVideoThumbnail: _getVideoThumbnail
            };
        })(jQuery);
        

        现在你可以这样调用

         videoIframe.getVideoThumbnail(123);
         videoIframe.getVideoThumbnail(561);
        

        jsfiddle

        【讨论】:

          猜你喜欢
          • 2014-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 2015-12-06
          相关资源
          最近更新 更多