JS箭头函数 什么时候用 ,什么时候不能用,我总结出了4点

8,428 阅读3分钟

前言

大家好,我是zz,相信大家平时在码代码中,都知道箭头函数的用法,但是在面试中,让他讲讲箭头函数的用法,都讲的很片面,通过阅读本文,我们带大家系统的总结下箭头函数,形成自己的箭头函数的知识结构,这样在面试是面试官问到就小菜一碟。

箭头函数的定义

箭头函数定义包括一个参数列表(零个或多个参数,如果参数个数不是一个的话要用 ( .. ) 包围起来),然后是标识 =>,函数体放在最后。

箭头函数与普通函数的区别

箭头函数

let arrowSum = (a, b) => { 
   return a + b
}

普通函数

let zz = function(a, b){
    return a + b
}

箭头函数的用法

我们打印fn函数的原型,我们会发现箭头函数本身没有this;

var fn = (a, b) => {
    console.log(this, fn.prototype);
    //window, undefined
        var fn2 = () => {
            console.log(this, '测试');
            // window
        };
        fn2();
}
fn()

箭头函数的arguments 我们会发现这样写会报语法错误

var fn = (a) => {
    console.log(a.arguments)
}
fn();
// TypeError: Cannot read property 'arguments' of undefined

我们换一种情况,我们看代码会发现箭头函数argemnets指向了上一个函数

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


var z = function(a){
    console.log(arguments);
    bb();
    function  bb() {
        console.log(arguments);
        let ac = () => {
            console.log(arguments);
            //arguments 指向第二层函数
        };
    ac();
    }
}
z()

什么时候不能用箭头函数

1. 通过构造函数调用

let Foo = () =>  {
		
}
let result  = new Foo();
//TypeError: Foo is not a constructor

2. 需要使用prototype

let foo = () =>  {
		
}
console.log(foo.prototype)
//underfind

3. 没有super

连原型都没有,自然也不能通过 super 来访问原型的属性,所以箭头函数也是没有 super 的,不过跟 this、arguments、new.target 一样,这些值由外围最近一层非箭头函数决定

总结

  • 如果你有一个简单语句的在线函数表达式,其中唯一的语句是return某个计算出的值,而且这个函数内部没有this引用,且没有自身引用(比如递归,事件绑定/解绑定),且不会要求函数执行这些,那么我们可以安全的把它重构为=>箭头函数

  • 如果你的内层函数表达式依赖于它的函数中调用 let self= this 或者.bind(this)来确保适当的this绑定,那么内层函数表达式可以转换为=>箭头函数

  • 如果你的内函数表达式依赖于封装函数像 let args = Array.prototype.slice.call (arguments)的词法复制,那么这个内层函数表达式应该可以安全的转换=>箭头函数

  • 所有的其他情况——函数声明,较长的多函数表达式,需要词法名称标识符(比如递归 , 构造函数)的函数,以及任何不符合以上几点特征的函数一般都应该避免=>箭头函数

关于this arguments 和 super 的词法绑定。这是利用es6的特性来修正一些常见的问题,而不是bug或者错误。