Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using self invoking anonymous functions

I am trying to build a shopping cart for learning purpose. I have following codes

HTML

<div id="MyCart" class="product-cart">
    <ul>
        <li class="item"></li>
        <li class="item"></li>
        <li class="item"></li>
    </ul>
</div>

js

var cart = (function () {

    cart.createCart = function (cartId) {
        console.log(cartId);
        cartId = document.getElementById(cartId);
    }   


    return cart;
}());

var shoopingCart = cart.createCart("MyCart");

But this code throws following error

Uncaught TypeError: Cannot set property 'createCart' of undefined

After spending few hours in internet and following some tutorials I did following changes to the code and then it started working.

But still I dont understand what i have done here

var cart = (function (cart) {

    cart.createCart = function (cartId) {
        console.log(cartId);
        cartId = document.getElementById(cartId);
    }   


    return cart;
}(cart || {}));

var shoopingCart = cart.createCart("MyCart");

Can some one please explain me why the code started to work after passing cart || {} expression into the anonymous function? Some detailed explanation would be great. :)

like image 996
It worked yesterday. Avatar asked Jul 10 '15 08:07

It worked yesterday.


People also ask

What is self-invoking anonymous function?

A self-invoking (also called self-executing) function is a nameless (anonymous) function that is invoked immediately after its definition. An anonymous function is enclosed inside a set of parentheses followed by another set of parentheses () , which does the execution. (function(){ console.

What is the use of self-invoking function?

Self-Invoking Functions A self-invoking expression is invoked (started) automatically, without being called. Function expressions will execute automatically if the expression is followed by (). You cannot self-invoke a function declaration.

How do you execute an anonymous function?

Another use case of anonymous functions is to invoke the function immediately after initialization, this is also known as Self Executing Function. This can be done by adding parenthesis we can immediately execute the anonymous function.

When would you use an anonymous function?

Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function.


1 Answers

So without the variable passed into the scope.

var cart = (function (cart) {

    // can't add a property or method onto undefined.
    cart.createCart = function (cartId) {
        console.log(cartId);
        cartId = document.getElementById(cartId);
    }   


    return cart;
}()); // without any value here ^ cart will be undefined.

var shoopingCart = cart.createCart("MyCart");

However, if you pass the variable to the context:

var cart = (function (cart) {

    // cart now is an object which you can attach a property or method
    cart.createCart = function (cartId) {
        console.log(cartId);
        cartId = document.getElementById(cartId);
    }   


    return cart;
}(cart || {})); // pass in cart, or if it is null a new object {}

var shoopingCart = cart.createCart("MyCart");

So an IIFE looks like this:

(function () { })();

so ignoring the function you get ( )(); in that second pair of parenthesis you pass the parameters to the function in the first set. This is because IIFE creates a whole new clean scope. This is why we use IIFE because it can isolate global variables that we use in them.

so if you have this:

<script>

var someGlobalVariable = "hey";

(function () {

   // using someGlobalVariable here will be fine

   var myIIFEScopedVariable = "ho"; 

})();

// trying to access myIIFEScopedVariable here will fail because again, it hasn't been defined here.

</script>

So IIFE's are great for controlling what you have in scopes.

The cart || {} is a JavaScript null coalesce, so it says, pass in cart but if it is null give it an empty object

like image 66
Callum Linington Avatar answered Sep 21 '22 02:09

Callum Linington