高阶函数

123 阅读2分钟

JS高阶函数

箭头函数

箭头函数是匿名函数,一般做为参数传递

1.如果函数体只有一句,那么可以省略{ },同时默认会返回函数体的结果,不能写return

2.如果只有一个参数,那么可以省略( ) 3.如果没有参数,( )也不能省略

let test = (参数) => {函数体}

箭头函数的语法有多种写法技巧

演示:

    <button>点击</button>
    <script>
        // 箭头函数的时候 
        // const func2 = (num1) => num1 + 100;

        // 定义一个箭头函数 没有形参 没有返回值 2行实际业务
        const func1 = () => {
            console.log('执行1');
            console.log('执行2');
        }
        func1()
        // 没有形参、没有返回值、业务只有一行代码 大括号都可以省略
        const func2 = () => console.log('执行业务');
        func2()
        // 只有一个形参、没有返回值、业务只有一行代码
        const func3 = sum => console.log(sum + 10);
        const func = (sum) => console.log(sum + 10);
        func3(20)
        func(30)
        // 两个或者多个参数(括号不能省略)、没有返回值、业务只有一行代码
        const func4 = (a, b) => console.log(a + b);
        func4(10,20)
        // 没有形参,有返回值 业务两行代码
        const func5 = () => {
            let a = 100
            return a + 100
        }
        console.log(func5());
        // 没有形参、有返回值,业务一行代码
        const func6 = () => {return 200 + 100}
        console.log(func6());
        // 没有形参、有返回值,业务一行代码 等价上述写法
        const func7 = () => 100 + 300 // 默认100+300 有返回值return
        console.log(func7());

        const button = document.querySelector('button')
        button.addEventListener('click', ()=>{
            console.log(123456);
        })
    </script>

forEach( )

forEach( ) 方法用于调用数组的每个元素,并将元素传递给回调函数。

注意: forEach() 对于空数组是不会执行回调函数的。

    <script>
         // forEach()	数组每个元素都执行一次回调函数。    = 类似以前的for   forEach 高阶函数(可以接收一个形参-函数)
        // for循环可以通过 break来打断、 forEach不能通过break打断
        const arr = ['a', 'b', 'c']
        // 以前的函数写法function
        arr.forEach(function(value, index){
            console.log(`值是 ${value} 下标是${index}`);
        });
        // 现在用箭头函数表达
        arr.forEach((value, index) => console.log(`值是 ${value} 下标是${index}`));
        arr.forEach(value =>  console.log(`值是 ${value}`))
    </script>

forEach(): 没有返回值,本质上等同于 for 循环,对每一项执行 function 函数。即map是返回一个新数组,原数组不变,forEach 是改变原数组。

数组常用的方法

方法描述
every()检测数值元素的每个元素是否都符合条件。
filter()检测数值元素,并返回符合条件所有元素的数组。
find()返回符合传入测试(函数)条件的数组元素。
findIndex()返回符合传入测试(函数)条件的数组元素索引。
forEach()数组每个元素都执行一次回调函数。
includes()判断一个数组是否包含一个指定的值。
indexOf()搜索数组中的元素,并返回它所在的位置。
isArray()判断对象是否为数组。
join()把数组的所有元素放入一个字符串。
map()通过指定函数处理数组的每个元素,并返回处理后的数组。
reduce()将数组元素计算为一个值(从左到右)。
reverse()反转数组的元素顺序。
some()检测数组元素中是否有元素符合指定条件。
sort()对数组的元素进行排序。

map( )

当我们使用箭头函数 也是常用到数组的一些使用方法

接下来会用到 map( )

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。

    <script>
        map()
        function map(){
            // map 根据原来的数组 来返回新的数组
            // 也会循环数组 在循环的回调函数中可以返回新的数据 组装成新的数组

            const arr = ['a', 'b', 'c'];
            // 可以返回 ["我的字母是a","我的字母是b","我的字母是c"]

            const newArr = arr.map((value) => '我的字母是' + value); // [1,1,1]
            console.log(newArr);

            const list=[10,11,12];
            const newList=list.map(value=>value+1);// [11,12,13]
            console.log(newList);
        }
    </script>

当数组里包含对象

演示:

    <script>
        map()
        function map(){
            const objectArr=[{name:"悟空"},{name:"八戒"}];
            const newObjectArr=objectArr.map(value=>{
            // 1 
            	value.color="red";
            // 2 
              return value
            })  // [{name:"悟空",color:"red"},{name:"八戒",color:"red"}]
           	console.log(newObjectArr);
        }
    </script>

join( )

join( ) 方法用于把数组中的所有元素转换一个字符串。

元素是通过指定的分隔符进行分隔的。

把数组里的名字输入到标签里

返回 之后 让他们能显示在页面上

需要把它转成字符串

	 <script>
        map()
        function map(){
            const texts = ['刘德华', '郭德纲', '林志颖']
            // 返回  [<div>刘德华</div>,<div>郭德纲</div>,<div>林志颖</div>]
            const newTexts = texts.map(value => `<div>${value}</div>`);
                // [<div>刘德华</div>,<div>郭德纲</div>,<div>林志颖</div>] 
                // 把它转成字符串
            const html = newTexts.join('')

            document.body.innerHTML = html
        }
    </script>
	 <script>
        map()
        function map(){
            // 后面更简洁的写法
            const renderHTML = value => `<div>${value}</div>`
            document.body.innerHTML = ['刘德华', '郭德纲', '林志颖'].map(renderHTML).join('')
        }
    </script>

every()

every( ) 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

every( ) 方法使用指定函数检测数组中的所有元素:

  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
  • 如果所有元素都满足条件,则返回 true。

注意: every( ) 不会对空数组进行检测。

注意: every( ) 不会改变原始数组。

      every();
      function every() {
			// 会返回 true或者false
        // 如果数组中每一个元素都复合条件,every返回true

        const arr = [1, 6, 3, 4];
        // 判断数组中每一个元素,是不是都小于 5 如果是  返回true

        // every当中的函数,要求每一个都return 了true 最后 every的返回值才是true
        const result = arr.every((value) => {
          if (value < 5) {
            return true;
          } else {
            return false;
          }
        });
        console.log(result);
      }
        // 有一个数组,存放每一个人 关于肺炎的检查结果
        const arr = [true, true, true, true, true]; // true就表示安全,false 中招
        // 我想要判断一下  这个人群安不安全  (只要有一个为false,不安全) 要求每一个都为true才安全

        const result = arr.every((value) => {
          if (value === true) {
            return true;
          } else {
            return false;
          }
        });
        console.log(result);
        // every 如果是空数组,调用every 直接返回true
          let arr=[];
          const result=arr.every(value=>console.log(12));// result = true
          console.log(result);


          // every:
          // 会返回true或者false
          // 要求数组中每一个元素都符号条件,every 得到true
          // 如果空的数组调用了every。 得到结果 也是true

some( )

some( ) 方法用于检测数组中的元素是否满足指定条件(函数提供)。

some( ) 方法会依次执行数组的每个元素:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。

注意: some( ) 不会对空数组进行检测。

注意: some( ) 不会改变原始数组。

      some();
      function some() {
        // 检测数组,其中只要有一个元素符合条件,some返回true (every要求每一个都符合)
        const arr = [1, 3, 4, 6, 2];
        // 这个数组里面有没有元素大于6的
        const result = arr.some((value) => value > 6);
        console.log(result);

        /* 
        every 和 some 一起记
        every 要求全部都符合
        some 最少有一个符合即可 
         */
      }

数组去重案例

1 输入框绑定键盘按下事件

​ 1 判断按下的是不是 回车键

​ 2 是的话 获取输入框的值

​ 3 判断当前要显示的数据 是否已经存在于数组中 filter 可以 some可以

​ 如果是已经存在 就不要继续添加

​ 如果是不存在 就继续添加

​ 4 把它添加到数组中

​ 5 写一个方法 把数组的数据 拼接成li标签,插入到 ul中

使用 some( ) 方法

    <input type="text" />
    <ul></ul>
    <script>
      const input = document.querySelector('input');
      const ul = document.querySelector('ul');
      const arr = ['a', 'b'];
      render();

      input.addEventListener('keydown', function (event) {
        //判断按下的是不是回车
        if (event.key === 'Enter') {
          // console.log(this.value);

          // some 如果数组中有一项 是返回了true 整个some方法就返回了true
          // 调用some方法的时候,在它的回调函数中 拿数组中的元素 和 当前要添加的元素 做比较 如果相等 就返回true 表示找到了重复

          const isHas = arr.some((value) => value === this.value); // 在我的数组中找到了和你待添加的元素 一样的值 返回true
          if (isHas) {
            // 有重复了 不要再添加
            console.log('有重复了 不要再添加');
          } else {
            // 没有重复 你可以添加
            // 把它添加到数组中
            arr.push(this.value);
            // 数组发生了改变 重新调用render方法 来实现页面的渲染
            render();
          }
        }
      });

      function render() {
        const html = arr.map((value) => `<li>${value}</li>`).join('');
        ul.innerHTML = html;
      }
    </script>

for循环写法

    <input type="text" />
    <ul></ul>
    <script>
      const input = document.querySelector('input');
      const ul = document.querySelector('ul');
      const arr = ['a', 'b'];
      render();

      input.addEventListener('keydown', function (event) {
        if (event.key === 'Enter') {
          // 定一个变量,表示数组有没有重复的数据
          // 假设它 没有重复
          let isHas = false;
          for (let index = 0; index < arr.length; index++) {
            // 判断数组中的每一个元素 和 当前要输入的值做比较
            // 如果找到了,设置 isHas=true 同时 打断循环
            if (arr[index] === this.value) {
              // 找到重复了
              isHas = true;
              break;
            }
          }

          // 判断数据有没有重复
          if (isHas) {
            // 有重复
            console.log('有重复');
          } else {
            // 没有重复 添加
            arr.push(this.value);
            render();
          }
        }
      });

      function render() {
        const html = arr.map((value) => `<li>${value}</li>`).join('');
        ul.innerHTML = html;
      }
    </script>

filter()

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意: filter() 不会对空数组进行检测。

注意: filter() 不会改变原始数组。

      filter();
      function filter() {
        // 过滤, 过滤出满足条件的数据 =>新的数组
        const arr = [1, 2, 3, 4, 5, 6, 7];
        // 返回 奇数
        const newArr = arr.filter((value) => {
          // 如果你return 了 true 表示当前的value你想要
          if (value % 2 !== 0) {
            // value  1 2 3 4 5 6
            // value%2!==0   value=[1,3,5,7]
            // 奇数
            return true;
          } else {
            return false;
          }
        });
        console.log(newArr);
      }

简洁点的写法

      filter();
      function filter() {
        // 过滤, 过滤出满足条件的数据 =>新的数组
        const arr = [1, 2, 3, 4, 5, 6, 7];
        // 返回 奇数
        const newArr = arr.filter((value) => value % 2 !== 0);
        console.log(newArr);
      }

数组去重案例

使用 filter() 方法 完成

    <input type="text">
    <ul></ul>
    <script>
        let arr = []
        const input = document.querySelector('input')
        const uls = document.querySelector('ul')
        input.addEventListener('keydown', function (event) {
            if (event.key === 'Enter') {
                // filter 来解决
                // filter 过滤
                // 先过滤出  和当前的输入框的值 不相等的 数据
                // 然后再添加
                // 当前输入框的值 "d"
                // 我数组 ['a','c','d']
                // 数组过滤 不包含 "d"  => ['a','c']
                // ['a','c'] 再次添加 'd' 进去 就可以了

                // 过滤出不包含 当前输入框的值的数组
                const newArr = arr.filter((value) => value !== this.value)
                 // 让我们的旧的数组 等于你过滤后的数组
                arr = newArr
                arr.push(input.value)
                liHtml()
            }
        })
        liHtml()

        function liHtml() {
            const lis = arr.map((value) => `<li>${value}</li>`).join('')
            uls.innerHTML = lis
        }
    </script>

数组去重4(了解)

数组去重 一堆方法

indexOf find findIndex includes set every

for forEach some

includes( )

includes( )方法

    <input type="text" />
    <ul></ul>
    <script>
      const input = document.querySelector('input');
      const ul = document.querySelector('ul');
      let arr = ['a', 'b'];
      render();

      input.addEventListener('keydown', function (event) {
        if (event.key === 'Enter') {
          const isHas=arr.includes(this.value)
          if(!isHas){
          arr.push(this.value);
          render();
          }
        }
      });

      function render() {
        const html = arr.map((value) => `<li>${value}</li>`).join('');
        ul.innerHTML = html;
      }
    </script>

find( ) 方法

    <input type="text" />
    <ul></ul>
    <script>
      const input = document.querySelector('input');
      const ul = document.querySelector('ul');
      let arr = ['a', 'b'];
      render();

      input.addEventListener('keydown', function (event) {
        if (event.key === 'Enter') {
          const item=arr.find(value=>value===this.value);
          if(!item){
            arr.push(this.value);
            render();
          }
          render();
        }
      });

      function render() {
        const html = arr.map((value) => `<li>${value}</li>`).join('');
        ul.innerHTML = html;
      }
    </script>

箭头函数-返回对象

假如 设一个数组 arr = ['a', 'b', 'c'];
用箭头函数写 最后返回 [ {name:"a",name:"b",name:"c"} ]

下面写一些常见的会犯错的写法

<script>
      const arr = ['a', 'b', 'c'];
      // 返回 [  {name:"a",name:"b",name:"c"} ]
      const newArr=arr.map(value=>name:value ); // 排除!

      const newArr=arr.map(value=>{name:value} ); // 思路正确 代码不正确

      const newArr=arr.map(value=>{
        name:value
      } ); // 思路正确 代码不正确

      const newArr=arr.map(value=>{
        name:value
        return undefined
      } ); // 思路正确 代码不正确

      const newArr=arr.map(value=>{
        console.log(1);
        console.log(2);
      } ); // 思路正确 代码不正确

      console.log(newArr);
    </script>

当我们使用箭头函数 会认为 这个大括号{} 是 块级空间 符号 而不是对象的符号

      箭头函数 会认为 这个大括号 是  块级空间 符号 而不是对象的符号
      const newArr1 = arr.map((value) => { name: value; }); // 这个大括号 是表示 对象的符号 还是表示 可以块级空间
      const newArr2=arr.map(value=> {
      console.log(123) ;
      console.log(123) ;
      console.log(123) ;
      return undefined
      } );

      // js认为 大括号是 块级空间 可以写js语句
      {
        console.log(123);
        console.log(123);
        console.log(123);
      }
      let obj={ // js会认为大括号是 对象的符号 里面不能写 语句
        console.log(123);
        console.log(123);
        console.log(123);
      }
 // 箭头函数 的返回值 可以被省略
      const func = (num) => num + 1; // 相当于 return num+1

      const func1 = (num) => {
        return num + 1;
      }; // 这个大括号表示 块级空间
      
		 const func2 = (num) => {
        num + 1;
      }; // 会执行 num+1 但是没有返回值

      const func3 = (num) => {
        let num1 = num + 1;
        let num2 = num1 + 2;
      };
      console.log(func3());

      const func4 = (num) => {
        return { a: 123 };
      };
      console.log(func4());

      const func5 = (num) => {}; // 只要直接出现 大括号 就表示 块级空间 和它里面写什么代码没有关系
      console.log(func5());

      const func6 = (num) => {
        a: 2;
      }; // 这个大括号就是对象(你的认为!! 浏览器还是一样 大括号就是块级空间)
      console.log(func6());

		// 如果你一定要在箭头函数中想要通过省略 return的方式来 返回对象,请你加上一个小括号
      const func7=(num)=>({a:123});// => 右边加了小括号 表示想要返回 小括号里面的数据 return {a:123};
      const func8=(num)=>{a:123};// => undefined

      console.log(func7()); {a:123}
      console.log(func8());// undefined