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() {...})();
withnew 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
inf
(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
How to Access the Contents of an Iframe With JavaScript/Jquery
Is There an "Exists" Function For Jquery
Scroll to an Element With Jquery
How to Initialize a JavaScript Date to a Particular Time Zone
How to Pad a Value With Leading Zeros
Http Get Request in JavaScript
How to Debug My JavaScript Code
Setting "Checked" For a Checkbox With Jquery
How to Convert a String to an Integer in JavaScript
How to Round to At Most 2 Decimal Places, If Necessary
How to Do String Interpolation in JavaScript
Looping Through Array and Removing Items, Without Breaking For Loop
When Is .Then(Success, Fail) Considered an Antipattern For Promises
Formatting a Number With Exactly Two Decimals in JavaScript
Why Is Extending Native Objects a Bad Practice
Difference Between Object Keys With Quotes and Without Quotes