Home > OS >  Why is Object constructors property globally scoped?
Why is Object constructors property globally scoped?

Time:09-21

Given the following:

function MyClass() {
  this.name = "Agnus"

  return function() {
    console.log(this.name)
  }
}


const user = new MyClass() //this = "MyClass"
const r = MyClass() //this = "window"

console.log(name) //Agnus, this = "window"
r() //Agnus, this = "window"

My expectation was that on calling r(), I will get a error as the value of "this" is window for its case but instead it returned me "Agnus". On checking, I found that the properties of the object constructor MyClass are available from global.

enter image description here

I am having little difficulty to wrap my mind around such behavior, so it will be really nice if someone can explain me a bit about this.

Thank you for your help.

CodePudding user response:

When you use new, you set the this to a new empty object whose internal prototype is the constructor's .prototype. That is:

new MyClass()
function MyClass() {
  // `this` is now equivalent to Object.create(MyClass.prototype)

But if you explicitly return an object from a constructor function, the this will essentially be discarded, and the returned object will be used instead. Here, the returned object is the function, and the

this.name = "Agnus"

line assigns to an object which is never referenced again.

In contrast, when you don't use new, and the function you call isn't a property of an object (or bound, or an arrow function), this will be either the global object (in sloppy mode), or undefined (in strict mode). In sloppy mode,

function MyClass () {
    this.name = "Agnus"

does

window.name = "Agnus";

And then when you invoke the returned function later with r(), since it's not a property of an object, its this is the global object - whose name is Angus.

To reduce confusion, I recommend

  • Avoiding returning objects explicitly from constructors
  • Always using new when invoking a constructor

You don't have to, but if you do that, you'll confuse yourself (and other readers of the code) less.

Strict mode is a good idea too.

  • Related