Home > Net >  Using methods to select an object's property and assign it a value creates an error
Using methods to select an object's property and assign it a value creates an error

Time:10-20

I am trying to write a method that based on some value, returns a property that I'd like to define in another method. However, I am having a strange 'Uncaught ReferenceError: Invalid left-hand side in assignment' error.

If I use a method to return a property of the object and I try to assign a new value to it, it spits out the error. But if I call the object.property and assign it a new value, it works.

Further, I run a test: the object.property == object.method(value) (which calls the property) returns true!

It seems like I am using the = correctly.

const test = () => {
    const y = 1; 
    const z = 2; 

    const mySelector = function(value) {
        if (value > 0) {
            return this.y;
        }
        else {
            return this.z;
        }
    }

    const definer = function (value){
        mySelector(value) = 9;
    }

    return {y, z, mySelector, definer}
}


let testInstance = test();

// this line spits out a an error: 
testInstance.definer(-1); // Uncaught ReferenceError: Invalid left-hand side in assignment

testInstance.z = 9; // but this is ok

testInstance.z == testInstance.mySelector(-1) // true

CodePudding user response:

mySelector(value) = 9 You can't make an assignment this way.

We can imagine this line as follows.

  1. You give the -1 argument to the definer function and call it.
  2. We are now inside the definer function, and we are passing the value -1 to the mySelector function.
  3. We are inside the mySelector function. -1 is not greater than 0. The else block runs and we return the z corresponding to the value 2 to the definer function.
  4. And we are in the definer function again. The value 2 came from the mySelector function. We can now write 2 instead of mySelector(value).
    The resulting image is 2 = 9. Yes, we found it! This is an "invalid left-hand side in assignment" error.

Maybe now it has made more sense what caused the error that popped up.


EDIT

"what's the best way to do so?" It would not be correct to say that the best way is this or that. There is more than one way to get the result you want.

I will mention a few more points in response to your comment.

let testInstance = test()

The test function returns an object. and this object has four properties named "y, z, mySelector, definer" and values defined for these properties.

The testIstance variable now references this object.

testInstance.z = 9

In this line where you wrote, you access the z property of the testInstance object and change its value. Everything works fine here.

testInstance.z == testInstance.mySelector(-1)

But this line has a deeper information to know, this keyword.

I will not go into the details of the this keyword here. Therefore, you can understand better by reading and applying from the source I have given. But I will briefly explain why this line returns true.

First of all, let's not forget that we set the value of the z property of the testInstance object to 9 in the previous line of this line. (testInstance.z = 9)

Now we know that when we access the z property of the testInstance object on the left side of the equation, it will give us the value 9. Let's simulate it,

9 == testInstance.mySelector(-1)

Now let's examine the right-hand side of the equation. We call the mySelector method of the testInstance object. This method returns this.y or this.z depending on the condition. And in our example the else block will work because of the -1. The main part starts here.

Simply, whenever you create a javascript object, the methods of this created object can access the object itself with the this keyword. Here the keyword this points to our testInstance object.

MDN

When a function is called as a method of an object, its this is set to the object the method is called on.

Let's continue where we left off, the else block is processed and this.z returns.

Since in our example we are calling the mySelector method of the testInstance object, the this keyword points to our testInstance object. And we previously set the value of the z property of the testInstance object to 9. That's why it returns 9 from this.z.

And the result is 9 == 9, true.

A quick note about 'this'

ES5 Function

const test = () => {
  const mySelector = function(value) {
        console.log(this) // this -> points to the object itself
  }

  return { mySelector } 
}

ES6 Arrow Function

const test = () => {
  const mySelector = (value) => {
        console.log(this) // this -> points to the window object
  }

  return { mySelector } 
}

In your example, mySelector function is written with the es5 syntax, it points to the testInstance object itself. But if it was written in es6 syntax, testInstance.z == testInstance.mySelector(-1) would return false here. Because the this keyword would point to the window object, and since the window object has no z property, it returns undefined.

9 == undefined, false.

Final touch, a function's this keyword behaves a little differently in JavaScript compared to other languages. Researching and practicing this topic is an important step towards understanding the results.

  • Related