第六周第四天笔记

1. 验证正则表达式中的全局g对几种方法的影响

  • test校验方法:正则的方法
    • 总结:1)不添加全局g时,lastIndex值始终是0,所以每次检验匹配时,都是从0开始查找,查找到就返回true,查找不到就返回false;2)添加全局g后,test方法会对lastIndex值进行叠加改变,每检验一次,lastIndex值就改变一次,下次查找的时候从lastIndex值开始查找;
     <script>
         var str="yuanmeng00huadianyuanmenghuadian11";
         var reg=/yuanmeng\d+/;
         var reg1=/yuanmeng\d+/g;
         //不添加全局g;
         console.log(reg.test(str));//结果为true;
         //添加全局g;
         console.log(reg1.lastIndex);//结果为0;
         console.log(reg1.test(str));//结果为true;查找到的结果为yuanmeng00;
         console.log(reg1.lastIndex);//结果为10;
         console.log(reg1.test(str));//结果为false,从索引为10的字符开始查找,查找不到,返回null;
     </script>
    
  • exec方法:正则的方法
    • 总结:1)不添加全局g,每次查找的时候,都是从0开始,reg的lastIndex一直是0;2)正则exec方法中添加g,那么,每使用一次就查找一个,然后以数组的形式输出,每次查找输出后,下次查找的位置通过reg的lastIndex属性值记录住,再次使用exec方法查找时,就从上次结束的地方开始查找;
     <script>
        var str="yuanmenghuadianyuanmenghuadian11";
        var reg=/yuanmeng/;
        var reg1=/yuanmeng/g;
        //2.1 验证不添加全局g
        console.log(reg.exec(str));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        console.log(reg.lastIndex);//结果为:0
        console.log(reg.exec(str));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        console.log(reg.lastIndex);//结果为:0
        console.log(reg.exec(str));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        console.log(reg.lastIndex);//结果为:0
        //总结:不添加全局g,每次查找的时候,都是从0开始,reg的lastIndex一直是0;
        //2.2 验证添加全局g
        console.log(reg1.exec(str));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        console.log(reg1.lastIndex);//结果为:8
        console.log(reg1.exec(str));//结果为:["yuanmeng", index: 15, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        console.log(reg1.lastIndex);//结果为:23
        console.log(reg1.exec(str));//结果为:null
        console.log(reg1.lastIndex);//结果为:0
        console.log(reg1.exec(str));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
        //总结:正则exec方法中添加g,那么,每使用一次就查找一个,然后以数组的形式输出,每次查找输出后,下次查找的位置通过reg的lastIndex属性值记录住,再次使用exec方法查找时,就从上次结束的地方开始查找; 
     </script>
    
  • match方法:字符串的方法
    • 总结:字符串match方法,本质就是查找内容,查找到一个就返回一个数组,数组中有三项;与exec方法获取的相同;
    • 总结:1)当不添加全局g时;match方法相当于exec方法,查找到内容,以一个数组的方式返回,里面有三项;2)当添加全局g时,match方法,就把所有满足reg规则的内容,作为数组元素,返回一个新的数组;
     <script>
         var str="yuanmenghuadianyuanmenghuadian11";
         var reg=/yuanmeng/;
         var reg1=/yuanmeng/g;
         console.log(str.match(reg));//结果为:["yuanmeng", index: 0, input: "yuanmenghuadianyuanmenghuadian11", groups: undefined]
         console.log(str.match(reg1));//结果为:["yuanmeng", "yuanmeng"]
         //总结:当不添加全局g时;match方法相当于exec方法,查找到内容,以一个数组的方式返回,里面有三项;
         //当添加全局g时,match方法,就把所有满足reg规则的内容,作为数组元素,返回一个新的数组;
     </script>
    
  • replace方法:字符串的方法
    • 总结:1)字符串replace方法在使用的时候,只要在字符串中只要找到一个被替换的内容,就停止,然后替换掉,返回一个新的字符串;注意:只要找到一个就结束;2)当正则的表达式不添加全局g时,此时就代表查找一次,当使用的时候,只要找到一个,也是停止,只不过是把替换的内容,换成了一个规则,本质没有变化;3)当正则表达式中添加了全局g后,意思是在全局中查找,是查找所有满足正则规则的内容,然后进行全部替换,返回新的字符串;
     <script>
         var str="yuanmenghuadianyuanmenghuadian11";
         var reg=/yuanmeng/;
         var reg1=/yuanmeng/g;
         console.log(str.replace(reg,"meihao"));//结果为:meihaohuadianyuanmenghuadian11
         console.log(str.replace(reg1,"meihao"));//结果为:meihaohuadianmeihaohuadian11
         //总结,不添加全局g,那么在查找的时候,找到一个就停止,然后替换掉,再结束,返回新的字符串;
         //添加全局g,那么在查找的时候,查找到全部,然后全部替换,再结束,返回新的字符串;
     </script>
    

2. 字符串的repalce方法与正则配合后的变化

  • 总结:
    • 字符串replace方法,本质就是查找被替换的内容,然后将其替换,返回一个新的字符串,但是需注意的一点是,每次查找只查找一个,只要有一个就停止,然后替换一个,结束,不会同时替换两个满足要求的内容;
    • 不添加全局g,跟上述方法结果一样,仍然只是查找一个,然后替换一个,结束;
    • 添加全局g,改变查找规则,在查找的时候,将满足规则的内容全部查找到,然后全部替换,最后结束;
    • 正则改变的,只是一个规则,不会改变replace的特性,只是改变了查找规则;
    • 实质:字符串原有的replace方法,特性没有改变,只不过是通过添加正则,来改变了查找的规则;由原来的查找一个,改为查找所有,而这个起决定性作用的就是正则,它制定的规则;
<script>
    //需求:利用字符串的replace方法,将str中的两个huadian,全都替换成huandianxiehe;
    var str="huadianhuadian";
    str=str.replace("huadian","huadianxiehe");
    console.log(str);//结果为:huadianxiehe huadian;
    str=str.replace("huadian","huadianxiehe");
    console.log(str);//结果为:huadianxiehe xiehe huadian;
    //总结:字符串replace方法,本质就是查找被替换的内容,然后将其替换,返回一个新的字符串,但是需注意的一点是,每次查找只查找一个,只要有一个就停止,然后替换一个,结束,不会同时替换两个满足要求的内容;
    //替换一次,然后再添加代码,去替换第二次的时候,是从第一个开始查找,如果中途查找到内容,就会停止,不会再继续,导致的问题是,最后那个huadian永远不会被查找到;

    //正则中的replace方法;
    //1.正则表达式中不添加全局g;
    var str="huadianhuadian";
    var reg=/huadian/;
    str=str.replace(reg,"huadianxiehe");
    console.log(str);//结果为:huadianxiehe huadian
    str=str.replace(reg,"huadianxiehe");
    console.log(str);//结果为:huadianxiehe xiehe huadian
    //总结:不添加全局g,跟上述方法结果一样,仍然指挥查找一个,然后替换一个,结束;
    //2. 正则中添加全局g,
    var str="huadianhuadian";
    var reg=/huadian/g;
    console.log(str.replace(reg,"huadianxiehe"));//结果为:huadianxiehe huadianxiehe
    //总结,添加全局g,改变查找规则,在查找的时候,将满足规则的内容全部查找到,然后全部替换,最后结束;
    //大总结:正则改变的,只是一个规则,不会改变replace的特性,只是改变了查找规则;
    //实质:字符串原有的replace方法,特性没有改变,只不过是通过添加正则,来改变了查找的规则;由原来的查找一个,改为查找所有,而这个起决定性作用的就是正则,它制定的规则;
</script>

3. replace方法中的回调函数

  • 回调函数:把函数的定义阶段作为参数,赋给另外一个函数,这样的函数就叫做回调函数;
  • replace方法中的回调函数:
    • replace方法中的回调函数调用的次数,取决于正则匹配的次数,匹配几次,就调用几次;
    • replace方法,每查找到一次符合正则的内容,就调用一次函数,同时传入当前获取内容的三项参数,其实可看作对内容的所有满足情况的遍历;
    • replace方法中的回调函数会传入实参,传入的内容为exec获得的三项内容值,如1)item:大正则内容(如果有小分组,则第二项为小分组的内容);2)index:每次查找到的内容,开头对应的索引值;3)input:字符串;
     <script>
         //回调函数:把函数的定义阶段作为一个参数赋给另外一个函数,这个函数就叫做回调函数;
         var str="yuanmengyuanmeng";
         var reg=/yuanmeng/g;
         //replace中的回调函数调用的次数,取决于正则匹配成功的次数;
         //replace中的回调函数,拿到的参数跟exec拿到的返回值是一样的;
         str=str.replace(reg,function (item,index,input) {
             //检验回调函数中传入了哪些实参,用arguments
             console.log(arguments);//结果为:["yuanmeng", 0, "yuanmengyuanmeng"];
             return "yuanmengpeixun";
         });
         console.log(str);//结果为:yuanmengpeixunyuanmengpeixun
     </script>
    
  • 实例1:过滤敏感词,即利用replace方法,将特定的词替换成对应数目的*号;
    • 知识点:replace方法中使用回调函数,获取第一个大正则内容参数;
     <body>
     <textarea id="t1" cols="30" rows="10">
         天空蓝和美丽的大地收到印度那地方黑发黑非法是否IE或打开IE减肥,印度减肥而恢复饿得慌IE反对党的凤飞飞欢迎和热爱,祖国人民都非常爱戴天空蓝和美丽的大地;
     </textarea>
     <input type="button" value="过滤敏感词"/>
     <textarea id="t2" cols="30" rows="10"></textarea>
     <script>
         var oT1=document.getElementById("t1");
         var oT2=document.getElementById("t2");
         var oBtn=document.getElementsByTagName("input")[0];
         var reg=/(天空蓝|美丽的大地|印度)/g;
         oBtn.onclick=function(){
             oT2.value=oT1.value.replace(reg,function (item) {
                 //此时获得的第一个参数为大正则内容,如天空蓝,美丽的大地,印度,这些都是字符串,遍历字符串,来决定*的个数
                 var str="";
                 for(var i=0; i<item.length; i++){
                     str+="*";
                 }
                 return str;
             });
         };
     
     </script>
     </body>
    
  • 实例2:模板修改
    • 知识点:replace方法中使用回调函数,回调函数中传入的第一项为大正则的内容,第二项为小分组的内容;
     <script>
         var str="my name is {0},i come from {1},my age is {2}";
         var ary=["果木山","保定",26];
         var reg=/{(\d)}/g;
         var res=str.replace(reg,function ($1, $2) {
             //$1代表大正则的内容,$2代表小分组的内容
             return ary[$2];
         });
         console.log(res);//结果为:"my name is 果木山,i come from 保定,my age is 26"
     </script>
    
  • 实例3:数字变汉字
     <script>
         //需求:将数字变为汉字;
         var str="我以后的目标是工资达到15555元";
         var ary=["零","壹","贰","叁","肆","伍","陆","柒","捌","玖"];
         var res=str.replace(/\d/g,function ($1) {
             return ary[$1];
         });
         console.log(res);//结果为:我以后的目标是工资达到壹伍伍伍伍元
     </script>
    
  • 实例4:去除字符串中的空格
     <script>
         var str="   meihoa   miehfaofie    ";
         //需求1:只去除开头和结尾的空格
         var reg=/(^\s+)|(\s+$)/g;
         var res=str.replace(reg,"");
         console.log("("+res+")");//结果为:(meihoa   miehfaofie)
         //需求2:去除所有的空格
         var reg2=/\s+/g;
         var res2=str.replace(reg2,"");
         console.log("("+res2+")")//结果为:(meihoamiehfaofie)
     </script>
    
  • 实例5:利用对象不重名的特性来统计字母的重复次数
    • 思路:
      1. 利用对象的不重名特性,统计单词,以及出现的次数
      2. 找到出现最多的次数;假设法
      3. 通过次数找字母
     <script>
         //需求:求出现次数最多的单词(不分大小写),以及出现了多少次;
         //第一步:利用对象的不重名特性,统计单词,以及出现的次数
         var str="aaaabbdddDJJJLLLIIEEaaBBDbbcccCCC";
         var obj={};
         for(var i=0; i<str.length; i++){
             var cur=str[i].toLowerCase();
             if(obj[cur]){
                 obj[cur]++;
             }else{
                 obj[cur]=1;
             }
         }
         //第二步:找到出现最多的次数;
         //假设法:假设a的次数最多
         var max=obj.a;
         for(var attr in obj){
             if(obj[attr]>max){
                 max=obj[attr];
             }
         }
         //第三步,通过次数找单词
         var ary=[];
         for(var atr in obj){
             if(obj[atr]==max){
                 ary.push(atr);
             }
         }
         var str=ary.join("、");
         console.log("出现最多次数的单词是:"+str);//结果为:出现最多次数的单词是:a、b、c
         console.log("出现的最多的次数是"+max+"次");//结果为:出现的最多的次数是6次
     </script>
    

4. replace方法与exec方法及match方法之间的联系

  • exec方法:目的是捕获满足reg规则的内容,返回一个数组,数组中有三项;每次只能拿到一个满足规则的内容;
  • match方法:目的是查找所有满足reg规则的内容,然后组成一个新的数组,返回;可以拿到全部满足规则的内容;
  • replace方法:目的也是查找所有满足reg规则的内容,进行替换;但是当存在回调函数时;其目的跟match方法很像;每查找到一次,回调函数就执行一次,就传入一次参数,参数值与exec获得的值相同,意思就是对exec进行了多次使用,直到查找完;同时在回调函数中获取的第一项,就是每次查找到的内容,每调用一次回调函数,就是获取match方法获得的数组中的每一项,也就是对match方法获取数组进行一次遍历;

5.RegExp类实例私有属性lastIndex

  • lastIndex属性:正则RegExp类实例的私有属性;
    • 正则表达式中,若不添加全局g,则lastIndex值始终为0,test方法和exec方法不会改变它,每次查找都从0开始查找;
    • 正则表达式中,若添加全局g;则test方法和exec方法,都会对lastIndex值产生影响,lastIndex值记录本次查找到内容后,内容结尾的下一项的索引值,下次再查找时,会继续从lastIndex值开始查找;两种方法混合使用时,会对lastIndex值进行叠加影响;
     <script>
         var str="meihao1231meihao443343tiankong23243meihao5";
         var reg=/meihao\d{1}/;
         //1.当不填加全局g时,lastIndex值一直为0;
         console.log(reg.lastIndex);//结果为:0;
         console.log(reg.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         console.log(reg.lastIndex);//结果为:0;
         console.log(reg.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         console.log(reg.lastIndex);//结果为:0;
         console.log(reg.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         //2.当添加了全局g后,lastIndex值会变化
         //2.1 exec对lastIndex的影响
         var reg1=/meihao\d{1}/g;
         console.log(reg1.lastIndex);//结果为:0;
         console.log(reg1.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         console.log(reg1.lastIndex);//结果为:7;
         console.log(reg1.exec(str));//结果为:["meihao4", index: 10, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         console.log(reg1.lastIndex);//结果为:17;
         console.log(reg1.exec(str));//结果为:["meihao5", index: 35, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         console.log(reg1.lastIndex);//结果为:42;
         console.log(reg1.exec(str));//结果为:null;
         console.log(reg1.lastIndex);//结果为:0;
         console.log(reg1.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined]
         //总结:exec方法会对lastIndex值进行影响;lastIndex值记录本次查找到内容后,内容结尾的下一项的索引值,下次再查找时,会继续从lastIndex值开始查找;
         //2.2 test对lastIndex的影响
         var reg2=/meihao\d{1}/g;
         console.log(reg2.lastIndex);//结果为:0;
         console.log(reg2.test(str));//结果为:true;
         console.log(reg2.lastIndex);//结果为:7;
         console.log(reg2.test(str));//结果为:true;
         console.log(reg2.lastIndex);//结果为:17;
         console.log(reg2.test(str));//结果为:true;
         console.log(reg2.lastIndex);//结果为:42;此时开始查找的位置是最后一位的下一位;后面已经没有东西,所以查找不到对应内容;
         console.log(reg2.test(str));//结果为:false;
         console.log(reg2.lastIndex);//结果为:0;重新从开始查找,循环;
         console.log(reg2.test(str));//结果为:true;
         //总结:test方法会对lastIndex值进行影响;lastIndex值记录本次查找到内容后,内容结尾的下一项的索引值,下次再查找时,会继续从lastIndex值开始查找;
         //2.3 两种方法混合使用对lastIndex值的影响;
         var reg3=/meihao\d{1}/g;
         console.log(reg3.lastIndex);//结果为:0;
         console.log(reg3.test(str));//结果为:true;
         console.log(reg3.lastIndex);//结果为:7;
         console.log(reg3.exec(str));//结果为:["meihao4", index: 10, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined];
         console.log(reg3.lastIndex);//结果为:17;
         console.log(reg3.test(str));//结果为:true;
         console.log(reg3.lastIndex);//结果为:42;
         console.log(reg3.exec(str));//结果为:null;
         console.log(reg3.lastIndex);//结果为:0;
         console.log(reg3.exec(str));//结果为:["meihao1", index: 0, input: "meihao1231meihao443343tiankong23243meihao5", groups: undefined];
         //总结:两种方法混用时,会对正则上面的属性lastIndex值进行重复修改;每次校验或exec捕获时,都是从lastIndex值开始;
     </script>
    
    • 实例:
     <script>
         var str="alpha(opacity:10)";
         var reg=/alpha\(opacity:(\d+)\)/g;//小括号当做字符使用时,需要加转义符;
         console.log(reg.lastIndex);//结果为0;
         if(reg.test(str)){//此时使用test方法,将lastIndex值改变
             console.log(reg.lastIndex);//结果为17;下次操作时,从索引17开始查找;
             console.log(reg.exec(str));//结果为null;此时exec将lastIndex值再次改变;
             console.log(reg.lastIndex);//结果为0;
         }else{
             alert(false);
         }
         //正则中添加全局g后,每次进行test检验或exec捕获后,都会对lastIndex值进行改变;
     </script>
    

6.RegExp类静态属性

  • RegExp类静态属性:类作为对象角色,添加的属性,成为对象的私有属性,与实例无关,但是必须在进行test方法或exec方法匹配后,才可以使用$1来获取小分组内容;
     <script>
         var str="alpha(opacity:10)";
         var reg=/alpha\(opacity:(\d+)\)/;//小括号当做字符使用时,需要加转义符;
         console.log(RegExp.$1);//结果为:空;意思是默认情况下RegExp类对象上不存在$1属性,必须匹配后,才具有;
         if(reg.test(str)){
            console.log(RegExp.$1);//结果为:10;
         }else{
             alert(false);
         }
         //exec方法和test方法,是正则类原型身上的公有属性;
         //私有属性必须配合exec方法和test方法使用,指的就是匹配到小分组,才能获取私有属性;
         //$1是正则类作为对象时,身上的私有属性,也成为静态属性;
         //其中$1,第一个小分组内容;$2,第二个小分组内容
         //不会改变lastIndex属性;
     </script>
    

7. 重复子项

  • 定义:重复子项,就是如"\1","\2"等字符,代表的意思是:"\1"指与第一个小分组的样式一样;"\2"指与第二个小分组的样式一样;
      <script>
          //重复子项:就是\1跟第一个小分组一样;\2跟第二个小分组一样;
          var reg=/\w(\w)\1(\w)\2/;
          console.log(reg.test("abbcc"));//结果为:true;
          console.log(reg.test("12233"));//结果为:true;
          //正则reg的意思是,总共五位数,第三位与第二位相同(第一个小分组),第五位和第四位相同(第二个小分组);
          var reg2=/\w(\w)(\w)\w\1\2/;
          console.log(reg2.test("abcdbc"));//结果为:true;
          console.log(reg2.test("abcdbb"));//结果为:false;
          //正则reg2的意思是,总共六位数,第五位与第二位相同(第一个小分组),第六位与第三位相同(第二个小分组);
          //重复子项\1,\2的位置不重要,它们代表的是跟小分组一样的东西;
      </script>
    
  • 实例:利用重复子项来统计字母的重复次数
    • 思路:
      1. 将str进行排序,按照拼音形式,让重复的字母挨在一起;
      2. 书写正则样式,使用replace方法
    • 知识点:
      • 字符串转数组方法,数组sort方法,数组转回字符串方法;
      • 正则表达式var reg=/(\w)\1+/gi分析:第一位为字母数字下划线,第二位跟第一位相同,"+"代表可以有多个重复的,"g"代表全局搜索多项,"i"代表忽略大小写;
      • replace方法中回调函数的参数
     <script>
         var str="aaaabbdddDJJJLLLIIEEaaBBDbbcccCCC";
         //第一步:将str进行排序,按照拼音形式
         //分析:字符串转数组,数组sort方法,数组转回字符串
         var ary=str.split("");//分离器为空的字符串;
         ary.sort(function (a, b) {
             return a.localeCompare(b);
         });//sort方法,按照拼音a-z的顺序排列;
         var str2=ary.join("");//连接符为空的字符串;
         // 此时str2为"aaaaaabbbbBBcccCCCdddDDEEIIJJJLLL";
         //第二步:书写正则样式,使用replace方法
         var reg=/(\w)\1+/gi;
         //分析:第一位为字母数字下划线,第二位跟第一位相同,"+"代表可以有多个重复的,"g"代表全局搜索多项,"i"代表忽略大小写;
         var max=0;
         var maxStr="";
         str2.replace(reg,function ($1,$2) {
             //此时,获得的参数,第一项为大正则的内容,第二项为小分组的内容;
             //$1的长度用于获取重复字母的次数,$2用于获取重复的字母
             //假设法,判断最大值;
             if($1.length>max){
                 max=$1.length;
                 maxStr=$2;
             }else if($1.length==max){
                 maxStr+="和"+$2;
             }
         });
         console.log("出现的最多的次数是"+max+"次");//结果为:出现的最多的次数是6次
         console.log("出现最多次数的单词是:"+maxStr);//结果为:出现最多次数的单词是:a和b和c
     </script>
    

8. 封装urlParse()方法

  • 需求:封装方法,把链接中传给后台的参数,以一个新对象的形式返回
  • 知识点:
    • 封装方法要封装到所属类的原型上;
    • 正则表达式var reg=/([^?=&]+)=([^?=&]+)/g;解读:"[^?=&]"的含义是除了?,=,&这三个符号,"+"多个,"="必须要有等号;
    • 思路分析:第一,封装方法,this指向字符串实例对象,默认返回值为字符串实例对象;第二,封装函数执行的返回值为对象,所以需要修改构造函数中的返回值;
 <script>
     //需求:封装方法,把链接中传给后台的参数,以一个新对象的形式返回
     //思路:创建正则表达式,利用replace方法,查找到满足规则的内容,通过在正则中添加小分组,来在回调函数中农获取参数;
     var str="https://baike.baidu.com/pic/%E6%9C%B4%E4%BF%A1%E6%83%A0/3420577/0/e61190ef76c6a7eff1edd899f5faaf51f2de6641?fr=lemma&ct=single&pic=e61";
     //链接中给后台传的参数,是在问号之后;
     //封装方法:封装到字符串类的原型上
     String.prototype.urlParse=function () {
         //this代表str
         var reg=/([^?=&]+)=([^?=&]+)/g;
         //分析:"[^?=&]"的含义是除了?,=,&这三个符号,"+"多个,"="必须要有等号
         var obj={};
         this.replace(reg,function($0,$1,$2){
             obj[$1]=$2;
         });
         return obj;//如果不填返回值,会默认返回实例对象,此时返回引用数据类型,会对其重新赋地址;
     };
     var obj=str.urlParse();
     console.log(obj);//结果为:{fr: "lemma", ct: "single", pic: "e61"};
 </script>

9. 日期格式化封装formatDate()方法

  • 获取日期中的数据:var str="2018-08-22 20:35:56",获取字符串中的数字信息,返回一个数组
    • 严格匹配:
      • 思路:通过正则方法,严格制定捕获规则,通过小分组,单独获取每项信息,然后通过replace中的回调函数获取每项值,但是需要通过call方法来将arguments类数组转化为数组,然后传入参数,截取相应的项;
       <script>
           var str="2018-08-22 20:35:56";
           var reg=/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;
           var ary;
           str.replace(reg,function(){
               ary=Array.prototype.slice.call(arguments,1,arguments.length-2);
           });
           console.log(ary);//结果为:["2018", "08", "22", "20", "35", "56"]
       </script>
      
    • match方法
      • 思路:制定正则方法,获取所有满足规则的内容;
       <script>
           var str="2018-08-22 20:35:56";
           var reg=/\d+/g;
           var ary=str.match(reg);
           console.log(ary);//结果为:["2018", "08", "22", "20", "35", "56"]
       </script>
      
    • split方法
      • 思路:制定分离方法,将字符串分割成数组;
       <script>
           var str="2018-08-22 20:35:56";
           var reg=/[^\d]+/g;//指的是非数字查找;
           var ary=str.split(reg);
           console.log(ary);//结果为:["2018", "08", "22", "20", "35", "56"]
       </script>
      
  • 利用日期模板,将日期进行转换;
    • 思路:通过正则表达式中的大正则拿到被替换的内容,通过小分组拿到对应的值,作为数组的索引值,进行替换;
     <script>
         var str="2018-08-22 20:35:56";
         var strTemplate="{0}年{1}月{2}日 {3}时{4}分{5}秒";
         var reg=/\d+/g;
         var ary=str.match(reg);
         var reg2=/{(\d)}/g;
         var str2=strTemplate.replace(reg2,function ($0, $1) {
              return ary[$1];
         });
         console.log(str2);//结果为:2018年08月22日 20时35分56秒
     </script>
    
  • 封装日期格式化formatDate()方法
     <script>
         var str="2018-8-22 20:35:56";
         //var strTemplate="{0}年{1}月{2}日 {3}时{4}分{5}秒";此时的strTemplate为默认模板,在没有传进实参时,用此模板;
         //封装到字符串原型上;
         String.prototype.formatDate=function(template){
             template=template || "{0}年{1}月{2}日 {3}时{4}分{5}秒";
             //含义:如果传入实参,template就为实参值,如果不传实参,那么template为undefined,给template重新赋值后面的模板;
             var ary=this.match(/\d+/g);
             var reg=/{(\d)}/g;
             var rem=template.replace(reg,function ($0, $1) {
                 return ary[$1];
             });
             return rem;//此时返回值设置为字符串,不是this,也不默认返回this;
         };
         var res=str.formatDate();
         console.log(res);//结果为:2018年8月22日 20时35分56秒
         var res2=str.formatDate("{0}年{1}月{2}日");
         console.log(res2);//结果为:2018年8月22日
         var res3=str.formatDate("{3}时{4}分{5}秒");
         console.log(res3);//结果为:20时35分56秒
     </script>
    

10. 知识点积累

10.1 "||"和"&&"的应用

  • 知识点:
    • 代码a || b中,若a为假,返回b;若a为真,返回a;
    • 代码a && b中,若a为真,返回b;若a为假,返回a;
  • 验证:
     <script>
         //知识点1:"||"在用于判断时的应用
         var temp="tiankong";
         var mm=temp||"meihao";
         console.log(mm);//结果为:"tiankong"
         var temp1=false;//可以是undefined,只要为假;
         var mm1=temp1||"meihao";
         console.log(mm1);//结果为:"meihao"
         var temp2;
         var ttn=null;
         var mm2=temp2||ttn;
         console.log(mm2);//结果为:"null";
         //总结:总结:代码a || b 中,1)如果a为真,则不会运行b,返回的结果为a的内容,不只是true,而是a的内容;2)如果a为假,则运行b,返回的结果为b的内容,b可以是真,也可以是假,返回的都是b;(可以是false,undefind,null);
     
         //知识点2:"&&"在用于判断时的应用
         var xmp="tiankong";
         var nn=xmp && "meihao";
         console.log(nn);//结果为:"meihao";
     
         var xmp1="tiankong";
         var xxn;
         var nn1=xmp1 && xxn;
         console.log(nn1);//结果为:"undefined";
     
         var xmp2;
         var nn2=xmp2 && "meihao";
         console.log(nn2);//结果为:"undefined";
     
         var xmp3;
         var xxn3=null;
         var nn3=xmp3 && xxn3;
         console.log(nn3);//结果为:"undefined";
     
         var xmp4=(4==5);
         var nn4=xmp4 && xxn4;
         console.log(nn4);//结果为:"false";
         //总结:代码a && b 中,1)如果a为假,则不会运行b,返回的结果为a的内容(可以是false,undefind,null);2)如果a为真,则运行b,返回的结果为b的内容,b可以是真,也可以是假,返回的都是b;
     </script>
    
  • 实例应用:函数调用时,"||"对实参赋值与否的应用
     <script>
         var ary=[1,2,3];
         var ary1=[4,5,6];
         function add(arg) {
             //函数中如果没有传实参,形参值就为undefined;
             arg=arg || ary;
             //含义:如果arg为真,即函数中传入实参,那么arg就为实参值;如果arg为假,即函数中没有传入实参,那么arg就为ary;
             console.log(arg);
         }
         add();//执行函数后,打印的结果为:[1,2,3];
         add(ary1);//执行函数后,打印的结果为:[4,5,6];
     </script>
    

10.2 正则只匹配不捕获

  • 知识点:正则表达式中,添加括号会捕获为小分组内容,然后返回在数组中,现在不想捕获小分组内容,小括号的作用只是分组的作用,提高优先级;
  • 代码:var reg1=/tiankong(?:\d+)/指的是匹配(\d+)的内容,不获取小分组的内容;
     <script>
         var str="tiankong123";
         var reg=/tiankong(\d+)/;
         console.log(reg.exec(str));//结果为:["tiankong123", "123", index: 0, input: "tiankong123", groups: undefined]
         //需求:只进行匹配,不进行捕获,即不去捕获小分组的内容;利用"?:";
         var reg1=/tiankong(?:\d+)/;
         console.log(reg1.exec(str));//结果为:["tiankong123", index: 0, input: "tiankong123", groups: undefined]
     </script>
    

10.3 小括号的用法

  • 分组
  • 提高优先级:/^(18|19)$/;验证18或19;
     <script>
          //目的:验证18或19
          var reg=/^18|19$/;//分析:1加8或1加9,以1开头,以9结尾;
          console.log(reg.test("18219"));//结果为true;
          console.log(reg.test("119"));//结果为true;
          //注意:当使用|的时候必须加小括号;
          //正确写法:
          var reg1=/^(18|19)$/;
          console.log(reg1.test("189"));//结果为false;
          console.log(reg1.test("18"));//结果为true;
     </script>
    
  • 小分组:匹配和捕获
  • 小分组:只匹配不捕获,小括号中添加?:
     <script>
         var str="tiankong123";
         var reg=/tiankong(\d+)/;
         console.log(reg.exec(str));//结果为:["tiankong123", "123", index: 0, input: "tiankong123", groups: undefined]
         //需求:只进行匹配,不进行捕获,即不去捕获小分组的内容;利用"?:";
         var reg1=/tiankong(?:\d+)/;
         console.log(reg1.exec(str));//结果为:["tiankong123", index: 0, input: "tiankong123", groups: undefined]
     </script>
    
  • 注意:在正则表达式中如果需要使用字符()必须要添加转义符"";
     <script>
         var str="alpha(opacity:10)";
         var reg=/alpha\(opacity:10\)/;//小括号当做字符使用时,需要加转义符;
         console.log(reg.test(str));//结果为:true;
     </script>
    

10.4 中括号的用法

  • 中括号中不会出现两位数;只能出现一个;
     <script>
          //[abc]意思是abc中的任何一个;不会出现两个;
          var reg=/^[11-89]$/;//分析:1或1-8或9,三者中的任何一个
          console.log(reg.test("1"));//结果为true;
          console.log(reg.test("6"));//结果为true;6在1-8之间;
          console.log(reg.test("11"));//结果为false;11不在三者之间;
     </script>
    
  • 中括号[]里面的字符意义会发生改变,分为两种
    • 如"+","."这些元字符,代表加,小数点;都不用加转义符;但是在其他的时候必须加转义符才能代表加,小数点的意思;
      • 对比1:[+-]指的是+或-,二者任何一个;此时中括号中的+号,不用加转义符,就代表加号的含义;
      • 对比2:(\+|-)指的是+或-,二者任何一个;此时在小括号中的+号需要添加转义符;才代表加号的含义;
    • 如"\w","\s","\d"这些元字符,带斜杠的仍然代表元字符的含义;
    • 中括号和小括号的共同点:是在使用或的时候,功能是一样的;都代表两者其一;
      • 中括号:[ab]指的就是a,b二者中任何一个;
      • 小括号:(a|b)指的也是a,b二者中任何一个;
      • 弊端:当a,b为数字时,必须是一位数时,才能用中括号,如果为两位数,只能用小括号;如[1234]代表的意思是1234四位数中的任何一个数;而(12|34)代表的是12或34;
      • 注意:尽量不要用小括号,因为在exec方法捕获时,会对小括号进行小分组;会导致错乱;可以用?:解决;

10.5 量词元字符"?"问号的用法

  • 0或1:代表可有可无;如有效数字正则表达式中的使用;
    • 如:(\.\d+)?)代表小括号中的数据可有可无;
  • 解决正则查找中的贪婪性:放在正则捕获中的量词元字符后面
    • 如:var reg=/\d+?/g代表捕获数字时,匹配多个数字的内容,但是在输出的时候,只输出一个数字;
  • 只匹配不捕获:用于小分组,在小分组中代码前添加?:;
    • 如:var reg1=/tiankong(?:\d+)/代表的意思是,只匹配到(\d+)内容,但是不会捕获(输出)小分组的内容;

11 回调函数callback

  • 定义:把函数的定义阶段,作为参数,传给另外一个函数,这个函数就叫做回调函数;
  • 知识点:
    • 回调函数中的this,一般为window,可以通过call改变this指向;
    • callback什么时候被调用,以及被调用多少次,取决于father这个函数
    • 回调函数可以传参
    • 回调函数的返回值,以及赋给的函数的返回值,回调函数被调用多次,会有多个返回值,然后放在数组中,以数组形式返回给father函数;
     <script>
         var obj={};
         function f1(n,m){
             console.log(this+(n+m));
             return "meihao";
         }
         function father(n){
             var ary=[];
             for(var i=0; i<4; i++){
                /* n(2,3);//回调函数执行,传入实参;this为window;*/
                 n.call(obj,2,3);//改变回调函数中的this指向为obj,并且传入实参;
                 ary.push(n(2,3));//将回调函数每次的返回值放进数组;
             }
             return ary;
         }
         var res=father(f1);//函数在定义阶段,会新建一个堆地址,然后把这个地址赋给函数名f1,此时把f1作为参数,传给father函数,则f1函数为回调函数;
     </script>
    

12 数组forEach方法

  • 定义:数组forEach方法作用是遍历数组实例对象,然后执行多次回调函数,每次给回调函数传入实参;
  • 知识点:
    • forEach方法可以有两个参数:callback,thisArg;(第二个参数是可选的,它是用来改变this指向的);
    • forEach方法中的回调函数,被调用的次数跟数组的长度一样,即遍历数组;
    • 回调函数接收3个参数:item(数组中的每一项) index(索引) input(原始数组);
    • forEach方法本身没有返回值;
    • 第二个参数thisArg,如果不设置,则回调函数中的this一般指向window,如果设置,那么this就指向thisArg值;
    • 兼容性:IE8及其以下浏览器不兼容;
     <script>
         //检验forEach方法的返回值:如果返回值只有一个undefined,说明forEach方法没有返回值;如果接收到的是一个数组,数组元素为undefined,那么说明forEach方法有返回值,但是回调函数没有返回值;
         var ary=[10,20,30,40,50];
         var obj={};
         var res=ary.forEach(function (item,index,input) {
             console.log(arguments);
             //打印结果为五个数组,第一个数组的内容为:[10, 0, Array(5)],说明forEach会遍历数组;
         },obj);
         console.log(res);//结果为:undefined;证明forEach没有返回值;
     </script>
    

13 封装浏览器兼容的ForEach方法

  • 知识点:
    • 浏览器兼容与否的判断条件为:判断数组类原型上是否存在forEach属性,用in判断;
    • 封装思路:分析封装方法的作用,是否需要传参数,是否有返回值;
  • 封装思路:
    • 封装方法,封装到所属类的原型上
    • 浏览器兼容时,使用forEach方法,如果浏览器不兼容,那么使用自己封装的方法;
    • 封装方法时,要了解其作用,是否需要参数,是否需要返回值
    • forEach方法的作用就是多次调用回调函数,调用的次数为数组实例对象的长度,如果添加thisArg值,则在调用回调函数时,改变其this指向;
    • forEach方法中,调用回调函数时,会给其传入三个实参,分别是:item数组每一项,index数组对应项的索引值, input原始数组;
    • forEach方法中不需要返回值;
     <script>
         //需求:封装forEach浏览器都兼容的方法,把ary数组克隆一份
         var ary=[10,20,30,40,50];
         //浏览器兼容与否,判定条件是:不同浏览器下数组类原型对象上是否存在forEach属性;即利用in来判断属性,a in b 指的是a是否为b的属性
         //封装到数组类的原型上
         Array.prototype.ForEach=function (callback,thisarg) {
             thisarg=thisarg || window;//意思为:如果传入实参,那thisarg就为实参值,如果没有传入实参,那么thisarg为window;其中window为对象;
             //此时this代表的是数组ary;
             //1)如果浏览器兼容,直接用浏览器支持的属性;
             if("forEach" in Array.prototype){
                 this.forEach(callback,thisarg);
               //Array.prototype.forEach.call(this,callback,thisarg);也可以写此行代码;
                 return;//阻断程序执行;不需要返回值;
             }
             //2)不兼容的时候封装一个方法
             //方法会传两个实参,一个是回调函数的定义阶段,一个是thisArg;
             //方法的作用,就是对回调函数进行多次调用,次数为数组实例对象的长度;
            for(var i=0; i<this.length; i++) {
                callback.call(thisarg, this[i], i, this);
                //没有返回值,所以不需要添加return;
            }
         };
         function fn(item,index,input) {
              console.log(arguments);
         }
         ary.ForEach(fn);
     </script>
    

14 数组map方法

  • 定义:数组map方法代码格式跟forEach方法一样,也是遍历数组,多次调用回调函数,改变回调函数this指向,但是唯一不同的是,map方法有返回值,返回值为一个数组,数组元素为回调函数每次执行后的返回值;
  • 知识点:
    • map方法唯一的不同是,存在返回值,返回值为一个数组,由回调函数每次执行后的返回值组成;
    • map方法的其他特性跟forEach方法一样;
    • map方法:IE8及其以下浏览器不兼容;
     <script>
         var ary=[10,20,30,40,50];
         var res=ary.map(function (item, index, input) {
             return item+index;
         });
         console.log(res);//结果为:[10, 21, 32, 43, 54]
     </script>
    

15 封装浏览器兼容的Map方法

  • 知识点:
    • 与forEach方法不同点,map方法具有返回值;
     <script>
         var ary=[10,20,30,40,50];
         //封装方法要在所属类的原型上封装
         Array.prototype.Map=function (callback, thisarg) {
             thisarg=thisarg || window;
             if("map" in Array.prototype){
                 return this.map(callback,thisarg);
             }
             var ary1=[];
             for(var i=0; i<this.length; i++){
                 var rem=callback.call(thisarg,this[i],i,this);
                 ary1.push(rem);
             }
             return ary1;
         };
         function fn($1,$2) {
             return $1*$2;
         }
         var res=ary.Map(fn);
         console.log(res);//结果为:[0, 20, 60, 120, 200]
     </script>
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • 1.1 正则基础 正则的含义:由特定的符号组成的具有特殊含义的代码; 正则的目的:就是制定一些规则,来操作(校验/...
    果木山阅读 95评论 0 0
  • 前言 最先接触编程的知识是在大学里面,大学里面学了一些基础的知识,c语言,java语言,单片机的汇编语言等;大学毕...
    oceanfive阅读 3,068评论 0 7
  • --------------------------正则的作用--------------------------...
    G_whk阅读 618评论 1 5
  • 前言 作为一个程序员,要出去装逼,手中必备的技能就是正则表达式。程序员的正则表达式,医生的处方和道士的鬼画符,都是...
    Layzimo阅读 549评论 0 6
  • //定义正则表达式的两种方式,在用构造函数的时候,有些地方是要加转义字符的。 //1、字面量。 var reg =...
    xiaobing0324阅读 494评论 0 0