0

Hello everyone,

I'm trying to figure out, why is the Cookie module only accessible after it has been instantiated using new operator... I thought that if I exported the Cookie module in shim config and added the module name to the per-requisites in app.js, it would be globally accessible. But it's not.

Can you please advise on what may be wrong with my module?

cookie.js

define("Cookie",function (){
    function Cookie()
    {}

    Cookie.prototype.add = function ()
    {
        doStuff();
    }

    Cookie.prototype.remove = function ()
    {
        doStuff();
    }

    return Cookie;
});

main.js

requirejs.config({
    baseUrl: 'js/lib',
    paths: {
        app: '../app',
    },
    shim:{
        Cookie: {
            exports : 'Cookie'
        }
    }
});

app.js

define(['Cookie'],function(Cookie)
{
    Cookie.add(); 
    Cookie.remove(); 
}
Wracker
  • 589
  • 10
  • 32

2 Answers2

2

There are many problems with this code. As Andy pointed out, the way Cookie is defined you need to instantiate it. If you expect to have only one Cookie instance in your application then yes, return new Cookie() would be indicated but if you want to create many instances, then return Cookie is the thing to do and then you use new Cookie in each module where you import it, any time you need to create Cookie instances.

However, there are these additional problems with the code you show in the question:

  1. Your file is named cookie.js but you define it as Cookie, different capitalization. Rule of thumb: RequireJS is case-sensitive so the file and the module name should correspond, unless you somehow override it somewhere else, which is not the case in the code you show.

  2. You use define('Cookie', which assigns the name Cookie to your module. The documentation of RequireJS recommends quite clearly to not assign module names manually. r.js will assign names when you optimize. Or if you don't optimize, then RequireJS will assign a module name from the file name. When you do optimize, if you have a name already assigned, r.js cannot do its work. (Yes, there are times you want to assign the name yourself but if you can't name a concrete reason why in a specific instance you need to set the name yourself, then most likely you are doing it wrong.)

  3. You use a shim configuration for a module that calls RequireJS' define function. The shim option is only for modules that do not call define. If you give a shim to a module that calls define you enter undefined behavior territory and if it works, that's just luck. It may work now and fail tomorrow, or it may fail when RequireJS introduces a new version that does assign some defined behavior to using shim for modules that call define.

Louis
  • 146,715
  • 28
  • 274
  • 320
0

Because Cookie is a constructor. You need to return new Cookie();

There's more information about the reasons why new should be used on this StackOverflow page.

...if you forget [new], you will be calling the object constructor as a regular function. If your constructor doesn't check its execution context then it won't notice that 'this' points to different object (ordinarily the global object) instead of the new instance. Therefore your constructor will be adding properties and methods to the global object (window). If you always check that 'this' is an instance of your object in the object function, then you won't ever have this problem.

Community
  • 1
  • 1
Andy
  • 61,948
  • 13
  • 68
  • 95