Search code examples
javascriptfunctionself-invoking-function

Self invoking functions javascript to clean up variables on global namespace


Learning javascript and I wanted to get feedback on self invoking functions.

I read that creating global variables is not the way to go.

This the original

// Footer of page
<script>
    var lat = 51.505 // retrieved from db
    var lon = -0.09  // retrieved from db

    var map = L.map('map').setView([51.505, -0.09], 13);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    L.marker([lat, lon]).addTo(map)
        .bindPopup('You are here.')
        .openPopup();
</script>

Refactored

// Footer of page
<script>
    (function(){
        var createMap = function() {
            var lat = 51.505 // retrieved from db
            var lon = -0.09  // retrieved from db

            var map = L.map('map').setView([lat, lon], 13);

            L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            }).addTo(map);

            L.marker([lat, lon]).addTo(map)
                .bindPopup('You are here.')
                .openPopup();
        }(); // createMap function self invocation
    })(); // anonymous function self invocation
</script>

I'm unsure if my refactored version makes sense since I'm creating a function var createMap inside an self invocation anonymous function.

I didn't want to cloud up the global namespace with my lat & lon variables, which is retrieved from the database.

UPDATE

Or will the following make more sense. A self invoking anonymous function with the variables and code inside. This will not interfere or add the assigned variables to the global namespace?

// Footer of page
<script>
    (function(){
        var lat = 51.505 // retrieved from db
        var lon = -0.09  // retrieved from db

        var map = L.map('map').setView([lat, lon], 13);

        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        L.marker([lat, lon]).addTo(map)
            .bindPopup('You are here.')
            .openPopup();
    })(); // anonymous function self invocation
</script>

Solution

  • Lose the createMap function, there's no need for that, since you're already using the outer IIFE (Immediately-Invoked Function Expression). This way you're not polluting the global namespace:

    (function() {
        var lat = 51.505 // retrieved from db
        var lon = -0.09 // retrieved from db
    
        var map = L.map('map').setView([lat, lon], 13);
    
        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);
    
        L.marker([lat, lon]).addTo(map)
            .bindPopup('You are here.')
            .openPopup();
    })(); // anonymous function self invocation