Why can I do this:
Array.prototype.foo = function() { this.splice(0, this.length); return this.concat([1,2,3]); }
But I can't do this:
Array.prototype.foo = function() { return this = [1,2,3]; }
Both functions destroy the value of this and change it to [1,2,3]
but the second one throws the following error: Uncaught ReferenceError: Invalid left-hand side in assignment
I suspect it's because allowing assignment means I could potentially change the array to something else (like a string), but I'm hoping someone out there knows for sure and/or has a more detailed explanation.
No, you can't assign values to functions.
A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned. Let's try to understand by a simple example.
In JavaScript, the this keyword refers to an object. Which object depends on how this is being invoked (used or called). The this keyword refers to different objects depending on how it is used: In an object method, this refers to the object.
The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible. Every function includes prototype object by default.
You're confusing objects with references.
An array is an object, when you use a literal like [1,2,3]
you're making a new array.
A variable name like this
or a
is a reference to an object. If it helps, imagine an object as a person, and the reference as their nickname. You can have more than one reference to the same object, for example:
var a = [1,2]; var b = a; b.push(3); alert(a.length); // Gives "3"
Imagine if you had a friend named Sarah. You also sometimes call her "Ace". If Sarah gets a haircut one day, Ace has a haircut too, because "Sarah" and "Ace" are both different names for the same person.
If you use a mutating array method like a.push
or a.splice
(concat
however is not one!), you change the existing Array object, and a
still refers to the same object. This is like getting a hair cut - you may look different, but you're still the same person.
When you assign a reference to a new value, with a = [1,2,3]
, you're creating a new array, and changing a
to refer to it. This is like finding a new friend with different hair, and deciding to call her Ace instead.
Now this
is a special name generated by Javascript. It's not a given name like Sarah, but more of a title, like "mother". Your mother can get a new haircut, but you can't get a new mother. Likewise, you can't change what this
refers to from inside a function.
It's not permitted to assign a value to this
within a function. Suppose that you could do this, and your code looked something like:
Array.prototype.foo = function() { return this = [1, 2, 3]; } var a = ["beans", "rice"]; a.foo(); // a now points to an object containing [1, 2, 3]
Now, what if you did this:
var a = ["beans", "rice"]; var b = a; // b refers to the same object as a b.foo(); // what does b refer to now? how about a?
The act of calling a function .foo()
on an object should not change the identity of the object. This would be very confusing for the caller if b
suddenly started referring to a different object than a
simply because some method was called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With