ES6+新增常用内容总结(四)

369 阅读6分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

箭头函数

  在ES6中新增了箭头函数,相对于传统函数来讲,箭头函数在写法上更加的简洁方便,
  而且箭头函数在this方面也进行了改进,今天我们就来看看ES6中的箭头函数和箭头函数中的this

箭头函数的写法

再看箭头函数的写法之前,我们先看一下常规函数的写法,JS中的函数由function关键字,params参数和被花括号包裹的函数体所组成,为了区分我们先把这样的函数,叫做常规函数,常规函数既可以用声明式写法,也可以用赋值的写法:

声明式写法
    function testA(a){ 
        console.log(a)
    }
    testA('我是a')
赋值的写法
    let testB = function(b){
        console.log(b)
    }
    testB('我是B')

看完常规函数的写法后,我们一起来看看箭头函数的写法,定义箭头函数语法上要比常规函数简洁的多,ES6中允许使用箭头 => 来定义箭头函数,箭头函数省去了function关键字,函数的参数放在 => 前面的括号中,函数体跟在=>后面的花括号中,下面让我们来看看箭头函数的写法,

//常规函数
    let testB = function(msg){
        console.log(msg)
    }
    testB('我是常规函数')
// 箭头函数
    let testB = (msg)=>{
        console.log(msg)
    }
     testB('我是箭头函数')

这样对比看来箭头函数在写法上是不是比常规函数更改简洁和方便,不过箭头函数在写法还有一些规则,让我一起来看一下,我们从箭头函数的参数和函数体两个方面来看

箭头函数的参数

  1. 如果箭头函数没有参数,那么直接写一个空括号即可
let fun1 = () => { console.log('我是没有参数的'); };
  1. 如果箭头函数的参数只有一个,那么可以省去包裹参数的括号,如果有多个参数的话,就需要加括号了,并且每个参数用逗号分隔
//一个参数的
    let fun1 = msg => { console.log(msg); };
    fun2('我是有一个参数的')
// 多个参数的
    let fun1 = (msg,msg1,msg2) => { console.log(msg,msg1,msg2); };
    fun2('我是','有''多个参数的')

箭头函数的函数体

  1. 如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的JS表达式,可以省去函数体的大括号{ }和return,如果函数体没有{ }的话箭头函数会帮你return的,例如:
   常规函数的写法:
     // 返回变量
     let fun = function(val){
         return val
     }
     // 返回表达式
     let sum = function(num1, num2) { 
         return num1 + num2; 
     };
     
   箭头函数的写法:
    //返回变量
        let fun = val => val; 

    //返回表达式
        let sum = (num1, num2) => num1 + num2; 

  1. 如果箭头函数的函数体只有一句代码,就是返回一个对象,可以像下面这样写:
正确写法:
    let item = id => ({ id: id, name: "Temp" }); 
错误写法:
    let item = id => { id: id, name: "Temp" };

原因是因为对象的大括号会被箭头函数解析为函数体的大括号,所以会报错
  1. 如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void关键字
    let fun = () => void noRerurn();

箭头函数和常规函数的不同之处

我们看完上边箭头函数的写法可以看出,箭头函数在写法上比常规函数更加的简洁和清晰,相对来说箭头函数在写法上简洁和清晰,不太方便我们去读代码,接下来让我继续看一下箭头函数相对于常规函数还有那些不同

箭头函数没有原型属性(prototype)

// 箭头函数 
let a = () => {};  console.log(a.prototype); 
    // undefined 
// 普通函数 
function a() {};  console.log(a.prototype); 
    // {constructor:f}。

箭头函数this指向不同

在常规函数中,this是指向调用它的对象。如果用作构造函数,this指向创建的对象实例。而箭头函数本身没有this,箭头函数的this指向是在定义时继承第一个外层函数的this,所以,箭头函数中的this指向在被定义的时候就已经确定,并且之后永远不会改变

注意:箭头函数中的this是在定义时就被指向的而不是在调用时 切记!!!

let obj = { 
    a: 10, 
    b: () => { 
        console.log(this.a); // undefined 
        console.log(this); 
        // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 
    }, 
    c: function() { 
        console.log(this.a); // 10 
        console.log(this); // {a: 10, b: ƒ, c: ƒ} 
    } 
 }
  obj.b();
  obj.c();

call | apply | bind 无法改变箭头函数中this的指向

call | apply | bind方法可以用来修改函数执行时this的指向,但是箭头函数的this是在定义时就被指向了,而且是永远无法修改的,所以这些方法也无法修改箭头函数的this指向

let name = 'Kobe Bryant'; 
let fun = () => { 
    console.log(this.name) 
}; 
fun(); // Toney 
fun.call({ name: 'James' }); // Kobe Bryant 
fun.apply({ name: 'Wade' }); // Kobe Bryant 
fun.bind({ name: 'Jordan' })(); // Kobe Bryant

箭头函数不能作为构造函数使用

构造函数是通过new关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定this的过程,而箭头函数没有自己的this。创建对象过程,new 首先会创建一个空对象,并将这个空对象的__proto__指向构造函数的prototype,从而继承原型上的方法,但是箭头函数没有prototype。因此不能使用箭头作为构造函数,也就不能通过new操作符来调用箭头函数

    let People = (name, age) => { 
        this.name = name; 
        this.age = age; 
    }; 
    let p = new People('Kobe Bryant', 41); //报错 People is not a constructor

image.png

箭头函数中没有arguments

argument是JavaScript中的一个关键字,用于指向调用者传入的所有参数。在箭头函数中如果要拿到传入的所有参数,需要用到rest参数(...变量名)

    // 普通函数 
    function A(a){ 
        console.log(arguments); 
    } 
    A(1,2,3,4,5,8); // [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ] 
    // 箭头函数 
    let B = (b)=>{ 
        console.log(arguments); 
    } 
    B(2,92,32,32); // Uncaught ReferenceError: arguments is not defined 
    // rest参数... 
    let C = (...c) => { 
        console.log(c); 
    } 
    C(3,82,32,11323); // [3, 82, 32, 11323]

箭头函数不能当做Generator函数,不能使用yield关键字

箭头函数注意事项和适用以及不适用的场景

注意事项

  1. 箭头函数一条语句返回对象字面量,需要加括号
  2. 箭头函数在参数和箭头之间不能换行
  3. 箭头函数的解析顺序相对 || 靠前
  4. 箭头函数的this指向是在定义时,而不是调用时
  5. 如果外层的普通函数的this指向发生改变,箭头函数的this跟着会发生改变

适用场景

  1. 简单的函数表达式,得出唯一的 return 返回值,函数内部无 this 引用
  2. 内部函数需要借助bind调用外部函数的this时。
  3. 函数的参数操作需要用数组的方法时

不适用场景

  1. 执行语句比较多、需要用到递归、引用函数名以及事件绑定、解绑定。
  2. 箭头函数的this意外指向和代码的可读性

结语

关于ES6的箭头函数,我这里总结的还是不太全,如果有错误希望各位大佬多多指教,同时也希望这篇文章能帮助到一些同学学到一些东西,如果感觉写的还不错,能否给点个赞,也欢迎大家评论区讨论和探讨,谢谢大家