5

Can you name an instance the same as its constructor name?

var myFunc = new function myFunc(){};

?

As it seems, this replaces the Function Object with the new instance... which means this is a good Singleton.

I haven't seen anyone using this, so I guess, there are downsides to this that I am unaware of...

Any thoughts?

Bastien Jansen
  • 8,756
  • 2
  • 35
  • 53
user2071276
  • 113
  • 6
  • @PeeHaa埽 If you're not a JS guy, it doesn't matter if it looks strange to you as much... If it looked weird to a JS developer, then I would care more – Ruan Mendes Apr 16 '13 at 18:02
  • Actually it does. Because I am here to learn... – PeeHaa Apr 16 '13 at 18:02
  • @PeeHaa埽 Then this is a lesson? – Ruan Mendes Apr 16 '13 at 18:03
  • 1
    What's the point of the second `myFunc` there? You can just as easily create a single instance of a class by saying `var myFunc = new function() { ... }`. – Joe Enos Apr 16 '13 at 18:03
  • 1
    The lesson being my assumption is correct that it indeed does look strange? – PeeHaa Apr 16 '13 at 18:03
  • @PeeHaa埽 I did miss the fact that the constructor was defined inline, that doesn't make a lot of sense, I concur – Ruan Mendes Apr 16 '13 at 18:04
  • It could be implemented as funciton myFunc(){} var myFunc = new myFunc(). the idea id to create a singleton. and is this a good implantation of one. – user2071276 Apr 16 '13 at 18:08
  • Well... you could implement a lot of things in javascript. Doesn't make it a good idea ;) – PeeHaa Apr 16 '13 at 18:09
  • @PeeHaa埽 I'm curious: Would you still find it weird if the function wasn't named? `var myFunc = new function() {...}` – Ruan Mendes Apr 16 '13 at 18:37
  • Not really. That makes sense to me (syntax wise)`. Still don't see why on earth you want to do that though. – PeeHaa Apr 16 '13 at 18:38
  • @PeeHaa埽 I do agree, sorry about the misunderstanding earlier, you helped me improve my answer a lot! – Ruan Mendes Apr 16 '13 at 18:41

2 Answers2

1

YES...

However, it does look weird that you're creating a named function but never refer to it by name.

The more common pattern(s) I've seen are

function MyClass(){
    this.val = 5;
};
MyClass.prototype.getValue = function() {
    return this.val;
}
MyClass = new MyClass();

But when people do that I wonder why they don't just use a literal object

var MyClass = {
    val: 5,
    getValue: function() {
        return this.val;
    }
}

And I would even prefer to use the module pattern here

var MyClass = (function(){
    var val = 5;
    return {
        getValue: function() {
            return val;
        }
    };     
})();

Disclaimer

Now whether the singleton pattern should be used, that's another question (to which the answer is NO if you care about testing, dependency management, maintainability, readability)

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • What is the use of `new function`? – PeeHaa Apr 16 '13 at 18:02
  • I didn't notice that part, that is surely a bit weird, let me fix the answer – Ruan Mendes Apr 16 '13 at 18:02
  • If you try to overwrite MyClass->val after "MyClass = new MyClass()" what happens? – Kris Georgiev Apr 16 '13 at 18:17
  • @KrisGeorgiev In all but the last case, you are overwriting the `val` property of `MyClass` (the object, not the class that is not the cosntructor that is notreachable anymore). In the last example, it's creating a new property on the object. I'm not sure what the point of your question is... – Ruan Mendes Apr 16 '13 at 18:22
0

As it seems, this replaces the Function Object with the new instance

No, it does not replace anything. The name of a function expression (that's what you have) is only accessible inside the function itself, not outside of it. It would be exactly the same as if you omit the name:

 var myFunc = new function(){};

In general, if you don't want certain symbols accessible, just don't make them global. Define those symbols inside a function and just return whatever you want to make accessible, e.g:

var myobj = (function() {
    function Foo() {};
    // do whatever
    return new Foo();
}());

However, if you just want to create a single object, it is often easier to use an object literal:

var myobj = {};

There is no reason to use a constructor function if you only want to create a single instance from it. If you want to establish inheritance, you can use Object.create [MDN]

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Obviously this could be possible, but for readability reasons, you do not want to declare the instance the same place as the constructor this might be a good way to go about it... – user2071276 Apr 16 '13 at 18:14
  • The variable does shadow the named function, doesn't it? – Ruan Mendes Apr 16 '13 at 18:15
  • @Juan: As I said, a named function expression does not create a symbol with that name in the enclosing scope. The name is only available inside the function. Try `var foo = function bar() {}; alert(bar);`. – Felix Kling Apr 16 '13 at 18:17
  • I mean an example like what the OP has... where the variable and function names are the same. Something like `(function() { console.log("Before", MyFun); var MyFun = new function MyFun() {}; console.log("After", MyFun); })()`, the output is `Before undefined` followed by `After MyFun {} ` http://jsfiddle.net/WWLJ7/ – Ruan Mendes Apr 16 '13 at 18:28
  • @Juan: http://jsfiddle.net/WWLJ7/1/ ... the name of the function is not available in the enclosing scope. The function object will never be assigned to `MyFun` at any point. – Felix Kling Apr 16 '13 at 18:37
  • @FelixKling But in your example, you're not creating a name conflict ("where the variable and function names are the same"), which would create the "shadowing". I guess I don't understand what you're saying... – Ruan Mendes Apr 16 '13 at 18:39
  • @Juan: By choosing two different names `A` (variable) and `B` (function), I can show that there never is a conflict or shadowing because symbol `B` will never be created. The name you give to the function is completely irrelevant. – Felix Kling Apr 16 '13 at 18:40