问题
I was reading the Mozilla Documentation, but I don't understand the this
which is passed into the function. Could anyone explain more about the usage of the this
argument here?
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this); //Why is this passed here?
};
var obj = new Counter();
obj.add([2, 5, 9]);
obj.count
// 3
obj.sum
// 16
回答1:
Per the Mozilla documentation:
thisArg
OptionalValue to use as
this
when executing callback.
And also:
If a
thisArg
parameter is provided toforEach()
, it will be passed tocallback
when invoked, for use as itsthis
value. Otherwise, the valueundefined
will be passed for use as itsthis
value. (Emphasis added)
What passing the thisArg
to forEach
does is bind the context. By default, this
in forEach
is the global window
object, because undefined
is used for this
. Passing the context permits you to access things from that context.
In the prototype, this
is the Counter
constructor, and passing then allows you to set the context of which this
is inside the forEach
. So, instead of this
being window
inside the forEach
, it is now Counter
, and you can access variables such as this.sum
otherwise not available due to the context.
回答2:
Since functions are self contained, your doing:
function x(){
this.test = 5
}
it only exists within the scope of the function.
If you start nesting functions as you have, if you want the scope to remain the same, you need to inform the function just that.
It is along the same lines of using the bind
function.
function test(){
this.a = 4;
var y = function(){
this.a += 1;
}.bind(this);
}
if you didnt bind, for example, this.a would would be undefined, so the line: this.a += 1;
would be the same as saying: this.a = undefined + 1
but when you bind, it will say: this.a = 4 + 1
回答3:
You can prevent the scoping by using arrow function in es6.
An arrow function expression has a shorter syntax compared to function expressions and does not bind its own this, arguments, super, or new.target.
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array.forEach(entry=>{this.sum += entry;++this.count});
};
var obj = new Counter();
obj.add([2, 5, 9]);
console.log(obj);
This comes handy when the alternative methods available in es5 are using bind()
to bind the this
parameter, or using the thisArg
that comes with forEach
as already explained in the other answers.
来源:https://stackoverflow.com/questions/39813975/this-context-in-foreach