这些情况下不建议你使用箭头函数

3,261 阅读3分钟

箭头函数作为ES6新增的语法,在使用时不仅能使得代码更加简洁,而且在某些场景避免this指向问题。但是箭头函数不是万能的,也有自己的缺点以及不适用的场景,虽然可以解决this只想问题,但是也可能会带来this指向问题。具体场景具体分析,本文就深入探讨箭头函数。

箭头函数没有自己的this,其this取决于上下文中定义的this。关于this指向的原理,可参考JavaScript 的 this 原理 - 阮一峰的网络日志 (ruanyifeng.com)

箭头函数的缺点

  1. 箭头函数没有arguments参数列表,普通函数可以直接获取到

    arguments是调用函数时,传递给函数的一个类似数组的对象,几乎所有的函数都有此局部变量,可直接访问并使用传递给函数的参数列表,箭头函数除外。该变量不是数组对象,只是类似于数组,没有数组的常用方法。

    let fn1 = () => {
        console.log('arguments', arguments);
    }
    fn1(1, 2); // arguments is not defined
    let fn2 = function() {
        console.log('arguments', arguments);
    }
    fn2(1, 2); // Arguments对象,可查看具体的参数
    
  1. 无法通过apply、call、bind改变this的指向。箭头函数的this默认指向父作用域或者当前调用对象,无法通过call等修改,但是function申明的函数可以修改this

    this指向是js中经常容易出错的地方。箭头函数的this指向是固定的,一般都是指向父作用域,默认指向window,不能在apply、call、bind中改变this的指向。普通函数的this指向不是固定的,有可能根据传入的对象改变。

    console.log('this1', this); // 指向window
    let fn3 = () => {
        console.log('this2', this); // 指向window
    }
    fn3.call({x: 'y'}); // 传入新的对象
    // fn3.apply({x: 'y'});
    let fn4 = function() {
        console.log('this3', this); // 指向{x: 'y'}
    }
    fn4.call({x: 'y'});
    

不适用的场景

  1. 对象的方法,不建议使用箭头函数

    let obj = {
        key: 'key',
        getKey: () => {
            return this.key;
        },
        getKey2() {
            return this.key;
        }
    };
    obj.getKey(); // this指向window,返回值取决于window中是否有对应的属性
    obj.getKey2(); // this指向obj,返回 'key'
    
  2. 对象的原型的方法,不建议使用箭头函数

    每个对象都有原型,原型也是一个对象,因此也不能添加箭头函数的方法

    let obj = {
        key: 'key'
    };
    obj.__proto__.getKey = () => {
        console.log('this', this); // this指向window
        return this.key;
    }
    obj.getKey();
    
  3. 箭头函数不能用作构造函数

    定义一个构造函数可通过函数定义或者使用class定义一个类。箭头函数不能用作构造函数,可使用普通函数

    let fn5 = (userName, passwd) => {
        this.userName = userName;
        this.passwd = passwd;
    }
    let f1 = new fn5('张三', '123'); // fn5 is not a constructor
    console.log(f1.userName);
    let fn6 = function (userName, passwd) {
        this.userName = userName;
        this.passwd = passwd;
    }
    let f2 = new fn6('张三', '123');
    console.log(f2.userName); // 张三
    
  4. 监听事件中需要使用this时不建议使用箭头函数

    比如在addEventListener中,如果要在回调函数中使用this,那么就不建议使用箭头函数,而是应该普通函数,更好的是使用已定义的函数名,便于回收事件监听,避免可能的内存泄漏。

    dom.addEventListener('click', () => {
        console.log('this', this); // this指向window
    })
    
  5. Vue的生命周期以及methods中的方法不建议使用箭头函数

    页面中创建的Vue实例,本质上来说也就是一个对象,其生命周期就是对应的属性,methods也是一个对象。在Vue的生命周期或者methods中使用箭头函数,则this的指向将不是当前Vue实例,而是window对象,如果在方法中使用了this,则可能会抛出错误。

    export default {
        mounted() {},
        // mounted: () => {}
        methods: {
            getKey() {},
            // getKey: () => {}
        }
    }
    

总结

  • 箭头函数有优点,也有缺点,不可盲目使用,一定要清楚的知道为什么要使用箭头函数,为什么不能使用箭头函数
  • 箭头函数可解决this指向,也可能带来this指向问题

原创不易,转载请注明出处