Clarification regarding scope and correct use of this


#1

Hi all,
Thanks in advance for any clarification you can contribute.
Below are two solutions both of which will run and pass the exercise requirements.
What I can't figure out is why.

In version 1: Both times; first under the cashRegister.add() and again under cashRegister.voidLastTransaction()
The variable lastTransactionAmount is coded as this.lastTransactionAmount

// Version 1 using this.lastTransactionAmount

var cashRegister = {
    total:0,
    lastTransactionAmount: 0,
    //Dont forget to add your property
    add: function(itemCost) {
        this.lastTransactionAmount = itemCost;
        this.total +=  itemCost;
    },
    scan: function(item,quantity) {
        switch (item) {
        case "eggs": this.add(0.98 * quantity); break;
        case "milk": this.add(1.23 * quantity); break;
        case "magazine": this.add(4.99 * quantity); break;
        case "chocolate": this.add(0.45 * quantity); break;
        }
        return true;
    },
    //Add the voidLastTransaction Method here
    voidLastTransaction(){
        this.total -= this.lastTransactionAmount;
    }
    
};

cashRegister.scan('eggs',1);
cashRegister.scan('milk',1);
cashRegister.scan('magazine',1);
cashRegister.scan('chocolate',4);

//Void the last transaction and then add 3 instead
cashRegister.voidLastTransaction();
cashRegister.scan('chocolate',3);

//Show the total bill
console.log('Your bill is '+cashRegister.total);

...and so far this makes sense.

Now in version 2: After replacing this.lastTransactionAmount with lastTransactionAmount everything still continues to work the same.

How is that possible when if we do the same for total (i.e. replace this.total with total) which is defined in the same scope as lastTransactionAmount we get: ReferenceError: total is not defined but not the same error for lastTransactionAmount?

// Version 2 using only lastTransactionAmount

var cashRegister = {
    total:0,
    lastTransactionAmount: 0,
    //Dont forget to add your property
    add: function(itemCost) {
        lastTransactionAmount = itemCost;
        this.total +=  itemCost;
    },
    scan: function(item,quantity) {
        switch (item) {
        case "eggs": this.add(0.98 * quantity); break;
        case "milk": this.add(1.23 * quantity); break;
        case "magazine": this.add(4.99 * quantity); break;
        case "chocolate": this.add(0.45 * quantity); break;
        }
        return true;
    },
    //Add the voidLastTransaction Method here
    voidLastTransaction(){
        this.total -= lastTransactionAmount;
    }
    
};

cashRegister.scan('eggs',1);
cashRegister.scan('milk',1);
cashRegister.scan('magazine',1);
cashRegister.scan('chocolate',4);

//Void the last transaction and then add 3 instead
cashRegister.voidLastTransaction();
cashRegister.scan('chocolate',3);

//Show the total bill
console.log('Your bill is '+cashRegister.total);


https://www.codecademy.com/en/courses/close-the-super-makert/0/5?curriculum_id=506324b3a7dffd00020bf661


#2

You're storing it globally, you'll run into trouble when using multiple instances of your cashRegister.

To be fair it's just a single object, not something that resembles classes of other languages. Still shouldn't be global, it should be contained in the object.

Methods don't receive the object that they are called on as an argument. They refer to the object they were called on through this


#3

Firstly, thanks for your reply.

I understand why we need to use this. and how it enables the method to know which instance of the object's we're calling from, as in version 1 of the above posted code.

My question was, why does version 2 work?
Specifically, why does it not throw up a ReferenceError: lastTransactionAmountis not defined
but it does throw one up for total?


#4


#5

Again, yes, I fully understand how it's being stored globally.

But my question was why is it that when both variables total and lastTransactionAmount are in the same scope and called in the same methods; why then does only total throw up a ReferenceError and the lastTransactionAmount works just fine sans this.

So the missing piece of the puzzle was on the first line of the add method.
The first line in the add method implicitly creates lastTransactionAmount as a global due to the =
However, the same does not work for total due to the += which expects total to be pre defined.

Thanks again for your help.


#6

Oh. Sorry.

I'm not blameless, especially not the second time around. but definitely try to strip things down to a bare minimum :X

I took that as "Since it's not defined in the method, where is it getting its value from?"