this 在JS代码中很常见,比如下边的代码:
let car =
{
name:" ",
showName:function(){console.log(this.name);}
};
car.name = "ford";
car.showName();//"ford"
代码中car对象里的showName方法用到了this,并在最后一行调用了showName方法。这个this代表的是调用showName的对象,也就是car。
所以可以总结为谁调用了这个方法,那么方法里的this就代表谁。
那么我们来看一看其他有趣的例子:
let car =
{
name:"ford",
showName:function(){console.log(this.name);}
};
let {showName} = car;
showName();//name is property of undefined
上边的例子是我们把showName函数从car中剥离出来了,(如果对属性剥离不熟悉的读者请看JS对象的讲解)最后一行执行时没有调用此函数的对象,那么this也就成了undefined的了,所以就会出现错误。那么如何修改呢?
let showName = showName.bind(car);
showName();//'ford'
就用到了我们之前讲过的bind方法(具体的bind介绍在JS函数),将showName进行配置,设置好调用此函数的对象再执行就好了。
bind固然可以解决这种问题,但是是不是有点脱裤子放屁的感觉。。。接下来咱们介绍另一种方法
--call
showName.call(car);//打印出‘ford’
call 方法也会像bind一样将showName方法的调用对象和参数进行设置,但与bind不同的是,call配置好后会立即执行该函数。而bind则是将配置好的方法存在变量中等待执行语句。
还有一个跟call类似的方法--apply,同样也可做方法的配置并执行方法,但不同点在于参数。call可以添任意个数的的参数来匹配要做配置的方法,但apply只有两个参数,一个是同call一样的配置调用对象,另一个是数组,存储参数:
let car =
{
name: 'ford',
getName: function(arg1,arg2)
{
console.log(arg1);
console.log(arg2);
console.log(this.name);
}
};
let {getName} = car;
getName.call(car,'paramenter1','paramenter2');//'paramenter1 paramenter2 ford'
getName.apply(car,['paramenter1','paramenter2']);//'paramenter1 paramenter2 ford'
上边代码call和apply执行后打印的是一样的。
值得注意的是,arrow function箭头函数对this并不感冒,它并不知道this代表着什么,所以箭头函数的this指的是函数外的this。上代码!
let car = {
name:'ford',
getName : ()=>{console.log(this);}
};
car.getName();//undefined
因为是箭头函数,所以getName中的this 不再代表car,即使是car调用了它。this指的是getName方法外的this,也就是car object里的this,但是car里边没有this的定义,所以返回undefined。利用箭头函数的特性,我们可以写出下边代码:
let car =
{
name: ['ford','BMW'],
prop: '4 wheel',
getCar: function()
{
this.name.forEach(n=>{
console.log(n+"--"+this.prop);
});
}
};
car.getCar()//'ford--4 wheel' 'BMW--4 wheel'
由于forEach参数为箭头函数,则函数里的this指的是forEach外边的this,forEach的外边就是getCar方法内部,getCar方法使用的是正常的函数,所以getCar方法里的this也就指向了car对象,那么forEach里的this.prop也就顺理成章的指向了car中的prop。
对象中的getter&setter对this的应用
let car =
{
_name:'ford',
get name(){return this._name}
set name(val){this._name = val}
}
console.log(car.name)//ford
car.name = 'BMW';
console.log(car.name)//BMW
对于JS的getter和setter,this的应用也是一样的,代表着调用它的对象。