箭头函数在对象、方法和类中的使用的差别

在对象中

看下面的一个例子,这里的 this 指向的是哪里呢?

const money = {
    a: 1, 
    fn: () => {
        console.log(this)
    }
}

按照箭头函数定义的解释,谁实例化(或定义)就指向谁,那这里的 this 应该是对象 money。

事实却不是这样,执行上面结果如下:

arrow_this_obj.png

可以这样来理解,箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承this。这里字面量的方式定义它封闭函数可以理解为就是 Window,所以这里箭头函数的 this 也指向 Window

另一种理解是箭头函数是用当前的词法作用域覆盖 this 本来的值,上面代码里词法作用域中 this 指向的是 Window

在方法中

function dollar() {
    this.fn = () => {
        console.log(this)
    }
}

new dollar().fn() // this -> dollar

在类中

class Dollar {
    fn = () => {
        console.log(this)
    }
}
new Dollar().fn() // this -> Dollar


class RMB {
    constructor(fn) {
        this.fn = fn
    }
}
new RMB(new Dollar().fn).fn() // this -> Dollar

  • 按照上面描述,this 继承自上一层,箭头函数定义在方法或类中指向的就是实例本身,不论方法在哪里执行、谁来执行。

普通函数中 this 的行为

this 指向执行这个方法的上下文(对象或类)
函数根据它是被如何调用的来定义这个函数的this值

首先看一个普通的例子

class abe {
    fn() {
        console.log(this)
    }
}
class dd1 {
    constructor(d) {
        this.fn = d.fn
    }
}

new abe().fn() // this -> abe
new abe().fn.call(new dd1({})) // this -> dd1
new dd1(new abe()).fn() // this -> dd1

从这个结果可以看出 this 指向执行时的上下文,即谁执行指向谁。

const aba = {
    a: 1,
    fn: function() {
        console.log(this)
    }
}

function abi() {
    this.fn = function() {
        console.log(this)
    }
}
class abe {
    fn() {
        console.log(this)
    }
}

分别在对象、方法、类中验证,普通函数定义的 this 指向都满足一致的规则,谁执行指向谁。

结论

  • 普通函数中 this 指向执行这个方法的上下文(对象或类),谁执行指向谁
  • 箭头函数中 this 继承自上一层的 this,谁实例化指向谁,没有实例的指向上一层(比如对象中定义的方法)
  • 不论普通 function 还是 arrow function ,直接执行的 this 大多是指向当前定义的上下文
  • 箭头函数的特点,语法简单、没有自己的 this、arguments、new、prototype

一个特殊的箭头函数

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。
箭头函数没有定义this绑定。

function c() {
    this.fn = () => {
        console.log(this)
    };
    return this
}

new c().fn() // c
c().fn() // window
// 可以这样理解
// c() 没有执行上下文默认是 window,那箭头函数指向上一层也是 window
// new 的操作是创建一个空对象并将这个对象做为 this 的上下文
'use strict';
var obj = {
  a: 10
};

Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this);
    return this.a+10; 
   // 代表全局对象 'Window', 因此 'this.a' 返回 'undefined'
  }
});

obj.b;

参照

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容