Ad

Why Is 'this' Keyword Required Inside Constructor Function In JavaScript?

- 1 answer

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 ?

Ad

Answer

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());

Ad
source: stackoverflow.com
Ad