美文网首页
高阶函数

高阶函数

作者: Ht_何甜 | 来源:发表于2018-08-13 18:35 被阅读0次

高阶函数

  • 函数作为参数
  • 函数作为返回值的时候

作为参数

function eat(fn){
    setTimeout(function(){
        console.log('吃晚饭');
        //吃完晚饭之后做的事情
        fn();
    },2000);
}
eat(function(){
    console.log('去唱歌')
});

回调函数

回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。

//定义主函数,回调函数作为参数
function A(callback){
    callback();//需要在主函数内调用
    console.log('我是主函数')
}
//定义回调函数
function B(){
    setTimeout("console.log('我是回调函数')",3000)
}
//调用主函数,将函数B传进去
A(B);
//--->我是主函数
//--->我是回调函数
//主函数执行完,回调作为参数的B函数,这个过程叫回调

函数作为参数案例

var arr=[5,8,3,12];
//sort()中有个参数为函数,这个函数有2个参数,a,b,这个函数的返回值,返回>0 或<0 或=0
arr.sort(function(a,b){
    return a-b;
});
console.log(arr)//-->arr[3,5,8,12]

//自己定义sort(sort的运行原理)
//给Array数组原型对象增加一个方法
Array.prototype.mySort=function(fn){//此处的函数在外部调用时,
//要传两个参数并定义下是返回>0 或<0 或=0,来决定这个数组是从大到小还是从小到大排序
//外层循环控制趟数
    for(vari=0;i<this.length-1;i++){
    //内层循环
        var isSort=true;//假设排好顺序
        //是否真的排好序?看内层循环是否交换顺序
        //内层循环次数为this.length-i-1
        for(var j=0;j<this.length-i-1;j++){
        //判断第一项如果比后一项大,就交换顺序
            if(fn(this[j],this[j+1])>0){
            //fn(a,b),把相邻的两项传给fn,并和0比较
                isSort=false;//如果>0,就没排好序,isSort为false
                var tmp=this[j];
                //定义一个中间变量,并给this[j]重新赋值this[j]=this[j+1];
                //交换顺序
                this[j+1]=tmp;
            }
        }
        if(isSort){
        //排好序就终止循环
            break;
        }
    }
}

函数作为返回值

//函数:生成1-10的随机整数
//Math.random生成的是0-1之间的小数,[0,1)
function getRandom(){
    return parseInt(Math.random()*10)+1
}

//生成1-10的随机整数,并且在第一次调用后生成的随机数,以后的每一次调用都返回第一次的随机值
function getRandom(){
    var random = parseInt(Math.random()*10)+1
    //这个函数返回了一个函数
    return function(){
    //返回父函数的random
        return random;
    }
}
//调用getRandom返回的是一个函数,需要用变量接收
var fn=getRandom();
console.log(fn)

//求两个数的和
//100+m    1000+m  10000+m
function getFun(n){//n指的是100/1000/10000
    return function(m){
        return n+m;
    }
}
//求100+m
var fn100=getFun(100);//100-->n
//求1000+m
var fn1000=getFun(1000);
console.log(fn100(1));//1-->m
console.log(fn1000(1));

闭包

闭包就是能够读取其他函数内部变量的函数。

在js中,只有函数内部的子函数才能读取取局部变量

闭包可以在一个作用域中可以访问另一作用域的变量

闭包的用途

  • 可以在函数外部读取函数内部成员
  • 让函数内成员始终存活在内存中
  • 闭包特点:延展了函数的作用域范围

闭包案例

<ul id="heros">
    <li>安其拉</li>
    <li>李白</li>
    <li>诸葛亮</li>
    <li>狄仁杰</li>
</ul>
<script>
//方式一,对象的自定义属性:
    //给li注册点击事件
    var heros = document.getElementById("heros")
    var list = heros.children
    for(var i = 0; i < list.length; i++){
        var li=list[i];
        list[i].index=i;//给li用index记录索引,等于循环的每一项i
        //第一次循环的i=0,记录给第一个li
        list[i].onclick=function(){
        //点击li的时候输出当前li对应的索引
           // console.log(i);//-->4
             //循环的过程中,没有触发函数,就会继续循环,循环到最后,i=4,
             //因为此时的function是在for循环结束后调用
           console.log(this.index)//-->this是点击的li,index为他的索引
        }
    }
  
//方式二,闭包:
    var heros = document.getElementById("heros")
        var list = heros.children
        for(var i = 0; i < list.length; i++){
            var li=list[i];
            <!--下面这个自调用函数,每循环一次触发调用一次,给每个i的li注册点击事件-->
            (function(i){
                    list[i].onclick=function(i){
                //点击li的时候输出当前li对应的索引
                }
            })(i)//自调用函数
            
        }
</script>

闭包案例

字体大小
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<button id="btn3">按钮3</button>

<script>
    var btn1=documentElementById('btn1')
    var btn2=documentElementById('btn2')
    var btn3=documentElementById('btn3')
    //创建一个函数,设置body字体大小
    function makeFun(size){
        return function(){            document.body.style.fontSize=size + 'px'
        }
    }
//函数嵌套函数,内部函数size访问到了外部函数size的变量,产生了闭包。
//btn1.onclick调用makeFun,返回了他内部的函数,并调用这个函数
    btn1.onclick=makeFun(12);
    btn2.onclick=makeFun(14);
    btn3.onclick=makeFun(16);
</script>

递归

递归:函数自己调用自己

//斐波那契数列1,1,2,3,5,8,
//前两个数相加是后一个数
//前两个个数为n-1 ,n-2
function fn(n){
    if(n===1 || n===2){
        return 1;
    }
    return fn(n-1) + fn(n-2)
}

对象的拷贝

 var obj1={
            name:'郑州',
            age:19,
            sex:'男'
        }
        var obj2={}
        //封装函数  把o1的成员复制给o2
        function copy(o1,o2){
            for( var key in o1){
                o2[key]=o1[key];
            }
        }
        copy(obj1,obj2);
        console.dir(obj2)
  • 浅拷贝
    只能复制对象的第一层属性,当其中的属性又是一个对象时,只能复制这个对象引用,不能创建一个新的对象

  • 深拷贝
    如果对象的某个属性为数组或对象,就让他这个属性等于空数组或空对象,再让o1的这个属性拷贝到o2的这个对象中

  • 为什么先判断数组?因为数组也是对象,当对象放在前面时候,会把数组一起判断为对象。

    var obj1={
    name:'郑州',
    age:19,
    sex:'男'
    }
    var obj2={}
    //深拷贝
    function deepCopy(o1,o2){
    for( var key in o1){
    //如果key是数组Array[]
    if(o1[key]instanceof Array){
    o2[key]=[]; //初始化一个空数组
    deepCopy(o1[key],o2[key]);
    }else if(o1[key]instanceof Object){
    //如果key是复杂类型Object{}
    o2[key]={};
    deepCopy(o1[key],o2[key]);
    }else{
    //如果key这个属性时基本类型
    o2[key]=o1[key];
    }
    }

      }
    

    }
    copy(obj1,obj2);
    console.dir(obj2)

遍历DOM树

//遍历指定元素下所有的子元素
//增加回调函数,
function loadTree(parent,callback){
//循环结束条件:没有子元素parent.children.length=0
    for(var i=0; i<parent.children.length; i++){
        //遍历第一级子元素
        var child=parent.children[i];
        <!--console.log(child);-->
        //如果有回调函数,回调函数的参数为child
        if(callback){
        //处理找到的子元素
            callback(child)
        }
        //调用递归
        //子元素作为父元素继续循环遍历子元素
        loadTree(child);
    }
}
<!--loadTree(document.body)-->
<!--//遍历ul中所有的子元素-->
<!--loadTree(document.getElementById('list'))-->
var ul document.getElementById('list');
//调用loadTree ,回调函数function(element),element为上面的child参数,给这个参数获取点击事件,点击打印元素内容
loadTree(ul,function(element){
    element.onclick=function(){
        console.log(this.innerText)
    }
})

正则表达式

作用

  1. 给定的字符串是否符合正则表达式的过滤逻辑(匹配)
  2. 可以通过正则表达式,从字符串中获取我们想要的特定部分(提取)
  3. 强大的字符春替换能力
  4. 使用正则表达式找到匹配的做过滤

正则表达式组成

  • 普通字符

  • 特殊字符(元字符):正则表达式中有特殊意义的字符

    元字符 说明
    \d 匹配数字
    \D 匹配任意非数字的字符
    \w 匹配字母或数字或下划线
    \W 匹配任意不是字母或数字或下划线
    \s 匹配任意空白符
    . 匹配换行符意外的任意单个字符
    ^ 匹配以谁开始的文本
    $ 匹配以谁结束的文本

    限定符 说明

    • 重复0次或更多次
      
    • 重复1次或更多次
      

    ? 重复0次或1次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n次到m次

其他

  • [] 字符串用中括号括起来,表示匹配其中的任一字符,相当于或的意思
  • [^] 匹配除中括号以内的内容
  • \ 转义符
  • | 或者,选择两者中的一个。注意|将左右两边分为两部分,而不管左右两边有多长多乱
  • () 从两个直接量中选择一个,分组
  • eg:gr(a|e)y匹配gray和grey
  • [\u4e00-\u9fa5] 匹配汉字

练习

正则表达式工具

//邮箱验证  100010   ---> ^[1-9]\d{5}$
//验证手机号 18820288976  ---> ^[1-9]\d{10}$
//验证日期  2018-8-11 --->  ^\d{4}-\d{1,2}-\d{,2}$
//验证邮箱  xx@sss.com.cn ---> ^\w+@\w+(\.\w)+$

JavaScript 中使用正则表达式

创建正则对象

//第一种方式:
//内置对象 RegExp
//第一个参数 模式 pattern
//第二个参数 flag i 忽略大小写 g 全局匹配
var regularExpression = new RegExp('ab[a-z','i');
var str = 'xyz';
var str2 = 'abc';
console.log(regularExpression.test(str));//-->false
console.log(regularExpression.test(str2));//-->true

//第二种方式
var regularExpression = /ab[a-z]/i;
var str2 = 'abc';
console.log(regularExpression.test(str2));//-->true

跟正则表达式相关的方法

==i 忽略大小写==

==g 全局匹配,全局匹配就可以找到所有符合条件的==

  1. RegExp对象
  • test() 匹配
  • exec() 提取,只返回第一个匹配到的结果,没有匹配到就是null
  1. String对象
  • match() 提取多个内容
  • replace() 替换 replace(被替换的,替换成什么),只能替换掉第一个查找到的元素
  • split() 切割,用什么分割成字符串数组
  • search()

exec()

var str = '张三:2500,李四:3000,王五:50000'
var reg = /\d+/gi;//全局匹配并且忽略大小写
//循环找到所有匹配条件的
do{
    var content = reg.exec(str);//提取字符串
    if(content){//判断找到content
        console.log(content[0])//content这个数组的第一个是要找的
    }
}while(content);//不符合条件跳出循环

match()

var str = '张三:2500,李四:3000,王五:50000'
var reg = /\d+/g;//数字正则表达式
//提取多个内容
console.log(str.match(reg));//-->[2500 ,3000,50000]

分组提取

var dateStr = '2015-1-5';
var reg = /\d{4}-\d{1,2}-d{1,2}/;
reg.test(dateStr);//将dateStr匹配个reg对象,才能使用分组$
console.log(RegExp.$1);//-->2015
console.log(RegExp.$2);//-->1
console.log(RegExp.$3);//-->5

split()

var dateStr = '2015-1-5';
console.log(dateStr.split('-');//-->["2015","1","5"]

var dateStr = '2015-/-5'; //正则表达式分割
console.log(dateStr.split(/[/-]/);//-->["2015","1","5"]

replace()

var str = "  123  aaa  ccc";
//trim() 去除前后空格
console.log(str.trim()) //-->"123  aaa  ccc"
console.log(str.repalce(/\s/g,'x')//--> "xx123xxaaaxxccc"
console.log(str.split(" "))//-->[" "," ","123"," "," ","aaa"," "," ","ccc"]
console.log(str.split(' ').join(''));//-->"123aaaccc"
//join把split把空去掉,用空连接数组并转为字符串

贪婪模式和非贪婪模式

  • 贪婪模式
    匹配标签:<.+>会把标签和标签的内容匹配到
  • 非贪婪模式:<.+?>不包含标签内容

三元运算符

  • 表达式 1 ? 表达式2 :表达式3
    • 表达式1:布尔类型表达式-->返回布尔值

    • 表达式1 成立 返回表达式2的值

    • 表达式1 不成立 返回表达式3的值

      //取最大值
      var num1 = 3;
      var num2 = 6;
      console.log(num1>num2 ? num1 : num2)
      //如果 num1>num2 返回num1 否则 返回num2

隐式类型转换

  • false: 0 '' NaN null undefined 其他都为 true
  • num=0 --->false
  • !true=false

while循环、do...while

while(循环条件){//循环条件为true执行循环体
    //循环体
}

//do...while不管条件成立不都会执行一次
do{
    //循环体
}while(循环条件)

分隔符

将数组用| 或其他分隔符分割

var arr = ['1','3','5','7']

//方法一:元素后面加分隔符
var seperator = '|'
var str="";//先定义一个空字符串,在拿到每一项拼接到这个字符串中
for(var i=0; i<arr.length; i++){
    str=srt+arr[i]+seperator
}
console.log(srt);//--> 1|3|5|7|

//方法二:往第二个元素之前加分隔符
var seperator = '|'
var str = arr[0];//先把第一项存起来,不参与循环
for(var i=1; i<arr.length ;i++){
    str +=  seperator + arr[i]
}
console.log(srt);//--> 1|3|5|7

数组案例

将数组中的0项去掉,并将不为0的存入新数组

var num=[2,7,9,0,1,0,5,0]
var newArray = [];
for(var i=0; i<num.length;i++){
    if(num[i] !== 0){
        newArray[newArray.length] = numbers[i];
        //newArray.length相当于新数组的索引i
    }
}
console.log(newArray);//-->[2,7,9,1,5]

相关文章

  • python学习(三)函数式编程

    高阶函数 函数也是变量,函数参数为函数的函数,称作高阶函数 自定义高阶函数 内建高阶函数 map/reducema...

  • 11.Lambda和高阶函数(Lambda and Higher

    高阶函数 kotlin_Lambda,高阶函数 *swift_高阶函数

  • Python | 高阶函数基本应用及Decorator装饰器

    一、高阶函数 理解什么是高阶函数?以及高阶函数的基本应用方法 ▲ 高阶函数 在了解什么是高阶函数之前,我们来看几个...

  • 四、函数进阶

    一. 高阶函数 参数类型包含函数类型或返回值类型为函数类型的函数为高阶函数。 常见的高阶函数 高阶函数的调用 二....

  • Kotlin 高阶函数

    什么是高阶函数 将函数作为参数或者返回值的,称高阶函数。 定义高阶函数 action是一个高阶函数,(Int) -...

  • 高阶组件

    高阶组件 先来引入这个概念 高阶函数是什么? 高阶函数就是一个函数返回一个函数eg: 高阶组件 类同 高阶组件就是...

  • [JS函数] (Array)の高阶函数

    JS函数 高阶函数 高阶函数英文叫Higher-order function。那么什么是高阶函数? JavaScr...

  • HOC - High Order Component 高阶组件

    高阶函数 简而言之,可以接收函数作为参数的函数就是一个高阶函数。 上面的hoc函数就是一个高阶函数。 高阶组件 高...

  • Day10. 高阶组件

    1. 认识高阶函数 什么是高阶组件呢?认识高阶函数.png 高阶函数: 接收一个或多个函数作为输入, 输出一个函数...

  • Python高阶函数

    本文要点 1.什么是高阶函数 2.python中有哪些常用的高阶函数 什么是高阶函数? 在了解什么是高阶函数之前,...

网友评论

      本文标题:高阶函数

      本文链接:https://www.haomeiwen.com/subject/sqaubftx.html