1

I am fairly new to Javascript and stomped across this while writing some frontend code. I reproduced this here:

var obj1 = {

  func1(val) {
    if (!this.obj2) {

      this.obj2 = {
        func2() {
          console.log(val);
        }
      }
    }
    this.obj2.func2();
  }
}
obj1.func1(10);
obj1.func1(20);

Why is the value of the val not getting changed inside the func2() method? It seems that only the value is getting copied to the object obj2 without taking the reference into consideration.

But it works perfectly when I change the code to this:

var obj1 = {

  func1(val) {
    this.val = val;
    var that = this;
    if (!this.obj2) {

      this.obj2 = {
        func2() {
          console.log(that.val)
        }
      }
    }
    this.obj2.func2();
  }
}
obj1.func1(10);
obj1.func1(20);

Can anyone tell the reason behind the difference? Is it something to do with the scope?

3 Answers 3

1

In the first snippet, when you do

if (!this.obj2) {
  this.obj2 = {
    func2() {
      console.log(val);
    }
  }
}

The obj2 method that has been assigned, which gets assigned once and never again, closes over the val parameter in its scope when it was assigned - that is, when obj1.func1(10) was run.

In the second snippet, you assign to the val property of the instance every time func1 runs:

func1(val) {
  this.val = val;

so by the time you log that.val later, it's always the parameter you just passed.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the quick response. If I understand correctly, func2 is a closure, right? And the second snippet works because func2 closes over the that variable, but not over the that.val. So, it can still access the modified value through that object reference. Is this correct?
Yes, in the first, the assigned function closes over the parameter passed to the method when the method is called for the first time. In the second, closures don't have anything to do with it - the difference is that the second has this.val = val;, changing the instance, so logging the property on the instance shows a change. If you changed the first snippet to this.val = val; on the first line, you'd also see the change logged.
1

On the first case, you have:

    if (!this.obj2) {
      this.obj2 = {
        func2() {
          console.log(val);
        }
      }
    }

So you make func2 always console.log the value it was originally created with. The second time it's called it will just call func2 with original val because functions retain access to the original scope they were declared (this is called closure).

The second time, when you do

this.val = val;
var that = this;

You're going to console.log a dynamic reference to this, so it's going to be value you passed because the this is going to be different on this scop

Comments

0

as far as I can understand the "This" keyword in javascript always points to the app itself or a global object. What you just did is setting a reference to the variable you are trying to use which is how I remedy this behaviour mistimes. I hope this helped at least?

have a look at this post. understanding the this keyword

cheers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.