4

As you know in Javascript, it's very common to use the following expression as an IIFE (Immediately Invoked Function Expression) :

(function(){
  //code ...
})();

I'm wondering if we can say that the following expression is an IIFE (when no return value needed):

new function(){
 //code ...
}

Or

new function(global){
  //code..
}(this);

Even though it's an object . Thanks .

Answer :

[ Thanks to @le_m , @vol7ron and @Bergi , here is the short answer ] Can we say that he following expression is an IIFE (Immediately Invoked Function Expression) ?

new function(){
 //code ...
}

Or

new function(global){
  //code..
}(this);

The answer is NO. And what's that ? It's just an unnamed object with an anonymous constructor, so we're not talking about functions here (plain and simple).

Bbird
  • 53
  • 6
  • 4
    Not if you expect other developers to understand what you are referring to. – charlietfl Jun 03 '17 at 14:48
  • I'm surprised this pattern actually works, haven't come across this. The code in the function is executed immediately, so I guess you could, in fact, call it an IIFE – Patrick Hund Jun 03 '17 at 14:48
  • yes @Bbird but it's generally bad practice. However, because `'use strict';` is advised to be inside function blocks, it doesn't mean this won't be a generally accepted practice in the future. – vol7ron Jun 03 '17 at 14:58
  • @vol7ron Are you saying the pattern itself is bad practice? I use it regularly prior when coding for pre ES2015 environments. It is very useful when you want to construct an object and evaluate an expression for at least one of its key's names, since you can't do that with object literals before computed property names were added in ES2015. – Paul Jun 03 '17 at 15:07
  • @Paulpro yes, for the same reason that stated, it's not common practice and therefore bad practice. The community has moved from a place where less code and higher performance are key, to where better maintainability is desired. Plenty of studies suggest more money is saved when maintenance costs (due to time, complexity, etc) are lower. Of course, you may be using it properly — I can't make that judgment from here ;) – vol7ron Jun 03 '17 at 15:07
  • Thank you @vol7ron – Bbird Jun 03 '17 at 15:07
  • @Paulpro I want to add the OP asked about a standalone IIFE using the `new Function` syntax. In your case, it sounds like you're using `new function` during an assignment, which is fine. `var func = new Function(){…}` -- there's an obvious lhs vs rhs pattern. When it's a standalone, self-executing block, it's less clear what actions are being performed. – vol7ron Jun 03 '17 at 15:11
  • @vol7tron I think that charlietfl is just saying that other developers won't understand if you call this an IIFE, which I fully agree with. I would call it an immediately invoked anonymous constructor I guess, if I had to name it. – Paul Jun 03 '17 at 15:12
  • yes, we are saying the same thing – vol7ron Jun 03 '17 at 15:12
  • @Paulpro This is a good name – Bbird Jun 03 '17 at 15:13
  • they are different at least in the sense that `this` does not refer to the same thing – Kevin Jun 03 '17 at 15:15
  • All: there are plenty of cases to use `new Function`, but as an IIFE, it is bad practice compared to `(function())` syntax. That said, John Resig had used it for micro-templating, which I can't exactly argue against. For example, refer to:https://johnresig.com/blog/javascript-micro-templating/ (2008) – vol7ron Jun 03 '17 at 15:15
  • And by the way, in case you wanna pass the global variable : new function(global){/*code..*/}(this); – Bbird Jun 03 '17 at 15:34
  • @vol7ron even John Resig didn't use `new function() { }` – Bergi Jun 03 '17 at 16:54
  • @Bergi correct, as you may have noticed in my comment, I lost track of the question and the general syntax (`new Function` vs `new function`). Good catch ;) – vol7ron Jun 03 '17 at 17:22

2 Answers2

3

Yes it is an Immediately Invoked Function Expression (IIFE), though this pattern is not generally used.

From MDN Docs:

IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

new function(){
 //code ...
}

So according to the definition, your example is a Javascript function and runs the definition immediately.

From Wikipedia:

An immediately-invoked function expressio is a JavaScript programming language idiom which produces a lexical scope using JavaScript's function scoping. Immediately-invoked function expressions can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function.

In the mentioned example, the pattern does provide a lexical scope to the variables in the definition and encapsulates the methods and definitions from global environment.

kvn
  • 2,210
  • 5
  • 20
  • 47
2

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).

le_m
  • 19,302
  • 9
  • 64
  • 74
  • I figured this would come up, especially since the `new` keyword is used. There is going to be some technical semantics involved and I look forward to reading how others interpret this. – vol7ron Jun 03 '17 at 15:31
  • Yah, but as you know , functions in javascript are special objects, and what i did here, is creating an object with an anonymous constructor (A function ) . So the function(method) is invoked behind the scene. – Bbird Jun 03 '17 at 15:36
  • 1
    The `new Function` is calling a function constructor, which internally creates a function object. I think @le_m is technically correct. There is a distinction between a function statement, expression, and object. I suppose the semantics come into play on what "IIFE" means. Is *function expression* in the acronym to mean the syntax, or does it also include the internally invoked function expression (the function body/statements), which are invoked immediately using the `new Function` constructor? – vol7ron Jun 03 '17 at 15:39
  • I retract a little -- I forgot we were talking about `new function` and not `new Function`, which are different. Isn't the `function(){}` (lower case) that follows the `new` operator still an expression, specifically a *function* expression? – vol7ron Jun 03 '17 at 15:43
  • @vol7ron You are right, it includes a function expression. I will update the answer. – le_m Jun 03 '17 at 15:46
  • 2
    How about **ICFE** - immediately *constructed* function expression? :-P – Bergi Jun 03 '17 at 16:51
  • @Bergi but it's more than constructed because the statements are evaluated. So invoked could be appropriate – vol7ron Jun 03 '17 at 17:23
  • @vol7ron No, [constructing](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-construct-argumentslist-newtarget) implies calling / invoking the constructor function (= evaluating its body). The "beauty" of I**C**FE is that `constructed` refers to the used new operator and distinguishes it from a simple function expression. – le_m Jun 03 '17 at 17:29
  • 1
    If you're going to go that route, you might as well refer to it as it is more commonly known elsewhere (**IIC**), which brings me to a bookmark I never followed up with from a few years ago: http://2ality.com/2013/11/immediately-invoked.html – vol7ron Jun 03 '17 at 18:51
  • @vol7ron Nice reference, I'll include that in this answer. – le_m Jun 03 '17 at 18:52