Is It Right to Think of a JavaScript Function Expression That Uses the 'New' Keyword as 'Static'

Is it right to think of a Javascript Function Expression that uses the 'new' keyword as 'static'

No, it is not static because it still has a constructor property pointing to your "anonymous" function. In your example, you could use

var gameData2 = new (gameData.constructor)();

to reinstantiate a second object, so the "class" (instance actually) is not really "static". You are basically leaking the constructor, and possibly the data that is bound to it. Also, a useless prototype object (gameData.constructor.prototype) does get created and is inserted in the prototype chain of gameData, which is not what you want.

Instead, you might use

  • a single, simple object literal (as in Daff's answer). That means you don't have a constructor, no closure-scoped private variables (you have used none anyway) and no (custom) prototype.
  • the (revealing) module pattern (as in jAndy's answer). There you'd have an IIFE to create closure-scoped variables, and can return any kind of object.
  • an actual constructor ("class") that can be instantiated later (when needed), and yields the same singleton object always.

This is what the singleton pattern would look like:

function GameData() {
if (this.constructor.singleton)
return this.constructor.singleton;
else
this.constructor.singleton = this;

// init:
// * private vars
// * public properties
// ...
}
GameData.prototype.storageAvailable = function () {
if (typeof (Storage) !== "undefined") {
return true;
}
else {
return false;
}
};

var gameData = new GameData();
var gameData2 = new GameData();
gameData === gameData2 === GameData.singleton; // true

Yet, the prototype is quite useless because you have only one instance of GameData. It would only get interesting with inheritance.

Why functions don't use new keyword while being declared in constructors?

new is an operator. It allocates an object instance (and assigns it a prototype). The functions you create aren't instances of any sort of class, and are not going to be created in multiple copies. The static declaration defines the only instance that will exist.

Can we say this is an IIFE ?!?- In Javascript

Is new function(){ ... } an IIFE?

Now, IIFE stands for Immediately Invoked Function Expression. And a FunctionExpression is defined as follows:

function BindingIdentifierₒₚₜ ( FormalParameters
) { FunctionBody }

So, are we dealing with a function expression? Let's analyze your syntax:

"type": "ExpressionStatement",
"expression": {
"type": "NewExpression",
"callee": {
"type": "FunctionExpression",
"params": [],
"body": {
...
},
"arguments": []
}

This shows us that your code is not a function expression, but it includes a function expression as a part of the NewExpression.

Is this expression immediately invoked? In a way, yes - see [[Construct]] invocation. The constructor function is immediately invoked.

Still, I wouldn't call the whole thing an IIFE as the outer expression is not a function expression. Some call this expression Immeditately Invoked Constructor or IIC instead (thanks to @vol7ron, @Bergi for pointing this out).

Why would using new and constuctor functions in JavaScript be wrong

using new and constructor functions is wrong and should not be used.

Read Is JavaScript's "new" keyword considered harmful? - No, it is not. A few (correct) arguments are

  • It's confusing to newbies because of hiding the prototypical concept. To quote @Aadit:

    [With new] the constructor function becomes simpler. However it becomes very
    difficult to explain prototypal inheritance to a person who knows
    nothing about it. It becomes even more difficult to explain it to a
    person who knows classical inheritance.

  • Constructors do silently fail when forgetting new
  • In a few instances, the pure Object.create approach is cleaner
  • Building a class hierarchy is complicated and often done wrong

However, once you understand these, new is harmless. Actually, every time you need instance initialisation plus prototypical inheritance, constructors with new are the way to go.

They go against the prototype nature of JavaScript.

This will never change. I hardly can imagine why anyone would criticise this, prototypical inheritance is far more powerful than class inheritance. Probably they are only arguing against the syntax.

Could someone please enlighten me and show a situation where using new and constructor functions is so bad it should never be used?

It should not be used when not needed. Singletons can easily be created using the module pattern and object literals; inheritance does not help here. See Is it right to think of a Javascript Function Expression that uses the 'new' keyword as 'static' for an example.

How do function expressions work in Javascript in the parser?

if I included (function() {...})(); on a line in my Javascript code, it would immediately execute. Is this true?

Yes. It's called an immediately executed function expression.

Is it because the function is wrapped in the parentheses or because of the appended parenthesis, or something else?

The wrapping parentheses are of no significance to the execution, you could in fact omit them (when you use the result in another expression, to avoid the syntactic ambiguity with a function declaration) or place them differently. However, the "appended parenthesis" are just a plain function call: anything_that_resolves_to_a_function()

I read on the MDN docs on Table 3.7 that () and new are one way to call/create a new instance of something.

Yes. You shouldn't use new function() { … } though.

so could I achieve the same result of (function() {...})(); with new Function(...);?

No. The Function constructor is a completely different beast.

What is the difference between immediately executed functions and using the keyword new?

f() and new f are almost identical (compare this and that). Of course, new does a lot more work preparing an object you're going to throw away.

You cannot blindly replace f() with new f if

  • you're using this in f (obviously)
  • you're returning non-objects

For example, these two calls will produce different results:

x = 5 + (function () {
return 123;
})();

y = 5 + new function () {
return 123;
};

In other cases, if you don't mind wasting resources and validators shouting at you, new is fine.



Related Topics



Leave a reply



Submit