如何创建IIFE Javascript模块的多个实例?

时间:2015-10-15 11:23:00

标签: iife javascript

我处理的是一个巨大的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模式一起创建它。这是正确的方法吗?

4 个答案:

答案 0 :(得分:6)

  

这是正确的方法吗?

没有。 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();

答案 1 :(得分:0)

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

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

您可以尝试:

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

var video1 = videoIframe(jQuery);
var video2 = videoIframe(jQuery);

答案 2 :(得分:0)

我做了一些小修改。希望它会有所帮助

    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

答案 3 :(得分:0)

只需将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
        };
    }());
};