By Boudhayan Dev


2019-04-15 09:01:29 8 Comments

I am trying to instantiate a constructor function using the new keyword in JavaScript. However, it is not working as expected -

var a = function () {
            abc = function () {
                      return  "abc";
                  }
        }

var obj = new a();

If I do -

obj.a(); . It says -

Uncaught TypeError: obj.abc is not a function

But if I just access it without the object obj, it works

abc();

But the whole problem is resolved if I use this for the inner function -

var a = function () {
            this.abc = function () {
                           return  "abc";
                       }
        }

So my question is, if I declare abc() without 'this' keyword, isn't its scope inside the a function. Why is it being treated like a global function when it is declared inside the function a ?

3 comments

@T.J. Crowder 2019-04-15 09:05:12

if I declare abc() without this keyword, isn't its scope inside the a() function. Why is it being treated like a global function when it is declared inside the function a ?

It isn't declared anywhere. The code in a assigns to an undeclared variable, which creates an implicit global (in loose mode, the default).

This is one of many good reasons to use strict mode ("use strict"; at the top of the script). In strict mode, assigning to an undeclared variable is an error (just like reading from an undeclared variable is). More in my blog post The Horror of Implicit Globals.


And yes, as you've discovered, this. is never optional in JavaScript as it is in Java or C#. To refer to the instance being created within a when you do new a(), you must use this.

Side note: The overwhelming convention in JavaScript is that constructor functions (functions you call via new) start with a capital letter. So A rather than a, or perhaps Example:

var Example = function () {
    this.abc = function(){
        return "abc";
    };
};

var obj = new Example();
console.log(obj.abc());

You might consider putting abc on the prototype rather than recreating it on every call to a:

var Example = function () {
};
Example.prototype.abc = function(){
    return "abc";
};

var obj = new Example();
console.log(obj.abc());

Or with ES2015+ class syntax:

class Example {
    abc(){
        return "abc";
    }
}

var obj = new Example();
console.log(obj.abc());

@Kévin Bibollet 2019-04-15 09:06:25

Declaring a variable/function without any keywork will make it a global one:

abc();

abc = function() {
  console.log('global abc');
};

// same as:
//window.abc = function() {...};
window.abc();

Using let and your function will be scoped:

{
  let abc = function() {
    console.log('let abc');
  }
}

abc(); // ReferenceError: abc is not defined

If you declare a function with var, you will be able to execute it even after closure end, but not before, and if not declared insinde a function:

//abc(); // TypeError: abc is not a function

{
  var abc = function() {
    console.log('var abc');
  }
}

abc(); // will work

let a = function() {
  var cde = function() {
    console.log('var cde');
  }
  
  cde(); // will work
}

cde(); // ReferenceError: cde is not defined

Finally, this will make a object property:

let a = function() {
    this.abc = function() {
      console.log('this.abc');
    };
}

let obj = new a();
obj.abc();

a.abc(); // TypeError: abc is not a function

@Boudhayan Dev 2019-04-15 09:53:14

Hello, I wanted to know why is this needed inside constructor function ? If I don't use this, the inner function is being assigned to global scope. why ?

@Kévin Bibollet 2019-04-15 10:03:56

Look at T.J. Crowder 's answer. It is well explained.

@Jack Bashford 2019-04-15 09:06:07

That's because you haven't declared abc as a property of the newly constructed object - you're making it into a globally available function by omitting the var keyword. If you want to make it accessible without using this, try this:

var a = function() {
  var abc = function() {
    return "abc";
  }
  return { abc };
}

var obj = new a();
console.log(obj.abc());

@T.J. Crowder 2019-04-15 09:10:55

Why create and return a new object (which doesn't have a.prototype as its prototype) from a when a is already being called via new, and so a new object (with the correct prototype) has already been created? All th eOP needs to do is what they shows in their question: this.abc = function() { /*...*/ };.

@RobG 2019-04-15 09:13:13

"That's because you haven't declared abc as a property…", you mean as a variable, properties are created. ;-)

@T.J. Crowder 2019-04-15 09:24:42

(OMG the number of typos in my comment above. sigh)

Related Questions

Sponsored Content

14 Answered Questions

[SOLVED] What is the 'new' keyword in JavaScript?

29 Answered Questions

23 Answered Questions

[SOLVED] Set a default parameter value for a JavaScript function

28 Answered Questions

[SOLVED] Is there a better way to do optional function parameters in JavaScript?

43 Answered Questions

[SOLVED] JavaScript closure inside loops – simple practical example

5 Answered Questions

[SOLVED] What is TypeScript and why would I use it in place of JavaScript?

  • 2012-10-02 16:37:58
  • Mohammed Thabet
  • 461101 View
  • 1528 Score
  • 5 Answer
  • Tags:   javascript typescript

11 Answered Questions

[SOLVED] Define global variable in a JavaScript function

3 Answered Questions

[SOLVED] JavaScript plus sign in front of function name

7 Answered Questions

[SOLVED] What do parentheses surrounding an object/function/class declaration mean?

  • 2009-01-13 20:48:07
  • user54692
  • 101891 View
  • 283 Score
  • 7 Answer
  • Tags:   javascript syntax

3 Answered Questions

[SOLVED] Declaring javascript object method in constructor function vs. in prototype

  • 2012-03-19 14:49:08
  • Joe Alfano
  • 63943 View
  • 144 Score
  • 3 Answer
  • Tags:   javascript oop

Sponsored Content