this与正则

26 阅读10分钟

this指向

  • 一个 JS 给我们提供的变量
  • 这个变量的值取决于你函数的调用方式, 跟函数怎么写, 没有任何关联
function fn() {
            console.log(this);// window
            // JS 给我们提供的一个变量
        }
        // 1. 在全局直接调用, this === window
        fn()  // 调用了一次函数

        var obj = {
            name: 'QF001',
            age: 18,
            objfn: fn
        }
        obj.objfn() // fn()  相当于调用了一次函数
        // {name: 'QF001', age: 18, objfn: fn}   // 相当于调用的是obj
        // console.log(obj.objfn);
        /*function fn(){
            //   console.log(this);// window
               // JS 给我们提供的一个变量
            }
            fn()
        */

        // ***** 问题1  fn 为啥不加括号?????


        // 3. 将刚才的函数放在一个定时器或者倒计时器中  this === window
        setTimeout(function () { console.log(this); }, 100)
        setTimeout(fn, 100)
        //  window
        // ******  记住这个倒数计时和计时器用法



        // 4. 当作一个事件处理函数使用      在事件处理函数中, this 指向了 事件源

        var box = document.querySelector('div')
        box.onclick = function () {
            console.log(this); // window
        }
        box.onclick = fn;// window

        // 5. 自执行函数    (定义之后, 自己会执行一次)      this === window     
        (function () { console.log(this); })() // window

正则

  • 正则表达式(规则表达式)
  • 由我们自己书写 一个 "规则",专门用来检测"字符串",是否符合我们的规则
  1. 创建正则
    • 字面量
      var reg = /abc/;
      console.log(reg);
   * 内置构造函数
     var reg1 = new RegExp('qweq');
     console.log(reg1); 
  • 正则元字符
    • 正则的元字符 (在正则中, 有一些符号代表了一些含义, 然后我们把这种符号叫做 元字符)
      1. \w   =>  匹配数字字母下划线          a-zA-Z0-9_
      2. \W   =>  匹配非数字字母下划线        除了 a-zA-Z0-9_ 之外的字符串
      3. \d   =>  匹配数字                    0-9
      4. \D   =>  匹配非数字                  除了 0-9 以外的
      5. \s   =>  匹配空白字符                ''
      6. \S   =>  匹配非空白字符              
      7.  .   =>  匹配任意非换行的字符         
      8.  \   =>  转义符号
   转移符号:    ****非常重要*****
      如果原本有特殊含义, 那么加上 \  后就取消了特殊含义, 转为一个普通文本, 比如 .
      如果原本没有特殊含义, 那么加上 \ 后就回去正则中找, 有没有这样特殊符号, 如果有就会具有特殊含义, 比如说 w
 
      但是 字母 q, 本身没有特殊含义, 加上 \ 后去正则中找, 也没有这样的特殊符号, 所以加上也没用
  • 正则的检测方法: 正则.test(传入你要检测的字符串, 也可以是一个变量), 检测完成后有一个返回值, 是布尔值
// var reg1 = /w/   // 要求字符串中包含 'w'
        // var reg2 = /\w/   // 要求字符串中包含 数字字母下划线
        // var reg3 = /./  // 匹配任意非换行的字符串
        // var reg4 = /\./ // 要求字符串中包含一个 小数点
        // var reg5 = /q/  // 要求字符串中包含 'q'
        // var reg6 = /\q/  // 会将字母q转成具有特殊含义的符号, 但是正则中没有这样的符号, 所以写了跟没写一样
        // var reg7 = /\\/ // 第一个转义符将第二个转义符取消特殊含义, 最后字符串中需要包含一个 普通文本 \


        //  \w
        // var reg = /\w/ //要求  '字符串'  中包含  数字字母下划线

        var str1 = '123'
        var str2 = 'aqaf123'
        var str3 = 'adsaff'
        var str4 = '@$#%'

        console.log(reg.test(str1));//true  
        console.log(reg.test(str2));//true 
        console.log(reg.test(str3));//true 
        console.log(reg.test(str4));//false


        //  \d
        //  \D
        var reg = /\d/  //要求  '字符串'  中包含   数字
        var reg = /\D/     //要求  '字符串'  中包含  非数字 
        var str1 = '123'
        var str2 = 'aqaf123'
        var str3 = 'adsaff'
        var str4 = '@$#%'


        console.log(reg.test(str1));//true  
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//false
        console.log(reg.test(str4));//false

        console.log(reg.test(str1));//false  
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true
        console.log(reg.test(str4));//true

        //   \s
        var reg = /\s/   //要求  '字符串'  中包含 空白字符

        var str1 = '11233'
        var str2 = 'sfff 23'
        console.log(reg.test(str1));//false  
        console.log(reg.test(str2));//true



        var reg = /abc/
        var reg1 =new RegExp('abc');
        console.log(typeof reg);//object
        console.log(typeof reg1);//object
        console.log(reg instanceof RegExp);
        // 判断 reg 是否是 RegExp 的实例
        // true
        // reg 是否是 RegExp 的实例
        /**
          正则的限定元字符
              一般是和元字符合在一起使用, 限制了前边的元字符出现几次
         
          1. *        表示的含义是前一个内容重复至少 0 次     0~正无穷次      \d*
          2. +        表示的含义是前一个内容重复至少 1 次     1~正无穷次      \d+
          3. ?        表示的含义是前一个内容重复 0 次 或者 1 次   也就说可以出现 0~1 次   \d?
          4. {n}      表示的含义是前一个内容重复 n 次     \d{3}
          5. {n,}     表示的含义是前一个内容最少重复 n 次     n~正无穷次      \d{5,}
          6. {n,m}    表示的含义是前一个内容最少重复 n 次, 最多重复 m 次      \d{5,10}
        */
var reg = /\d*/ // 要求这个字符串中 ****包含一个数字**** , 这个数字出现最少 0 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'

        console.log(reg.test(str1));//true
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true
        相当于**从左到右**解析,只要碰到符合条件的字符串就返回 true
        如果 在 ***严格模式****  会报错

        var reg = /\d+/ 
        // 要求这个字符串中 ****包含一个数字**** , 这个数字出现最少 1 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'

        console.log(reg.test(str1));//false
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true


        var reg = /\d?/ 
        // 要求这个字符串中 ****包含一个数字**** , 这个数字最少出现 0 次 最多 1 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'

        console.log(reg.test(str1));//true
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true

        var reg = /\d{1}/ 
        // 要求这个字符串中 ****包含一个数字**** , 这个数字 需要重复出现 1 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'
        
        console.log(reg.test(str1));//false
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true
        console.log(reg.test(str3));//true
    


        var reg = /\d{1,}/ 
        // 要求这个字符串中 ****包含一个数字**** , 这个数字 最少出现 1 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'

        console.log(reg.test(str1));//false
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true

        var reg = /\d{1,3}/ 
        // 要求这个字符串中 ****包含一个数字**** , 这个数字 最少出现 1 次 最多出现 3 次
        var str1 = 'abc'
        var str2 = 'abc1'
        var str3 = 'abc123'

        console.log(reg.test(str1));//false
        console.log(reg.test(str2));//true
        console.log(reg.test(str3));//true
        /**
          正则的边界元字符
        
          ^ 表示的是开头, 一般写在正则开始的位置      /^abc/
          $ 表示的是结尾, 一般写在正则结束的位置      /abc$/
        
          如果同时存在, 那就代表严格判断      /^abc$/     字符串必须是 abc
        */
var reg = /\d?/ // 要求这个字符串中包含一个数字, 这个数字最少出现 0 次 最多 1 次

        var reg = /^\d$/   // 要求这个 **字符串***必须是**一个**数字***, 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// false 



        var reg = /^\d?$/   
        // 要求这个 **字符串***必须是**一个**数字*** 这个数字最少出现 0 次 最多 1 次, 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// false 
        console.log(reg.test(str4));// true 
        console.log(reg.test(str5));// true 


        var reg = /^\d{2,3}$/   
        // 要求这个 **字符串***必须是**数字*** 这个数字最少出现 0 次 最多 1 次, 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// false 
        console.log(reg.test(str4));// false 
        console.log(reg.test(str5));// false 
        console.log(reg.test(str6));// true 

        var reg = /^\w$/   
        // 要求这个 **字符串***必须是**一个**0~9/a~z/A~Z/_***, 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        var str7 = '_'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// false 
        console.log(reg.test(str4));// true 
        console.log(reg.test(str6));// false 
        console.log(reg.test(str7));// true 


        var reg = /^\w{1}$/   
        // 要求这个 **字符串***必须是****0~9/a~z/A~Z/_***,出现1次,
        // 当 给后面加 * + ? {1}{1,}{1,3} 表示出现次数 表示不在是一个 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        var str7 = '_'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// false 
        console.log(reg.test(str4));// true 
        console.log(reg.test(str6));// false 
        console.log(reg.test(str7));// true

        var reg = /^\w+$/
        // 要求这个 **字符串***必须是****0~9/a~z/A~Z/_***,出现最少 1 次,
        // 当 给后面加 * + ? {1}{1,}{1,3} 表示出现次数 表示不在是一个 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        var str7 = '_'
        console.log(reg.test(str1));// true
        console.log(reg.test(str2));// true
        console.log(reg.test(str3));// true 
        console.log(reg.test(str4));// true 
        console.log(reg.test(str6));// true 
        console.log(reg.test(str7));// true

        var reg = /^\w{1,}$/   
        // 要求这个 **字符串***必须是****0~9/a~z/A~Z/_***,出现1次,
        // 当 给后面加 * + ? {1}{1,}{1,3} 表示出现次数 表示不在是一个 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        var str7 = '_'
        console.log(reg.test(str1));// true
        console.log(reg.test(str2));// true
        console.log(reg.test(str3));// true 
        console.log(reg.test(str4));// true 
        console.log(reg.test(str6));// true 
        console.log(reg.test(str7));// true

        var reg = /^\w{2,5}$/
        // 要求这个 **字符串***必须是****0~9/a~z/A~Z/_***,出现最少 0 次,
        // 当 给后面加 * + ? {1}{1,}{1,3} 表示出现次数 
        /*相当于进入严格模式*/
        var str1 = 'aasd'
        var str2 = '123sadds'
        var str3 = '12323'
        var str4 = '1'
        var str6 = '123'
        var str7 = '_'
        console.log(reg.test(str1));// true
        console.log(reg.test(str2));// false
        console.log(reg.test(str3));// true 
        console.log(reg.test(str4));// false 
        console.log(reg.test(str6));// true 
        console.log(reg.test(str7));// false
        /**
    正则的特殊元字符
   
        1. ()   /(abc){2}/
            含义1: 当成一个整体
            含义2: 单独捕获 (欠着)
   
        2.  |       /ab(c|d)/
            或: 符号左边的字符  或者  右边的字符    满足一个就行
            补充: 或的分界线在哪里
                如果没有小括号, 那么直接将这个正则分为两个正则
                如果有小括号, 那么 或 到小括号的位置就结束了
   
        3. []       [abcde] [a-z]
            包含    包含其中的一个就行
            注意:   中括号只占用一个字符
   
        4. [^]          [^abcde]    [^0-9]
            不包含      除了这些之外的都可以
            注意:       中括号只占用一个字符
   
        5. -
            到(至)
            一般是和 包含 或者 不包含
            [0-9]   数字0~9
            [^0-9]  除了数字0~9之外的
        */
//  ()
        var reg = /(abc){2}/;
        console.log(reg);      /*  /(abc){2}/  */

        var str1 = 'abc';
        var str2 = 'abcabc'; 
        var str3 = '1234#@abcabc&^%$'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// true
        console.log(reg.test(str3));// true

        var reg = /^(abc){2}$/; // 表示当前字符串必须是 abcabc
        console.log(reg);      /*  /(abc){2}/  */

        var str1 = 'abc';
        var str2 = 'abcabc';
        var str3 = '1234#@abcabc&^%$'
        console.log(reg.test(str1));// false
        console.log(reg.test(str2));// true
        console.log(reg.test(str3));// false
        //表示当前字符串必须是 abcabc

        // 2.  | 
        // var reg = /^(abc|def){2}$/
        /* 就是说 小括号的重复两次  
         然后出现两次 ,左边只要是按abc或者是def就行
                       右边只要是按abc或者是def就行
         */

        /**
         *  前三位字符要么是 abc 要么是 def
         *  因为有{2} 的存在所以前边的整体还会再次出现
         *  所以还有后三位字符, 后三位字符要么是 abc 要么是 def
         * 
         * 
         *  注意 前三位和后三位直接没有说一定要一模一样
        */
        // 当前字符串是 abc 或者 def 都可以, 只要重复出现两次就好


        
        console.log(reg.test('abcabc')) //true
        console.log(reg.test('defdef')) //true

        console.log(reg.test('abcdef')) //true
         
        console.log(reg.test('defabc')) //true

        console.log(reg.test('qweqwe')) //false


        var reg1 = /^abc|def$/
        // /**
        //  *  /^abc/
        //  *  /def$/
        // */
        console.log(reg1.test('abc'))   // true
        console.log(reg1.test('qbc'))   // false
        console.log(reg1.test('def'))   // true
        console.log(reg1.test('deq'))   // false


        var reg2 = /^ab(c|d)ef$/
        /**
         *  /^abcef$/
         *  /^abdef$/
        */
        console.log(reg2.test('abcef'))
        console.log(reg2.test('abdef'))

        // []
        var reg = /^[0-9]$/ // 当前字符串必须是一个数字, 并且只能有 1 位

        console.log(reg.test('q'))  // false
        console.log(reg.test('5'))  // true
        console.log(reg.test('99'))  // false

        // [^] 
        var reg = /^[^0-9]$/ // 当前字符串是 0-9 之外的字符, 并且只能有 1 位

        console.log(reg.test('q'))  // true
        console.log(reg.test('5'))  // false
        console.log(reg.test('99'))  // false



        /**
         *  正则的重复元字符
         *
         *      符号: \1    \2  \3  \4
         *      含义: 代表当前正则中第几个小括号的值
        */

        var reg = /^(abc|def)\1$/
        // // 要么重复 abc 要么重复 def

        console.log(reg.test('abcabc')) // true
        console.log(reg.test('defdef')) // true
        console.log(reg.test('abcdef')) // false
        console.log(reg.test('defabc')) // false

        // ???
        var reg = /<div></div>/
        var reg = /<div><\/div>/
        var reg = /^<(div|p)><\/div>$/
                var reg = /^<(div|p)><\/\1>$/
        // //    \/  的的含义是  因为把<div></div> 中 / 号会被认为正则符号   / /
        // //     所以要加个转义符号  转换为 普通符号
                console.log(reg.test('<div></div>'))  // true
                console.log(reg.test('<p></p>'))      // true
                console.log(reg.test('<span></span>'))// false 
                console.log(reg.test('<div></p>'))    // false 
            /**
            正则的标识符(修饰符)
           
                1. i    忽略字母大小写
                2. g    全局捕获(欠着)
           
                注意: 标识符必须写在正则的最后
            */
        var reg = /^[a-c]$/  // 字符串必须是a-c中的某一个
        console.log(reg.test('a'));//true
        console.log(reg.test('A'));//false
         证明 正则区分大小写 

        var reg = /^[a-cA-C]$/    // 字符串必须是a-c A-C 中的某一个 忽略大小写
        console.log(reg.test('a'));//true
        console.log(reg.test('A'));//true
        表示可以为大写也可以为小写



        var reg = /^[a-c]$/i    // 字符串必须是a-c A-C 中的某一个 忽略大小写
        console.log(reg.test('a'));//true
        console.log(reg.test('A'));//true
                /**
                  正则的捕获
                 
                      语法: 正则.exec(字符串)
                 
                          1. 没有符合条件的字符时捕获的内容为 null
                 
                          2. 正则没有小括号也没有修饰符g
                              每一次捕获都是从当前字符串下标0的位置开始捕获, 捕获到第一个符合条件的结束
                              然后将捕获到的内容放到一个数组中的 下标 0 的位置
                 
                          3. 正则没有小括号但是有修饰符g
                              第一次捕获捕获到内容之后, 下一次捕获的时候会从上一次捕获结束的位置开始继续捕获
                              一直到某一次捕获不到内容了, 会返回一个 null
                              然后如果继续下一次捕获, 那么会重新从字符串下标 0 的位置重新开始捕获
                 
                          4. 有小括号
                                  捕获的时候会将捕获到的内容放到 数组下标0 的位置
                                  然后将正则中每一个小括号捕获到的内容从数组下标1开始, 按照顺序放过去
                */

        var reg = /\d{3}/
           console.log(reg.test('qwertyuio'));// false
        // 1. 不能正确捕获到内容
           console.log(reg.exec('qwertyuio')) // null

        // 2. 有能够捕获到的内容, 但是现在正则中没有小括号也没有修饰符g
        console.log(reg.exec('abc123def456qwe789'));
        // 下标0 为 123
        console.log(reg.exec('abc123def456qwe789'));
        // 下标0 为 123



        // 3. 有能够捕获到的内容, 正则中只有修饰符 g, 没有小括号
        var reg = /\d{3}/g
        var str = 'abc123def456qwe789'
        console.log(reg.exec(str));
        // 下标0 为 123 
        console.log(reg.exec(str));
        // 下标0 为 456 
        console.log(reg.exec(str));
        // 下标0 为 789 
        console.log(reg.exec(str));
        //  null 
        console.log(reg.exec(str));
        // 下标0 为 123



        // 4. 有小括号
        var reg = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/

        var str = '411381200503241234'

        console.log(reg.exec(str));
        /*
            0: "411381200503241234"
            1: "4113"
            2: "81"
            3: "20"
            4: "05"
            5: "03"
            6: "24"
            7: "12"
            8: "34"
        */
        /**
         正则的两大特性
        
             => 懒惰
                 每一次捕获的时候 都会从字符串 [0] 的位置开始
                 解决:
                     给正则后加一个修饰符g
        
             => 贪婪
                 每一次捕获的时候都尽可能的夺取捕获内容
                     解决:
                         使用非贪婪的限定符
                         非贪婪的限定符: *?      +?      ??      {n,}?   {n,m}?
        
                 贪婪: 尽可能多拿
                 非贪婪: 尽可能的少拿
        */
var str = '<div class="box" id="id_box" data-id="QF001"><span></span></div>'

        var reg = /<div.*>/
        //  . 表示 非空字符串 
        //  * 表示 至少出现0次
        //  <div.*> 至少出现0次 非还行的div

        console.log(reg.test(str));//true
        console.log(reg.exec(str)); 
        /* 下标0 为  
        <div class="box" id="id_box" data-id="QF001"><span></span></div>
        */


        var reg2 = /<div.*>/g
        console.log(reg2.exec(str));
        // /* 下标0 为  
        // <div class="box" id="id_box" data-id="QF001"><span></span></div>
        // */
        console.log(reg2.exec(str));
        // null





        var reg1 = /<div.*?>/

        console.log(reg1.exec(str));
        /*
        下标 0 为
        "<div class=\"box\" id=\"id_box\" data-id=\"QF001\">"
        */*
        /**
          字符串中能与正则一起使用的方法
        
              1. search 查找字符串中是否有满足条件的内容, 如果找到返回下标, 没找到返回 -1
        
              2. match    找到字符串中符合正则规则的部分返回出来
                  2.1 如果正则没有 修饰符g    那么和正则的exec是一样的
                  2.2 如果正则有 修饰符g, 会将捕获到的所有内容放到一个数组中, 返回出来
        
              3. replace  找字符串中符合正则规则的部分, 将这一部分替换
        */
// search 
        var reg = /\d{3}/

        var str1 = '你好123'

        var str2 = '你好'

        console.log(str1.search(reg)); // 2 
        console.log(str2.search(reg)); // -1 


        // match

        var reg1 = /\d{3}/
        var str1 = 'hello123word456XXXX789'
        console.log(str1.match(reg1))
        // // 下标0 为123 的数组
        console.log(str1.match(reg1))
        // 下标0 为123 的数组
        // 和捕获不加修饰符给一样

        var reg2 = /\d{3}/g
        console.log(str1.match(reg2))
        //['123', '456', '789']
        //  将获取的符合条件的数字   作为数组索引0的值放到这个数组里面


        // replace

        var reg1 = /\d{3}/
        var str1 = 'qwe123qwe456'
        var str2 = 'qwe abc def' 
        console.log(str1.replace(reg1,'***'));
        //qwe***qwe456
        console.log(str2.replace(reg1,'####'));
        //qwe abc def