函数
箭头函数
箭头函数的出现, 又让代码简洁了不少, 不需要再去写 function 关键字了。
基础用法
function sum(a, b) {
return a + b;
}
const sumFun = (a, b) => {
return a + b;
};
console.log("sum(1, 2):", sum(1, 2));
console.log("sumFun(1, 2):", sumFun(1, 2));
this 指向
1 非箭头函数的 this 指向。
function sum(a, b) {
console.log(this);
return a + b;
}
sum(1, 2);
能看到这里的 this 指向windows,我们只需要记得非箭头函数 this 指向的始终是调用它的对象。 那这里为什么指向windows呢, 是因为sum 之前省略了window, 准确的调用应该是 window.sum(1, 2), 只不过非严格模式下, window 可以省略。
再看一个例子:
const obj = {
name: "cool",
age: 20,
getIntro() {
console.log(this);
return `cool's age is 20`;
},
};
obj.getIntro();
这里能看到getIntro 函数里面的this 是obj,这里面都是没有箭头函数的, 所以就只需要看是谁调用的这个函数就行了,this 就指向这个对象。
再来看
const obj = {
name: "cool",
age: 20,
getIntro() {
setTimeout(function () {
console.log(this);
});
return `cool's age is 20`;
},
};
obj.getIntro();
setTimeout 的回调函数里面我也没有使用箭头函数, 看到控制台打印的this 是window 对象,这个其实就和第一个例子是一样的。
再来看:
const obj = {
name: "cool",
age: 20,
getIntro() {
setTimeout(function () {
const tt = {
name: 'tt',
getTT() {
console.log(this);
},
};
tt.getTT();
});
return `cool's age is 20`;
},
};
obj.getIntro();
这里能看到 getTT() 函数里的this 就是 tt 对象,因为在外面我们执行了 tt.getTT() 这个函数, 由于不是箭头函数, 我们只需要记得非箭头函数 this 指向的始终是调用它的对象。
2 箭头函数的 this 指向。
对于箭头函数, 我们要记住的就是它本身没有this, 所以它的this 都是上一级给它的。
来看例子
const sum = (a, b) => {
console.log(this);
return a + b;
};
sum();
这里能看到我们定义的这个箭头函数里面的this 是window, 这个我们直接定义一个function 的函数 里面的this结果是一样,但是意义是不一样的,刚刚说过,箭头函数里面本身是没有this的, 所以它这个this 哪里来的呢,就是从它的外面, 上一级找来的, 它的外层就是window 对象, 所以这里的this就指向window。
再来看一个例子
const obj = {
name: "cool",
age: 20,
getIntro: () => {
console.log(this);
return `cool's age is 20`;
},
};
obj.getIntro();
这里obj 的 getIntro 方法 我用了箭头函数定义,所以这里的this 就指向调用它的上一级,调用它的是obj 对象, 上一级就是window, 所以这里的this 就指向window, 注意了,这里的this 不是指向obj对象, 所以在getIntro 函数里面, 是不能用this.age 来获取对象的age 属性的。
再来看一个例子
const obj = {
name: "cool",
age: 20,
getBestFriend: function () {
return {
name: "test",
getIntro: () => {
console.log(this);
},
};
},
};
obj.getBestFriend().getIntro();
这里的getIntro() 是一个箭头函数, 所以它没有this, 所以 向它的上一级找, 它的上一级getBestFriend() 函数是一个普通函数, 所以它的this指向就是调用它的对象obj, 所以我们看到控制台打印的this 就是obj 对象, 我们改下代码
const obj = {
name: "cool",
age: 20,
getBestFriend: ()=> {
return {
name: "test",
getIntro: () => {
console.log(this);
},
};
},
};
obj.getBestFriend().getIntro();
由于getIntro,getBestFriend 都是箭头函数, 所以此刻的this 就指向window。
再来看
const obj = {
name: "cool",
age: 20,
getBestFriend() {
setTimeout(() => {
console.log(this);
});
},
};
obj.getBestFriend();
这里setTimeout的回调函数 用了箭头函数, 所以向它的上一级找this , 上一级getBestFriend 用的普通函数定义的, 所以它的this 指向调用它的函数 obj, 所以控台打印的this 就是obj, 来修改下代码
const obj = {
name: "cool",
age: 20,
getBestFriend: () => {
setTimeout(() => {
console.log(this);
});
},
};
obj.getBestFriend();
这里我们的setTimeout 的回调函数以及getBestFriend 函数都是箭头, 所以他俩都没this,只能指向调用getBestFriend 函数对象的上一级 window, 所以这里控制台打印的this 就是window
什么时候用箭头函数?
从上面的例子, 我们能看到,记住下面两点, 就知道啥时候该用啥时候不该用了。
1 定义对象的函数的时候,不要用箭头函数, 如果用了箭头函数, 在函数体里面就不能通过this.xx获取该对象属性了。
2 回调函数中建议用回调函数,如果回调函数中还用普通函数定义, 那返回的this 一定是window对象, 所以建议在回调函数使用箭头函数,这样就会向回调函数的上一级寻找this, 找到你需要的对象。