js第三周

106 阅读12分钟

正则表达式

语法::/正则表达式/

1.最简单的正则:关键字原文本身:"no"/no/ig

  i:忽略大小写
  g:全部
复制代码

2.备选字符集:一个备选字符集:规定了一位字符克用的备选字符列表

  /[备选字符列表]/
      强调:1.一个中括号,只能匹配一位字符
          2.正则默认只要满足后,就不在管理后续操作,
      解决:只要是做验证:必须在备选字符集前加^,后面加$,.表示从头到尾完全匹配
           1.如果备选字符集中,unicode号是连续的,可以省略中间部分
           2.除了xxx之外,其他的的都可以.
                 [^xxx]
                 [^0-9]
复制代码

3.预定义字符集:

  一位数字:\d    ==>[0-9]
  一位数字.字母.下划线:\w    ===>[0-9A-Za-z]
  一位空白符:\s  ==>空格.制表符.换行
  一位除了换行外的任意字符:  .   
建议:不管是备选字符集,还是预定义字符集,一个都只管一位
复制代码

4.量词:规定了一个字符集出现的次数

 1.有明确的数量
     字符集{n,m}:前边相邻的字符集,最少出现n次,最多出现m次
     字符集{n,}:前边相邻的字符集,最少出现n次,多了不限
     字符集{n}:前边相邻的字符集,必须出现n次
 2.没有明确数量
    字符集? : 前边相邻的字符集,可有可无,最多一次
    字符集* : 前边相邻的字符集,可有可无,多了不限
    字符集+ : 前边相邻的字符集,至少一次,多了不限
复制代码

指定匹配的位置

   ^:以xx开头
   $:以xx结尾
     特殊:如果^和$同时出现:前加^后加$,代表要求从头到尾完全匹配
复制代码

选择和分组

    选择:规则1|规则2  可有在多个规则中选择满足的规则进行执行
    分组:添加子规则:(规则1|规则2)
复制代码

预判

 密码强度
      (?![0-9]+$)字符集量词   不能全由数字组成
     (?![0-9A-Z]+$)字符集量词    不能全由数字组成,不能全由大写组成,不能全由数字和大写组成
      (?![a-z0-9]+$)(?![a-zA-Z]+$)(?![0-9A-Z]+$)[0-9A-Za-z]{2,4}    不能是纯数字.纯大写.纯小写组成,不能是小写和数字组成,不能是小写和大写组成,不能是数字和大写组成
复制代码

字符串中支持正则表达式的API

1.分割

    var arr=str.split(reg);
复制代码

2.替换字符串

 1.基本替换发
     var newStr=str.replace(reg,"新内容");
      特殊:
       1.默认只会替换第一个关键字,想要替换所有要加后缀g
       2.替换的内容只能是一个固定的新内容
 2.高级替换法
      var newStr=str.replace(/[正则表达式]/,function(a,b,c){
            console.log(a);  匹配到的关键字
            console.log(b);  匹配到的关键字的下标
            console.log(c);  原文本身
            return a.length==2?"**":"***";
       });
 3.格式化
      var newStr=str.replace(reg,function(a,b,c...){
	console.log(a);//正则匹配到的关键字
	console.log(b);//第一个分组获取到的内容
	console.log(c);//第二个分组获取到的内容
	return "格式化的东西"
      });
复制代码

3.正则对象

 创建正则对象:
     直接量方式:var reg=/正则表达式/后缀
     构造函数:var reg=new RegExp("正则表达式","后缀");
方法:var bool=reg.test(user);
     布尔值如果是true,说明输入符合我们的要求,flase说明不通过
复制代码

MATH:专门提供了数学计算

    强调:不能创建,不需要创建,直接使用
    唯一的属性:Math.PI
复制代码

API

1.取整

   上取整:只要超过一点点,就会去下一个整数,此方法小数位数不能超过15位,否则会失效  : Math.ceil(num);
   下取整:不管超过多少,都会省略小数部分,此方法小数位数不能超过15位,否则会失效:  Math.floor(num);
   四舍五入取整:Math.round(num);
   arseFloat(num.toFixed(d));  既有四舍五入功能,又具有保留自定义小数位数的操作,结果是一个字符串
复制代码

笔试题

 封装一个函数,实现可以自定义保留小数位数并且四舍五入的功能,打单不允许使用toFixed
   function round(num,d){
        num*=Math.pow(10,d);
        num=Math.round(num);
        num/=Math.pow(10,d);
        return num.toString();
   }
复制代码

2.乘方和开方

  乘方:Math.pow(底数,幂);  简化连续的乘法
  开方:Math.sqrt(num);  只能开平方
复制代码

3.最大值和最小值

  语法:Math.max/min.apply(Math,arr);
  apply:自己没有的方法可以去借用,可以将数组打散为单个参数进行传入
复制代码

4.绝对值:将负数转为整数

  Math.abs(num);
复制代码

5.随机数

 公式:parseint(Math.random()*(max-min+1)+min);
 Math.random()已经是一个随机数,随机小数0-1,有可能取到0,取不到1.
复制代码

Date:封装了一个日期对象,提供了对日期事件进行操作的API

1.创建日期对象

   1.创建当前时间: var new=new Date();
   2.创建自定义时间: var birth=new Date("yy/MM/dd hh:mm:ss");
                   var birth=new Date(yy,MM,dd,hh,mm.ss);
   3复制一个日期对象: var end=new Date(now);
       为什么:日期对象的API都是直接修改原日期对象,使用API后,无法同事保存旧的日期对象
       何时使用:在调用日期对象的API前要先复制,在使用API
  4.var xx=new Date(毫秒数);
复制代码

2.操作

  1.两个日期对象之间可以相减,得到毫秒差,换算出想要的任何一部分
   2.API
      分量:时间单位  FullYear  Month  Date  Day  Hours  Minutes  Seconds
            1.每一个分量都有一堆方法: getxxx()/setxxx()
            2.固定套路:对着某个日期直接做加减
                 date.setXXX(date.getXXX()+3)
            3.格式化字符串:
                 国际日期格式化为本地日期:date.toLocalString();
                   问题:1.具有浏览器的兼容性问题
                       2.不可以在使用日期对象的API,也不会在带有进制操作
                       好处:转为了字符串,可以用字符串的API
复制代码

Error 错误对象

1.浏览器自带的4种错误类型

 语法错误:SyntaxError  -可能是符号错误
 引用类型:ReferenceError -没有创建过,就去使用了
 类型错误:TypeError  -不是你的方法,却使用了
 范围错误:RangeError  -只有一个API:num:toFixed(d);,范围是0-100之间
复制代码

2.错误处理

  当程序发生错误,保证程序不会异常中断的机制
  语法: try....cacth...语句
          try{
                 肯出错的代码
          }cacth(err){
                 console.log(err);  提示用户错误的原因是什么
          }
                 后续的代码都可以执行
  不推荐使用:try...cacth...的效率非常 低下,推荐使用if...elser
复制代码

3.抛出自定义错误

  throw new Error("自定义错误信息");
复制代码

Function 函数对象-方法

创建

    1.声明方式:function 函数名(形参列表){函数体;return 结果;}
        具有完整的声明提前
    2.直接量方式:var 函数名=function(形参列表){函数体;return 结果;}
        也有声明提前,但赋值留在原地
    3.构造函数方式-函数体不是固定:var 函数名=new Function("形参1","形参2",...,"函数体");
        函数体是动态拼接的时候,不能省略""部分
复制代码

调用

    函数名();
    元素.onclick();
复制代码

重载

 相同的函数,根据传入的实参不同,会自动选择对应的函数执行
 问题:js不支持重载,不允许同事存在多个同名函数,如果存在多个同名函数,最后一个会覆盖之前的所有函数
 解决:arguments对象-只能在函数内部可用,是一个类数组对象
       作用:接住所有的实参
       相同:支持下标,支持length,支持遍历
 变相实现重载:通过判断arguments的不同,执行不同的操作
复制代码

匿名函数

概念:没有名字的函数,没有变量名/函数名引用着,调用完毕后悔立即释放-是一次性函数
1.匿名自调函数:代替全局作用域
        (function(){
            函数体; 
        })()
2.匿名函数回调:某个函数调用时,传入的实参又是一个函数,而且不需要我们调用,会自动执行
复制代码

Function

闭包:作用域

  1.全局作用域:成员随处可用,可用反复使用,容易被污染
  2.函数作用域:成员只有当前函数调用时内部可用,调用完了就会释放
复制代码

函数的执行原理

1.程序加载时:
   创建执行环境栈(ESC):保存函数调用顺序的数组
   首先压入全局执行环境(全局EC)
   全局EC中引用着全局对象window
   window中保存着全局变量
复制代码
2.定义函数时
    创建函数对象:封装函数的定义
    在函数对象中创建scope属性,记录着自己来自的作用域
    全局函数的scope都是window
复制代码
3.调用函数时
   在执行环境栈ESC压入新的函数的EC
   创建活动对象AO:保存着本次函数调用时用到的局部变量
   在EC中添加scope chain属性引入Ao
   设置Ao的parent属性为函数的scope引用的对象
复制代码
4.调用时
    变量的使用规则:优先使用局部的,局部没有找全局,全局没有报错
复制代码
5.调用完
    函数的EC会出栈,AO会自动释放,局部变量也会自动释放
复制代码

作用域链

    以EC中的scope chain属性为起点,经Ao逐级引用,形成的一条链式结构
        作用:查找变量
复制代码

闭包

目的:保护一个可以反复使用的局部变量的一种词法结构,结合了全局和局部的优点
   唯一的缺点:受保护的变量永远不能释放,用多了会导致内存泄漏
   只会在防抖节流里面使用:
        1.创建一个外层函数
        2.在其中创建一个受保护的局部变量
        3.外层函数调用要返回内层函数,此内层函数在操作受保护的变量
复制代码

笔试题:

  1.判断闭包,找到受保护的变量,确定其值
  2.外层函数调用几次,就创建了几个闭包,受保护的变量就有九个副本
  3.同一次外层函数调用,返回的内层函数,都是在使用同一个受保护的变量
复制代码

固定语法:

   function 外层函数(){
       受保护的变量;
         return function(){
            不断的操作受保护的变量;
        return 结果;
        }
   }
   var 内层函数=外层函数();
复制代码

三个事件需要防抖节流

  1.elem.onmousemove-鼠标移动事件,每次移动就会触发
  2.input.oninput -input每次修改就会触发
  3.window.onresize-屏幕每次改变大小就会触发
  固定公式:
      function 函数名(){
      var timer=null;
      return function(){
           判断有没有定时器,有就清楚
                if(time){
                     clearTimeout(timer)
                }
                timer=setTimeout(function(){
                     要做的操作
                },毫秒数)
                    console.log(timer);  定时器的序号
                    }
                }
                var animate=函数名();
复制代码

Object:面向对象开发方式

    特点:封装 继承 多态
复制代码

1.封装/创建/定义/声明/实例化

    1.直接量方式
        var obj={
            "属性名"=:属性值,
            ...
            "方法名":function(){},
            ...
        }
      强调:1.属性名和方法名的""可以省略,但不推荐
          2.如何访问对象属性和方法
              obj.属性名;   ===obj["属性名"]
              obj.方法名();  ====obj["方法名"]();
          3.访问到不存在的属性,返回undefined
          4.也可以在后续随时添加自己想要的东西
     特殊:this在当前对象的方法内,指向当前调用的方法对象
         1.单个元素绑定事件this->单个元素
         2.多个元素绑定事件thia->当前触发的元素
         3.函数中也可以使用this->当前调用函数的对象
         4.构造函数中出现this->当前正在创建的对象
复制代码

预定义构造函数

     var obj=new Object();  空对象
         obj.属性名=属性值;
         ...
         obj.方法名=function(){}
         ...
复制代码

自定义构造函数

    1.创建一个构造函数
        function 类名(形参,...){
            this.属性名=形参1;
            this.属性名=形参2;
            ...
        }
    2.反复调用构造函数创建出多个对象
        var xx=new 类名(实参,...)
复制代码

面向对象

继承
    定义:父对象的成员(属性和方法).字对象可以直接使用
    原型:保存一类子对象共有属性和共有方法的原型对象
复制代码

如何找原型对象

    1.对象名.__proto__  至少要创建一个对象才可以使用
    2.构造函数名.prototype
        new 构造函数(Object RegExp....)
复制代码

在原型对象中添加共有属性和共有方法

    原型对象.属性名=属性值
    原型对象.方法名=function(){}
复制代码

原型链

    自己没有的方法和属性,可以顺着原型链一直向上找,直到最顶层:Opject.prototype
    作用:查找属性和方法
复制代码

判断一个属性是自有还是共有

    1.判断自有:obj.hasOwnProperty("属性名");
        如果结果为true.说明是自有
        如果结果为false,可能共有,看能是没有
    2.判断条件:obj.hasOwnProperty("属性名")==false;//可能是共有也可能是没有
        "属性名" in obj;//in关键字会查找自己的原型
	if(obj.hasOwnProperty("属性名")==false && "属性名" in obj){
		console.log("共有")
	}else{
		console.log("没有")
	}
    示例:    
        
        if(obj.hasOwnProperty("属性名")){
	console.log("自有");
        }else{
	if(obj.hasOwnProperty("属性名")==false && "属性名" in obj){
	console.log("共有")
        }else{
	console.log("没有")
	}
        }
复制代码

修改/删除属性

    自有:修改:obj.属性名=新值;
    删除:delete obj.属性名;
    共有:修改:千万不要在本地做操作,那会导致在本地添加上一个同名属性,优先使用自己的,但并没有修改原型对象
    删除:千万不要在本地做操作,那会导致白做没有任何效果
    强调:一定要找到原型再做操作
复制代码

为一类人添加方法

    为老IE的数组添加indexOf方法 - 原本只有字符串可以使用,是后续升级数组才能使用的
if(Array.prototype.indexOf === undefined){//老IE
        Array.prototype.indexOf = function(key,starti){
	starti===undefined&&(starti=0);
	for(var i=starti;i<this.length;i++){
                if(this[i]==key){
                    return i;
                }
	}
	return -1;
        }
}
复制代码

为一人添加共有方法

    构造函数名.prototype.函数名=function(){
	this->函数中的代表当前调用此函数的对象
}
复制代码

判断x是不是一个数组

    1、判断当前x对象是否是继承自Array.prototypeArray.prototype.isPrototypeOf(x);
	true说明是一个数组

2、判断当前x对象是否是由此构造函数所创建
	x instanceof Array
	true说明是一个数组

3Array.isArray(x); - 只有数组才有此方法
	true说明是一个数组
            
    4、在Object的prototype中保存着最原始的toString方法
            原始的toString输出的结果:[object 构造函数名]
复制代码

多态

    子对象觉得父对象提供的方法不好用,可以再本地定义一个同名成员,优先使用离自己更近的方法
同一个函数名,但根本不是同一个方法
    固定套路:
f(Object.prototype.toString.apply(arr)==="[object Array]"){
            数组
}
复制代码

如何设置自定义继承

设置单个对象的继承:
        obj.__proto__=新对象

设置多个对象的继承:
        构造函数名.prototype=新对象
        注意时机:在创建对象之前就设置好父对象


作者:前端小奇
链接:juejin.cn/post/704033… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。