zoukankan      html  css  js  c++  java
  • ES6函数比对ES5函数

    简介

    这里只做简单的ES6函数与ES5函数对比,把ES6函数中新增的方法或者用法介绍一下。方便大家学习、记忆。随着社会发展,浏览器肯定会在不久全部支持ES6语法,因为现在的IE8用户都很少了,做web前端将不再受此束缚!

    函数参数的默认值

    其他语言已经支持函数参数默认值,咱们Js也不会落后的。例:

    //es6写法
    /**
     * @a {number} 默认值10
     * @b {number} 默认值20
     * */
    function fn(a=10,b=20){
        console.log(a,b);
    }
    fn();//没有传递参数
    fn(1,3);//传递了参数
    
    //es5写法
    /**
     * @a {number} 默认值10
     * @b {number} 默认值20
     * */
    function fn(a, b) {
      a = a || 10;//设置默认值
      b = b || 20;//设置默认值
      console.log(a, b);
    }    
    1. 先说说es5写法这种写法,如果a传递的是false或者(求值为false的值) 则a会使用默认值10,这样代码就没有按照我们期望的那样去执行。
    //修改es5写法让它实现类似于es6:
    //es5写法
    /**
     * @a {number} 默认值10
     * @b {number} 默认值20
     * */
    function fn(a, b) {
       a = a!==undefined?a:10;//设置默认值
       b = b!==undefined?b:20;//设置默认值
      console.log(a, b);
    }    
    1. es6写法如果传入undefined,将触发该参数等于默认值,其他值不会触发默认值。
    2. es6设置默认参数值,在函数体内不允许再次使用let或者const声明。例:
    /**
     * es6写法
     * @a {number} 默认值10
     * @b {number} 默认值20
     * */
    function fn(a=10,b=20){
        let a=100;//会报错哦!
        const b=20;//会报错哦!
        console.log(a,b);
    }
    1. 设置参数默认值会产生单独的作用域。
    /**
     * es6写法
     * 默认值会产生单独的作用域,作用域的代码也是按照先左后右顺序执行。
     * @a {number} 默认值10
     * @b {number} 默认值10+20
     * */
    function fn(a=10,b=a+20){//如果这里是(a=b+20,b=10)调用时a没有传递参数此时会报错!
        console.log(a,b);
    }
    //复杂的例子
    /*-----------一条华丽的分割线-------------*/
    
    /**
     * ----------默认值会产生单独的作用域-----------
     * 调用函数fn 时,未传递参数,【默认参数单独作用域】a值为undefined,b值为undefined。
     * 当执行b()函数时,则查找到a值为undefined,不在查找全局a。
     * 因此为结果为:a的值为: undefined
     * */
    var a='全局变量';
    function fn(a,b=function(){ console.log('a的值为:',a);}){
        b();
    }
    fn();//a的值为: undefined
    
    /**
     * ----------默认值会产生单独的作用域-----------
     * 调用函数fn 时,未传递参数,b值为undefined。
     * 当执行b()函数时,则寻找a值发现全局a。
     * 因此为结果为:a的值为: 全局变量
     * */
    var a='全局变量';
    function fn(b=function(){ console.log('a的值为:',a);}){
        b();
    }
    fn();//a的值为: 全局变量
    
    **
     * 现在再来理解一下这个。看看你能答对吗?
     * */
    var a = '小小坤';
    function fn(a, y = function() {a = '小小坤1';}) {
       var a = '小小坤2';
       y();
      console.log(a);
    }
    
    fn() // 答案是?
    console.log(a); // 答案是?
    1. 使用参数默认值时,函数不能有同名参数。
    function fn(a,a,b){
        console.log(a,b);//不报错
    }
    function fn(a,a,b=1){
        console.log(a,b);//报错
    }

    rest 参数

    ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。例:

    //es6写法
    /**
     * @b {arry} 参数列表
     *  
     * */
    function fn(...b){
        b.push('小小坤');
        console.log(b);
    }
    fn(1,'20');//[1, "20", "小小坤"]
    
    //es5写法
    /**
     * @a {number} 参数a
     * @b {number} 参数b
     * */
    function fn(a, b) {
       var arg=[].slice.call(arguments);
       arg.push('小小坤');
       console.log(arg);
    }

    需要注意的是:

    1. 函数length 属性不包含rest 参数
    (function(a) {}).length  // 1
    (function(...a) {}).length  // 0
    (function(a, ...b) {}).length  // 1
    1. rest 参数不可以这样使用,只能是最后一个参数
    function fn (a,...b,d){
       //会报错!    
    }

    箭头函数

    使用时注意事项:

    1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
    2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
    3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
    4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
    简单例子
    /*-----------例子--1------*/
    //es6写法
    var fn = n => n;
    
    //等同于es5 写法
    var fn = function(n) {
      return n;
    };
    /*-----------例子--2------*/
    //es6写法
    var fn = () => 5;
    // 等同于 es5 写法
    var fn = function () { return 5 };
    /*-----------例子--3------*/
    //es6写法
    var sum = (n1, n2) => n1 + n2;
    // 等同于es5 写法
    var sum = function(n1, n2) {
      return n1 + n2;
    };

    如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

    /*-----------例子--4------*/
    //es6写法
    var sum = (n1, n2) => { return n1+n2; }
    
    //由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
    // 报错
    let fn = id => { id: id, age: 18 };
    
    // 不报错
    let fn = id => ({ id: id, age: 18  });
    /*-----------例子--5------*/
    
    function fn() {
      setTimeout(() => {
        console.log('id:', this.id);
      }, 100);
    }
    
    var id = 21;
    
    fn.call({ id: 42 });
    // id: 42
    
    
    //ES5代码需要这样写
    function fn() {
      var _this=this;//存储this
      setTimeout(function() {
        console.log('id:', _this.id);
      }, 100);
    }
    var id = 21;
    fn.call({ id: 42 });
    /**
     *  上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在fn函数生成时,
     *  而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,
     *  这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),
     *  所以输出的是42。
     *  箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。
     * 
     *  另外,由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。
     * */
    1. this指向
    //this指向lib
    var lib={
        option:{
            name:'小小坤'
        },
        init(){
            this.click();
        },
        click(){
            setTimeout(()=>{
                console.log(this.option.name);
            },2000);
        }
    }
    lib.init();//小小坤
    1. 不能使用构造函数
    var des=(n)=>{this.n=n};
    new des(1);//des is not a constructor
    //因为没有this
    1. 没有arguments属性
    var des=(n)=>{console.log(arguments)};
    des();//arguments is not defined
    //可以这样使用
    var des=(...n)=>{console.log(n)};
    des(1,2,3,4,5);//[1,2,3,4,5]

    总结

    经过以上对比可以看出ES6写的代码会越来越少,代码质量也逐渐提升。比如默认参数,箭头函数,还有rest 参数,使用起来爽爆棚!没有在开发环境使用的ES6的同学我们也要抓紧学习啦!

  • 相关阅读:
    自旋锁和互斥锁区别
    NFS挂载Android文件系统
    查找文件命令
    make menuconfig出错解决方法
    专访Linux嵌入式开发韦东山操作系统图书作者--转
    Ubuntu进不入系统,一直停留在ubuntu图标画面(转)
    查看驱动打印信息
    aiku给你们最真心地学习建议--转
    SZ,RZ传送文件
    在Android下运行Linux平台编译的程序
  • 原文地址:https://www.cnblogs.com/xiaoxiaokun/p/8052426.html
Copyright © 2011-2022 走看看