普通函数与箭头函数
普通函数指的是用 function 定义的函数:
var hello = function() {
console.log("Hello, Fundebug!");
};
箭头函数指的是用=>定义的函数:
var hello = () => {
console.log("Hello, Fundebug!");
};
箭头函数与普通函数不只是写法上的区别,它们还有一些微妙的不同点,其中一个不同点就是 this。箭头函数没有自己的 this 值,箭头函数中所使用的 this 来自于函数作用域链。
this 到底是什么?
JavaScript 是一门比较奇特的语言,它的 this 与其他语言不一样,并且它的取值还取决于代码是否为严格模式(“use strict”)以及函数中的 this 值取决于这个函数是怎样被调用的。this就是代码执行时当前的context object。代码没有在任何函数中执行,而是在全局作用域中执行时,this 的值就是 global 对象,对于浏览器来说,this 就是 window。
当函数作为对象的方法被调用时,它的 this 值就是该对象:
var circle = {
radius:10,
getRadius() {
console.log(this.radius);
}
};
circle.getRadius(); // 打印 10
当我们需要在对象方法中嵌套一个内层函数时,this的指向就会给我们带来实际的困扰了,这时就需要使用一个临时变量self去保存这个this:
var circle = {
radius:10,
outerDiameter() {
var self = this;
var innerDiameter = function() {
console.log(2* self.radius);
console.log(this === window);
};
innerDiameter();
}
};
circle.outerDiameter(); // 分别打印20和true
outerDiameter 函数是 circle 对象的方法,因此其 this 值就是 circle 对象。但内层函数innerDiameter并不会继承外层函数 outerDiameter 的 this 值。因此outerDiameter 函数的 this 值就是 circle 对象,this.radius 等于 10。但是innerDiameter函数的this值不是circle对象。
因此,如果我们直接在 innerDiameter 函数中使用 this 的话,就会问题了:
// 使用普通函数
var circle = {
radius:10,
outerDiameter() {
varinnerDiameter =function(){
console.log(2*this.radius);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印NaN
.bind(this)
我们也可以使用.bind(this)来绑定this:
var circle = {
radius:10,
outerDiameter() {
varinnerDiameter = function() {
console.log(2*this.radius);
};
innerDiameter = innerDiameter.bind(this);
innerDiameter();
}
};
circle.outerDiameter(); // 打印20
箭头函数
箭头函数的 this 取值,规则非常简单,因为 this 在箭头函数中,可以看做一个普通变量。箭头函数没有自己的 this 值,箭头函数中所使用的 this 都是来自函数作用域链,它的取值遵循普通普通变量一样的规则,在函数作用域链中一层一层往上找。
对于需要使用object.method()方式调用的函数,使用普通函数定义,不要使用箭头函数。对象方法中所使用的 this 值有确定的含义,指的就是 object 本身。其他情况下,使用箭头函数。
varcircle = {
radius:10,
outerDiameter() {
varinnerDiameter = () => {
console.log(2*this.radius);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印20
对于内层函数 innerDiameter,它本身并没有 this 值,其使用的 this 来自作用域链,来自更高层函数的作用域。innerDiameter 的外层函数 outerDiameter 是普通函数,它是有 this 值的,它的 this 值就是 circle 对象。因此,innerDiameter 函数中所使用的 this 来自 outerDiameter 函数,其值为 circle 对象。
文章来源:https://blog.fundebug.com/2019/06/18/arrow-function-this/