最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to create multiple instances of IIFE Javascript module? - Stack Overflow

programmeradmin5浏览0评论

I'm dealing with a huge javascript codebase that I'm trying to reorganize. I'm not really an expert and I just started studying good javascript coding practices. So, one thing I'm trying to do is to divide all the code in modules. In this particular case I'm trying to create a module that would help me to optimize video embeds. I would like to pass the module an id and receive some html code or an image out of it.

I'm not putting the whole code here, but it's enough for the example:

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);

In another module I assign it to two variables:

    var video1 = videoIframe;
    var video2 = videoIframe;

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

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

And, of course, I'm not getting what I expected. After the second getVideoThumbnail call, it always prints 456.

Doing some research I understood that I'm creating a singleton, a single instance, and I'm only changing values inside that instance. I think I need a constructor for my module, but I'm not sure how to create it in bination with the IIFE pattern. And is it the right approach?

I'm dealing with a huge javascript codebase that I'm trying to reorganize. I'm not really an expert and I just started studying good javascript coding practices. So, one thing I'm trying to do is to divide all the code in modules. In this particular case I'm trying to create a module that would help me to optimize video embeds. I would like to pass the module an id and receive some html code or an image out of it.

I'm not putting the whole code here, but it's enough for the example:

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);

In another module I assign it to two variables:

    var video1 = videoIframe;
    var video2 = videoIframe;

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

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

And, of course, I'm not getting what I expected. After the second getVideoThumbnail call, it always prints 456.

Doing some research I understood that I'm creating a singleton, a single instance, and I'm only changing values inside that instance. I think I need a constructor for my module, but I'm not sure how to create it in bination with the IIFE pattern. And is it the right approach?

Share Improve this question asked Oct 15, 2015 at 11:23 CarloCarlo 4,1687 gold badges49 silver badges70 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6

And is it the right approach?

No. IIFEs are for things you want to do exactly once.

If you want to do something multiple times, then use a regular function and call it multiple times.

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();

The problem is that you are initializing object when assigning to videoIframe variable:

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

You can try with:

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

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

Just keep videoIframe as a function that returns your IIFE, instead of reusing the singleton. I kept the IIFE so the id and the inner functions keep being encapsulated and hence, not reachable if they're not in the returned interface object. If you are planning to create alot of these, it might be more efficient to just use a constructor and a prototype, so the inner functions don't get recreated for every instance.

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

I did some minor modification. Hope it will be helpful

    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);

Now you can call like this

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

jsfiddle

发布评论

评论列表(0)

  1. 暂无评论