ES6函数拓展,箭头函数及this指向,rest参数三个点

1.函数参数的默认值

ES6之前,不能为函数的参数设置默认值,只能在代码中进行判断

 //原来写法
      function show(a, b) {
    
    
          if (typeof b === "undefined") {
    
    
              b = 0;
          }
          console.log(a, b);//1 0
      }
      show(1);
 //ES6写法
      function show(a, b=0) {
    
    
          
          console.log(a, b);//1 0
      }
      show(1);
  //ES6写法错误写法 设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。
     function show(a=0,b ) {
    
    
         
         console.log(a, b);//1 undefined
     }
     show(1);

上述代码为什么不是输出0 undefined 呢?
设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。
因为1传给了形参a,发现a=0,但是a=0没有生效 ,仍然输出 a为1

函数的length属性为函数的参数个数。若设置了默认值,length的计数中是不计算设置了默认值的参数的。

function show(a,b) {
    
    
        console.log(show.length);//2
    }
    show(3,6);
 function show(a,b=0) {
    
    
        console.log(show.length);//1
    }
    show(3,6);

上述形参设置默认值,就不计入函数的参数所以为1,当你设置a=0时,函数的参数个数为0

作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。

等到初始化结束,这个作用域就会消失。

var a = 1;
function fn(a,b = a){
    
    
    console.log(b);//2
}
fn(2)

运行过程:传进去了一个参数2,这时括号里的a就为2, 因为(a,b = a)在同一个作用域,所以b=a=2
因为(a,b = a)在同一个作用域,所以它不会去外部继续寻找a的值

let a = 1;
function fn(b = a){
    
    
    let a = 2;
    console.log(b);
}
fn();//1

上述函数调用中,(b=a)是一个单独的作用域,a变量不存在,则会去外部寻找。

2.rest参数…

function sum(a, b) {
    
    
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );
虽然不会报错,但是多余的参数也不会起任何作用,
函数只会返回前俩个参数相加的结果。

Rest参数的操作符表示为3个点 … ,直白地讲,它的意思就是“把剩余的参数都放到一个数组中

举个例子,我们需要把所有的参数都放到数组args中:

function sumAll(...args) {
    
     //数组变量名为args
    let sum = 0;
    for (let arg of args) {
    
    //for   of 是遍历的一种方式
        sum += arg;
    }
    return sum;
}
alert(sumAll(1)); //1
alert(sumAll(1, 2)); //3
alert(sumAll(1, 2, 3));//6

2.1 基本用法

// 原来写法
     function fn(){
    
    
          for (var i = 0; i < arguments.length; i++) {
    
    
          console.log(arguments[i]);//1 3 4
          }
      }
      fn(1,3,4)*/
    //==============================
    //rest写法
     function fn(...v){
    
    
          for (var i = 0; i < v.length; i++) {
    
    
          console.log(v[i]);//1 3 4
          }
      }
      fn(1,3,4)

rest参数必须是最后一个正式参数。

//错误写法
    function fn(...v,a){
    
    
          for (var i = 0; i < v.length; i++) {
    
    
          console.log(v[i]);
          }
      }
      fn(1,3,4)
      //报错:Rest parameter must be last formal parameter  (Rest参数必须是最后一个形式参数)

2.2 rest参数和arguments对象的区别
arguments对象不是一个数组,只是一个类似数组的对象。不能使用数组的方法。

<script>
    function sort(...v){
    
    
    // return arguments.sort(); 报错 arguments.sort is not a function
    return v.sort()
}
console.log(sort(3,1,4,8));
</script>

Spread操作符(展开操作符)

let arr = [2, 3, 4, 5, 7, 8];
    console.log(...arr);
    // 输出的是一个一个的值   2, 3, 4, 5, 7, 8

比如,内建函数 Math.max 会返回参数中最大的值:

alert( Math.max(3, 5, 1) ); // 5

假如我们已有数组 [3, 5, 1],我们该如何用它调用 Math.max 呢?

直接把数组“原样”传入是不会奏效的,因为 Math.max 期待你传入一系列的数值型参数,而不是单一的数组:

let arr = [3, 5, 1];

alert( Math.max(arr) ); // NaN

这个时候我们就可以用…来解决

let arr = [3, 5, 1];

alert( Math.max(...arr) ); // 5(Spread 操作符把数组转为参数列表)

当我们在代码中遇到 “…” 时,它不是 Rest 参数就是 Spread 操作符。

我们可以使用下列方法区分二者:

  • 若 … 出现在函数的参数列表,那它表示的就是 Rest
    参数,它会把函数多余的实参收集到一个数组中。

  • 若 … 出现在函数调用或类似的表达式中,那它就是 Spread 操作符,它会把一个数组展开为逗号分隔的元素列表。
    ————————————————

详细解法在收藏es6res参数里面

数组去重(面试题):

不适用es6的方式:
数组去重

 let arr = [1, 1, 2, 3, 4, 4, 5]
                    let res = []
                    for(let i = 0; i < arr.length; i++){
    
    
                        //第一种
                        if(res.indexOf(arr[i]) == -1){
    
    
                           res.push(arr[i])
                       }
                        第二种
                       if(arr.indexOf(arr[i]) != arr.lastIndexOf(arr[i])){
    
    
                           arr.splice(i, 1);
                          i--
                      }
                    }

使用es6 去重
new Set() 集合的特点(元素是唯一的,没有顺序,接收的参数是数组),所以可以去重
但是去重后是一个set集合,不是我们想要的,转换为一个数组

  • 可以用…res参数,将其展开为一个一个的参数,然后套个数组[]
  let arr = [1, 1, 2, 3, 4, 4, 5]
            let res = [...new Set(arr)]
            console.log(res); //[1, 2, 3, 4, 5]
  • 也可以,用 Array.from方法将集合转换为数组
let arr = [1, 1, 2, 3, 4, 4, 5]
   let res = (new Set(arr));
        let yi = Array.from(res);
        console.log(yi);// [1, 2, 3, 4, 5]

3.箭头函数

3.1 定义

箭头函数是对于匿名函数表达式的一种简写方法。

3.2 语法

   //普通匿名函数
    var a = function (a, b) {
    
    
        console.log(a);//1
    }
    a(1);
        //箭头函数
        //()形参的位置
        //=> 箭头函数的标志
        //{
    
    } 函数代码块
     var a = (a)=> {
    
    console.log(a); }//1
     a(1);

用法的区别:

var fn = function(a,b){
    
    
    console.log(a+b);//30
    console.log("我是普通匿名函数");
}
fn(10,20);
var fn2 = (a,b)=>{
    
    
    console.log(a+b);//30
    console.log("我是箭头函数");
}
fn2(10,20);

3.3 其他写法

如果箭头函数只有一个形参,则可以省略小括号。

var fn = a =>{
    
    
       console.log(a);
}

如果只包含一个语句,则省略{}和return。

 var fn = a => a*a;
    console.log(fn(10));//100

箭头函数中没有arguments实参对象。

var fn = a => {
    
    
   console.log(arguments.length);//报错   arguments is not defined
}

3.4 箭头函数中this指向

 console.log(window.console.log() == console.log());//true

其实console.log()是window在调用

箭头函数内部的this是由上下文确定的。

它会找到自身定义的位置中的this值,作为自身的this。

<body>
    <div>1</div>
</body>
<script>
    let div = document.querySelector("div");
  / div.onclick = function(){
    
    
        console.log(this);//div
    }/
    //=============================================================
   // div.onclick = ()=>{
    
    console.log(this);}//window
   console.log(this);//window
 //可以理解为在这个代码块外面写一个this   console.log(this);这里面this指向谁,箭头函数中this就指向谁
 //===========================================================
div.onclick = function(){
    
    
      /   let fn = function(){
    
    
             console.log(this);//window
         }
         fn();}/其实是window.fn()
  //---------------------------------------------------       
        let fn = ()=>{
    
    
            console.log(this);//div
        }
 //    因为   console.log(this);//div所以上述箭头函数this指向为
        fn();
    }
 //================================================
    let obj = {
    
    
        name:"亚索",
        fn:function(){
    
    
            console.log(this);//obj
        },
        fun:()=>{
    
    
            console.log(this);//window
        }
    }
    obj.fn();
    obj.fun();*/
</script>

自执行函数

自执行函数:IIFE 在定义时立即执行的函数
1.声明一个函数
2.立刻调用。

函数分为两个阶段:
1.定义阶段
2.调用阶段
写法:

(function(形参){
    
    })(实参)
(function(形参){
    
    }(实参))

自执行函数的作用:
解决全局变量的污染
示例普通函数

<!-- <script>
    function arr(){
    
    
        alert("今天是个好日子")
    }
    arr();
</script> -->
<!-- <script>
   // 一种表示方法
    ( function arr(){
    
    
        alert("今天是个好日子")
    }());
</script> 
 <script>
    //二种表示方法
    ( function arr(){
    
    
        alert("今天是个好日子")
    })();
</script> ```

有参数的函数

<!-- <script>
    function arr(a){
    
    
        alert("方法执行了" +  a);
    }
    arr(1);
</script> -->
<!-- <script>
   ( function (a) {
    
     alert("方法执行了一" + a)}(1));
</script> -->
<script>
    var x = -function(a){
    
    return a;
             }(123);
            console.log(x);//-123
</script>

例子:需求,点击每一个就返回每一个的下标

<body>
    <ul>
        <li>这是第1个li</li>
        <li>这是第2个li</li>
        <li>这是第3个li</li>
        <li>这是第4个li</li>
        <li>这是第5个li</li>
        <li>这是第6个li</li>
    </ul>
</body>
<!-- <script>
    var lis = document.querySelectorAll("li");
    for (var i = 0; i < lis.length; i++) {
    
    
        lis[i].onclick = function () {
    
    
            console.log(i);//点击每次都是6,这不是我们想看到的
            //解决方法:将var换成let
        }
    }
</script> -->
 <script>解决方法二
     var lis = document.querySelectorAll("li");
    for (var i = 0; i < lis.length; i++) {
    
    
        (function(i){
    
    
            lis[i].onclick = function () {
    
    
            console.log(i);//点击第几个就会返回这个的下标
        }
        })(i);  
    }
</script> 

猜你喜欢

转载自blog.csdn.net/z18237613052/article/details/114038893
今日推荐