JS2

作者: fastwe | 来源:发表于2018-11-26 22:04 被阅读0次

    第五章*****************************************************************************************

    什么是索引数组: 下标都是数字的数组

    关联数组:

    什么是: 可自定义下标名称的数组

    为什么: 为了让每个元素都有一个专门的名称

    好处: 1. 便于维护;2.快速查找

    何时: 1. 希望每个元素都有明确的意义时

          2. 快速定位想要的元素时

    如何: 2件事(创建、访问)

    创建分2步:

        1. 先创建空数组:var arr=[];

        2.向空数组中添加新元素,要使用自定义的下标名称

           EX:ym["name"]="杨幂"

               ym["math"]=81;

               ym["chs"]=59;

               ym["eng"]=89;

    访问: 用法和访问索引数组完全一样,同变量的用法,只不过要使用自定义的下标名称

    关联数组中.length属性失效,永远等于0

    因为关联数组中没有数字下标,length无法+1

    遍历关联数组(键值对的集合): 只能用for( in )

    for(var key in arr){  /*in:自动依次取出arr中每个下标名称保存在变量key中;key:当前房间号:键*/

     arr[key];               //当前元素值: value,当前属性名: key

    }                          /*强调: key不能加引号, 因为每次循环都在变化*/

    索引数组:无法提前预知元素的具体位置,只能靠遍历查找,受元素个数和元素存储位置影响极大(慢)

    关联数组:直接通过下标定位元素位置,查找速度和元素个数及元素位置无关(快)

    关联数组原理:hash算法: 根据一个字符串,计算出尽量不重复的一个序号。相同的字符串计算出的序号一定相同,相同下标的值会覆盖原先的值

    向关联数组中保存元素:

        将自定义下标名交给hash算法,计算一个散列的位置序号。将元素保存到序号指定位置

    从关联数组中取值时:

        将自定义下标名交给hash算法,计算出和存入时完全相同的序号,引擎直接去序号位置获得元素

        优点: 不受存储位置和元素个数的影响

    _______________________________________________________________________________________________

    1. 数组API

    什么是数组: 存储多个数据,并提供了操作数据的API的对象

    API: 别人已经实现的,咱们用现成的程序

    将数组转字符串有2种:

     String(arr): 将arr中每个元素都转为字符串,用逗号连接

        何时: 给数组拍照,查看数组的中间修改状态,判断操作前后数组是否发生了变化

     arr.join("自定义连接符"): 将arr中每个元素都转为字符串,用自定义的连接符连接元素

        何时: 只要不希望使用逗号连接符时

    固定套路: 1. 把单词拼接为句子

              2. 无缝拼接:

                 错误: arr.join() <=> String(arr)  =>输出为逗号连接

                 正确: arr.join("")

                 重要用途: 判断数组是否为空

              3.动态生成页面元素(只会在元素之间添加连接符,所以要在arr.join("...")前后补全标签)

                 2步:① var html="<ANY>"+arr.join("</ANY><ANY>")+"</ANY>";

                        或 var html="<ul>"+uls.join("")+"</ul>";

                     ② elem.innerHTML=html;

    console.log(String(arr)),console.log(arr),console.dir(arr)

    console.log(arr); 先输出dir的结构,刷新后变为String(arr)

    仅输出内容,不关心结构: console.log(String(arr))

    查看数组存储结构: console.dir(arr)           /*dir查看结果时,不遵循先后执行的顺序*/

    判断数组中是否含有某个元素:

    数组可用indexOf搜索某个元素的下标,返回在数组中找到的给定元素的第一个索引,若不存在,则返回-1,但数组元素需要完全相等(===)才会搜索成功,且不识别NaN

    如: var arr = ['啦啦',2,4];

        arr.indexOf('啦');    //-1

        arr.indexOf('啦啦');  //0

    使用ES6的扩展运算符(...)代替cancat,可以更方便的合并数组

    如: var arr1 = [1,2,3];

        var arr2 = [4,...arr1,5];    //[4,1,2,3,5]

    toLocaleString()可将数组中的每个元素用逗号(,)隔开,组成字符串(调用join()方法)

    var str = arr.toLocaleString()

    _______________________________________________________________________________________________

    拼接和选取: 都无权修改原数组,只能返回新数组对象

    拼接: 将多个数组或元素,和当前数组拼接为一个新数组

          如何:var newArr=arr1.concat(值1,值2,arr2,...);

          强调: 1.不修改原数组,只返回新数组

                2. 可打散数组类型的参数为单个元素,再拼接           /*concat独有*/

          注意: 若是大数组会消耗大量内存,可用arr1.push.apply(arr1, arr2)代替,将arr2合并到arr1中

    选取: 复制原数组中指定开始位置到结束位置之间的多个元素,组成新数组———原数组保持不变

          如何:var subArr=arr.slice(starti,endi+1);

          强调: 1.不修改原数组,仅复制出想要的元素组成新数组

                2.如果一个API的两个参数都是下标时,就含头不含尾

          简写: 1. 如果参数位置离结尾近,可用负数下标:

                   arr.length-n 可简写为:-n(倒数第n个(不包含尾))(API自动加length)

                2. 可省略第二个参数(-1),表示一直选取到结尾

                3. 两个参数都可省略: 完整复制一个数组(地址值不同)

    _______________________________________________________________________________________________

    两个对象作比较(arr2==arr1):

    不做任何转换,直接比较两个对象的地址值,用于判断两个变量是否引用同一个对象

    引用类型的对象(arr2=arr1):用新变量修改对象,等效于直接修改原对象,新旧变量都受影响(地址值相同)

    复制数组(地址值不同):①选取复制: var arr2=arr1.slice();

                          ②复制索引数组:for(var i=0;i<arr2.length;i++){arr2[i]=arr1[i]};

                          ③复制关联数组:for(var key in arr1){key; arr2[key]=arr1[key]};

    _______________________________________________________________________________________________

    修改数组: splice(强调: 直接修改原数组)

    删除元素:arr.splice(starti,n)

      删除starti位置开始的n个元素

      强调: 不必考虑含头不含尾(n是个数)

      其实有返回值: 返回被删除的元素组成的临时数组

        var deletes=arr.splice(starti,n);            /*deletes保存了删除的元素*/

      简写: 1. 支持负数下标,表示倒数第n个(自动用length-n)

            2. 省略n(从starti 删到结尾)

    插入新元素:arr.splice(starti,0,值1,值2,...)       //删除0个

        在starti位置插入新的值1,值2,...

        强调: 1.原starti位置的值及其之后的值被向后顺移

              2.不支持打散数组类型参数(如果插入一个数组,将变成二维数组)

    替换: arr.splice(starti,n,值1,值2,...)

        先删除旧的,再在同一位置插入新的

        先删除starti开始的n个元素,再在starti位置插入值1,值2,...

        强调: 删除的个数和插入的个数不必相同

    翻转:  arr.reverse();

    _______________________________________________________________________________________________

    排序:

    什么是: 将数组中的元素按从小到大或从大到小的顺序重新排列

    何时: 任何数据在给用户展示前,必须先排序

    如何:arr.sort();             /*将 arr 数组按字符串升序,直接修改原数组*/

      原理: 将所有元素都转为字符串,再按字符串升序排列

      何时: 只有按字符串升序排列时,才用默认的sort()

    问题: 只能按字符串升序排列

    解决:自定义比较器函数:

      什么是: 专门比较任意两值大小的函数

      何时: 如果sort默认的排序规则不是想要的,可自定义比较器代替sort中默认的排序规则

    要求: 2个参数: a,b

    返回值: 如果a>b,就返回正数

            如果a<b,就返回负数

            否则返回0

    最简单的数字升序比较器

    function cmp(a,b){return a-b;};       /*定义比较器函数*/

    arr.sort(cmp);                        /*传入sort()中*/

    简化为:arr.sort(function(a,b){return a-b});   /*cmp=function(a,b){return a-b;}*/

                  /* 对对象的值进行排序: arr.sort(function(a,b){ return obj[a]-obj[a] }) */

    如何使用: 将比较器函数对象作为参数传入sort()函数中

    强调:不加()             /*cmp: 回调函数callback,不加()*/

    回调函数:自己定义的函数,自己不调用,不只调用一次,而是传入另一个函数中,被另一个函数反复调用

    何时: 只要对数字元素排序,都要自定义比较器函数

    递归调用:函数内又调用了自己(效率极低,几乎所有的递归都可用循环代替)

    问题2: 如何降序:

    解决: 只要颠倒比较器结果的正负号,就可改升序为降序

    最简单的数字降序比较器

    function cmp(a,b){return b-a};

    arr.sort(cmp);

    简化为: arr.sort(function(a,b){return b-a});

    _______________________________________________________________________________________________

    2. 栈和队列

    说明: js中没有专门的栈和队列结构,都是用普通数组模拟的

    栈stack:

    什么是栈: 一端封闭,只能从另一端进出的数组

              栈是限定仅在表头/表尾进行插入/删除操作的线性表

    何时: 只要希望始终使用最后进入数组的新元素时(先进后出)

    如何:

      1. 结尾出入栈:

        结尾入栈: arr.push(值)<=>  arr[arr.length]=值   /*在末尾追加一个新值*/

         强调: 1. 其实push可压入多个值: arr.push(值1, 值2)

               2. 不支持打散数组参数                     //可用来创建二维数组

        结尾出栈: var last=arr.pop();                   /*移出数组末尾的最后一个元素*/

      2. 开头出入栈:

        开头入栈: arr.unshift(值)                        /*在开头插入一个值*/

         强调: 开头入栈后的元素顺序和结尾入栈后的元素顺序是相反的

        开头出栈: var first=arr.shift();               /*移出数组开头的第一个元素*/

    队列queue:

    什么是: 只能从结尾进入,从开头出的数组,是事件循环(Event Loop)的基础结构

    何时: 只要希望按照先来后到的顺序使用数组元素时

    如何: 1. 从结尾入队列:arr.push(值);

          2. 从开头出队列:var first=arr.shift();

    堆:

    堆数据结构是一种树状结构,它使用key-value的形式存储,是无序的

    变量的存放:

    基本数据类型: 保存在栈内存中,占有固定大小的空间,通过按值来访问

    引用类型: 保存在堆内存中,因为值的大小不固定,所以不能保存到栈内存中,但内存地址大小是固定的,可以保存在栈内存中。当查询引用类型的变量时,先从栈中读取内存地址,然后通过内存地址找到堆中的值,一般叫做按引用访问

    _______________________________________________________________________________________________

    总结: 向数组中添加元素4种:

    1. concat():①不修改原数组,返回新数组

                 ②在结尾拼接元素

                 ③支持打散数组类型参数,另一个是.apply(),只有这两个能打散数组

    2. splice():①直接修改原数组

                 ②在任意位置插入新元素

                 ③不支持打散数组类型参数

    3. push():①直接修改原数组

               ②只能在结尾拼接元素

               ③不支持打散数组类型参数

    4. shift():①直接修改原数组

                ②只能在开头拼接元素

                ③不支持打散数组类型参数

    取出数组元素: 4种:

    1. slice():①可获取任意位置的任意个元素

                ②不修改原数组,返回选中的元素组成的新数组

    2. splice():①删除任意位置的任意个元素

                 ②直接修改原数组

                 ③返回被删除的元素组成的新数组

    3. pop():只能从结尾删除一个元素,并返回

    4. shift():只能从开头删除一个元素,并返回

    _______________________________________________________________________________________________

    3.二维数组

    什么是: 数组中的元素,又引用了另一个子数组

    何时:

      1. 保存横行竖列的二维数据

      2. 一个大的数组中,还需要对元素进行更细致分类

    如何创建: 2种:

    1. 先创建空数组,再添加子数组:

    var arr=[];

      arr[0]=[0,0,0,0];

      arr[1]=[0,0,0,0];

      ...

    2. 创建数组同时,初始化子数组

    var arr=[

      [0,0,0,0],

      ... ,

      [0,0,0,0]

    ];

    访问:arr[r][c](r行号,c列号)  用法和普通数组的元素及变量完全一样

    越界: 二维数组的行下标r,不能越界,越界报错

    遍历二维数组:

    for(var r=0;r<data.length;r++){         //外层循环控制行

      for(var c=0;c<data[r].length;c++){    //内层循环控制列

        data[r][c]                          //获得当前元素

    } }

    创建二维数组:

    var arr=[];

    for (var i=0;i<N;i++ ){

      arr[i]=[];                //创建一个二维数组,内容为空

      for (var j=0;j<M;j++){    //为二维数组赋值 或填充n个空元素: arr1[i]=new Array(n);

      arr[i][j]=0;

    } }

    冒泡排序算法(一维数组):

    function bubblesort(arr){

      for(varr=1;r<arr.length;r++){         //外层循环控制轮数

        for(vari=0;i<arr.length-r;i++){     //内层循环控制每轮中的比较次数

          if(arr[i]>arr[i+1]){               //如果i位置的值>i+1位置的值

            arr[i]^=arr[i+1];                //交换两位置的值

            arr[i+1]^=arr[i];

            arr[i]^=arr[i+1];

    } } } }

    第六章*****************************************************************************************

    三、String类型

    什么是: 由多个字符组成的"只读"字符数组

    String API: 强调: 所有String API都无权修改原字符串,只能返回新字符串

    VS 数组: 相同: 1. 下标;如:str[1]    2. .length

                 3.var subArr=arr.slice(starti,endi+1);(选取,无权修改原数组)

             不同: 类型不同, API不通用

    内置对象: ES标准中规定的,浏览器厂商已经实现的对象

    包括11个:

      String  Number  Boolean  —————  这3个是包装类型

      Array   Date    Math   RegExp

      Error

      Function  Object

      Global (在浏览器中被window代替)

    包装类型

    什么是:专门包装原始类型的值,并提供操作原始类型值的API

    为什么: 原始类型的值本身不具有任何功能,才需要包装类型对象的帮助,完成功能

    何时: 一般不必手动使用

          只要试图用原始类型的值调用函数时,都会自动创建包装类型的对象,调用对象的函数执行操作

    注意: 只要引用了字符串的属性(.属性),字符串就会通过调用new String(str)的方式转换成对象,这个对象继承了字符串的方法,并被用来处理属性的引用,一旦属性引用结束,这个新创建的对象就会销毁(实质上并不一定创建和销毁,但整个过程看起来是这样的)

    比如: n.toFixed(2) =>  typeof n =>  number

          <=>new Number(n).toFixed(2)

       str.charCodeAt() =>typeof str =>string

       <=>new String(str).charCodeAt()

    大小写转换

    将字符串中所有字母,统一转为大写或小写

    str.toLowerCase()          转小写

    str.toUpperCase()          转大写

    何时: 不区分大小时,都要先转为一致的大小写,再比较或判断: 验证码,用户名,电子邮件

    获得指定位置的字符: str.charAt(i)  =>  str[i]

    获得指定位置字符的unicode号: str.charCodeAt(i)        获得str中i位置的字符的unicode号

    将unicode号,反向转回文字:   String.fromCharCode(unicode号)    一次只能转一个字,要用循环

    获取子字符串:3种

    str.slice(starti, endi+1)

    str.substring(starti, endi+1)    用法同slice,但不支持负数参数(负数自动转为0,取较小的值作为开始位置)

    str.substr(starti, n)                从starti开始,获取n个字符,n是个数,省略则到结尾为止

    _______________________________________________________________________________________________

    查找关键词: 4种:

    1. 查找一个固定关键词的位置(仅查找规则内的第一个)

    var i=str.indexOf("关键词",fromi)

      在str中fromi位置之后,查找下一个"关键词"的位置

    返回值: 找到的关键词的下标位置i

            如果没找到,返回-1

      简写: 省略fromi,默认从0开始

    var i=-1;

    do{

      i=str.indexOf("关键词",i+1);

      if(i!=-1)

        console.log("在位置"+i+"发现关键词");

      else break;

    }while(true);

    2. 查找最后一个关键词的位置

    var i=str.lastIndexOf("关键词");

    用于获取文件的扩展名(取最后一个.后的剩余字符串)

    indexOf的问题: 只能查找一个固定关键词的位置

    解决: 正则表达式模糊匹配多种关键词

    3. 判断字符串中是否包含符合规则的关键词

    var i=str.search(/reg/i)    /*reg: 正则表达式,在str中找到第一个符合正则要求的敏感词的位置*/

    返回值: 返回关键词的下标位置i

            如果没找到返回-1

      问题: 正则表达式默认都是区分大小写的

      解决:在第二个/后加i,表示忽略(ignore)大小写

      何时: 只要仅判断有没有关键词时,首选search

      问题: 1. 只能查找第一个关键词,无法找所有

            2. 仅返回位置,无法返回关键词内容

    4. 查找所有关键词的内容

    var kwords=str.match(/reg/ig);        //也可使用字符串,结果为查找到的字符串

    返回值: 返回所有关键词组成的数组

            如果没找到,返回null

    使用正则时: 数组的第一个元素(下标为0)表示第一个分组,下标为2的是第二个分组

    使用/g时: 下标为0的是找到的第0个分组,下标为1的是第一个分组,下标为2的是第二个分组

    使用字符串时,下标为0的是找到的字符串,index是下标,input是要查找的字符串

      问题: 正则表达式默认只匹配第一个符合条件的敏感词

      解决:在第二个/后加g,表示查找全部(global)

      何时: 仅希望获得关键词内容时

      问题: 只能获得内容,无法获得每个敏感词的位置

      解决: 查找每个关键词内容,又查找位置: regExp.exec()

    _______________________________________________________________________________________________

    替换: 将字符串中找到的关键词,替换为指定的新内容(2种), (无权修改原字符串,只能返回新字符串)

    1. 简单替换: 将所有关键词都替换为同一种新值

    str=str.replace(/reg/ig,"新值");

    2. 高级替换: 根据每个关键词的不同,动态选择替换不同的新值

    str=str.replace(/reg/ig,function(kw){      /*回调函数,kw 自动获得本次找到的关键词*/

      return                                   /*根据不同的kw,动态返回不同的值*/

    })

    衍生:删除: 将关键词替换为""

    str=str.replace(/reg/ig,"")

    str.replace(/(^\s+)|(\s+$)/g, "")         //去掉字符串首尾的空字符

    切割: 按指定关键字,将一个字符串切割为多段子字符串(2种)

    返回: 返回的是多个子字符串组成的数组,切割后的结果中,不包含分隔符

    注意:当分隔符不为空字符("")时,分隔符在边界或连续出现两个时,会形成一个空字符

         分隔符的个数 = str.split("分隔符").length-1   //字符串分隔后组成的数组长度-1

    1. 简单: 分隔符是固定的:

    var subStrs=str.split("分隔符")            //不修改原字符串

    2. 复杂: 分隔符不是固定的:

    var subStrs=str.split(/reg/i);

    固定套路: 将字符串打散为字符数组: var chars=str.split("");

    多字符切割: var newStr = oldStr.split(/\:|\./g);

                var newStr = oldStr.split(/[共]|[注]|[元]/g);

    function zhao(str){         //查找一个字符串中每个字符连续出现的次数

      var arr1=str.split("");

      arr1.sort();              //查找一共出现的次数用arr.sort()先排序再查找

      for(var i=0,j=1;i<arr1.length;i++){

        if(arr1[i]===arr1[i+1]){

          j++;

        }else{

          console.log(arr1[i]+":"+j);

          j=1;

    } } }

    //截取url的后lastNum*2个字段

    function getUrlInfo(lastNum){

    var infoArr = location.href.split(/\?|\/|\&|\=/g);

      var arr = infoArr.slice(-lastNum*2);

      var result = new Object();

      for(var i=0; i<arr.length; i+=2){

        result[arr[i]] = arr[i+1];

      }

      return result;

    }

    _______________________________________________________________________________________________

    正则表达式:Regular Expression

    什么是: 规定一个字符串中字符出现规律的规则

    何时:2种: 1.模糊查找多种关键词

              2.验证用户输入的格式

    如何:

    1.最简单的正则表达式,就是关键词原文本身

    2.字符集

    什么是: 规定一位字符 备选字符列表 的集合

    何时: 只要一位字符,有多种可能备选时

    如何:[备选字符列表]                        // 表示选择其中之一

    强调: 中间不要加逗号(,)

          一个字符集([])只能规定一位字符的备选字

    简写: 如果字符列表中 部分备选字符的unicode是连续的,可用-省略中间字符

    比如: [0-9]              一位数字

          [a-z]              一位小写字母

          [A-Z]              一位大写字母

          [A-Za-z]           一位字母

          [0-9A-Za-z]        一位字母或数字

          [\u4e00-\u9fa5]    一位汉字

    特殊:[^字符列表]        除了××

    3.预定义字符集

    什么是: 对常用特定字符集的更简化写法:4个:

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

      \w        一位字母,数字或_  => [0-9A-Za-z_]

     \s       一位空字符: 空格,Tab...

     .        通配符(匹配除回车、换行\n\r外的任意字符)

      \D        类似[^0-9],非数字

      \W        类似[^0-9A-Za-z_],除\w外的符号

      \S        非\s的所有内容

    \***: 是转义字符,表示引用符   比如: \.  匹配点字符   \$匹配美元符号

    空字符和空字符串不一样,空字符用|表示

    4.量词

    什么是: 规定一位字符集出现次数的规则

    何时: 只要规定一位字符集出现的位数/次数

    如何: 量词必须紧跟在修饰的字符集之后,用来修饰相邻的前一个字符集

    包括: 2大类:

      ① 有明确数量边界的:

         字符集{n,m} 至少n个,最多m个

         字符集{n,}  至少n个,多了不限

         字符集{n}   必须n个

      ② 没有明确数量边界的:

         字符集?   可有可无,最多1个

         字符集*   可有可无,多了不限

        字符集+   至少一个,多了不限

    5.选择和分组

    选择:或

    何时: 只要在多个规则中,任选其一匹配时

      规则1|规则2|规则三...  (只要满足3个规则之一即可)    /*|在正则中,优先级最低*/

    分组: 用()将多个规则分为一组

    何时: 只要希望一个量词同时修饰多个字符集时,就要先将多个字符集分为一组(),再用量词修饰分组

    为什么: 默认字符集仅修饰相邻的前一个字符集

    比如:   var reg=/(\d{2})\/(\d{2})\/(\d{4})/g;    //将'07/29/2017'分为3组

    反向引用:

    var str = '2017-07-29'.replace(/(\d{4})-(\d{2})-(\d{2})/g, '$2/$3/$1');  //str: 07/29/2017

    忽略分组: 不希望捕获某些分组,只需要在分组内加上?:即可

    var str = '2017-07-29'.replace(/(?:\d{4})-(\d{2})-(\d{2})/g,'$2/$1');     //str: 29/07

    $1~$9存放着正则表达式中最近的9个正则表达式的提取结果,这些结果按照子匹配的出现顺序依次排列

    语法: RegExp.$n

    这些属性是静态的,除了replace中的第二个参数可以省略RegExp外,其它地方使用都要加上RegExp

    身份证号: 15位数字  2位数字  1位数字或Xx  /*后两部分,可有可无,最多1次*/

        reg = \d{15}    (\d\d   [0-9Xx])     ?

    reg = /(^[1-9]\d{5}  (18|19|([23]\d))\d{2}  ((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)  \d{3}[0-9Xx]$)|(^[1-9]\d{5}  \d{2}  ((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)  \d{2}$)/

    手机号: +86或0086     可有可无,最多一次

             空格         可有可无,多了不限

             1

             3,4,5,7,8    选一个

             9位数字

        (\+86|0086)?\s*1[34578]\d{9}

    reg = /^0?(13[0-9]|14[57]|15[012356789]|17[013678]|18[0-9])\d{8}$/

    微 信 wei xin w x

        (微|w(ei)?)\s*(信|x(in)?)

    6.指定匹配位置:3种:

     ^字符串开头,比如: 字符串开头的空字符:^\s+

     $字符串结尾,比如: 字符串结尾的空字符:\s+$

                    比如: 开头或结尾的空字符:^\s+|\s+$

     \b单词边界:包括:  ^$ 空格 标点符号,比如: 查找单词no,匹配单词no: \bno\b

    纯英文格式电子邮件: var reg = /^[0-9A-Za-z_-]+@[0-9A-Za-z_-]+(\.[0-9A-Za-z_-]+)+$/

    银行卡: 借记卡、储蓄卡19位, 贷记卡、信用卡16位, 存折17位

      \B 非单词边界

    var reg = /([a-z])\1*/ig;   //定义正则表达式变量

    var reg =new RegExp("^[a-zA-Z]{9,20}$");

    var kw = str.match(reg);    //使用此变量时,不需使用斜杠

    判断是否是图片(带参数):  /\.(png|jpe?g|gif|svg)(\?.*)?$/.test(str)

    判断是否是视频(带参数):  /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/.test(str)

    _______________________________________________________________________________________________

    /([a-z])\1*/        //表示:  第一位必须是小写字母,\1表示匹配和第一个()中完全相同的内容

                                 *表示可有可无,多了不限,就算没有和它匹配的也选择它

                                 +表示至少一个,多了不限,有一个和它匹配的才选择它

    当 ? 紧跟在任何一个其他限制符(*  +  ?  {n}  {n,}  {n,m})后面时,匹配模式是非贪婪的,会尽可能少的匹配所搜索的字符串

    默认的贪婪模式则尽可能多的匹配所搜索的字符串

        例如:  对于字符串"oooo","o+"将尽可能多的匹配"o",得到结果 ['oooo'],而 "o+?" 将尽可能少的匹配"o",得到结果 ['o','o','o','o']

    m  多行,将开始和结束字符(^和$)视为在多行上工作,也就是分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处

    s  与m相反,单行匹配

    第七章*****************************************************************************************

    四、RegExp类型

    什么是: 专门封装一条正则表达式,并提供使用正则表达式执行查找和验证的API

    何时: 1. 使用正则表达式验证用户输入的字符串格式

          2. 即查找关键词内容,又查找关键词位置

    如何:

    创建: 2种

    ① 直接量(字面量)

    var reg=/正则/ig;             //i: 忽略(ignore)大小写;g: 查找全部(global)

    何时: 如果正则表达式是固定不变的

    强调: //之中不支持js表达式,不支持动态生成正则表达式,如果再出现/,就必须改为\/

    ② 使用正则表达式的构造函数

    var reg=new RegExp("正则","ig");

    如: var reg=new RegExp("^[a-zA-Z]","g")     //使用引号时,不加斜杠

        var reg=new RegExp(/^[a-zA-Z]/,"gi")    //有斜杠时,不加引号

    何时: 如果正则表达式需要动态拼接生成

    强调: ""中再出现\或",都要改为\\和\"

    API: 2个

    ① 即查找内容,又查找位置

    var arr=reg.exec(str)         /*在str中依次查找下一个符合reg规则的关键词的内容和位置*/

    返回值: 返回一个数组arr: 与正则表达式匹配的文本,后面依次为各个子表达式()的文本,用逗号分隔

                                                     最后一个arr["input"] 是要查找的内容str

           arr[0]本次找到的关键词的内容

           arr["index"]本次找到的关键词的下标位置

            如果没找到,就返回null

    问题: 每次只返回本次找到的一个关键词

    解决: 用循环反复调用reg.exec

    原理: 每次调用exec,做3件事:

         1. 将本次找到的关键词保存在arr的0位置

         2. 将本次找到的关键词位置保存在arr的index位置

         3. 每个reg对象都有一个.lastIndex属性, 标识下次开始的查找位置,开始时为0

            每执行完一次exec,exec会自动修改为: reg.lastIndex=当前位置index+关键词长度

    function cha(str){

      var  reg=/./g;                     //在全局查找关键词

      for(var i=0;i<str.length;i++){     //str.length: 字符串的长度

        var arr=reg.exec(str);

        console.log(arr[0]);             //关键词的内容

        console.log(reg.lastIndex-1);    //关键词的下标位置

    } }

    ② 验证字符串的格式

    var bool=reg.test(str);               /*验证str是否符合reg的规则要求*/

    验证通过返回true,不通过返回false,可直接当做判断条件

    问题: test默认只要部分匹配就返回true

    解决:从头到尾完全匹配(验证),必须在正则表达式中: 前加^,后加$

    _______________________________________________________________________________________________

    五、Math类型

    什么是: 专门保存数学计算的常量和函数的对象 的API

    何时: 只要进行数学计算

    如何:

    创建: Math不用创建,不能new,直接使用

         所有常量和API都用Math直接调用

    API

    取整: 3种:

    1.上取整: 只要超过,就取下一个整数

    Math.ceil(num)

    2.下取整: 只要超过,就省略小数部分

    Math.floor(num)

    Math.floor(num)   VS   parseInt(str)

    只能对纯数字           能先去掉数字之后的非数字字符,再取整

    3.四舍五入取整

    Math.round(num)

    Math.round                VS            n.toFixed(d)

    缺: 只能取整,不能指定小数位数        优: 可指定任意小数位数四舍五入

                                             金钱: Number(parseFloat(num).toFixed(2))

    优: 将返回number,可直接计算          缺: 将返回字符串类型,需要先转换为数字类型,再计算

    可自定义round函数

    4. 乘方和开平方

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

    Math.sqrt(n);         开平方

    5. 最大值和最小值

    Math.max(值1,值2,值3,...)

    Math.min(值1,值2,值3,...)

    问题: max/min不支持获得数组中的最大/小值,求出数组中的最大/最小值

    解决:Math.max.apply(null,arr)         /*apply: 调用,可自动打散数组类型参数*/

    6. 随机数

    Math.random()          取值: 0~1,默认得到一个随机小数

    公式:在任意[min,max]之间生成一个随机整数:var r=parseInt(Math.random()*(max-min+1)+min)

    简写: 如果min=0,即[0, max]之间: var r=parseInt( Math.random()*(max+1) )

    例: 随机数组中的数:var index = parseInt(Math.random()*arr.length)

    _______________________________________________________________________________________________

    六、Date类型

    什么是: 专门封装一个时间点,并提供操作时间的API

    何时: 只要存储时间或者计算时间

    如何:

    创建: 4种

    1. 创建日期对象,并自动获得当前系统时间

    var now=new Date();//强调: 只能获得客户端本地时间,标准格式,即格林尼治标准时(GMT)

    2. 创建日期对象,并封装自定义时间点

    var date=new Date("yyyy/MM/dd hh:mm:ss");  /*字符串中的月份为自动-1后的值*/

                                                   //时间格式也可为: '2017-12-30 21:15:00'

                                                   //或: 2018-03-06T17:12(部分浏览器有时差问题)

    部分手机(如iPhone)获取时间的方式与其它浏览器不同,需要兼容处理:

    new Date("2017-02-05 12:10:10.12")可能会发生错误,函数返回错误是"Invalid Date"

    var str = "2018-04-13 22:45:00";

    var arr = str.split(/[- : \/]/);

    var date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4] || '00', arr[5] || '00');

    因为iOS不能识别 - 形式,也可以替换为斜杠形式:

    date = date.replace(/-/g, '/');    // 2018/06/03 00:00:00

    若不是字符串: var date=new Date(yyyy, MM-1,dd,hh,mm,ss);

    如果只关心日期,不关心时间,后半部分时分秒可省略。省略后,默认是00:00:00

    3. 用毫秒数创建日期对象

    原理: 日期对象中保存的是1970年1月1日0点至今的毫秒数———整数

    为什么: 时间段,不受时区影响

           相同的毫秒数: 在不同时区可显示不同的时间点

    总结: 将来数据库中保存的时间都是毫秒数,不要用文字

    何时: 只要将毫秒数转化为当地时间格式时

    var ms=date.getTime();           /*将标准格式的date转化为毫秒数 ms*/

    var now=new Date().getTime();  //获取客户端1970年1月1日0点至今的毫秒数(缩写),时间戳

                                   //注意时区问题

                                   // +new Date()、Date now()    返回毫秒数

    var date1=new Date(ms); //将毫秒数 ms 转化为操作系统当前所在时区的对应时间(必须是Number类型)

    4. 复制一个日期对象:

    为什么: 日期的计算只能直接修改原日期对象

    后果: 计算后,无法保存计算前的原日期

    何时: 如果用户希望同时保留计算前后的开始时间和结束时间时,都要先将开始时间复制一份,再用副本计算结束时间

    如何:

    var date2=new Date(date1);

    _______________________________________________________________________________________________

    API: 3句话:

    1. 8个单位: FullYear年   Month月   Date日     Day星期            ———没有s

               Hours小时  Minutes分钟  Seconds秒  Milliseconds毫秒   ———都以s结尾

    2. 每个单位都有一对儿getXXX()/setXXX()方法

       getXXX()   负责获得指定单位上的数值

      setXXX(n)    负责修改指定单位上的数值,可自动调整时间进制

       特例: Day(星期)没有setXXX()方法

    3. 取值范围:除date(从1开始,31结束)外,其余都是从 0 开始到进制减 1 结束

       FullYear:                   和现实中年份一致

       Month: 0~11                现实中: 1~12,计算机中的月份值比现实中少1,需要修正

       Date: 1~31                 和现实一样

       Day: 0~6                   现实: 日~六,和现实中一致

       Hours: 0~23                和现实一样

       Minutes/Seconds: 0~59      和现实一样

    _______________________________________________________________________________________________

    日期计算

    1. 两日期对象可相减: 结果是毫秒差(ms),可用于倒计时

    2. 对任意单位做加减:3步:

      ①取值: var date1=now.getDate();

      ②做加减: date1+=30;

                 例如: 16+30=46

      ③放回去: now.setDate(date1);            /*setDate可自动调整进制*/

    简写:now.setDate(now.getDate()+n);

    问题: setDate直接修改原日期对象,无法保留开始时间

    解决: 在计算前,都要先将开始时间复制一个副本,再用副本计算结束时间

    倒计时:

    now/=1000, end/=1000;

    放在定时器中:

    now++;

    varT = parseInt((end-now)/1000);     //共剩多少时间(单位:秒)

    var d = parseInt(T/(3600*24));        //剩多少天

    var h = parseInt(T%(3600*24)/3600);   //剩多少小时

    var m = parseInt(T%(3600)/60);        //剩多少分钟

    var s =T%60;                         //剩多少秒

    日期格式化(new Date()系统时间,转字符串)

    date.toString()               返回当地时间格式的完整版本(系统时间格式)

    date.toLocaleString()         返回当地时间格式的简化版本(有时分秒),不同平台有可能不一样

    date.toLocaleDateString()     仅保留了日期部分

    date.toLocaleTimeString()     仅保留了时分秒部分

    date.toGMTString()            获得 0 时区的国际标准时间

    _______________________________________________________________________________________________

    new Date($.ajax({async: false}).getResponseHeader("Date"));    //获取服务器相应头附带的时间

    输出客户端时间:

    var weeks=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"];

    function fillTime(time){ return time>=10?time:"0"+time; }    //补全时间

    var now = new Date();

    var day = now.getDay();

    var year    = now.getFullYear();             //年份

    var month   = fillTime(now.getMonth()+1);    //月份

    var date    = fillTime(now.getDate());       //日期

    var hours   = fillTime(now.getHours());      //小时

    var minutes = fillTime(now.getMinutes());    //分钟

    var seconds = fillTime(now.getSeconds());    //秒

    var dateTime=year+'-'+month+'-'+date+' '+hours+':'+minutes+':'+seconds+'('+weeks[day]+')';

    console.log(dateTime);    //2017-09-02 13:21:06(星期六)

    const formatNumber = n =>{

      n = n.toString()

      return n[1] ? n : '0' + n

    }

    const formatTime = date =>{

      const year = date.getFullYear()

      const month = date.getMonth() + 1

      const day = date.getDate()

      const hour = date.getHours()

      const minute = date.getMinutes()

      const second = date.getSeconds()

      return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')

    }

    获取相邻的一段天数:

    var base = +new Date(2018, 1, 1);        //获取时间的毫秒数

    var oneDay = 24 * 3600 * 1000;

    for (var i = 0; i < 500; i++){

      var now = new Date(base += oneDay);

      date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));

    }

    UTC时间和GMT(本地)时间之间的转换:

    GMT转为UTC:

    var now = new Date();

    var nowUTC = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),

                          now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());

    UTC转为GMT:

    var nowGMT = Date.UTC(nowUTC.getFullYear(), nowUTC.getMonth(), nowUTC.getDate(),

                          nowUTC.getHours(), nowUTC.getMinutes(), nowUTC.getSeconds());

    var now = new Date(nowGMT)

    注: 以北京时间为准,UTC总是比GMT小8个小时

    常用API***************************************************************************************

    Math.atan(n)               //返回'反正切函数'arctan(n)的值,单位弧度,可转换为角度

      例: (Math.atan(a/b))*180/Math.PI

    Math.abs(x)                //返回数字的绝对值

      例: Math.abs(a) || 1;

    Math.min(x,y)              //返回指定的数字中带有最低值的数字

    stringObject.substr(start,length)    //从字符串中抽取从start下标开始的指定数目(length)的字符

    +str+1          //+可使字符串变为数字类型再计算

    x=Number(x);    //手动将字符串类型的数字转换成Number类型,不直接修改原变量的值,而是返回新值

    相关文章

      网友评论

          本文标题:JS2

          本文链接:https://www.haomeiwen.com/subject/mslbqqtx.html