ES6(第三部分)

77 阅读4分钟

本人已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

大家好,我是掘金新用户小钻风头领,今天是我正式更文的第四天;

五、函数优化

5.1、参数展开/rest参数/剩余参数/可变参数

​ 剩余参数是将剩下的参数收集起来放在一个数组中。

5.1.1、案例1:rest参数

<script type="text/javascript">

    // 函数展开/可变参数
    function info(num1,num2,...args){
        alert(num1);
        alert(num2);
        alert(args);		// 30,40,50,args是一个数组,以数组的方式接收函数中剩余的参数
    }

    info(10,20,30,40,50);

</script>

==作用:收集函数参数中剩余的参数,必须作为最后一个参数位置。==

5.1.2、案例2:展开数组

<script type="text/javascript">

    let arr1 = [1,2,3];
    let arr2 = [4,5,6];

    let arr3 = [...arr1 , ...arr2];
    alert(arr3);

</script>

5.2、函数参数默认值

5.2.1、之前如何实现

​ 在ES6之前是不提供函数默认参数值的实现,只能通过变通写法。

<script type="text/javascript">

    // 假设num2的默认值是2
    function add(num1, num2){
        if (!num2){
            num2 = 2;
        }
        return num1 + num2;
    }

    console.info(add(10)); // 12
    console.info(add(10 , 8)); // 18

</script>

5.2.2、案例

<script type="text/javascript">

    // 假设num2的默认值是2
    function add(num1, num2 = 2){	// 直接在参数上直接赋值即可
        return num1 + num2;
    }

    console.info(add(20)); // 22
    console.info(add(20 , 8)); // 28

</script>

5.3、箭头函数

5.3.1、之前定义函数

<script type="text/javascript">

    // 使用function关键字定义函数.
    function show(username){	
        console.info("Hello:" + username);
    }

    show("张三");

</script>

5.3.2、案例1:单个参数

<script type="text/javascript">

    let show = username => console.info("Hello:" + username);

    show("李四");

</script>
/**
	语法:
		let 函数名 = 参数名 => 函数体
*/

5.3.3、案例2:多个参数

<script type="text/javascript">

    let add = (num1,num2) => console.info(num1 + num2);

    add(10,20);

</script>
/*
	多个参数需要使用【()】小括号给括起来.
*/

5.3.4、案例3:没有参数

<script type="text/javascript">

   let info = () => console.info("打印信息");

   info();

</script>
/*
	即使函数没有参数,也需要使用【()】小括号来去表示,来去代表参数部分
*/

5.3.5、案例4:函数体有多条语句

<script type="text/javascript">

    let length = (str) => {
        if(str){
            return str.length;
        }
        return 0;
    }

    console.info(length("123"));

</script>
/*
	函数体有多条语句时候,需要使用【{}】花括号包裹起来
*/

5.3.6、案例5:关于函数体的其他说明

如果函数中有单个表达式或语句:那么==1、函数体外部的{}是可以省略的;2、使用return可以省略。==

5.3.6.1、细节1:如果是单个表达式,则自带return

<script type="text/javascript">

    // 求两个数的和
    let sum = (num1 , num2) => {
        return num1 + num2;
    }

    alert(sum(10,30));

</script>
<script type="text/javascript">

    // 求两个数的和
    let sum = (num1 , num2) => num1 + num2;		// 自带return

    alert(sum(10,30));

</script>

5.3.6.2、细节2:如果是单条语句,花括号可以省略

<script type="text/javascript">

    // 求两个数的和
    let sum = (num1 , num2) => {
        alert(num1 + num2);
    }

    sum(10,25);

</script>
<script type="text/javascript">

    // 求两个数的和
    let sum = (num1 , num2) => alert(num1 + num2);

    sum(10,25);

</script>

5.3.7、箭头函数中的this

​ 在普通函数中的this指向的是谁调用了这个函数,那么这个函数中的this就是谁。

​ ==箭头函数不绑定this,换句话说,箭头函数是没有自己的this,如果在箭头函数中使用this,那么this指向的是箭头函数所在定义位置中的this,也就是说箭头函数定义在哪里,箭头函数中的this就指向谁。通俗一点说,箭头函数里的this指的是定义这个箭头函数时外层代码的this。==

5.3.7.1、案例1

  • ES5代码

    <script type="text/javascript">
    
        function Person(){
            this.username = "HelloWorld";
            this.run = function(){
                console.info(this.username + "在跑步");
            }
        }
    
        var p1 = new Person();
    	// HelloWorld在跑步,原因是run方法是p1对象调用者,那么run方法中的this指向的就是p1这个实例对象,而p1的实例对象中有username属性是HelloWorld.
        p1.run();				
    
        var p2 = p1.run;
    	// undefined在跑步 , 原因是run方法是window对象直接调用的,那么run方法中的this指向的就是window,而window是没有username属性的,所以是undefined。
        p2();
    
    </script>
    
  • ES6代码

    <script type="text/javascript">
    
        function Person(){
            this.username = "HelloWorld";
            this.run = () => {
                console.info(this.username + "在跑步");
            }
        }
    
        var p1 = new Person();
    	// HelloWorld在跑步
        p1.run();
    
        var p2 = p1.run;
    	// HelloWorld在跑步,可以看到,更改了run方法的调用,但是依然没有影响到run方法中的this的指向
        p2();
    
    </script>
    
    <script type="text/javascript">
    
        function Person(){
            this.username = "HelloWorld";
            this.run = () => {
                console.info(this.username + "在跑步");
            }
        }
    
    	// 先调用一下
        Person();
    
        var p2 = run;
    	// HelloWorld在跑步
        p2();
    
    </script>
    

    ==可以发现:箭头函数中的this的指向就是:箭头函数定义在哪里,那么箭头函数中的this指向就是哪里,箭头函数中的this就是外层代码this的引用。本例:箭头函数中的this就是Person函数中的this。==

5.3.7.2、案例2

  • ES5代码

    <script type="text/javascript">
    
        var person = {username: "HelloWorld"};
    
        function fn1(){
            return function(){
                console.info(this.username);
            }
        }
    
        var fn = fn1.call(person);
        fn();	// undefined
    </script>
    
  • ES6代码

    <script type="text/javascript">
    
        var person = {username: "HelloWorld"};
    
        function fn1(){
            return ()=> {
                console.info(this.username);
            }
        }
    
        var fn = fn1.call(person);
        fn();	// HelloWorld
    </script>
    

5.3.7.3、案例3

  • ES5代码

    <script type="text/javascript">
    
       var obj = {
           age: 20,
           run: function(){
               console.info(this.age);
           }
       };
    
       obj.run(); // 20
    </script>
    
  • ES6代码

    <script type="text/javascript">
    
       var obj = {
           age: 20,
           run: ()=>{
               console.info(this.age);
           }
       };
    
       obj.run();  // undefined
    </script>
    

5.4、对象的函数属性简写

5.4.1、之前写法

<script type="text/javascript">

    let person = {
        username : "张三",
        run: function(address){	 // 属性:function函数
            console.info(this.username + "在" + address + "跑步");
        }
    };

    person.run("操场");

</script>

5.4.2、箭头函数写法

<script type="text/javascript">

    let person = {
        username : "张三",
        run: (address) => {
          console.info(person.username + "在" + address + "跑步")// 注意这里不能用this.username
        }
    };

    person.run("操场");

</script>

5.4.3、对象的函数属性写法

<script type="text/javascript">

    let person = {
        username : "张三",
        run(address){				// 在对象中直接定义函数。
            console.info(this.username + "在" + address + "跑步");
        }
    };

    person.run("操场");

</script>

5.4.4、对象的其他简单写法

  • 以前写法

    <script type="text/javascript">
    
        let name = "HelloWorld";
        let age = 23;
    
        let person = {name:name , age:age};
    
        console.info(person.name + "," + person.age);
    
    </script>
    
  • ES6新写法

    ​ 键值对出现了重复,ES6 中,如果属性名和和所分配的变量名一样,就可以从对象属性中删掉这些重复的变量名称。

    <script type="text/javascript">
    
        let name = "HelloWorld";
        let age = 23;
    
        let person = {name, age};
    
        console.info(person.name + "," + person.age);
    </script>
    

5.5、箭头函数结合解构表达式

5.5.1、之前写法

<script type="text/javascript">

    let person = {
        username: "张三",
        age: 12
    }

	// 打印对象
    function info(obj){
        console.info("姓名是:" + obj.username);
    }

    info(person);

</script>

5.5.2、改进1:使用箭头函数

<script type="text/javascript">

    let person = {
        username: "李四",
        age: 12
    }

    let info = (obj) => console.info("姓名是:" + obj.username);

    info(person);

</script>

5.5.3、改进2:使用箭头函数+解构表达式

<script type="text/javascript">

    let person = {
        username: "王五",
        age: 12
    }

    let info = ({username:name}) => console.info("姓名是:" + name);

    info(person);

</script>

5.6、map和reduce

5.6.1、map:映射

5.6.1.1、说明

map():该函数的参数接收一个函数fn,将原数组中的所有元素用这个fn函数处理后放入新数组返回。

5.6.1.2、案例1

​ ==给定一个数组,将数组中的每个元素求平方然后组成一个新的数组==

<script type="text/javascript">
    let arrs = [1,2,3,4,5,6];

    let arrsNew = arrs.map(item => {
        return item * item;
    });
    console.info(arrsNew);
</script>
<script type="text/javascript">

    let arrs = [1,2,3,4,5,6];

    let arrsNew = arrs.map(item => item * item); // 使用箭头函数改造一下
    console.info(arrsNew);

</script>

5.6.2、reduce:合并/汇总

5.6.2.1、说明

reduce() :该函数的参数接收一个函数fn(必须)和一个初始值value(可选),fn函数接收两个参数:

  • 第一个参数是上一次reduce处理的结果

  • 第二个参数是数组中要处理的下一个元素

    reduce() 会从左到右依次把数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数。

5.6.2.2、案例1:没有初始值

​ ==给定一个数组,求数组中所有元素的和==

<script type="text/javascript">

    let arrs = [1,2,3,4,5,6];

    let result = arrs.reduce((a,b) => {
        return a + b;
    });

    console.info(result);	// 21
</script>

5.6.2.3、案例2:有初始值

​ ==给定一个数组,求数组中所有元素的和,指定一个初始值10==

<script type="text/javascript">

    let arrs = [1,2,3,4,5,6];

    let result = arrs.reduce((a,b) => {
        return a + b;
    },10);

    console.info(result);
</script>

5.7、filter:过滤

5.7.1、说明

​ 用于把数组中的某些元素过滤掉,返回剩下的符合条件的元素。实现方式是:filter函数的参数接收一个函数,然后把传入的函数作用于每一个元素,然后根据返回值是true和false决定保留还是丢掉该元素。

5.7.2、案例

​ 给定一个数组,过滤掉不能被3整除的数,然后返回新数组。

<script type="text/javascript">

    // 过滤掉不能被3整除的数
    let arrs = [12,34,56,41,24];

    let result = arrs.filter(function(item){
        return item % 3 == 0;
    });

    console.info(result);

</script>
<script type="text/javascript">

    // 过滤掉不能被3整除的数
    let arrs = [12,34,56,41,24];

    let result = arrs.filter(item => item % 3 == 0);	// 使用箭头函数实现

    console.info(result);

</script>

5.8、forEach:迭代

5.8.1、说明

​ 用来遍历数组

5.8.2、案例

<script type="text/javascript">

    // 过滤掉不能被3整除的数
    let arrs = [12,34,56,41,24];

    arrs.forEach(function(item,index){
        alert(index + ", " + item);
    })

</script>
<script type="text/javascript">

    // 过滤掉不能被3整除的数
    let arrs = [12,34,56,41,24];

    arrs.forEach((item,index) => {alert(index + ":" + item)});

</script>