0

I have used the following method to define instances of objects without defining classes :

var obj = new function () {
  this.x = 25;                // Public variable
  var y = 10;                 // Private variable

  this.print = function () {  // Public function
    alert( this.x + y );    
  }
}

obj.print();

Does this have any demerits as compared to other Module patterns ? ( For JSLint says odd construct at line 1 )

Protomen
  • 9,471
  • 9
  • 57
  • 124
Megh Parikh
  • 924
  • 2
  • 7
  • 25
  • what's the point to create only one instance without opportunity to create more? – Kirill Pisarev Jan 20 '15 at 10:30
  • The code is part of my game http://meghprkh.github.io/samehue/ where classes like Manager, Input Manager, Display Manager are created only once but they help segregate the code into sort of namespaces. – Megh Parikh Jan 20 '15 at 10:32
  • 1
    general practice is to use self executing functions for this – Kirill Pisarev Jan 20 '15 at 10:39
  • Sounds like what you actually need is a singleton http://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript – atmd Jan 20 '15 at 10:43
  • @KirillPisarev Can you please give an example as how it can be used in my case ? I tried to read http://esbueno.noahstokes.com/post/77292606977/self-executing-anonymous-functions-or-how-to-write . – Megh Parikh Jan 20 '15 at 10:44
  • @atmd Singleton requires a lot of boilerplate. For example you have to redeclare the public variables and functions at the end while this method requires only adding `this` to the public variables – Megh Parikh Jan 20 '15 at 10:52
  • It may require more code, but it's a well used pattern for a reason. Also, using the Function constructor is a big perf hit – atmd Jan 20 '15 at 10:56
  • @atmd I dont think this is a function constructor that I am using. See this http://www.tutorialspoint.com/javascript/javascript_function_constructors.htm . This is perhaps a new Module pattern I am talking about. (I use `function` and not `Function` ) – Megh Parikh Jan 20 '15 at 11:05
  • 1
    What if I use the revealing module pattern and it requires access to another object defined by another script file? Will it raise any error? – Megh Parikh Jan 20 '15 at 11:13
  • @user2368055 I dont understand stivlo's answer's relation with this question. – Megh Parikh Jan 20 '15 at 11:26
  • 1
    There is nothing wrong in using this method (that I can think of). The problem is it very risky. What happens if you forget to write `new`. This won't throw any error as it is a valid assignment. In such case not only your variable `obj` will get messed up (it will become a 'function') but also your global scope will get corrupted if the function is executed. If the function is executed then `this` inside the function points to global scope and all the bindings are done to the global scope. You definitely don't want to do that. – Anurag Peshne Jan 20 '15 at 12:21
  • 1
    Why is this Question on hold? I feel it is quite clear what OP is asking. – Anurag Peshne Jan 20 '15 at 12:21
  • I feel it is clear what I am asking. Except that earlier it was a little misworded (I did not know that they were called module patterns) due to which the answer by @user2368055 is a little irrelevant now – Megh Parikh Jan 20 '15 at 12:26
  • @AnuragPeshne your comment is good and should be converted to answer. – Megh Parikh Jan 20 '15 at 12:29
  • Can the people keeping this question on hold please elaborate their reason as to what is unclear? – Megh Parikh Jan 20 '15 at 12:30
  • @MeghParikh thanks but I'm sure there are also other better reasons to not to make objects that way. We should reopen this question so that others can contribute. Besides I'm sure many newbies will have the same doubt. Please rephrase the question in a better way. – Anurag Peshne Jan 20 '15 at 13:31

2 Answers2

1

If you just need a aggregated scopes, use Self-Executing Anonymous Functions :

var obj = (function () {
  var y = 10;                 // Private variable

  return {
    x: 25,                    // Public variable

    print: function () {      // Public function
      alert( this.x + y );    
    }
  }
})();

obj.print();

The differencies between self-executing anonymous functions and creating instance of anonymous class is only in ideology. SEAF is for once and class is for multiple usage. BTW actually the same thing happens in both times. When you call new to the function, it returns a new object with the properties of this, it's the same we can see in SEAF.

Kirill Pisarev
  • 844
  • 4
  • 11
0

When you set print directly on the object (with this.print) you use some memory to store the property (here method) for each object (instantiation of your class). When you define it on the prototype, all the instances will share the same property (so the same memory).

You will also have some troubles to use inheritance.

If you only want one instance of your "class", you certainly should use a pattern singleton. But for a more powerful solution I would suggest you to try a framework implementing a dependency injection component because singleton is almost an anti-pattern. You can find an example of this kind of framework following the link in my profile (you cannot use it without a node.js server but it is a nice example).

Finally, you may define your class like the following:

var Class = function() {
  this._x = 25;                // Public variable
  this._y = 10;               // Private variable
}

Class.prototype.print = function() {
  alert(this._x + this._y); 
}

Object.defineProperty(Class.prototype, 'x', {
    get: function() { return this._x; }
});

var obj = new Class();
obj.print();

alert(obj.x);
alert(obj.y); 
Community
  • 1
  • 1
Gnucki
  • 5,043
  • 2
  • 29
  • 44
  • How is `y` a private variable? Try adding `alert(obj._y)` to the end. – Megh Parikh Jan 20 '15 at 11:41
  • 1
    There is no clean and easy way to define a private property. I personally use _ to specify a private property and set an accessor on it to define its accessibility. But of course, this won't ensure that someone use the _ property instead. I updated my answer. – Gnucki Jan 20 '15 at 11:51
  • I think that the thing about memory also occurs in self-executing anonymous functions but I am unsure about your method (though I cant use it due to the amount of boilerplate involved) – Megh Parikh Jan 20 '15 at 12:32
  • 1
    I just gave you what I thought are good practices to do OOP in javascript (and generally) today. Of course, changing this in a big project can require a lot of time! And yes, the self-executing anonymous function will have the same behaviour for memory as your own solution. – Gnucki Jan 20 '15 at 13:07