0

I was trying something different and ended up with these codes..

var f1 = function() {
             this.x = 10;
             this.innerf = function() {    console.log(this.x);   }
         }

var of1 = new f1();
of1.innerf();

var f2 = function() {
             return function() {
                 this.x = 10;
                 this.innerf = function() {    console.log(this.x);    }
             }
         }

var of2 = new f2();
of2.innerf(); 

It is throwing error ??! of2.inner is not a function

So, my anonymous function is returning same function body to my variable. Why still i cannot able to instantiate??

AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
Jyotirmay
  • 1,533
  • 3
  • 21
  • 41

3 Answers3

5

The first part returns an object of which you can call the innerf method.

The second part returns a function that would return an object if you called it. But you don't.

This would work. Call the function f2(). It's return value is the anonymous function. Then, with new <return value of f2>(), you can create an instance of the object.

var f2 = function() {
             return function() {
                 this.x = 10;
                 this.innerf = function() {    console.log(this.x);    }
             }
         }

var of2 = new (f2())();
of2.innerf();

// The two lines above can also be written as:

var of3constructor = f2(); // This returns the inner anonymous function.
var of3 = new of3constructor(); // This creates an instance by invoking the anonymous function.
of3.innerf();
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Confused :( :( .. can you please elaborate. – Jyotirmay Jun 23 '15 at 20:54
  • There is a difference between the function (the declaration of a piece of functionality) and the result of a function (the value you get when calling it). Your second function doesn't return an instance of the anonymous function in it, but instead it returns the inner function itself. You first need to create an instance of that inner function before you can call it's method. – GolezTrol Jun 23 '15 at 20:59
  • 1
    I must add that I made this code working to show the error in your thinking, but in itself it doesn't make much sense. I wouldn't know a good purpose for this. – GolezTrol Jun 23 '15 at 21:01
  • @Jyotirmay - Using `new` on the function in the f2 variable will create an instance of f2. It will then return a function instead of the instance object. As a result of2 will be equal to the returned function. That function has no `innerf` property. If you were to call that function, it would also have no `innerf` property because `this` wouldn't be scoped. You would have to use `new` on the `of2` value again. However, there was no point in using new on `f2` when all you wanted was to use `new` on the returned function. – Travis J Jun 23 '15 at 21:03
  • In order to do that you would take the returned value of the f2 function (f2()), note that it is wrapped in () because that will allow us to use that value in an expression, which is going to be to use new in conjunction with the function value returned. Thus you would use new (f2())(). The last `()` is used to invoke the returned function which is used by convention with new. – Travis J Jun 23 '15 at 21:03
  • no need to use new in the example when calling function f2. just use f2. – ecarrizo Jun 23 '15 at 21:05
  • Yeah,this might have no use, but, i just want to know the reason, why its behave like that?? @GolezTrol – Jyotirmay Jun 23 '15 at 21:06
  • 1
    @ecarrizo - That would result in an error. "Uncaught TypeError: Cannot read property 'innerf' of undefined". There would be no instance to use without using `new`, and as a result `this` would not be scoped to the return function, it would be scoped to window. In other words, that would require `var of2 = (f2())(); window.innerf();//10` – Travis J Jun 23 '15 at 21:07
  • @TravisJ yeah i miss read the example thinking about other thing – ecarrizo Jun 23 '15 at 21:10
  • I've added a couple of lines that first store the result of f2() in a variable. I hope that untangling of parentheses makes it a bit more clear what is going on. – GolezTrol Jun 23 '15 at 21:13
  • thanx guys, can able to visualise the difference now. :) – Jyotirmay Jun 23 '15 at 21:22
1

Examples that work:

Creating it directly:

var f1 = function() {
    this.x = 11;
    this.innerf = function() {    
        console.log(this.x);   
    }
}
var of1 = new f1();
of1.innerf();

Returning a new object from a function:

var f2 = function() {
    return new function() {
        this.x = 12;
        this.innerf = function() {    
            console.log(this.x);    
        }
    }
}

var of2 = f2();
of2.innerf(); 

Returning an object:

var f3 = function() {
    return {
        x: 13,
        innerf : function() {
            console.log(this.x);
        }
    }
}

var of3 = f3();
of3.innerf(); 

Another one:

var f4 = function() {
    return function() {
         this.x = 10;
         this.innerf = function() {    
             console.log(this.x);    
         }
    }
}

var of4 = new (f2())();
of2.innerf(); 

Remember that when you call a function without the "new" keyword "this" points object where the functions was declared, in this case "window"

ecarrizo
  • 2,758
  • 17
  • 29
  • okay.. whenever we will use new, will it automatically run my function?? As you did not use '()' after functions. even i tried code like that. and it works fine. So just to confirm. @ecarrizo – Jyotirmay Jun 23 '15 at 21:19
  • Sorry did not see the edit. Yes, using functionName() and the pharentessis will call a function, if you use new, it will initialize an object, if you are not creating an Object (executing a function directly) the use of new is useless. you can read how it works http://stackoverflow.com/questions/6750880/javascript-how-does-new-work-internally – ecarrizo Jun 23 '15 at 21:24
0

You need to return this from the inner function to the outer function. Also you need to run the inner function immediately.

jsFiddle: http://jsfiddle.net/5dxybbb5/

var f1 = function() {
             this.x = 10;
             this.innerf = function() {console.log(this.x);}
         }

var of1 = new f1();
of1.innerf();

var f2 = function() {
             return function() {
                 this.x = 10;
                 this.innerf = function() {console.log(this.x);}
                 return this;
             }();
         }

var of2 = new f2();
of2.innerf(); 

Also this explains the () after a function declaration What is the (function() { } )() construct in JavaScript?

Community
  • 1
  • 1
Sean Wessell
  • 3,490
  • 1
  • 12
  • 20