Search code examples
javascriptfunctionnew-operator

javascript call function with new keyword


function outer(abc) {
  this.abc = abc;
   return function inner() {
    this.abc = abc;
    return this.abc;
  }
}

In the above code I cannot intantiate outer function like below

  var obj = new outer(123);
   console.log(obj.abc)
//here obj.abc get undefined

but the below code works when removed the return keyword for outer function

function outer(abc) {
      this.abc = abc;
       function inner() {
        this.abc = abc;
        return this.abc;
      }
    }
 var obj = new outer(123);
       console.log(obj.abc)

I have one more concerned is that why cannot I create object of returned function like below?

function outer(abc) {
      this.abc = abc;
       return function inner() {
        this.abc = abc;
        return this.abc;
      }
    }
var obj2= new outer(11)();
console.log(obj2.abc)

Solution

  • If you use a function with new (thus creating an object instance) and return from this function the returned value will be used as result of new instead of this object instance. When you return a function and call it directly without binding to a context its context would be window in a browser:

    If the constructor function returns a non-primitive, this return value becomes the result of the whole new expression. Otherwise, if the constructor function doesn't return anything or returns a primitive, newInstance is returned instead. (Normally constructors don't return a value, but they can choose to do so to override the normal object creation process.) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

    function outer(abc) {
      this.abc = abc;
       return function inner() {
        console.log(this);
        this.abc = abc;
        return this.abc;
      }
    }
    
    console.log((new outer)());

    To fix your code just remove dependence on this:

    function outer(abc) {
      this.abc = abc;
       return function inner() {
        return abc;
      }
    }
    
    console.log((new outer(123))());

    Anyway I think your pattern here doesn't make much sense. Seems you want to achieve a pattern that would be done much cleaner and easier.
    And to be more specific @VLAZ has pointed that this.abc = abc; in the outer class is pointless since not used later, that I noticed also but avoided to gain some focus on it. Ok as a part of JS learning though...

    @silentmantra Please clear one more doubt of below code, I will surely accept your answer. why I cant create object of inner function where it returns nothing. function outer(abc) { this.abc = abc; return function inner() { this.abc = abc; } } var result = new outer(23)(); console.dir(result);

    As mentioned and shown above when you call the returned function you lose your this context and it becomes window (default one). So basically window.abs returned and it's 11 since you have assigned to it. and your final console.log(obj2.abc) doesn't make sense since you try to get a prop of a number:

    function outer(abc) {
          this.abc = abc;
           return function inner() {
            this.abc = abc;       
            return this.abc;
          }
        }
    
    var obj2= new outer(11)();
    
    console.log(obj2)
    
    console.log(obj2.abc) // 11 doesn't have 'abs' property
    
    console.log(window.abc) // oops, but window has

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this