admin管理员组

文章数量:1336331

I am writing functions inside Immediately-Invoked Function Expressions (IIFE).

(function(){
  "use strict";
  function EventService(){
    //MASTER CLASS
  }
  EventService.prototype.eventObj = function(){
    var ES = getEvwentMapping();
    return EventService;
  };
  EventService.prototype.popup = function(){
    eventService.eventObj.createPopup();
  };
  EventService.prototype.drilldown = function(){
    eventService.eventObj.createDrilldown();
  };
})();


eventService();

Here I am getting error as eventService() is undefined.

I am writing functions inside Immediately-Invoked Function Expressions (IIFE).

(function(){
  "use strict";
  function EventService(){
    //MASTER CLASS
  }
  EventService.prototype.eventObj = function(){
    var ES = getEvwentMapping();
    return EventService;
  };
  EventService.prototype.popup = function(){
    eventService.eventObj.createPopup();
  };
  EventService.prototype.drilldown = function(){
    eventService.eventObj.createDrilldown();
  };
})();


eventService();

Here I am getting error as eventService() is undefined.

Share edited Feb 10, 2014 at 16:19 manuell 7,6205 gold badges33 silver badges63 bronze badges asked Feb 10, 2014 at 15:01 Anup SinghAnup Singh 1,5733 gold badges16 silver badges32 bronze badges 4
  • 4 Yes. your function is not available in the global scope. – putvande Commented Feb 10, 2014 at 15:02
  • add window.eventService = eventService; in (function(window){ })(window); – Vedant Terkar Commented Feb 10, 2014 at 15:04
  • Why do you think you need an IIFE here anyway? You IIFE doesn't actual execute anything anyway. – Matt Burland Commented Feb 10, 2014 at 15:11
  • Your code is not correct. You can not call the createPopup of something that is not defined; the eventService.eventObj evaluates to undefined. What you probably want to do is eventService.prototype.eventObj() which again is not the best solution. A better way is to call this.eventObj().createPopup() – ppoliani Commented Feb 10, 2014 at 16:02
Add a ment  | 

3 Answers 3

Reset to default 6

Yes, your function is enclosed in your IIFE and doesn't bee part of any external scope. If you need it outside your function, then try returning it and assigning it to a variable. For example:

var eventService = (function(){
    "use strict";
    function eventService(){
         //MASTER CLASS
    }
    eventService.prototype.eventObj = function(){
        var ES = getEvwentMapping();
        return EventService;
    };
    eventService.prototype.popup = function(){
        eventService.eventObj.createPopup();
    };
    eventService.prototype.drilldown = function(){
        eventService.eventObj.createDrilldown();
    };
    return eventService;
})();

Or the module patern suggested by @ppoliani is also good if you have several functions and/or properties you need to expose.

Another question, however, is why you think you need an IIFE here anyway? This would work the same by just removing the IIFE altogether.

Here's how you'd use the thing:

var myES = new eventService();
myES.popup();

http://jsfiddle/k7ZJY/

EDIT: As I said before, there is no reason to actually use an IIFE here because you aren't hiding anything and you code doesn't actual execute anything anyway. But, one way you might use this is to create a singleton and I'm wondering if that was your actual objective here. What you could do is this:

var eventServiceSingleton = (function(){
    "use strict";
    function eventService(){
         //MASTER CLASS
    }
    eventService.prototype.eventObj = function(){
        var ES = getEvwentMapping();
        return EventService;
    };
    eventService.prototype.popup = function(){
        eventService.eventObj.createPopup();
    };
    eventService.prototype.drilldown = function(){
        eventService.eventObj.createDrilldown();
    };
    return new eventService();
})();

Now you have a fully constructed eventService assigned to the variable eventServiceSingleton and there is no way to create another eventService object. So now:

 eventServiceSingleton.popup();   // works

but:

 var anotherEventService = new eventService();    // eventService is undefined

You need to apply the module pattern which returns a constructor.

var EventService = (function(){

   "use strict";

   function EventService(){
    //MASTER CLASS
   }

   EventService.prototype.eventObj = function(){
     var ES = getEvwentMapping();
     return ES;
   };

  EventService.prototype.popup = function(){
    this.eventObj().createPopup();
  };

  EventService.prototype.drilldown = function(){
    this.eventObj().createDrilldown();
  };

  return EventService;
})();

and then you can simply invoke the method by doing

var eventService = new EventService();
eventService.popup();

The issue is that you are trying to apply a sort of encapsulation with the aid of JavaScript closures; that is anything defined within the closure is not accessible from the outside unless you explicitly export them.

However, you're definitely doing something wrong here; As @Matt Burland mentioned, you don't need to use an IIFE here. You can benefit from a IIFE when you want to conceal some variables so that you don't pollute the global scope or you simply don't want to make them accessible. I cannot see that intention in your code.

The main reason for using IIFE is because you want to leave a minimal footprint -- no unnecessary variables left behind.

if you only want to invoke eventService once, then you just need to invoke eventService at the end of your IIFE.

(function(){
  "use strict";
  function eventService(){
    //MASTER CLASS
  }
  eventService.prototype.eventObj = function(){
    var ES = getEventMapping();
    return eventService;
  };
  eventService.prototype.popup = function(){
    eventService.eventObj.createPopup();
  };
  eventService.prototype.drilldown = function(){
    eventService.eventObj.createDrilldown();
  };
  eventService(); // This is all you need to invoke just once
})();

However, if you want to save a reference to the eventService function to invoke it more than once, then that needs to be the return value of your IIFE.

var eventService = (function(){
  "use strict";
  function eventService(){
    //MASTER CLASS
  }
  eventService.prototype.eventObj = function(){
    var ES = getEventMapping();
    return eventService;
  };
  eventService.prototype.popup = function(){
    eventService.eventObj.createPopup();
  };
  eventService.prototype.drilldown = function(){
    eventService.eventObj.createDrilldown();
  };
  return eventService; // return the function for future invocations
})();

eventService();

本文标签: JavaScript prototype inside quotImmediatelyInvoked Function ExpressionsquotStack Overflow