前言:今天看了下廖旭峰老师的JS基本知识中的箭头函数一章,被箭头函数的this的作用域搞的云里雾里。倒不是说讲的不好,而是本人初学小白,很多专业词就没理解,比如稳重的“词法作用域”,而这又是理解箭头函数的关键所在,所以经过查找,发现这篇博客的解释得做容易理解并且和透彻。
误区场景:
eg:
varobj={
field:'hello',
getField:()=>{console.log(this.field) }
}
obj.getField()//undefined
这里最终会打出undefined,因为getField中的this就是window,而window是没有field这个属性的,所以就是undefined了。
所以我们一般不建议对象中定义函数的时候使用Arrow Function,毕竟this就会造成错误了。所以应该这么写
varobj={
field:'hello',
getField(){console.log(this.field) }
} 或者:
obj={
field:'hello',
getField:function() {
var fn ()=>{console.log(this.field)};
return fn();
}
}
obj.getField()
这样this就是obj了。
同样的,我们在写RN的时候有注意到:给TouchableOpacity 的onpress赋值回调函数的时候,大多数的情况下会设置箭头函数,箭头函数的函数体内调用我们的在模块中定义 的函数,否则我们需要在模块的构建方法中将模块中的函数绑定this,才能让模块中的函数正确的拿到其他变量和参数。比如下面的代码:
箭头函数示例:
<TouchableOpacity style={styles.scannerImage onPress={()=>{this.BtnOnPress}}/>
普通函数:
<TouchableOpacity style=={styles.scannerImage onPress={this.BtnOnPress}/>
BtnOnPress函数,该函数在模块内定义
BtnOnPress(){
console.log('enter****');
console.log('this is ---- ' + this);
}
如果使用了箭头函数,那么我们在BtnOnPress中打印出来的this,就是当前模块,如果用了普通函数,this打印出来的是TouchableOpacity对象,但如果我们在模块的constructor中添加了this.BtnOnPress = this.BtnOnPress.bind(this);那么就会打印出当前模块对象。这也就是了箭头函数的词法作用域:arrow funtion会查找TouchableOpacity的this也就是当前模块,但普通函数由于是TouchableOpacity对象调用的,在不bind this的情况下this.BtnOnPress里的this就不是当前模块了。
总结:由于箭头函数是在定义时就定义了作用域(词法作用域),而其他普通函数是在调用时才绑定的作用域,所以,最后示例中的getField 指向的是普通函数,obj.getField()调用时,函数内部的this就是调用者obj,而getField中的fn箭头函数,根据词法作用域,由内至外查找this,由于fn本身没有this,所以就会去getField查找this,发现getField是有this的(也就obj),obj.getField()调用时,内部箭头函数的this其实就是obj.