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.
- You give the
-1
argument to thedefiner
function and call it. - We are now inside the definer function, and we are passing the value
-1
to themySelector
function. - We are inside the
mySelector
function.-1
is not greater than0
. The else block runs and we return thez
corresponding to the value2
to thedefiner
function. - And we are in the
definer
function again. The value2
came from themySelector
function. We can now write2
instead ofmySelector(value)
.
The resulting image is2 = 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.
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.