• 深入理解箭头函数和传统函数的区别


    深入理解箭头函数和传统函数的区别

    箭头函数是从其它语言借鉴过来的一种表达形式,如java,c++等都有类似的表达形式,也被称为lambda表达式,即匿名函数。
    那么js箭头函数是什么呢?它和传统函数又有什么区别你?

    一、更为简洁的表现形式
    // 传统函数
    const fn_a = function(a){
        return a
    }
    console.log(fn_a(1))   //打印 1
    // 箭头函数
    const fn_b = b => b
    console.log(fn_b(1));   //打印 1
    

    箭头函数函数相对于传统函数,它有着更简洁的表现形式,除了function的定义之外,连{ ... }和return都省略掉了。
    不同的场景下箭头函数还有着不一样的表现形式:

    // 有内部逻辑时
    x => {
        x = "我想变化一下";
        return x;
    }
    
    // 多个参数
    (x, y) => x + y
    
    // 没有参数
    () => "我的入参呢?"
    
    二、没有arguments
    // 传统函数
    const a = function(){
        return Array.from(arguments)
    }
    console.log(a(1,2,3));   //输出:[1,2,3]
    // 箭头函数
    const b = () => Array.from(arguments)
    console.log(b(1,2,3));  // 报错,arguments is not defined
    
    三、不能用作Generator函数
    // 传统函数
    const a = function*(){
        return "我想成为Generator函数!"
    }
    console.log(a());   // 输出a{<suspended>}
    
    // 箭头函数
    const b = *() => "我想成为Generator函数!";  
    // 报错:Unexpected token '*'
    const b = ()* => "我想成为Generator函数!"; 
    // 报错:Unexpected token ')'
    

    箭头函数是无法定义成Generator函数的,因此yield也是无法使用的。

    四、不能使用new命令
    // 传统函数
    const A = function(){
        console.log("A");
    }
    const aa = new A();
    
    // 箭头函数
    const B = () => {
        console.log("B");
    }
    const bb = new B();  //报错:B is not a constructor
    
    五、不能调用apply、call
    // 箭头函数
    const man = {
        sex:"男",
        a: function(){
            console.log(this.sex);
        },
        b: () => {
            console.log(this.sex);
        },
    
    }
    
    man.a.apply(man);   //男
    man.b.apply(man);   //undefined
    
    man.a.call(man);   //男
    man.b.call(man);   //undefined
    

    传统函数可以通过apply、call改变函数的this指向,而箭头函数不可以。

    六、this指向(重点)

    这是传统函数和箭头函数最主要的差异。也是箭头函数出来的意义所在。
    我们在例子中去看它们差异:

    var context = "window"
    var obj = {
        context: "obj",
        fn: function(){
            console.log(this.context);  //"obj"
            const _this = this;
            function a(){
                console.log(this.context);  //"window"
                console.log(_this.context);  //"obj"
            }
            const b = () => {
                console.log(this.context);  //"obj"
                console.log(_this.context);  //"obj"
            }
            a();
            b();
        }
    }
    obj.fn();
    

    在传统函数执行的时候,this的指向是根据上下文执行环境来确定的,上述例子我们分步看this:
    ①:obj.fn();从全局上下文栈进入obj.fn的执行栈,由于是从obj引用fn上下文栈,因此此时this是obj对象;
    ②:obj.fn执行过程中创建了上下栈a;
    ③:执行a方法,执行时由于是在全局环境中,所以此时this指向的是window。


    总结:
    传统函数的创建是会开辟一个栈内存的,因此它的this指向是根据栈内存被调用时所在上下文环境所决定的,而箭头函数是不会开辟一个栈内存的,它不像传统函数是一个引用类型,因此它的this指向也是在它被创建时候就固定了,固定指向创建它的内存块的上一层内存块,如:window引用了b内存,b内存创建了箭头函数,此时this指向就是window。
    这也是箭头函数无法被apply、call改变this指向,也不能执行new命令,因为这些都是服务于有内存指向的引用类型。

  • 相关阅读:
    先进的无人机GPS/GNSS模块解决方案
    Homography详解&&在MVSNet中的应用
    mysql explain extra值枚举
    数据驱动的软件智能化开发| ChinaOSC
    steam搬砖还能不能做,能赚到钱吗?
    ✔ ★【备战实习(面经+项目+算法)】 10.21学习时间表(总计学习时间:5h30min)(算法刷题:7道)
    纽约纳斯达克大屏投放受众群体有哪些-大舍传媒
    ftp靶机_获取shell
    【AI】Python 实现 KNN 手写数字识别
    用于设计 CNN 的 7 种不同卷积
  • 原文地址:https://www.cnblogs.com/YmmY/p/15974500.html