Function Level Scope broken in constructor?

Function Level Scope broken in constructor?
0

#1

Hi,

I came across this example while trying to learn about constructors in JS, however the thing that as confused me is that we always talk about function level scope in JS , then how come sum and mul are able to access the properties of read and give proper results …Also when i use

function read()
function sum()
function mul()

instead of this,read, this.sum, this.mul it gives error why ?

function Calculator() {

  this.read = function() {
    this.a = +prompt('a?', 0);
    this.b = +prompt('b?', 0);
  };

  this.sum = function() {
    return this.a + this.b;
  };

  this.mul = function() {
    return this.a * this.b;
  };
}

let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );

#2

Hi @amitshrivastavafcc, if we look closely where we are calling read() with the instance of Calculator(), we are passing calculator as (this). This is interpreted to be the object which is left of read(), i.e in line calculator.read(), “this” is calculator. So in read method, all the variables like a and b are added to this “this”. Similar for this.sum and this.mul. If you would console.log(this) in every inner method , this thing would be very clear to you.
You are actually working on the same instance of the Calculator, like:
Calculator {a: 10, b: 12, read: ƒ, sum: ƒ, mul: ƒ}. Hope this clarifies.


#3

@rachnaban - thanks , but are you saying everything gets added to this , that is a bit confusing , so does this override the function scope ?


#4

Of course it does, that’s why you’re explicitly using it. If you just used “a” in read(), that would be a function-local variable. But you’re specifically using the one of the object. Which may not exist yet — eg. if you call mul before calling read.


#5

The best way to understand this is as follows:

The “this” keyword points to the context of where the function is called from. Now, what is context?

In your code, Calculator( ) is a function which is defined in the global scope. The global scope is its context.
So, when you use “this” keyword inside Calculator( ), it refers to the global scope.

This means that “this.read” = “window.read” i.e. your “read function” is attached to the global scope and not to the Calculator function itself.

Sure, the read function is defined inside Calculator, but that doesn’t mean its attached to Calculator function especially when you have defined it as “this.read”.

this.read is saying — Hey I am a function and I am attaching myself to whatever “this” represents, which happens to be the global scope.

Try an experiment by running the following commands in the order:

Calculator( ) //this invokes Calculator function, and then also registers the read( )
window.read( ) //this will access the read function, now that Calculator has defined it
console.log (window.a, window.b) //this will allow you to access the variables which you have defined inside read( )

If the above explanation sounds confusing, I highly recommend reading through the following 2 resources: