I found this answer: How to modify "this" in javascript
But I did not like it. Surely there must be a way to somehow modify this
?
You can think of this
as an implicit, immutable, value accompanying a function call.
There are a number of ways it can be set, the most common being that a call of the form o.f()
sets this
to o
within f
. Of course, this
can also be set with call
and apply
and bind
, and in other ways as well.
this
is not like other function parameters. If were a normal parameter, its value could in theory be changed. Instead, it represents a value, a sort of lexical placeholder for the value of this
. In other words, if I call
f.call(5)
and then write
function f() { console.log(this); }
You can think of the this
as being lexically replaced by the value 5. So if I tried to write
function() { this += 5; }
you can think of this as being the equivalent of
function() { 5 += 5; }
which is obvious nonsense. I cannot replace the value 5 with something else. By the same token, if I said
o = {
f: function() { this = o2; }
};
and then call o.f()
, the function is essentially rewritten as
function() { { f: ... } = o2; }
which is equal nonsense. I cannot re-assign the value of an object.
Since this
is a value, not a parameter, it cannot be assigned to or changed. It is not a valid left-hand-side for an assignment, any more than 42
is. We cannot change the value of the value named 42
. We cannot change the value of the value named this
.
The reason for this is that is the specification. In theory, one can imagine a version of JavaScript where this
was mutable. There is no definitive reason why this should not be possible. After all, no matter where it comes from, within the function it is simply a value. It would be confusing, and could result in unexpected behavior, but there is no reason why it could not work.
The primary reason this is not supported is simply that that is not how the language is defined. If your question is "why is the language defined that way", then that is something for language historians to answer. However, one can imagine good reasons for this, involving intuitive code behavior.
Consider the following code:
o = {
f: function() {
this.doSomething();
this = o2;
this.doSomething();
};
It is going to be extremely hard for normal human beings to understand such code. The same two this.doSomething()
calls do two different things due to the intervening change to this
. This alone is a more than adequate reason to prohibit changing the value of this
. All the more so since there is no logical reason for needing to do this, since I can replace the last two lines with a simple o2.doSomething()
.
Just to be clear, of course when we talk about "changing this
", even if we could do that, which we can't, we couldn't possibly mean somehow changing the outside value this
refers to. We all know that in the following case:
function a(x) { x = 2; }
var y = 1;
a(y);
The change to x
within a()
is purely local, and can't possibly affect y
. The same thing would apply equally to this
of course.
One more note on objects wrapping primitives. We know we can write
o5 = Object(5);
to get an object wrapping the number 5. Now I can define a method on this object, as in
o5.f = function() { console.log(this); };
and calling o5.f()
will log
Number {[[PrimitiveValue]]: 5}
So since this object "is" a number, certainly in this case I should be able to say
o5.f = function() { this++; };
But no. this
is not the number 5; it's an object wrapping 5. Those are two very different things. The function above is essentially equivalent to saying
o5.f = function() { Object(5)++; }
which yields
Uncaught ReferenceError: Invalid left-hand side expression in postfix operation
Now I can do arithmetic on the object, such as Object(5) + 1
, because JS will coerce the object to its underlying primitive before adding one. But I cannot re-assign to this object any more than any other. And I cannot modify the primitive number underlying the object. Once the wrapper object is created, the primitive value underlying it is locked in forever.
So the answer to your question is "no, there is no way to change this
". Which is not to say there are not other ways to do other things to accomplish whatever it is you want to accomplish.
Actually the problem here is that when you binding the function to a number then the this
is getting changed to number and now when you are doing the assignment operation this += 5;
the left hand side is not a variable where we can store the new value as its a primitive number instance. so to overcome that what you can do is you can store the this value in another variable say me
and then do the operation as following:
(function() {
var a = function(v) {
v += 10;
a = function() {
var me = this;
console.log(this); //logs Number {[[PrimitiveValue]]: 10}
me += 5;
console.log(me); //logs 15
}.bind(v)
//a();
}
a(0);
a();
})();
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
Simple types (except objects and arrays) is immutable. You can't modify it and save in source variable.
function foo() {
this.val+=10;
}
a=function(obj) {
a=foo.bind(obj);
}
But you can wrap it into object. See: http://jsfiddle.net/5dhm8fsn/
I don't know any language that allows you to alter this
.
you might want to think of this
as an address:
my house "sits" on Sesame street 10. of course, I can invite designers who can change who my Sesame-street-10-house looks like, but can I suddenly make Sesame street 10 turn into Sesame street 15? of course not. I can't just rip an entire piece of land and pass it 5 houses ahead.
going back to programing context, this
(eventually) is interpreted to the memory block your object sits in. you can change that object which sits on the specified memory block, but you can't just change the block address.