4

Is there any difference between these 2 apart from the resolving constructor?

var Person = function(living, age, gender) {
    this.living = living;
    this.age = age;
    this.gender = gender;
    this.getGender = function() {
        return this.gender;
    };
};

var Person = function Person(living, age, gender) {
    this.living = living;
    this.age = age;
    this.gender = gender;
    this.getGender = function() {
        return this.gender;
    };
};

Both could be invoked using

var p = new Person("Yes",25,"Male");

The first one resolves to function() where the latter resolves to person(), but I would like to know if there is any advantage of using one over the other

Ian
  • 50,146
  • 13
  • 101
  • 111
isJustMe
  • 5,452
  • 2
  • 31
  • 47

1 Answers1

6

They are identical for the purposes you speak of.

The only difference that inside the second function you have a clean reference to the function from within itself.

Formally

The language specification states:

FunctionExpression :

function Identifier(opt) ( FormalParameterListopt ) { FunctionBody }

The identifier (in this case Person) in the function expression is optional

The reasoning for that is explained a bit later in the language specification:

NOTE The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

In practice

You can use the second option in two situations:

When it makes your code more understandable:

   (function removeBodyDivs(){
        //does logic removing
        //divs from the body
   })();

Can be more understandable than:

   (function (){
        //does logic removing
        //divs from the body
   })();

When doing recursion, for example

  var f = function fib(n){
      return n<2?2:(fib(n-1)+fib(n-2));
  }
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • But how does this relate to a constructor? For a normal function, that makes sense. But for a constructor, I can't see it having any effect. You never call the constructor from within – Ian May 21 '13 at 22:29
  • @Ian Good question, just because you _should't_ do something doesn't mean people don't do it. You can, for example return an object from a constructor function which would make the `new` 99.9% meaningless. http://jsfiddle.net/NuT5F/ . I did start with "They are identical for the purposes you speak of." – Benjamin Gruenbaum May 21 '13 at 22:33
  • 1
    @Ian: "You never call the constructor from within" --- imagine a tree-like structure. Some particular node of a particular type may create a nested node of the same type by default. – zerkms May 21 '13 at 22:37
  • @zerkms But you would still use `new`, right? You wouldn't need the second name for the expression, would you? I'm just trying to visualize when `var a = function a() {};` would be useful when using `new a()`. With normal functions and normal function calls, it makes sense to me at least – Ian May 21 '13 at 22:39
  • @Ian: you would need a name for the function to be able to invoke it. – zerkms May 21 '13 at 22:44
  • @zerkms I still don't see a point. If you're using the function as a constructor, how does it help in this situation: http://jsfiddle.net/4Bt85/ ? I'm seriously just trying to understand. In that case, if you just want to **call** `Person`, it wouldn't make sense, unless you use `new`. And then in that case, why bother adding the second `Person`? As a normal function, like the `fib` example in this answer, it makes sense – Ian May 21 '13 at 22:49
  • @Ian: actually I was wrong. It doesn't make sense, and doesn't make sense for fibonacci numbers as well – zerkms May 21 '13 at 22:52
  • @zerkms Really? Or are you just being sarcastic? :) – Ian May 21 '13 at 22:54
  • @zerkms it makes sense for fibonacci numbers because sometimes you don't have a reference to the function itself (for example, it is referenced as a parameter in an object literal). I completely agree with Ian though that using it in a function acting as a constructor like that is kind of pointless, though possible. (I see the 'recursive descent' construction case you were talking about earlier, but even within it it seems pointless. – Benjamin Gruenbaum May 21 '13 at 22:54
  • @Benjamin Gruenbaum: `function fib(n){ return n<2?2:(fib(n-1)+fib(n-2)); }` -- you just don't need `var f` in this cae – zerkms May 21 '13 at 22:54
  • @zerkms Here is a common use case for that http://jsfiddle.net/fBXGv/1/ . This is common especially when performing `Object.create` in order to put stuff on the prototype. – Benjamin Gruenbaum May 21 '13 at 22:56
  • 1
    @Benjamin Gruenbaum: yep, for objects it makes sense. – zerkms May 21 '13 at 22:57
  • 2
    Additional point: Having named constructor might be useful in debugging. – mrówa May 21 '13 at 23:04