js第三周总结

98 阅读13分钟

正则表达式

什么是正则表达式:定义字符串中字符出现规则的表达式
何时使用:分割、替换、验证
语法:
    /正则表达式/;
            1、最简的正则:/关键字原文/"no" -> /no/后缀
            后缀:g:全部      i:忽略大小写
            
            2、备选字符集:/[备选字符集]/;
                        强调:1、一个中括号,只管一位字符
                              2、正则表达式默认只要满足了就不管后续了,我们希望从头到尾完全匹配,解决:前加^后加$:/^[备选字符集]$/;
                            
                    特殊:如果备选字符集中ascii码是连续的,那么中间部分可以-省略
                    比如:以为数字:[0-9]
                         一位字母:[A-Za-z];
                         一位数字、字母、下划线:[0-9A-Za-z_]
                         一位汉字:[\u4e00-u9fa5]
                         
         除了xxx之外的:[^0-9] - 很少使用,范围太广了
         
         3、预定义字符集:前辈们提前预定义了一些字符集,方便我们程序员 - 简化备选字符集
                 一位数字:\d => [0-9]
                 一位数字、字母、下划线:\w = >[0-9A-Za-z_];
                 一位空白字符:空格、回车、制表符\s
                 
                 一位除了换行之外的任意字符:. - 很少使用,范围太广了
                 
                 建议:优先使用预定义字符集,预定义字符集满足不了再用备选字符集补充
                 
         4、问题:不管是预定义字符集还是备选字符集,一个都只管一位
         量词:规定一个字符集出现的次数:
             1、有明确数量:
                 字符集{n,m}:前边相邻的字符集,最少n次,最多m次
                 字符集{n,}:前边相邻的字符集,最少n次,多了不限
                 字符集{n}:前边相邻的字符集,必须n次
                 
             2、无明确数量:
                 字符集?:前边相邻的字符集,可有可无,最多一次
                 字符集*:前边相邻的字符集,可有可无,多了不限
                 字符集+:前边相邻的字符集至少一次,多了不限
                 
          5、选择和分组:
                  选择:在两个规则中选择一个
                          规则1|规则2
                  分组:将多个字符集临时组成一组规则
                          (规则1|规则2)
                          
           6、指定匹配位置:
                       开头:^
                       结尾:$
                       特殊:两者同时出现,前加^后加$,表示从头到尾要求完全匹配 - 只要是做验证必须加上
          
          
          7、预判:密码强度验证
          
              /^(?![0-9]+$)[0-9A-Za-z]{4}$/; - 前面的预判意思是:不能纯由数字组成,可能由大写、小写
		/^(?![A-Za-z]+$)[0-9A-Za-z]{4}$/; - 前面的预判意思是:不能纯由大写字母组成,也不能纯由小写字母组成,也不能纯由大写和小写字母组成
		
		/^(?![0-9a-z]+$)(?![A-Za-z]+$)[0-9A-Za-z]{4}$/; - //4位密码,数字和字母都可以,至少要有一位大写和一位数字。
		/^(?![0-9a-z]+$)(?![A-Za-z]+$)(?![A-Z0-9]+$)[0-9A-Za-z]{4}$/; - //4位密码,数字和字母都可以,至少要有一位大写和一位数字和一位小写。
		/^(?![0-9A-Za-z]+$)[0-9A-Za-z\u4e00-\u9fa5]{4}$/ - //至少要有一位汉字
                    
                    

String支持正则的API:

      1、分割:var arr=str.relace(str/reg,"新内容");
        //replace支持正则,搭配上后缀就可以替换所有的关键字,而且替换往往都要加后缀
        //问题:只能替换为固定的内容
        
      2、高级替换法:
              var newStr=str,replace(/[][][][][]+/g,function(a,b,c){
              console.log(a);//要替换的关键字 - 正则匹配到的关键字
              console.log(b);//要替换的关键字的下标 - 正则匹配到的关键字的下标
              console.log(c);//原文本身
              return a.length==2?"**":a.length==3?"***":"***";
              });
              
       3、格式化:
               var idCard="500243199805207472";
               var reg=/\d{4}(\d{4})(\d{2})(\d{2})\d{4}/;
               idCard=idCard.replace(reg,function(a,b,c,d){
         //在replace的时候,如果正则出现了分组,那么我们会得到更多的形参
         //再形参a的后就会再出现n个形参,具体多少个看有多少个分组
         //第一个分组获取到的内容会保存在第二个形参之中
         //第二个分组获取到的内容会保存在第三个形参之中
         //...
         //倒数两个形参分别是下标和原文
         return b+"年"+c+"月"+d+"r+”日";
         })
         
          
         

正则对象: 创建:

     1、直接量方式:var reg=/正则表达式/后缀;
     2、构造函数方式:var reg=new RegExp("正则表达式","后缀");
     
     方法:1个
     验证:var bool=reg.test(用户输入的);
             true->说明用户输入正确
             flase->说明用户输入错误
             
             

Math数学对象:专门提供了数学计算的API

           强调:不需要创建,直接使用的,有浏览器的js的解释器自动创建
           属性:Math
           方法:
               1、取整:
                       1、上取整:超过一点点,就会取下一个整数
                       var num=Math.ceil(num);
                       2、下取整:无论超过多少,都会省略小数部分
                       var num=Math.floor(num);
                       3、四舍五入取整:
                               var num=Math.round(num);//进制只看小数的第一位
                               
                      //取整方式:以上三个+parseint(str)+*num.toFixed(d);
                      个人推荐:*num.toFixed(d),优点:可以四舍五入保留指定小数位数
                      缺点:返回的结果是一个字符串,建议搭配上parseFloat一起使用
                      
      笔试题:不允许使用toFixed的情况下,自己封装一个函数,实现toFixed的功能,并且最后返回一个数字,看用户提供的数字和保留几位小数,对着用户的这个数字*10的几次方(保留几位小数),在使用Math.round四舍五入取整对着这个数字/10的几次方(保留几位小数)
      
             2、乘方:Math.pow(底数,幂)  === 底数**幂
               开平方:Math.sqrt(num)
               
            3、绝对值:把负数转为正数
                    Math.abs(num);
                    
            4、最大值和最小值:
                    var max/min=Math.max/min(a,b,c,d,e.....);
                    问题:本身不支持数组参数的
                    解决:固定用法:
                            var max/min=Math/min.apply(Math,arr);
                            apply其中一个功能是可以将数组打散为单个元素
                            
           5、随机整数:Math.random() - 在0-100之间取出一个随机的小数,可能取到0,但是绝对不可能取到1,意味着可能取到最小数,但是不能取到最大数
           公式:parseint(Math.random()*(max-min+1)+min);
           

Date日期对象

    创建:
        1、创建一个当前日期时间:
            var now=new Date();
            
        2、创建一个自定义时间:
                var birth=new Date("yyyy/MM/dd hh:mm:ss");
        3、创建一个自定义时间:
            var birth=new Date(yyyy,MM,dd,hh,mm,ss);
                //修正月份:从0开始的,0 => 11月
                
        4、复制一个日期:
            为什么:日期的所有的API都是直接修改原日期的,无法获得修改之前的日期,所以,在执行API之前先进行复制,然后在对复制的日期进行操作
            var end=new Date(start);
            
         操作:
             1、两个日期对象之间可以相减,得到一个毫秒差,通过毫秒差就可以换算出你想要的任何一部分 - 日期的本质其实就是保存的毫秒差
             var date=new Date(毫毛数);
             
             2API:
                 分量:时间的单位
                 年月日星期:FullYeayMonthDateDay
                 时分秒毫秒:HoursMinutesSecondsMilliseconds
                 每一个分类都有一对儿getXXX/setXXX
                     其中getXXX负责获取某一个分量的值
                     其中setXXX负责设置某一个分量的值
                     
              特殊:
                  1、取值范围:
                          FullYeay - 当前的年份
                          MOnth - 0~11
                          Date - 1~31
                          Day:0~6
                          Hours:0~23
                          MinbtesSeconds:0~59
                  2、在设置时间的时候,如果超过了范围,会自动进制
                  3Day是不允许设置的
                  
              3、如果希望对某个分量进行加减操作,推荐一句话完成
              date.setXXX(date.getXXX()+/-num)
              
              4、格式化日期为字符串:
                  作用:1、date->string:stringAPI更多更实用
                        2、默认的标准国际日期,不是所有人都认识
                 date.toLocaleString();//转本地字符串
                 问题:存在兼容问题
                 解决:自定义日期格式化format
        

Error错误对象:

    1、快速找错
    2、记得有时候可能要防一手用户

1、浏览器自带四种错误类型,可以快速找到自己的错误:
    语法错误:SyntaxError-多半是语法、符号错了
    引用错误:ReferenceError-没有创建过却使用了
    类型错误:TypeError-不是你的方法/属性却用了
    范围错误:RangeError-只是一个API:num.toFixed(d);//d取值范围的,0~100之间
    
2、只要发生错误,就会报错,会导致后续代码终止执行了(后面代码没有效果、如果做的是APP、软件发生报错,则会闪退体验感差)我们不希望
    错误处理:就算发现错误,我们也不希望报错而是给一个错误提示,后续代码依然可以继续执行
    语法:
        try{
            只放可能出错的代码
        }catch(err){
            只有发生错误后才会执行
        }
      try...catch...的性能很差,几乎是所有代码中效率最差的
      可用一个技术代替:if...else...
      开发经验:提前预判用户:记住一切的客户端输入/用户输入都是坏人-一定要做好防护
      
 3、抛出自定义错误:
         throw new Error("自定义错误描述")
         
         

function:

     1、创建:
         声明方式:function 函数名(形参列表){函数体 return返回值}-具有完整的声明提前
         直接量方式:var 函数名=function(形参列表){函数体 return返回值}-只提前函数名部分,函数名其实就是一个变量
         构造函数:var 函数名=new function(“形参1”,形参(2),...,"函数体");
       何时:如果你的函数体不是固定的,而是动态拼接的(函数体现在毕竟是一个字符串)
       
     2、调用:
         var 接住结果=函数名(实参列表)
         
     3、考点:
             1、如何创建
             2、什么是作用域
             3、什么是声明提前
             4、什么是按值传递
             5、什么是重载:相同的函数名,传入不同的实参,可以自动选择对应的函数执行
             为什么:减轻程序员的压力
             问题:js的语法不支持重载的
                         js不允许多个同函数名存在,如果同时存在,最后的会覆盖之前的
             解决:在函数中有一个对象-arguments对象
             什么是arguments:自动创建的,是一个类数组对象,不是数组
             作用:接收所有的实参
                  以后有没有实参无所谓了,变相的实现了重载,可以在函数内部判断arguments的不同,执行不同的操作
                  
             只有3个点和数组相同:
                     1、都有下标
                     2、都有length
                     3、都可以遍历
                     
           正式开发中,开发结束后,需要做代码优化,可能就会将多个函数整合为一个函数
           

匿名函数:没有名字的函数,理论上来说我们无法调用

    1、自调:函数自己调用自己
            语法:
                    (function(){
                        //代替全局代码
                 })();
                 
                 
             特点:自调的代码只能执行一次===全局代码
             为什么:节约内存,因为匿名函数,没有变量引用着,用完后,就会立即释放
             
   2、回调:将函数作为了实参,传递给其它函数使用
           1、学习回调的目的:让我们知道哪些讲回调,匿名函数,只要不是自调,就是回调
           arr.sort(function(a,b){return a-b})
           str.replace(reg,function(){})
           btn.onclick=function(){}
           
           2ES6有一个技术箭头函数:简化一切的回调函数
           
           

function:

    作用域:
            1、全局:随时可以用,可以反复使用。缺点:容易污染
            2、局部:只能在函数调用时内部可用,不会被污染。缺陷:一次性的,是会自动释放的
            
   函数执行的原理:
           1、程序加载时:
                   创建执行环境栈(ECS):保存了函数调用的顺序的数组
                   首先压入全局执行环境(全局EC)
                   全局EC引用着全局对象window
                   window中保存着全局变量
                   
           2、定义函数时:
                   创建函数对象:封装代码段
                   在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
                   全局函数的scope都是window
                   
         3、调用前:
                 在执行环境栈(ECS)压入一个新的EC(函数的EC)
                 创建活动对象(AO):保存着本次函数调用时用到的局部变量
                 在函数中的EC有一个属性scope chain(作用域链)引用AO
                 
        4、调用时:
                正是因为有了前三个步骤,我们才有了变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
                
       5、调用完:
               函数的EC会出栈,AO无人引用,垃圾回收器登场,AO自动释放,局部变量也就自动释放
               

两链一包:

    作用域链:以函数的EC为起点,经过AO,逐级引用,形成的一条链式结构我们就称之为作用域链
    何时使用:保护一个可以反复使用的局部变量
    如何使用:
                1、两个函数进行嵌套
                2、外层函数创建收到保护的变量
                3、外层函数return出内层函数
                4、内层函数要去操作受保护的变量
      强调:
               1、判断是不是闭包,有没有两层函数嵌套,返回内层函数,内层函数在操作外层受保护的变量
               2、外层函数调用几次,就创建了几个闭包,受保护的变量就有了几个副本
               3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
               
      缺陷:受保护的变量,永远不会被释放,使用过多,会导致内存泄漏
      问题:应该在哪里使用?使用场景:防抖节流
              三个事件需要防抖节流:
                      
                      1、elem.onmousemove-频繁的修改DOM树,映像性能
                      2、input.oninput-每次input的内容修改都会触发,性能不好
                      3window.onresize
                      
                      xxx.以上三个事件=function(){
                              inner();
                 }
                 
           公式:
           function fdjl(){
               var timer=null;//局部的timer准备保存定时器,定时器的序号
               return function(){
                   if(timer!==null){clearTimeout(timer)}//停止一次性定时器
                   timer=setTimeout(function(){
                           操作
                   },1000)
               }
           }
           var inner=fdjl();
           

Object对象:

    1、面向对象:三大特点:封装、继承、多态
    1、笔试题:简单的说一说面向对象和面向过程开发方式的区别
    面向对象:对象,js有一句话万物皆对象,假设一个人是一个对象的话
    面向过程:经过:开始-结束,我们一直的开发方式都是面向过程:先干什么在干什么最后干什么
    
    为什么要面向对象:现实生活中所有的数据都必须包含在一个事物中才有意义
    何时要使用面向对象开发方式:以后做任何操作都要封装在一个对象中
    
    2、封装:创建自定义对象:
            1、直接量:
                var obj={
                    "属性名":属性值,
                    ...
                    "方法名":function(){操作},
                    ...
                };
                
             特殊:
                 1、其实属性名和方法名的“”可以不加的
                 2、访问对象的属性和方法
                     obj.属性名
                     obj.方法名()
                     js有一句话万物皆对象,一切对象的底层都是hash数组
                3、访问到不存在的属性,返回undefined
                4、可以随时随地的添加新属性和方法
                5、箭头函数this->window
                6、构造函数中的this->当前正在创建的对象
                
           2、预定义构造函数方式:var obj=new Object();//空对象
           //需要后续自己慢慢添加
           obj.属性值;
           obj.方法名=function(){}
           
    以上两个方法都有一个缺陷:一次只能创建一个对象
    
    
          3、批量创建对象:自定义构造函数方式
                  1、创建自定义构造函数
                          function 类名(name,age,hobby){
                   this.nanme=name;
                   this.agage;
                   this.hobby=hobby;
                          }
                          
                  2、调用构造函数创建出对象
                      var obj=new 类名(实参列表);
                      
           面向对象:
                   优点:
                       1、逼格高,所有的属性和方法都保存在一个对象之中
                       2、每个功能特地放开些-便于后期维护,哪怕没有注释,我也能一眼看懂代码
                       铁索链舟-一个方法触发多个方法联动
                       
                  缺点:对新手不友好,this指向变来变去的