wootscootinboogie
wootscootinboogie

Reputation: 8695

JavaScript - constructior inside IIFE

Why does the following bit of code not return a Person object? It instead returns undefined fiddle

var factory = (function () {
        function Person(name, salary) {
            this.name = name;
            this.salary = salary;
        }
        Person.prototype.talk = function () {
            console.log('talking...');
        }
        return {
            Person: Person
        }

    })();
    var x = factory.Person('me', 100);
x.talk(); //cannot read property talk of undefined

Upvotes: 0

Views: 60

Answers (3)

mpm
mpm

Reputation: 20155

BEcause it is not a proper factory :

var factory = (function () {
        function Person(name, salary) {
            this.name = name;
            this.salary = salary;
        }
        Person.prototype.talk = function () {
            console.log('talking...');
        }
        return {
            Person: function(name,salary){
              return new Person(name,salary);
            }
        }

    })();
    var x = factory.Person('me', 100);
x.talk(); //cannot read property talk of undefined

If you dont call new on Person , there will be no prototypal inheritance.

edit : you can be more abstract on the factory method so you can change the arguments of the constructor without affecting the factory

return {
   Person:function(){
        return  new (Function.prototype.bind.apply(Person,arguments));
        }
}

or make the constructor an impllcit factory

       function Person(name, salary) {
            if(!(this instanceof Person)){
              return new (Function.prototype.bind.apply(Person,arguments));
            }
            this.name = name;
            this.salary = salary;
        }

Upvotes: 3

plalx
plalx

Reputation: 43718

The appropriate answer already has been posted, however I just wanted to show a different way of achieving the same result by making sure the constructor always returns a new instance of Person, even if new is forgotten.

var factory = (function () {
        function Person(name, salary) {
            if (!(this instanceof Person)) return new Person(name, salary);

            this.name = name;
            this.salary = salary;
        }
        Person.prototype.talk = function () {
            console.log('talking...');
        }
        return {
            Person: Person
        }

    })();
    var x = factory.Person('me', 100);
x.talk();

Upvotes: 2

h2ooooooo
h2ooooooo

Reputation: 39532

var x = factory.Person('me', 100); will call factory.Person() (which just sets this.name and this.salary and doesn't return anything, hence undefined).

You want to use the new keyword:

var x = new factory.Person('me', 100);
//      ^^^

Fiddle

Upvotes: 2

Related Questions