从学习js以来,遇到了很多问题,js有很多需要掌握的地方。其中一个较难的点就是this的指向问题。这篇文章将会分享以下this在fuction和箭头函数内部的指向问题。个人感觉以下知识点的我现在基本上解决了this指向的许多问题。
无论什么时候,js都会把this放在function内部,如果函数是直接放在某个对象中的成员,那么,this的值就是这个对象。如果函数不是某个对象成员那么就设置为全局对象。
var obj = {
age: 18,
sayage: function() {
console.log(this.age);
}
} //18
这里是直接充当对象的成员,所以this指向的是这个对象。
var age = 19;
var obj = {
age: 18,
sayage: function() {
return function() {
console.log(this.age);
}
}
}
var say = obj.sayage();
say();
这里没有直接充当对象成员,所以指向了window.
var R = function() {
this.name = 'renjialei';
return {};
}
var r = new R();
console.log(r.name); //输出undefined
因为对象本身的话都自带有一个this返回值指向这个对象,但是这个this并不会被函数中我们通常说的this所继承,将对象或者函数作为返回值的,this指向将会指向全局。
箭头函数中的this指向说法不一,我个人比较为了好理解,综合了很多人的看法,形成了这样一种结论。首先箭头函数没有this指向,它是不能绑定this的,他的this指向定义时所处的那个对象,在判断时个人比较建议寻找它的父上下文。
var name = "renxiansheng";
var obj = {
name: "renjialei",
sayname: () => {
console.log(this.name);
}
}
obj.sayname(); //renxiansheng
这里输出结果是并不是"renjialei",原因很简单,箭头函数没有this, 就是this是继承自父执行上下文 中的this,比如这里的箭头函数中的this.x,箭头函数本身与say平级以key:value的形式,也就是箭头函数本身所在的对象为obj,而obj的父执行上下文就是window。
还有就是定时器里面的this指向,通过测试,定时器是不影响箭头函数this指向的。因为定义时定时器还没有生效,我们看下面这段代码。
var obj = {
age: 18,
sayage: function() {
setTimeout(() => {
console.log(this.age);
}, 3000);
}
}
obj.sayage(); //输出18
这里之所以输出18,是因为箭头函数里面的this会找到外面的充当方法的function,而它的this指向是指向obj的。所以最后输出18.在这一定要清楚的是只有函数内部才会生成this对象,对象里面是没有this指向的。
再来看一个例子
var name='renxiansheng';
var obj = {
name: 'renjialei',
sayname: {
sayname: () => {
console.log(this.name);
}
}
}
obj.sayname.sayname(); //输出 renxiansheng
可能很多人奇怪了,为什么输出结果是这样的呢,原因很简单,他会顺着作用域往上找,找到sayname,但对象没有this指向,就找到了最外层去,找到了window.
另外在说明一点,就是定时器是会对函数普通函数的this指向造成影响的。
var obj = {
say: setTimeout(
function() {
console.log(this);
}, 1000
)
}
obj.say; //输出window,因为最后调用函数的是定时器
最后在来一个高难度版本的,只要把这个理解掉,基本上this指向全部解决掉
var name = "ren";
var obj = {
name: 'renjialei',
sayname: {
name: 'xiansheng',
sayname: function() {
setTimeout(() => {
console.log(this.name)
}, 1000)
}
}
}
obj.sayname.sayname(); //输出xiansheng
还是那个套路,定时器在定义是并不影响this的指向,所以顺着这条链往上找,找到了充当sayname方法的函数,所以this指向了sayname对象。输出结果也就是它了。