javascript学习的第三周

第一天:

1、正则表达式:

  (1)最简单的正则:/关键字原文/后缀    (后缀:g:找全部   i:忽略大小写)

  (2)备选字符集:/^[备选字符集]$/

             []中括号只管一个字符,正则表达式默认只要满足就不管后续,因此从头到尾完全匹配需加前加^ 后加$

  (3)预定义字符集:

一位数字:\d === [0-9]

        一位字母、数字、下划线:\w     ===    [0-9A-Za-z_]

一位数字:\s ===   空格、制表符、换行

(4)量词:

        ①有明确的数量:

                {n,m} 前边相邻的字符集,至少n个,最多m个

                字符集:{n,}   前边相邻的字符集,至少n个,多了不限制

                字符集:{n} 前边相邻的字符集,必须有n个

        ②没有明确的数量:

                ?:前面相邻的字符集,可有可无,最多1个

                *:前面相邻的字符集,可有可无,多了不限

                +:前面相邻的字符集:至少1个,多了不限

(5)选择和分组

        ①选择:在两个规则中选一个

                规则1|规则2

        ②分组:

                (规则1|规则2)

 (6)密码强度:4位密码,数字和字母的组合,至少出现1位数字或1位字母

        /^[0-9A-Za-z]$/

        预判公式:/(?![0-9a-z]+$)(?![A-Za-z]+$)[0-9A-Za-z]{4}/

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

        (1)切割:var arr = str.split(reg);

        (2)替换:

                ①基本替换法:var newStr = str.replace(/正则表达式/后缀,"新内容");

                ②高级替换法:var newStr = str.replace(/正则表达式/后缀 ,function{

                                                     //a:代表正则匹配到的当前的关键字

                                                      return a.length = = 2 ? "**" : "***" ;

                                              });

                ③格式化:var id= "500112199909093798" ;

                                  var reg = /\d{6}\d{4}\d{2}\d{2}\d{4}/ ;

                                  id = ( reg,function(a , b ,c){

                                replace的时候正则出现了分组,会得到更多的形参,在形参a的后面会出现那个形参,看有多少个分组,第一个分组获得的内容将会保存在第二个形参中,第二个分组获得的参数内容会保存到第三个形参中。。。。。。

                                  return b+"年"+c+"月"+d+"日";

                                })

3、正则对象:

        创建:

                ①直接量方法:var reg = /正则表达式/后缀;

                ②构造函数方式: var reg = new RegExp("正则表达式","后缀");

        API:  var bool = reg.test(用户输入的内容);

                true->验证成功

                false ->验证失败

第二天:

1、Math对象

        属性:Math.PI  ===  3.1415926

        API:

                (1)取整:3种

                        ① 上取整:超过一点点就取下一个整数

                                var num = Math.ceil (num); //小数位数不能超过15位

                        ②下取整:无论超过多少,都会省略掉小数部分

                                var num = Math.floor(num);  

                        ③四舍五入取整:

                                var num = Math.round(num);

取整的方法还有parseInt(str可去掉单位)、num.toFixed(d) //d:小数位数

num.toFixed(d):

        优点:可四舍五入保留指定小数位数

        缺点:结果是一个字符串,搭配parseInt使用

                (2)乘方和开方

                        ①乘方:Math.pow(底数,幂);

                        ②开方:Math.sqrt(num); 只能开平方

               (3)最大值和最小值:

                        var 最大的/最小的 = Math.max/min(a,b,c...);

                        问题:本身不支持数组参数

                        解决:固定用法

                                var 最大的/最小的 = Math.max/min.apply(Math.arr);

                        apply的作用:可以将数组打散成单个元素

                (4)绝对值:var num = Math.abs(num);

                (5)随机数:Math.random();

                        parseInt(Math.random()*(max-min+1)+min);

2、Date日期对象

        创建:4种方法

        (1)创建一个当前日期:

                        var new = new Date();

        (2)创建一个自定义时间:

                        var birth = new Date("yyyy/mm/dd hh:mm:ss");

        (3)创建自定义时间:

                        var birth = new Date(yyyy,mm-1,dd,hh,mm,ss);

        (4)复制一个日期:(日期所有的API都是直接修改原日期的,无法获取到修改之前的日期)

                var star = new Date();

                var end = new Date(star);

操作:

        1、两个日期对象之间可以相减,得到一个毫秒差,换算出自己想要的某一部分 - 日期的本质其实就是保存的一个毫秒数

        创建的最后一个方式:var date=new Date(毫秒数);


         2、API:

             分量:时间的单位      年日月星期:FullYear Month Date Day

                                                时分秒毫秒:Hours Minutes Seconds Milliseconds

                每一个分量都有一堆getXXX/setXXX

                特殊:

                        ①取值范围:

                                FullYear:当前年份的数字

                                *Month:0~11

                                Date:1~31

                                *Day:0~6

                                Hours:0~23

                                Minutes,Seconds:0~59

                        ②Day,没有set方法

        3、如果希望对某个分量进行加减计算 :date.setXXX(date.getXXX()+/-n)

        4、格式化日期为字符串:

                date.toLocaleString();//本地日期格式

第三天:

1、Error对象 - 错误

        (1)浏览器自带4种错误类型:可以快速找到自己的错误

                语法错误:SyntaxError - 语法符号写错

                引用错误:ReferenceError - 没有创建就直接使用了

                类型错误:TypeError - 使用了不是自身的方法

                范围错误:RangeError - 只有一个API会碰到:num.toFixed(d);//d取值范围的

        (2)只要发生错误,就会报错,会导致后续代码终止,

                错误处理:就算发生错误,我们也不希望报错,而是给一个错误的提示,后续代码可以继续执行

               语法:

                        try{
                                  只放入你可能出错的代码
                       }catch(err){
                                 发生错误后才会执行
                                console.log(err);//err就是我们的错误提示,英文
                                console.log("中文错误提示");
                      } 

                可以用一个技术代替:if...else...

        (3)抛出自定义错误

                throw new Error("自定义错误信息") - 只要是报错都会卡主后续代码

2、Function对象:

        (1)创建:3种

                ①声明:function 函数名(形参,...){函数体;return 返回值;}

                ②直接量:var 函数名=function(形参,...){函数体;return 返回值;}

                ③构造函数:var 函数名=new Function("形参1","形参2",...,"函数体;return 返回值;");

        (2)调用时,如果有return,记得接住   var result=函数名(实参,...)

        (3)考点:

                ①重载:相同的函数名,传入不同的实参,可以自动选择对应的函数执行操作

                        问题:js的语法不支持重载! js不允许多个同名函数同时存在,如果同时存在,最后的会覆盖之前的所有

                        解决:在【函数中】有一个对象 - arguments对象:只能在函数中使用,自动创建,是一个类数组对象(类似数组)

                         作用:可以接收所有传入的实参

        (4)匿名函数:没有名字的函数

                ①匿名函数自调:

                        语法:(function(){

                                           //以后可以代替全局代码写法,尽量不要再外部再去书写JS(不用担心事件会被释放掉)

                                     })();

                ②匿名函数回调:将函数作为实参,传递给其他函数调用

                        学习回调的目的:知道哪些叫做回调:只要不是自调,就是回调

                               arr.sort(function(){})     str.replace(reg,function(){})    btn.οnclick=function(){}

第四天:

1、Function
   作用域:2种
    1、全局:随处可用,可以反复使用,缺点:容易被污染

    2、函数:只能在函数内部使用,不会被污染,缺点:一次性的,是会自动释放的

  函数的执行原理:
    1、程序加载时
       创建执行环境栈(ECS):保存函数调用顺序的数组
       首先压入全局执行环境(全局EC)
       全局EC引用着全局对象window
       window中保存着全局变量

    2、定义函数时
       创建函数对象:封装代码段
       在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
       全局函数的scope都是window

    3、调用前
       在执行环境栈(ECS)压入新的EC(函数的EC)
       创建活动对象(AO):保存着本次函数调用时用到的局部变量
       在函数的EC中有一个scope chain(作用域链)属性引用AO
       AO有一个parent属性是函数的scope引用着的对象

    4、调用时:正是因为前面三步,我们才有了变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错

    5、调用完:函数的EC会出栈,AO自动释放,局部变量也就自动释放了

    两链一包:
       作用域链:以函数的EC的scope chain属性为起点,经过AO,逐级引用,形成的一个链式结构
         作用:查找变量,带来变量的使用规则

    1、闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构 - 其实还是一个函数,写法和以前不同
    何时使用:希望保护一个可以【反复使用的局部变量】的时候
    如何使用:
        1、两个函数进行嵌套
        2、外层函数创建出受保护的变量
        3、外层函数return出内层函数
        4、内层函数要去操作受保护的变量

    强调:
        1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
        2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
        3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

    缺点:受保护的变量,永远都不会被释放,使用过多,内存泄漏 - 不可多用
    问题:应该在哪里用呢?
        1、三个事件需要防抖节流
            1、elem.onmousemove - 鼠标移动事件
            2、input.oninput - 每次输入/改变就会触发
            3、window.onresize - 每次窗口的大小发生变化就会触发

              
        防抖节流公式:
            elem.on需要防抖节流的事件=function(){
                fdjl();//内层函数只要一旦移动就会触发
            }

            function f1(){
                var timer=null;//3
                return function(){//
                    if(timer){clearTimeout(timer);timer=null;}
                    timer=setTimeout(function(){
                        //操作
                    },1000)
                }
            } 
            
            var fdjl=f1();

------------------------------------------------------------------------------------------------------------------------------
2、
Object:对象 - Array/String/RegExp...对象具有属性和方法,都是预定义好的,现在我们可以学习自定义对象
   面向对象:三大特点:封装、继承、多态
   1、
开发方式:面向对象 和 面向过程?
    面向过程:经过 - 开始->结束,我们一直的开发方式都是面向过程,先干什么在干什么最后干什么
    面向对象:对象(属性和方法),js有一句话万物皆对象,假设一个人是一个对象的话:

   2、封装:创建自定义对象:3种方法
    1、直接量方式:var obj={
                "属性名":属性值,
                ...
                "方法名":function(){},
                ...
               }
        强调:1、其实属性名和方法名的""可以不加 - 暂时建议你加上
              2、访问对象的属性和方法
              
 *obj.属性名    ===    obj["属性名"]
              
 *obj.方法名()    ===    obj["方法名"]();
                建议使用.去访问属性和方法,更简单
                
***JS中一切都是对象,一切对象的底层都是hash数组
              3、访问到不存在的属性,返回undefined
              4、可以随时随地的添加新属性和新方法
              5、如果我希望遍历出对象所有的东西,使用for in,obj[i]才能拿到,不要用.会出问题
              6、
***如果你希望在对象的方法里使用对象自己的属性:写为this.属性名

            *****难点:this的指向:
                1、单个元素绑定事件:this->单个元素
                2、多个元素绑定事件:this->当前触发的元素
                3、函数中使用this,this->谁在调用此方法,this指的就是谁
                4、定时器中this->window

    2、预定义构造函数方式:var obj=new Object();//空对象
            //需要自己后续慢慢追加属性和方法
            obj.属性名=属性值
            obj.方法名=function(){}

    以上两个方法都有一个缺陷:一次只能创建一个对象,适合创建单个对象的时候(第一种方法),第二种方法永远不远

    3、自定义构造函数方法:2步
        1、创建自定义构造函数
            function 类名(name,age,salary){
                this.name=name;
                this.age=age;
                this.salary=salary;
            }
            //千万不要在里面创建方法,每个对象都会创建一个方法,浪费内存 - 明天,继承将统一的方法放到原型上

        2、调用构造函数创建出对象
            var obj=new 类名(实参1,...)

第五天:

1、*****Object:
   1、*****继承:父对象的成员(属性和方法),子对象可以直接使用
     为什么:代码重用!节约内存空间!提升网站性能!
       何时继承:只要多个子对象公用的属性和【方法】,都要集中定义在父对象中

   2、***如何找到父对象(原型对象):保存一类子对象共有属性和共有方法的父对象
    1、对象名.__proto__;//必须先有一个对象
    2、构造函数名.prototype;//构造函数名,几乎人人都有,除了Math

   3、*面试题:两链一包:作用域链、原型链、闭包
    每个对象都有一个属性:__proto__,可以一层一层的找到每个人的父亲,形参的一条链式结构,就称之为叫做原型链
    可以找到所有父对象的成员(属性和方法),作用:找共有属性和共有方法的
    最顶层是Object的原型,上面放着我们一个眼熟的toString,怪不得人人都可以用到toString();
    JS万物皆对象

   4、有了原型对象,设置共有的属性和方法:
    1、原型对象.属性名=属性值;//添加了一个共有属性
    2、原型对象.方法名=function(){};//添加了一个共有方法

    ***继承具有非常多的鄙视题:
        1、判断是自有还是共有:
            1、判断自有:obj.hasOwnProperty("属性名");
                如果结果为true,说明是自有属性,如果结果为false,有两种可能,共有或没有
            2、判断共有:
                if(obj.hasOwnProperty("属性名")==false && "属性名" in obj){//in 会自动在obj的原型上进行查找
                    共有
                }else{
                    没有
                }

            公式:
            if(obj.hasOwnProperty("属性名")){//false
                console.log("自有")
            }else{  
                if("属性名" in obj){
                    console.log("共有")
                }else{
                    console.log("没有")
                }
            }

        2、删除自有和共有
            自有:修改:obj.属性名=新值;
                  删除:delete obj.属性名;

            共有:修改:obj.共有属性名=新值; - 非常危险的,并没有修改到爸爸,而是在本地添加了一个同名属性
                  删除:delete obj.属性名; - 无效,本地本来就没有此自有属性
                  找到原型,修改/删除原型        

        3、如何为老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;
                }
            }

        
        4、如何判断x是不是一个正则:4种方法:千万别用typeof,只能检查原始类型,不能检查引用类型
            1、判断x是否继承自Array.prototype
                Array.prototype.isPrototypeOf(x);

            2、判断x是不是由Array这个构造函数创建
                x instanceof Array;

            3、Array.isArray(x); - ES5提供的,只是ES5+,老IE不支持,此方法只有数组

            4、输出【对象的字符串】形式
               在Object的原型上保存着最原始的toString方法
               原始的toString输出形式:[object 构造函数名]
               ***多态:子对象觉得父对象的成员不好,在本地定义了同名成员,覆盖了父对象的成员
               固定套路:借用:Object.prototype.toString.apply(x);
                if(Object.prototype.toString.apply(arr)=="[object Array]"){
                    console.log("是数组")
                }else{
                    console.log("不是数组")
                }

        5、实现自定义继承:
            1、两个对象之间设置继承:
                子对象.__proto__=父对象
            
            2、多个对象之间设置继承:
                构造函数名.prototype=父对象
                时机:应该在开始创建对象之前设置好继承关系

         

                        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值