第三周

167 阅读15分钟

一、正则表达式

什么是正则表达式:定义符中字符串出现规则的表达式
使用:切割、替换、验证
语法:/正则表达式/
**1、最简单的正则**
    /123/ig(i:忽略大小写;g:全部)
**2、备选字符集**
    一个备选字符集:规定了以为字符可用的备选字符列表
    /[备选字符列表]/
    reg.test(user);用于验证,结果是一个布尔值
注意:
    1.一个括号只能匹配以为字符
    2.正则默认只要满足后,就不用管理后续操作,后续用户可以乱输入
        避免用户乱输入:/^[备选字符集]$/前加^后加$代表要求从头到尾要完全
        匹配--即用户输入的东西必须和正则规定的一样
特殊:
    1.如果备选字符集中,unicode号是连续的,那么中间部分可用-代替
    例如:一位数字:[0-9]  一位字符[A-Za-z] 一个汉字[\n4e00-\n9fa5]
    一个数字、字母、下划线[0-9A-Za-z_]
    除了xxx之外,其他都可以:[^xxx]
**3、预定义字符集**
    前辈们提供的一些常用的字符集的简化写法
    一位数字:\d;即[0-9]
    一位数字、字母、下划线:\w;即[0-9A-Za-z_]
    一位空白字符:\s;即空格、制表符、换行
    一位除了换行意外的任意字符:.     范围太广
**4、量词**
    规定了一个字符集出现的次数
1、有明确的数量
    字符集{n,m}:前边相邻的字符集,最少出现n次,最多出现m次
    字符集{n,}:前边相邻的字符集,最少出现n次,多了不限
    字符集{n}:前边相邻的字符集,必须出现n次
 2、没有明确数量
     字符集?:前边相邻的字符集,可有可无,多了最多一次
     字符集*:前边相邻的字符集,次数不限
     字符集+:前边相邻字符集,至少一次,多了不限
**5、制定匹配位置**
    ^:表示以什么开头
    $:表示以什么结尾
    特殊:如果两个同时出现,前加^后加$,表示要求从头到尾完全匹配所写的正则
**6、选择和分组**
    选择:规则1|规则2
        可以在多个规则中选择满足的规则进行执行
    分组:添加子规则:(规则1|规则2)
**7、预测**
    主要用于密码强度的限定
    语法:(?![0-9]+$)字符词量级,表示不能全部由数字组成
    (?![0-9A-Z]+$)字符集量词,表示不能全部由数字组成,不能全由大写字
    母组成,也不能全由数字和大写字母组成
    (?![a-z0-9]+$)(?![a-zA-Z]+$)(?![0-9A-Z]+$(?![0-9a-zA-Z+$))    表示不能是纯数字、纯大写、纯小写,也不能是小写和数字的组成,也不能是    小写和大写的组合,也不能是数字和大写的组合复制代码

二、字符串中支持正则表达式的API(分割、替换)

**1、分割字符串**
    语法:var arr=str.split(reg);
**2、替换字符串**
    1、基本替换法
    语法:
        var newstr=str.replace(reg,“新内容”);
    特殊:
        a、默认只会替换第一个关键字,想要替换所有的记得加上后缀
        b、替换的内容只能是一个固定的新内容
    2、高级替换法
    语法:
        var newstr=str.replace(/[我卧][艹草去曹]+/g,function(a,b,c)
        {a//表示正则匹配到的关键字b//表示正则匹配到的关键字的下标
        c//表示原文本身
        return a。length==2?“**”:“**”})
    3、格式化
        如果替换API使用正则时,并且里面带有分组,那么会得到更多的形参
    例:
        var newstr=str.replace(reg,function(a,b,c,d.....){
        a表示匹配到的关键字,b表示第一个分组获取到的新内容...
        return “格式化的东西”})
        var str=user.replace(/(\w)(\w*)/g,function(a,b,c){
             return b.toUpperCase()+c;})
**3、正则对象**
    创建正则对象:
        直接量:var reg=/正则表达式/后缀
        构造函数:var reg=new RegEp(“正则表达式”,“后缀”)
    方法:
        var bool=reg.test(user);
        bool值如果为true,则说明用户输入的符合我们的要求,false则不符合
复制代码

三、Math(专门提供了数学计算的API)

不需要创建,直接使用。唯一的属性:Math.PI
**1、取整**
    上取整:Math.Ceil(num);
        只要超过一点点,就会取下一个整数,此方法小数位数不能超过15位,否
        则会失效。
    下取整:Math.floor(num);
        不管超过多少,都会省略掉小数部分,此方法小数位数不能超过15位,否
        则会失效
    四舍五入取整:Math.round(num)
    注意:以上三个只能取整
    解决能取小数的问题:parseFloat(num.toFixed(d));d为要取的小数位数
    此方法既有四舍五入的功能,又具有保留小数点位数的操作,结果为字符串
例:封装一个函数,实现用Math.round保留小数位数,并且具有四舍五入的功能:
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.aqrt(num);只能开平方
**3、最大值和最小值**
    语法:Math.max/min(a,b,c,d,.....);
        获取到最大的一个数或者最小的一个数
    此方法原本不支持数组,可通过加apply来解决
    apply:自己没有的方法可以去使用,可以将数组打散为单个参数悄悄进行传入
**4、绝对值**
    将负数转为整数:Math.abs(num);
**5、随机数**
    只要页面上具有随机的功能,一点是用到了随机数
    Math.random()已经是一个随机数了,随机的小数位0-1,有可能取到0,但
    绝不可能取到1//意味着能取到最小值,不能取到最大值
    公式:
        parseI(Math.random()*(max-min+1)+min);
复制代码

四、Date

    封装了一个日期对象,提供了对日期时间进行操作的API
    以后只要网页上面跟日期相关的。都要使用date对象
1、创建日期对象
    a、创建当前时间
        var now=new Date();
    b、创建自定义时间
        var birth=new Date(“yyyy/mm/dd hh:mm:ss”);
    c、创建自定义时间
        var birth=new Date(yyy,MM,dd,hh,mm,ss);
        此方法的缺点:月份需要修正,计算机中月份是从0开始到112、复制一个日期对象
    理由:日期对象的API都是直接修改原日期对象,使用API后,无法同时保存住
        旧的日期对象
    何时使用:在调用日期对象的API之前都要先赋值,再使用
    语法:
        var end=new Date(now);
3、var xxx=new Date(毫秒数);
    计算器其实保存的是从197011日至今的毫秒数
    操作:
        1.两个日期对象之间可以相减,得到毫秒差,换算出你想要的任何一部分
        2.API
            分享:时间单位
            FullYear(年)  Month(月)  Date(日)  Day(星期)
            Hours(小时)   Minutes(分)   Seconds(秒)
        a、每个分量都有一对方法:getxxx()获取/setxxx()操作
        特殊:取值范围
            年:为当前年份     月:0-11月        日:1-31   时:0-23
            分:0-59   星期:0-6,代表星期日
         星期只有get没有set
         b、固定套路(对着某个日期直接做加减)
             date.setxxx(date.getxxx()+3)
         c、格式化字符串
             将国际化日期格式为本地化日期
                 date.toLoCaleString();
             缺点:①具有浏览器兼容性问题
                   ②不可以再使用日期对象的API,也不会再有进制操作了
             优点:将日期转为了自负循环,可以使用字符串的API
             解决:采用自定义format格式化
复制代码

五、Error错误对象

1、浏览器自带4中错误对象
    语法错误:
        SyntaxError    多半都是哪里的符号写错了
    引用错误
         Reference Error   根本没有创建符就去使用
    类型错误
        TypeError   不是你的方法,你却使用了
    范围错误
        RangeError    只有一个API:num toFixed(d);//d的范围只能0-100
2、错误处理
    当程序发生错误时,保证程序不会异常中断的机制
    出错后,会导致后续代码不能执行
        try...catch....语句
        try{可能出错的代码}catch(err){
                        console.log(err);//提示用户错误的原因}
        此方法的执行效率非常的低下,更推荐的是if..else
        要用if...else去预判用户的前提是要知道错误出现的原因
3、抛出自定义错误
    throw new Error(“自定义错误信息”)
复制代码

六、Function:函数对象

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

七、重载

    相同的函数,根据出入的实参的不同,会自动选择对应的函数执行
    作用:减少程序员的负担
    JS不支持重载,JS不允许同时存在多个同名函数,如果存在,最后的一个会覆
    盖之前的所有函数
解决JS使用重载的问题:
        采用  arguments对象————只能在函数内部可用,是一个类数组对象
        作用  接住所有的实参(以后甚至不用形参都可以)
与数组的3个相同点
    1.支持下标    2.支持length   3.支持遍历(遍历需用var in 循环)
变相实现重载,通过判断arguments的不同,执行不同的操作
复制代码

八、匿名函数

    没有名字的函数,没有变量名/函数名引用着,调用完毕后会立马释放
1、匿名函数自调:代替全局作用域
    (function(){函数体;})()
    好处:调用完毕后会自动释放
2、匿名回调函数
    某个函数调用时,传入的实参又是一个函数,而且不需要我们调用自动执行
        例如:
            arr.sort(function(ab){return a-b})
            arr.replace(reg.function(){})
    匿名函数不是低调就是回调
    后期可用箭头函数简化一切的回调函数
复制代码

九、函数的执行原理

1、程序加载时:
    创建执行环境栈(ECS):保存函数调用顺序的数组
    首先亚茹全局执行环境(全局EC)
    全局EC中应用着全局对象windo
    wind中保存着全局变量
2、定义函数时
    创建函数对象:封装函数的定义
    在函数对象中创建scope属性,记录着自己来自的作用域
    全局函数的scope都是window
3、调用函数前
    在执行环境栈ECS压入新的函数的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 内层函数=外层函数();
防抖节流:
    目的:坚守DOM树的渲染,DOM数据渲染的次数越频繁,页面的效率越低下
需要做防抖节流的3件事情
    1、elem.onmousemove————鼠标移动时间,每次移动就会触发
    2、input.oninut————inout每次修改的内容就会触发
    3window.onresize————屏幕每次改变大小就会触发
固定公式:
    function fdjl(){
        var timer=nullreturn function(){
        if(timer){
        clearTimeout(timer)}
        timer=srtTimeout(function(){
            要做的操作},毫秒数)
                conso.log(timer)定时器的序号}}
var animation=fsjl();
复制代码

十一、Object面向对象

**1、什么是面向对象**
    在程序中都有使用对选哪个来描述现实中的一个事物
    现实中事物的竖向,代码中就成了对象的函数属性
    现实中事物的方法,代码中就成了对象的函数
**2、封装、创建、定义、声明实例化**
    ①直接量方式       适合创建单个元素
         var obj={“属性名”:属性值,....“方法名”:function(){}}
   注意:其实属性名和方法名的“”可以省略,但是不推荐,JSON必须加“”
**3、访问对象属性和方法**
    obj.属性名===obj[“属性名”]
    obj.方法名()===obj[“方法名”]()
    访问到不存在的属性:返回undefined
    也可以在后续随时的添加自己想要的东西
注意:this在当前对象的方法内,指向的是当前调用方法对象
this指向:
    1.单个元素绑定事件————this指单个元素
    2.多个元素绑定事件————this指当前触发的元素
    3.函数中也可以使用this   指当前在创建的对象
    4.构造函数中如果出现了this    指当前正在创建的对象
只要以后对象的方法想要使用对象自己的属性,阿么就写this.属性名
**4、预定义构造函数**
    var obj=new Object();
    obj.属性名=属性值;      obj.方法名=function(){}
**注意:**
    直接量和构造函数方式仅适合创建单个对象,如果想要创建多个对象太繁琐
**5、自定义构造函数**
    1.创建
        function 类名(形参,.....){this.属性名=形参1this.属性名=形参2,......}
    2.反复调用构造函数创建出多个对象
        var  xxx=new 类名(实参....)
面向过程:开始→经过→结束
面向对象:属性和方法
    所有属性和方法都是包含在一个对象中的
面向对象的优点:
    ①所有的创作都包含在一个对象,显得更有意义
    ②便于维护
    ③一个方法调用,触发了一大堆 操作
缺点
    this指向难度大
复制代码

十二、继承

父对象的成员(属性和方法),子对象可以使用
目的:可使代码重用,节约内存空间
何时使用:
    只要多个对象公用的属性和方法,都应该集中定义在父对象中
    JS的面向对象是基于原型(父对象)的
什么是原型:
    保存一类对象共有属性和共有方法的原型对象(父对象)
如何找到原型对象
    原型对象.属性名=属性值
    原型对象.方法名=function(){}
    每一个对选哪个都有一个._ _proto_ _的属性指向着自己的原型
    每一个构造函数都有一个.prototype属性指向着自己的原型
复制代码

十三、原型链

自己没有的属性和方法,可以顺着原型链一直向上找,知道最顶层
Object.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(“没有”)}
删除/修改属性
    自有属性
        删除:delete obj.属性名;
        修改:obj.属性名=新值
    共有属性
        删除:不要再本地做操作,会导致白做,无任何效果
        修改:不能再本地做操作,否则会导致在本地上添加一个同名属性,没有
        修改原型对象
     一定要找到原型再做操作
为一类人添加方法
    如:为老IE数组添加indexof方法
    ifArray.property.indexOf===undefined){
        Array.property.indexOf=function(key.starti){
            starti===undefined&&(starti=0);
            forvar i=starti;i<this.length;i++){
                ifthis[i]==key){
                    return i;}
                        return -1;}}
为一人添加共有方法
    构造函数名.property.函数名=function(){
        this→函数中的代表当前调用此函数的对象}
判断x是不是一个数组
    1、判断当前xx对象是否是继承自Array.propertyArray.property.isPrototypeOf(x);
        true说明是一个数组
    2、判断当前x对象是否是由此构造函数所创建
        X inStanceOf Array
        true说明是一个数组
    3Array.isArray(x);只有数组才有此方法
        true说明是一个数组
    4、在Object的prototype中保存着最原始的to String方法
        原始的toString输出的结果:[Object 构造函数名]
        多态:
            子对象觉得福对选哪个提供的方法不好用,可以在本地定义一个同名
            成员,优先使用离自己更近的方法
            同一个函数名,但根本不是同一个方法
        固定套路:
            ifObject.prototype.toString.apply(arr)===
            “[object Array]”){数组}
如何设置自定义继承
    设置单个对象的继承:
        obj._ _proto_ _=新对像
    设置多个对象的继承
        构造函数名.prototype=新对象
        在创建对象之前就设置好父对象