• ES6中的函数(函数参数、默认值、箭头函数)


    一、函数参数的解构赋值

    function foo([a,b]) {
          console.log(a+b); // 3
    }
    foo([1,2]);
    
    function bar({c,d}) {
          console.log(c+d); // 7
    }
    bar({c:3,d:4});
    

    二、函数默认参数

    2.1 基本方式

    function foo(a,b=10) {
          console.log(a+b); // 1+10=11 => 11
    }
    foo(1);
    
    function bar([a,b=10]) {
          console.log(a+b); // 3+10=13 => 13
    }
    bar([3]);
    
    function fn({a,b=10}) {
          console.log(a+b); // 5+10=15 => 15
    }
    fn({a:5});
    

    2.2 可以预设实参

    function bar([a,b=10] = [20]) {
          console.log(a+b); // 20+10=20 => 20
    }
    bar();
    
    function fn({a,b=10} = {a:20}) {
          console.log(a+b); // 20+10=30 => 30
    }
    fn();
    

    2.3 预设实参的覆盖

    但如果传入实参,那么就会把预设的覆盖。

    function bar([a,b=10] = [20]) {
          console.log(a+b); 
    }
    bar([100]); // 100+10 => 110
    bar([100, 200]); // 100+200 => 300
    
    function fn({a,b=10} = {a:20}) {
          console.log(a+b); 
    }
    fn({a:100}); // 100+10 => 110
    fn({a:100,b:200}); // 100+200 => 300
    

    2.4 默认值可以是函数

    function getB() {return 10};
    function foo(a,b=getB()) {
          console.log(a+b); // 1+10=11 => 11
    }
    foo(1);
    

    三、箭头函数

    语法:参数=>函数体

    • 单行语句可以省略花括号,如果还是return语句,还可以省略return关键字。
    • 多行语句不可以省略花括号。
    • 一个参数可以省略圆括号,多个参数不可以省略圆括号。
    // 传统写法(无参数)
    let fn = function() {return 1;}
    // 箭头函数写法
    let fn = ()=>(1);
    let fn = ()=>1;
    
    // 传统写法(一个参数)
    let bar = function(a) {return 2};
    // 箭头函数写法
    let bar = (a)=>2;
    let bar = a=>2;
    
    // 传统写法(多个参数)
    let fn = function(a,b) {return a+b};
    // 箭头函数写法
    let fn = (a,b)=>a+b;
    
    // 多行语句时不可省略花括号
    let br = function(a,b) {
          let res = a+b;
          return res;
    }
    let br = (a,b)=>{
          let res = a+b;
          return res;
    }
    

    四、箭头函数的特点

    4.1 箭头函数内的this固定化

    函数体内的this对象是固定的,就是定义时所在的对象,而不是使用时所在的对象。

    • 普通函数内的this情境
    var id = 10;
    let obj = {
          id: 15,
          fn: function(){
                setTimeout(function(){
                      alert(this.id); // 10
                 },1000)
          }
    }
    obj.fn();
    

    分析:1秒后执行window.setTimeout(),this指向window,因此返回的结果是全局下的id:10

    如果想要获取obj内的id,一般采用_this = this的办法。

    var id = 10;
    let obj = {
          id: 15,
          fn: function(){
                _this = this; // 调用后,这里的this指向obj
                setTimeout(function(){
                      alert(_this.id); // 15
                 },1000)
          }
    }
    obj.fn();
    
    • 箭头函数内的this情境(1)
    var id = 10;
    let obj = {
          id: 15,
          fn: function(){
                setTimeout(()=>{
                      alert(this.id); 
                 },1000)
          }
    }
    obj.fn(); // 15
    obj.fn.call({id:123}); // 123
    

    分析:setTimeout()中用了箭头函数,因此箭头函数内的this对象就固定在父级作用域下的this上。(这里就是函数fn)
    也就是说,fn函数内的this指向了谁,箭头函数的this就指向了谁。
    当被obj调用时,fn函数的this指向了obj,所以返回obj下的id:15
    当被对象{id:123}调用时,fn函数的this指向了{id:123},所以返回该对象下的id:123

    • 箭头函数内的this情境(2)
    var id = 10;
    let obj = {
          id: 15,
          fn: ()=>{
                setTimeout(()=>{
                      alert(this.id); 
                 },1000)
          }
    }
    obj.fn(); // 10
    obj.fn.call({id:123}); // 10
    

    分析:当obj下的fn方法也用箭头函数,那么就会沿着作用域链往上找它的父级作用域的this,这里找到的是全局window。
    于是this就固定在了window上,不管谁去调用它,它都只会返回window下的id:10

    4.2 箭头函数没有arguments对象

    普通函数在初始化的过程中,会产生一个arguments对象用来保存实参。
    但是在箭头函数中是不存在的,如果要使用实参列表,那么用rest参数来代替。

    // 普通函数
    let fn = function(a,b,c) {
          console.log(arguments);
    }
    fn(1,2,3);
    
    // 箭头函数
    let bn = (...args)=> {
          console.log(args);
    }
    bn(1,2,3);
    

    4.3 箭头函数不可以用new实例化

    let Person = (name)=> {
          this.name = name;
    }
    let p = new Person('mm'); // TypeError: Person is not a constructor
    

    4.4 箭头函数不可以使用yield命令

    五、箭头函数的使用场景

    • 当我们要维护一个this上下文环境时,就可以用箭头函数。
    var id = 10;
    let obj = {
          id: 15,
          fn: function(){
                setTimeout(()=>{
                      alert(this.id); 
                 },1000)
          }
    }
    obj.fn(); // 15
    
    • 定义对象方法,且要用到this时,不要用箭头函数!
    let person = {
          name: 'mm',
          say: ()=>{
                console.log(this.name); // 'gg'
          }
    }
    var name = 'gg';
    person.say();
    
    • 监听DOM事件时,不要用箭头函数!
    let box = document.getElementById('box');
    box.addEventListener('click', function(){
          if(this.classList!='red') {
                this.classList = 'red';
          }else {
                this.classList = 'green';
          }
          console.log(this); // box
    });
    
    box.addEventListener('click', ()=>{
          if(this.classList!='red') {
                this.classList = 'red';
          }else {
                this.classList = 'green';
          }
          console.log(this); // window
    });
    

    六、总结

    1. 函数参数也可以解构赋值。
    2. 函数参数可以设置默认值,可以预设实参。
    3. 函数参数的默认值可以是函数调用。
    4. 箭头函数的语法:参数=>函数体
    5. 箭头函数的this是固定的,指向了父级作用域的this。
    6. 箭头函数没有arguments,可以用rest参数代替。
    7. 箭头函数不可以new实例化。
    8. 箭头函数不可以使用yield命令
  • 相关阅读:
    Android Studio移动鼠标显示悬浮提示的设置方法
    解决adb push时出现的"Read-only file system"问题
    VIM常见用法总结
    忘记oracle的sys用户密码怎么修改以及Oracle 11g 默认用户名和密码
    Oracle中session和processes的设置
    ssh相关原理学习与常见错误总结
    如何利用Oracle VM Templates 在几分钟内部署Oracle Real Application Clusters (RAC)
    Oracle导入导出常用命令
    Tomcat 到底依赖JRE还是JDK
    截取url参数值
  • 原文地址:https://www.cnblogs.com/buildnewhomeland/p/12836275.html
Copyright © 2020-2023  润新知