普通函数和箭头函数的this指向

普通函数与箭头函数

普通函数指的是用 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/

你可能感兴趣的:(普通函数和箭头函数的this指向)