高级js 未来某个大厂的某个大牛

本文详细探讨了JavaScript中的对象、原型、构造函数、原型链、继承机制,以及函数的this指向、call、apply、bind方法。通过实例解析了如何在JavaScript中实现对象的创建、属性的访问、方法的共享,以及函数内部的this绑定规则。此外,还介绍了箭头函数的使用,解构赋值和ES6中的let、const关键字。最后,简要提到了正则表达式在字符串处理中的应用。
摘要由CSDN通过智能技术生成

高级js
全为重要内容
对象是什么? 对象是属性和方法的集合体!
prototype!!!

  • 是什么:属性名;构造函数的属性名;内置的,不是我们写的;
  • 有什么特别之处:
    • 属性值是个对象,这个对象上可以添加很多方法(公共的方法);
    • 每个实例化对象都可以访问上面的方法,解决上面内存浪费的问题;
  • 官方名:构造函数的原型;
  • 规则:
    • JavaScript 规定,每一个构造函数都有一个prototype 属性名,对应的值保存地址,指向一个对象。

    • 我们可以把那些公共的方法,直接定义在 prototype 对象上,这样所有对象实例就可以共享这些方法。

      function Star(uname, age) {
      this.uname = uname;
      this.age = age;
      }

      // 记住:属性名prototype 属性值对象{} ----> Star.prototype = {} 不需要我们赋值;

      // 语法:定义
      Star.prototype.sing = function() {
      console.log(‘我会唱歌’);
      }

      var ldh = new Star(‘刘德华’, 18);
      var zxy = new Star(‘张学友’, 19);

      // 记住:虽然方法都是定义在 prototype属性值 对象上;但是实例化可以直接使用;
      // 这个方法都是去原型对象上找方法;使用是同一个方法;
      ldh.sing();//我会唱歌
      zxy.sing();//我会唱歌

      // 验证:
      console.log(ldh.sing === zxy.sing); // true

this指向!!!

  • 位置:函数内部;
  • this到底指向谁?规则:谁调用,this就是指谁!!
  • 场景1:事件绑定

自己理解 函数的this如果不new一个实例 那么this 指向是BOM 此时this指向 window

如果new了一个实例化对象 此时this指向的就是实例化对象

第二天

constructor 面试可能会问

constructor:

位置名:来自原型对象上默认位置名值:构造函数本身

意义:有个实例化对象,实例化.<<底杠>>proto<<底杠>>.constructor 找到这个实例化是由哪个构造函数!

代码:覆盖与否对代码开发没有任何影响;

原型链

查找机制:

  • 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  • 如果没有就查找它的原型对象(也就是 proto指向的 prototype 原型对象)。
  • 如果还没有就查找原型对象的原型(Object的原型对象)。
  • 依此类推一直找到 Object 为止(null)。
  • 如果还没有,就报错这个对象没有这个方法;Uncaught TypeError: XXX.fn is not a function

特点:

// 每一个实例化对象 都会有proto 非标准属性,指向其Star构造函数的.prototype

// 原型对象也是个对象;也是某个构造函数的一个实例化,也有相应的proto,指向其 构造函数的.proto

继承!!!

  • 为什么学习继承?
    • 有的构造函数上原型对象上已经实现一部分方法,
    • 我们需要这些方法,就需要把这个部分功能继承过来(内存地址上指向是同一个地址),而不是重新再写一次;
  • 大白话:想办法把别人原型对象 串 我们自己原型链;

继承-01-构造函数内部属性 call

新的语法:一次性把对方身上所有属性全部拿过!

call:打电话 呼叫;基础语法

function Other(house, money, car) {
    this.house = house;
    this.money = money;
    this.car = car;
  }
  var obj = {
    info: "我就是个单独对象",
  };

  Other.call(obj, 10, 20, 10);
  // call语法规则:【需要重点记忆】
  //      1.Other函数肯定是要执行!
  //      2.参数:第一个参数   Other执行,Other内部this上的所有的属性名 即将要去到 这个参数上;
  //              剩余参数,必须逗号分隔;就是OTher执行时,需要传入的实参;
  console.log(obj);
----------------------------------------------------------------------------------------
 // 构造函数的内部数据的继承:
  function Other(house, money, car) {
    this.house = house;
    this.money = money;
    this.car = car;
  }

  function My2(a, b, c) {
    // 这个My2构造函数内部的实例化对象
    Other.call(this, a, b, c);

    // 相当于:
    // this.house = a;
    // this.money = b;
    // this.car = c;
  }

  var m1 = new My2(10, 50, 60);
  console.log(m1);

  var m2 = new My2(20, 20, 20);
  console.log(m2);

继承-02-构造函数的原型对象

// 别人写好构造函数+原型对象
  function Other(house) {
    this.house = house;
  }
  Other.prototype.show = function() {
    console.log("你看老子多有钱,我有" + this.house + "套房子");
  };
  Other.prototype.sing = function() {
    console.log("你看老子多有钱,我会唱歌");
  };


  // 自己:
  function My(house) {
    Other.call(this, house);
  }
  // --------------------------------------------------------------------方式3:
  // 
  My.prototype = new Other();
  // My.prototype 本质是 {} __proto__ : Object的原型对象;自带了constructor:My;
  //              想被替换为 {} __proto__本来就是指向Other原型对象;
  //              o = new Other(); 就完成代替任务;{} __proto__本来就是指向Other原型对象;
  My.prototype.constructor = My;
  // 对上面的分解
  // var o = new Other(50); // o   {house:50 ,__proto__:Other.prototype}
  // My.prototype = o;

  My.prototype.dance = function() {
    console.log("我是My原型对象上一个方法");
  }

  // 测试My
  var m = new My(10);
  // m.dance();
  // m.show();
  // m.sing();
  console.log(m.house);

  // 测试Other:
  // var o = new Other(60);
  // o.show();
  // o.sing();
  // o.dance();
  // console.log(o);

ES6 类 基本语法

  // ES6:类型  构造函数相关:
  // 语法:class关键字 My类的名称(构造函数的名称)

  class My {
    constructor(name, age) {
      //特点1:构造器constructor函数,不需要写function,函数末尾没有逗号
      this.name = name;
      this.age = age;
    }
    show() {
      //特点2:下面直接写原型对象上方法就OK,prototype不出现
      console.log("我是个炫富的方法");
      console.log(this.name);
    }
  }

  // 使用:和过去是一样;实例化
  var m = new My("zs", 18);
  console.log(m);

ES6-类-继承-语法

extends 拓展;一个单词全部 属性和方法继承过来

  // ES6 类的语法
  class Other {
    constructor(house, car) {
      this.house = house;
      this.car = car;
    }
    show() {
      console.log(`你看,老子很有钱的!我有${this.house}套房子,有${this.car}辆车`);
    }
    fn() {
      console.log("我是other新的方法");
    }
  }

  class My extends Other {
    // My天地:
  }
  var m = new My(10, 10);
  console.log(m);

ES6-类-继承-super

// Other
  class Other {
    constructor(car, house) {
      // this.car = car;
      // this.house = house;
    }
    show() {
      console.log("我有很多钱,有" + this.car + "辆车," + this.house + "套房子");
    }
  }

  // 自己类:
  class My extends Other {
    // 除了继承过来的属性名 car house; 想添加一些自己的属性;
    constructor(a, b, money) {
      // 记住:
      //     虽然extends可以继承Other属性,但是如果 My要自己定义一些属性的话,需要关键字 super;把继承过来 car house属性 设置一个对应的值;至于来自变量哪个位置,无所谓!
      //     super调用 必须在 this 之前!不然就报错!
      //     如果被继承Other没有属性,必须安排 super()!
      super();

      this.money = money;
    }
  }

  // 测试
  var m1 = new My(55, 66, 1);
  console.log(m1);

  class Other {
    constructor(house, car) { // es5构造函数
      this.house = house; //未来某一次实例化对象
      this.car = car;
    }
    show() {
      console.log(`你看:老子有 ${this.house} 套房子;有 ${this.car} 辆的车!`);
    }
    teji() {
      console.log("特技:我会一瞬间花 100万!");
    }
    sing() {
      console.log("我会唱歌!!-----------------------");
    }
  }


  class My extends Other {
    // 自己构造器函数:
    constructor(x, y, z) {

      // 一定  
      super(x, y);
      // 1. 给被继承 类 构造函数 确定留几个位置;或者不预留位置;但是必须要调用 super();
      // 2. super 必须在this前面调用;   
      this.z = z;
    }
  }


  var m1 = new My(10, 20, 30);
  console.log(m1);

【场景2:在自己类下方法调用 继承过来 类的方法 super,(有可能会出现同名)】

10-小结

  • day01:为什么学构造函数,能够更合理创建一个对象;
  • day02: 为什么学继承?
    • 别人:写好一些构造函数 +原型对象;
    • 我们:非常想要!继承过来!
      • 把你的属性 call 过来
      • 把你的原型对象 想办法 串到我的原型对象;大家形成一个新的原型链;
    • ES6:
      • 基础语法;
      • 记住 super用 场景1 重点!

第三天 有点重要 涉及到 this指向 闭包 递归 函数自己封装深浅拷贝

函数

定义

  • 方式1 函数声明方式 function 关键字 (命名函数)

    function fn(){}

  • 方式2 函数表达式(匿名函数)

    var fn = function(){}

  • 方式3 new Function()

    var f = new Function(‘a’, ‘b’, ‘console.log(a + b)’);
    f(1, 2);

    var fn = new Function(‘参数1’,‘参数2’…, ‘函数体’)
    注意
    /*Function 里面参数都必须是字符串格式
    第三种方式执行效率低,也不方便书写,因此较少使用
    所有函数都是 Function 的实例(对象)
    */

调用

/* 1. 普通函数 */
function fn() {
    console.log('人生的巅峰');
}
fn();

/* 2. 对象的方法 */
var o = {
    sayHi: function() {
        console.log('人生的巅峰');
    }
}
o.sayHi();



/* 3. 构造函数*/
function Star() {};
new Star();



/* 4. 绑定事件函数*/
btn.onclick = function() {};   // 点击了按钮就可以调用这个函数 什么时候调用?用户点击的时候调用



/* 5. 定时器函数*/
setInterval(function() {}, 1000);  这个函数是定时器自动1秒钟调用一次


/* 6. 立即执行函数(自调用函数)*/
(function() {
    // console.log('人生的巅峰');
})();

this

函数内部的this指向:这些 this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同;指向我们的调用者.

改变this指向-01-call

应用场景: 经常做继承.

  // 语法:函数.call(); 算函数调用方式,配合call;
  // 作用:函数在该次的调用的时候,其函数内部this指向 我们指定参数1的那个对象;
  //       这个函数要执行的!
  // 参数:参数1:函数fn内属性名即将要去到这个参数上;
  //       
  function fn() {
    this.a = 10;
    this.b = 20;
  }
  // fn();           // this--->window
  // new fn();       // this--->返回的那个实例化对象

  var obj = {
    info: "我是obj内属性"
  };
  fn.call(obj); // this---->参数1;
  // console.log(obj.a, obj.b);
  // fn.call(window);  相当于  fn();


  // 延伸:
  var btn = document.querySelector("button");
  fn.call(btn);
  console.log(btn.a, btn.b);

改变this指向-02-apply

这个和call非常像 call第二参数需要用都好隔开, 但是apply第二参数是个数组!

 // apply
  // 作用:1. 函数在该次的调用的时候,其函数内部this  指向  我们指定参数的那个对象;
  //       2. 这个函数要执行的!
  // 参数:1. this  指向  我们指定参数的那个对象
  //       2. fn要执行的时候,把参数 作为一个数组传入;


  function fn(a, b, c, d, e) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
    this.e = e;
  }

  var obj1 = {
    info: "我是obj1上属性"
  };
  fn.call(obj1, 10, 20, 30, 40, 50);
  console.log(obj1);


  var obj2 = {
    info: "我是obj2上属性"
  }
  fn.apply(obj2, [10, 20, 30, 40, 50]);
  console.log(obj2);


  // 场景:需求 求 一堆数的最大值; 参数:只能逗号分隔传入,比如 现在想求一个数组的中最大值;   
  //       发现 让把形参形式 从逗号形式 需要转换为 数组形成  进行传入的话,需要用apply 第二个参数功能; 
  var arr = [15, 18, 99, 45, 74, 56, 999];


  // 常规:逗号分隔;上面的数组需要让下面方法求最大值,大家只能手动把数组中每一项输入到下面()内才能得到结果;
  var max = Math.max(15, 18, 99, 45, 74, 56, 999);
  console.log(max);


  // 需求:现在不想手动输入,不想使用for循环,只能把 逗号分隔形式 转化为 数组形式传入;
  var max = Math.max.apply({}, arr)
  console.log(max);

改变this指向-03-bind

  //  bind 
  //    作用:1.改变某个函数内部this指向!
  //         2.函数是不会被执行的!返回新函数,内部this已经为固定!

  //    参数 :本次代码执行后,函数内this的新的指向,
  //    返回值:返回全新的函数 内部this已经 被改变后的 函数!
  • 轮播图右侧点击的修改:

    MySwiper122.prototype.rClick = function() {

    // -------------------------------------------------------实际写法
    this.right.onclick = function() {
      this.index++;
    
      if (this.index == 6) {
        this.index = 0;
      }
    
      // 设置切换
      this.ul.style.left = -this.index * this.w + "px";
    }.bind(this); // 实例化对象
    
    
    // 执行过程:把 day-01 临时代替that要好!
    //       1.发现 赋值号
    //       2. 先执行右侧,把右侧结果 赋值给左侧!
    //          右侧:函数A.bind(); 函数A不执行!函数A.bind()会执行返回一个新的函数!就是右侧的结果!
    //          左侧:this.right.onclick 给 onclick位置 设置一个新的函数 (内部的this 已经被固定了!)
    

    };

改变this指向-三个方法异同

  • 函数遇见call、apply、bind:本次代码中,函数内部的this会指向为 遇见第一参数!

  • 面试题:

    • !相同点:都是可以改变函数内部this指向!
    • !不同点:
      • call 和 apply 会调用执行函数!bind 不会执行函数!
      • call 和 apply传递的参数不一样, call传递参数使用逗号隔开,apply使用数组传递;
  • 应用场景:

    1. call ES5构造函数的实例属性做继承.
    2. apply :参数形式 逗号形式---------------------->数组形式
      var res = Math.max.apply(Math, [10, 10, 50, 99])
    3. bind :不执行函数!如果我们只是想改变下函数内部this指向!不让函数执行!

闭包-定义-作用

函数内部:声明一个变量,局部变量。函数执行完成后,变量不能被其他地方使用,垃圾回收机制处理局部变量存储空间,重新释放空间;

闭包:局部变量和函数绑定在一起了!把这个变量隐藏在函数上;意味局部变量不会被内存垃圾回收机制进行回收!

大白话: 外边还能间接使用函数内部的变量,无行中我们隐藏了一个变量

表现:

  1. 必须是函数a套着函数b

  2. 函数b内部使用了函数a的局部变量

  3. 结果 : 使用的局部变量不会被回收, 这个变量和函数b隐藏绑定在一起了

    // 函数内部: 声明一个变量,局部变量。函数执行完成后,变量不能被其他地方使用,
    // 垃圾回收机制处理局部变量存储空间,重新释放空间;
    // 特点:变量不能被其他地方使用

    // 闭包:基本形式;
    // 1.函数套着函数;上午:里面的函数 作为 外面函数 返回值;
    // 2.里面的函数 用到 外面函数 的局部变量;

    // 闭包:局部变量和函数绑定在一起了!把这个变量隐藏在函数上;意味局部变量不会被内存垃圾回收机制进行回收!
    function demo() {
    var a = 10;

     return function() {
       a++;
       console.log(a);
     }
    

    }
    var fn = demo(); // 接受个函数体;绑定了一个隐藏变量a;
    fn(); // a++; console.log(a); 不能回收的a: 11;
    fn(); // 找那个不能回收那个a: 现在11; a++; console.log(a);
    fn(); // 找那个不能回收那个a: 现在12; a++; console.log(a);

    // 特点:给一个函数 隐藏一个一直要使用变量,变量不会被回收!
    // 这种变量只能是通过函数调用的方式才能获取,咱们直接获取的话是不能获取!

闭包-案例-如何使用

 // ------------------------------------------------------案例
  // 需求:分别点击每个按钮,在控制台输出对应的下标;webapi
  var btns = document.querySelectorAll("button");
  for (var i = 0; i < btns.length; i++) {
    (function(index) { // 内部形参:局部变量
      btns[index].onclick = function() {
        console.log(index);
      }
    })(i); // 实参
  }

  // 1.执行三次:每次都会有个立即执行函数执行;
  // 2.立即执行:内部 btns[index].onclick = function() {}  给每个按钮注册事件,不是执行后面函数;
  //            但是随着三次循环,构成3次闭包;
  // 3.用户点击的时候: console.log(index); 找和这个函数绑定在一起那个隐藏变量;

递归-1-基本使用

感觉: 函数内部代码的时候 发现细节的地方 需要把整个函数内部内容重写一遍的话, 就是递归!

定义

  • 递归:如果一个函数在其内部可以调用其本身,那么这个函数就是递归函数。
  • 简单理解: 函数内部自己调用自己;
  • 注意: 递归函数的作用和循环效果一样,执行过程不一样;由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。

使用

  • 递归:基本形式就是自己调用自己,什么时候用呢?
    • 函数内部:实现功能的基本流程;

    • 在写基本流程的时候,发现有的地方需要再次把 本函数的基本功能需要再次写一次的时候,递归!

    • 注意,递归会一直调用自己的;需要退出条件控制;

      // -------------------------------------执行过程;
      // function fn2() {
      // console.log(“我是fn2函数开始”);
      // console.log("-----");
      // console.log(“我是fn2函数结束”);
      // }

      // function fn1() {
      // console.log(“我是fn1函数开始”);
      // fn2();
      // console.log(“我是fn1函数结束”);
      // }

      // fn1();
      // 执行过程:fn2没有执行完 没有遇见 },fn1算没有执行完 没有};

      // --------------------------------------递归:
      // 函数:在内部调用自己;
      // 得有退出条件;栈溢出报错;

      // function fn() {
      // console.log(“fn函数的开始”);
      // fn();
      // console.log(“fn函数的结束”);
      // }
      // fn();
      // 如果没有退出条件,上一次函数在下一次函数没有执行完时,上一次不算执行完;

      // 和死循环有点不一样:每一次fn都能执行完;
      // function fn() {
      // console.log(“fn函数的开始”);
      // console.log(“fn函数的结束”);
      // }
      // while (true) {
      // fn();
      // }

递归-2-深浅拷贝

 // 笔试:非常大几率;
  function copy(_old) {
    // _old:接受准备要复制的数据,作为形参很合适;
    var _new; // 新的复制出来的数据;

    // 1.判断是否我数组
    if (_old instanceof Array) {
      _new = [];
      for (var i = 0; i < _old.length; i++) {
        // _old[i]
        _new[i] = copy(_old[i]);
      }

    }
    // 2.如果是个对象
    else if (_old instanceof Object) {


      _new = {};
      for (var key in _old) {
        // key:"a"  _old[key]:10
        // key:"b"  _old[key]:99
        // key:"c"  _old[key]:[66,77,88] 不能直接给
        // key:"d"  _old[key]:{info:"字符串"}

        // 思路:对  _old[key] 做一个数据类型判断,及作出不同动作;
        //       if 数组
        //       else if 对象
        //       else 简单
        // 感觉:函数内部代码的时候,发现细节的地方  需要把整个函数内容重新需要写一次的话,就是递归!
        _new[key] = copy(_old[key]); // 值如果是简单数据类
      }

    }
    // 3.不用判断:简单
    else {
      _new = _old;

    }

    return _new;
  }



  // JQ:$.extend() 查询 可以深度;
  //     $.clone(); DOM节点 

第四天 ECMAScript 6 介绍 ES6

01-let

  • let 定义变量,变量不可以再次定义,但可以改变其值;
  • 具有块级作用域
  • 没有变量提升,必须先定义再使用
  • let声明的变量不会压到window对象中,是独立的

如果使用var声明了变量,也不能再次用let声明了,反之也是不行的。

原因也是这个变量已经被声明过了。

不过这只是一种特殊情况了,实际开发要么全部使用var,要么全部使用let。

  // ************************************let
  //   【1.let 声明变量,不能再次声明了!】
  //   let a = "abc";
  //   console.log(a);
  //   // let a = 10;
  //   a = 10;
  //   console.log(a);


  //   【2. 块级作用域  {   } 块级作用域】 不会影响其他地方变量的值!
  //   {
  //     let age = 18;
  //     console.log(age); // 18
  //   }
  //   console.log(age);
  //   for (let index = 0; index < 3; index++) {
  //     console.log(index);
  //   }

  //   【3.没有变量提升,必须先定义再使用!】
  //   let a = 10;
  //   console.log(a);


  //   【4.let声明的变量不会属性window对象下属性,是独立的】
  //   let info = 10;
  //   console.log(window.info); // 报错?!不会!undefined

02-const

  • 使用const关键字定义常量

  • 常量是不可变的,一旦定义,则不能修改其值

  • 初始化常量时,必须给初始值

  • 具有块级作用域

  • 没有变量提升,必须先定义再使用

  • 常量也是独立的,定义后不会压入到window对象中

    // 声明 常量 :
    // 一开始就定下值是多少!
    // 后面也不能变!

    // 封装函数的时候:写配置项:常量
    // 常量:不能在改变!变量名(常量名字一般是全部大写)
    // const PI = 3.1415926;

    // 1.常量 不能被重新赋值!
    // PI = 3.14;

    // 2.初始化的时候,const 变量 = 必须给初始化的值!
    // const PI;
    // PI = 3.1415926; //报错!

    // 3. 具有块级作用域
    // 4. 没有变量提升,必须先定义再使用
    // 5. 常量也是独立的,定义后不会压入到window对象中

解构赋值

注意: 怎么区分 展开语法和解构赋值 看…后面的自定义名字有没有值, 有值就是展开语法,没值就是解构赋值

ES6 允许按照一定 模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

数组的解构

方便获取数组中的某些项

解构:解剖;意义:从数组或者对象快速拿到你需要的属性值!

 // 解构基本使用:
  //   let [a, b, c] = arr;
  //   console.log(a, b, c);


  //  其他
  //      1.变量多,值少
  //   let [a, b, c, d] = arr;
  //   console.log(a, b, c, d); // d 准备那数组中不存在一项 undefined!


  //      2.变量少,值多
  //   let [a, b] = arr;
  //   console.log(a, b); //  按照顺序解构赋值!


  //      3.就想获取其中某些位置的值!按需取值的!
  //        不需要用变量接收的值,用空位占位;
  //   let arr = [5, 9, 10, 8, 3, 2];
  //   let [, , a, , b] = arr; // 不需要的位置不需要用变量接收的值,用空位占位
  //   console.log(a, b);


  //      4. 剩余值:...
  //   let arr = [5, 9, 10, 8, 3, 2];
  //   let [a, b, ...c] = arr; // ... 剩下全部都被c 结构出来!
  //   console.log(a, b, c);

  //   // 快速复制数组!
  //   let [...newArr] = arr;
  //   console.log(newArr == arr);


  //       5.  复杂:数组套着数组
  //   let arr = ['zhangsan', 18, ['175cm', '65kg']];
  //   let [ , ,[a, b]] = arr;  // !对应形式!
  //   console.log(a, b);

对象的解构

方便解析对象中的某些属性的值

意义:模仿形式,点上获取数据;数组:位置,不讲究名字;对象:名字,不讲究位置!

  // 数组:讲究是位置一一对应的位置
  // 对象:属性名,位置上名字,没有顺序问题!

  // 对象解构基本使用:默认要求变量名和属性名一样!
  // let { bar,foo } = {foo: 'aaa',bar: 'bbb'};
  // console.log(foo,bar);


  // 其他
  //     1. 需要换个新的变量名 人性化
  // let { a, b:c } = { a: 'hello', b: 'world' };
  // console.log(a,c);

  //      2. 获取其中一个属性值!对名字单独写!
  // let { a:res } = { a: 'hello', b: 'world' };  
  // console.log(res);


  //     3. 剩余值:...
  // let obj = { name: 'zs', age: 20, gender: '男' };
  // // let {name,...a} = obj;
  // // console.log(a);
  // //       拷贝对象:
  // let {...newObj} = obj;


  //     4.复杂情况:对形式!对名字!
  // let obj = {
  //   name: 'zhangsan',
  //   age: 22,
  //   dog: {
  //     name: '毛毛',
  //     age: 3
  //   }
  // };

  // let {
  //   dog: {
  //     name,
  //     age: a
  //   }
  // } = obj;

  // console.log(name, a);

箭头函数-基本形式

  • ES6 中允许使用箭头定义函数 (=> goes to),目的是简化函数的定义并且里面的this也比较特殊。

  • 箭头函数的基本定义

    // -----------------------------------------------------------------1.基本使用
    // 函数:传统的方式
    // let fn = function(x) {
    // return x * x;
    // }

    // 1.简化为箭头函数:
    // let fn = (x) => {
    //   return x * x;
    // }
    // let res = fn(10);
    // console.log(res);
    
    
    // 2.形参 如果形参只有一个;()可以省略
    // let fn = x => {
    //   return x * x;
    // }
    
    
    // 3.函数体 如果只有一句话;{}可以省略 且返回这句话;
    // let fn = (x, y) => x * y;
    // let res = fn(2, 3);
    // console.log(res);
    
    //特点3箭头函数内部没有 arguments
    //let fn = () => {
    // console.log(arguments); // 报错,arguments is not defined
    //  };
    //  fn(1, 2);
    

箭头函数-this

箭头函数很特别!

箭头函数内部的 this 指向外部作用域中的 this

  • 箭头函数没有自己的 this

  • 如果箭头函数内部使用了 this ,那么在定义函数的时候,就已经确定了它的指向,而非运行阶段

  • 定义箭头函数时,按照作用域去查找这个this即可,即可确定this指向什么

  • 箭头函数:内没有自己的this; 在其内部用到this,肯定上一层作用域this; 直到找到全局的this:window;

  • function声明的函数:内部this规则 谁调用就是谁!
    // 注意:1.箭头函数不能当做构造函数使用(内部没有this)
    // 2.箭头不能使用 call apply bind(内部没有this)

    // ********************************************************this指向
    // 形式:function (){} this: 谁调用是谁!函数被调用被执行的时候! 【调用时候】
    // 形式:箭头函数 ()=>{} this:
    // 本身没有this,
    // 用的别人的this!
    // 箭头函数在定义设置的时候,按照作用域往上去查找这个this

    // ********调用时候
    // let obj = {
    //   fn: function() {
    //     console.log(this);
    //   }
    // }
    // obj.fn();
    
    // *********定义时候
    // let obj = {
    //   fn: () => {
    //     console.log(this);
    //   }
    // }
    // obj.fn();
    
    
    
    let obj = {
      fn1: function() {
    
        setTimeout(() => {
          console.log(this); // obj
        }, 0);
    
    
      },
      fn2: () => {
        setTimeout(() => {
          console.log(this); // window
        }, 0);
      },
      fn3: function() {
        setTimeout(function() {
          console.log(this); // window
        }, 0);
      }
    }
    

    MySwiper122.prototype.rClick = function() {

    // -------------------------------------------------------实际写法
    this.right.onclick = () => {
      // 原来this: DOM节点
      this.index++;
    
      if (this.index == 6) {
        this.index = 0;
      }
    
      // 设置切换
      this.ul.style.left = -this.index * this.w + "px";
    };
    

    };

箭头函数-形参默认值

ES6 之前函数不能设置参数的默认值

// ------------------------------------------------------------现在:
// 真的传入实参的值?不是调用!只是在设置默认值!
function fn(name = "ls", age = 10) {
    console.log(name, age);
}
fn(20, 30);


let aa = (name = "ls", age = 10) => {
    console.log(name, age);
}
aa("--------------");


-----------------------------------------------------------
    // ES5 中给参数设置默认值的变通做法
function fn(x, y) {
    y = y || 'world';
    console.log(x, y);
}
fn(1)
// ES6 中给函数设置默认值
function fn(x, y = 'world') {
    console.log(x, y);
}
fn(2)
fn(2,3)

箭头函数-rest参数

rest 参数:剩余参数,以 … 修饰最后一个参数,把多余的参数都放到一个数组中。可以替代 arguments 的使用

注意:rest 参数只能是最后一个参数

// 监听函数内部没有arguments 内部变量!arguments:解决的形参个数不确定的时候!
//       
// 【新知识:剩余参数,rest参数】
//  基本语法:(...自己设置的形参名字)
//  得到:形参个数的数组!

//  let fn = (...a) => {
//     console.log(a);【理解:...  看为  1,2,88,99,77】
//  }


// 其他使用理解:和数组解构很像!箭头函数同样适用!
function fn(a, b, ...c) {
    console.log(a, b, c);
}

fn(10, 50, 88, 99, 77, 55);

展开语法 注意有点像解构赋值但是不是

注意: 怎么区分 展开语法和解构赋值 看…后面的自定义名字有没有值, 有值就是展开语法,没值就是解构赋值

  • … 展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;

还可以在构造字面量对象时, 将对象表达式按key-value的方式展开

  // 展开语法:... 


  // ************************************场景1
  //  参数:逗号隔开,自己输入!
  //  曾经想法:数据逗号形式------->数组形式!  apply
  //   var arr = [1, 5, 8, 99, 56, 78];
  //   Math.max.apply(null, arr);

  //  现在:... 帮你把数组展开为 ------------>逗号分隔!
  //   var res = Math.max(...arr); // [1, 5, 8, 99, 56, 78]  ------------>1, 5, 8, 99, 56, 78
  //   console.log(res);


  // ************************************场景2
  //  
  //   let arr1 = [1, 2, 3];
  //   let arr2 = [4, 5, 6];
  // 拼接为一个新的数组
  //    曾经:let res = arr1.concat(arr2);

  //    现在:再新的数组展开
  //   let arr3 = [...arr1, ...arr2];


  // ************************************场景3:把对象属性展开到另外一个对象上
  // 对象   复制对象:潜拷贝

  let obj = {
    id: 1,
    info: "xxxxx"
  };

  let obj_1 = {
    ...obj,
    // name: "zs",
    // age: 18,
  }
  console.log(obj_1 == obj);

  //   --------------------对象解构
  // let obj = { name: 'zs', age: 20, gender: '男' };
  // // let {name,...a} = obj;
  // // console.log(a);
  // //       拷贝对象:
  // let {...newObj} = obj;

内置对象的扩展 【自学】

Array 的扩展

  • Array.from()
    • 把伪数组转换成数组

    • 伪数组必须有length属性,没有length将得到一个空数组

    • 转换后的数组长度,是根据伪数组的length决定的
      let fakeArr = {
      0: ‘a’,
      1: ‘b’,
      2: ‘c’,
      length: 3
      };

      let arr = Array.from(fakeArr);
      console.log(arr); // [‘a’, ‘b’, ‘c’]

      // 转数组的对象必须有length值,因为得到的数组的成员个数是length指定的个数
      // 上例中,如果length为2,则得到的数组为 [‘a’, ‘b’]

  • forEach遍历数组
    • 要为forEach传递一个函数进来

    • 为forEach传递的函数有三个形参,分别表示数组的值、下标、当前的数组
      // [xxx,xxx].forEach(function (value, index, arr) {
      // value 表示数组的值
      // index 表示数组的下标、索引
      // arr 表示当前的数组
      // });

      [3, 8, 4, 9].forEach(function (v, i, a) {
          console.log(v); // 表示数组的值 ,输出的结果是 3,8,4,9
          // console.log(i); // 表示数组的下标
          // console.log(a); // 表示数组
      });
      
      // 如果不需要下标和当前的数组,只使用value即可
      // 函数可以使用箭头函数
      [3, 8, 4, 9].forEach((item) => {
          console.log(item);
      });
      
      // 下面的意思是循环,在循环数组的时候,输出数组的每个值
      [3, 8, 4, 9].forEach(item => console.log(item));
      
  • 数组实例的 find() 和 findIndex()
    • find和findIndex方法,会遍历传递进来的数组
    • 回调函数有三个参数,分别表示数组的值、索引及整个数组
    • 回调函数中return的是一个条件,find和findIndex方法的返回值就是满足这个条件的第一个元素或索引
    • find 找到数组中第一个满足条件的成员并返回该成员,如果找不到返回undefined。
    • findIndex 找到数组中第一个满足条件的成员并返回该成员的索引,如果找不到返回 -1。
      // 语法结构
      let arr = [1, 2, 4, 0, -4, 3, -2, 9];
      arr.find(function (item, index, self) {
      console.log(item); // 数组中的每个值
      console.log(index); // 数组中的每个索引/下标
      console.log(self); // 当前的数组
      });
      // 用法:找数组中第一个小于0的数字
      let arr = [1, 2, 4, 0, -4, 3, -2, 9];
      let result = arr.find(function (item) {
      return item < 0; //遍历过程中,根据这个条件去查找
      });
      console.log(result); // -4
      findIndex 的使用和 find 类似,只不过它查找的不是值,而是下标
  • 语法类似的方法 : some/every/map/forEach/filter/reduce
  • 数组实例的 includes()
    • 判断数组是否包含某个值,返回 true / false
    • 参数1,必须,表示查找的内容
    • 参数2,可选,表示开始查找的位置,0表示开头的位置
      let arr = [1, 4, 3, 9];
      console.log(arr.includes(4)); // true
      console.log(arr.includes(4, 2)); // false, 从2的位置开始查,所以没有找到4
      console.log(arr.includes(5)); // false

String的扩展

  • includes(), startsWith(), endsWith()
    includes(str, [position]) 返回布尔值,表示是否找到了参数字符串

  • startsWidth(str, [position]) 返回布尔值,表示参数字符串是否在原字符串的头部或指定位置

  • endsWith(str, [length]) 返回布尔值,先截取length个长度的字符,然后判断结尾是什么。

    console.log(‘hello world’.includes(‘e’, 2)); // false 从位置2开始查找e,没有找到
    console.log(‘hello world’.includes(‘e’)); // true

    console.log(‘hello world’.startsWith(‘h’)); // 未指定位置,看开头是否是h,返回true
    console.log(‘hello world’.startsWith(‘l’, 2)); // 指定位置的字符是l,返回true

    console.log(‘hello world’.endsWith(‘d’)); // 未指定位置,结尾是d,返回true
    console.log(‘hello world’.endsWith(‘o’, 5)); // 先截取5个字符,即’hello’,判断hello的结尾是否为 ‘o’,返回true

  • repeat()
    repeat方法返回一个新字符串,表示将原字符串重复n次。
    let html = ‘

  • itheima
  • ’;
    html = html.repeat(10);

  • trim()trim() 方法可以去掉字符串两边的空白
    console.log(’ hello ‘.trim()); // hello
    console.log(’ hello '); // hello

Number的扩展

  • ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,功能完全保持不变。
    • Number.parseInt()
    • Number.parseFloat()
      console.log(parseInt(‘123abc’));
      // ES6中,将parseInt移植到了Number对象上
      console.log(Number.parseInt(‘123abc’));

Set 一般应用到去重

一般应用到去重

  • ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

  • Set本身是一个构造函数,用来生成 Set 数据结构。

    // 1. 基本使用
    let s = new Set();
    // 得到一个空的Set对象
    // 调用add方法,向s中添加几个值
    s.add(3);
    s.add(7);
    s.add(9);
    s.add(7); // Set对象中的成员都是唯一的,前面添加过7了,所以这里添加无效

    console.log(s.size);
    console.log(s); // {3, 7, 9}

  • Set 的API

    • size:属性,获取 set 中成员的个数,相当于数组中的 length

    • add(value):添加某个值,返回 Set 结构本身。

    • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

    • has(value):返回一个布尔值,表示该值是否为Set的成员。

    • clear():清除所有成员,没有返回值。

      // 将一些重复的值加入到Set对象中,看看效果
      const s = new Set();

      // 使用forEach遍历前面的数组,然后将数组中的每个值都通过Set对象的add方法添加到Set对象中
      [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
      // s = {2, 3, 5, 4}

  • 另外初始化Set的时候,也可以为其传入数组或字符串,得到的Set对象中的成员不会有重复。根据这个特点可以完成数组或字符串去重。

    // ---------------------------------------------------1.基本用法
    // let s = new Set();
    // // 方法:
    // s.add(3);
    // s.add(99);
    // s.add(88);
    // s.add(99);
    // s.add(3);

    // console.log(s.size); // s数据:包含不重复的数据
    // console.log(s);
    
    // -----------------------------------------------------2.应用
    // 1.用法;
    // let arr = [99, 99, 10, 20];
    // let s = new Set();
    // for (let i = 0; i < arr.length; i++) {
    //   s.add(arr[i])
    // }
    // arr = [...s];
    // console.log(arr);
    
    
    // 2.用法:
    let arr = [99, 99, 10, 20];
    let s = new Set(arr);
    arr = [...s];
    
    // 简化:
    arr = [...new Set(arr)];
    
    // ES5:
    var new_arr = [];
    for (let i = 0; i < arr.length; i++) {
      // 新数组里面没有 arr[i] 这个值,新的值;
      if (new_arr.indexOf(arr[i]) == -1) {
        new_arr.push(arr[i]);
      }
    }
    
  • for

    // 遍历Set对象,发现重复的值只有一份
    // for…in 循环中的 i 表示数组的下标,或对象的属性名
    // for…of 循环中的 i 表示数组的值,或对象的值
    for (let i of s) {
    console.log(i);
    }
    // 2 3 5 4

定义对象的简洁方式

let id = 1;
let name = 'zs';
let age = 20;

// 之前定义对象的方案
// let obj = {
//     // 属性: 值
//     id: id,
//     name: name,
//     age: age,
//     fn: function () {
//         console.log(this.age);
//     }
// };

// obj.fn();


// ES6的新方案
let obj = {
    id,  // 属性名id和前面的变量id名字相同,则可以省略 :id
    name,
    nianling: age,
    // 下面的函数是上面函数的简化写法,可以省略 :function  。但是注意这里仅仅是上面函数的简化,不是箭头函数
    fn () {
        console.log(name);
    }
};
obj.fn();

正则

介绍

  • 作用:正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式
  • 是什么:正则表达式也是对象。
  • 场景:正则表通常被用来检索、替换那些符合某个模式(规则)的文本,
    • 验证:例如表单,用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。
    • 过滤:正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
  • 要求
    • 灵活性、逻辑性和功能性非常的强。可以迅速地用极简单的方式达到字符串的复杂控制。
    • 对于刚接触的人来说,比较晦涩难懂。/^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/
    • 实际开发,一般都是直接复制写好的正则表达式. 但是要求会使用正则表达式并且根据实际情况修改正则表达式. 比如用户名: /1{3,16}$/

语法

  • 对象:{} [] 函数 DOM BOM 用户行为event 正则

  • 方式一:通过调用RegExp对象的构造函数创建

    var regexp = new RegExp(/123/);
    console.log(regexp);

  • 方式二:利用字面量创建 正则表达式; 正则对象和字母类字符串没有任何关系!

    var rg = /规则内容/;

test方法

  • test() 正则对象的方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符串。

    var rg = /abc/;
    console.log(rg.test(123));
    console.log(rg.test(‘abc’));

特殊字符

  • 一个正则表达式可以由简单的字符构成,比如 /abc/,也可以是简单和特殊字符的组合,比如 /ab*c/ 。其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如 ^ 、$ 、+ 等。
  • 参考:
    • 特殊字符非常多,可以参考: MDN
    • jQuery 手册:正则表达式部分 正则测试工具

边界符

  • 正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

    边界符 说明
    ^ 表示匹配行首的文本(以谁开始)
    $ 表示匹配行尾的文本(以谁结束)

  • 如果 ^和 $ 在一起,表示必须是精确匹配。

  • 注意:正则表达式里面不需要加引号 不管是数字型还是字符串型

    var rg = /abc/;
    // /abc/ 只要包含有abc这个字符串返回的都是true
    console.log(rg.test(‘abc’));
    console.log(rg.test(‘abcd’));
    console.log(rg.test(‘aabcd’));
    console.log(’---------------------------’);
    var reg = /^abc/;
    console.log(reg.test(‘abc’)); // true
    console.log(reg.test(‘abcd’)); // true
    console.log(reg.test(‘aabcd’)); // false
    console.log(’---------------------------’);
    var reg1 = /^abc$/; // 精确匹配 要求必须是 abc,而且只能是 abc 3个字符的 字符串才符合规范
    console.log(reg1.test(‘abc’)); // true
    console.log(reg1.test(‘abcd’)); // false
    console.log(reg1.test(‘aabcd’)); // false
    console.log(reg1.test(‘abcabc’)); // false

( | )

  • 从()内选出一组就可以

    var rg = /^(abc|bbb|ccc)$/;
    rg.test(“bbb”) // true;

[]

  • 表示有一系列字符可供选择,只要匹配其中一个就可以了

    var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
    console.log(rg.test(‘andy’));//true
    console.log(rg.test(‘baby’));//true
    console.log(rg.test(‘color’));//true
    console.log(rg.test(‘red’));//false
    var rg1 = /2$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
    console.log(rg1.test(‘aa’)); //false
    console.log(rg1.test(‘a’));//true
    console.log(rg1.test(‘b’));//true
    console.log(rg1.test(‘c’));//true
    console.log(rg1.test(‘abc’));//false

    var reg = /3$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
    console.log(reg.test(‘a’));//true
    console.log(reg.test(‘z’));//true
    console.log(reg.test(‘A’));//false

    //字符组合
    var reg1 = /4$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true

    //取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
    var reg2 = /[a-zA-Z0-9]$/;

    console.log(reg2.test(‘a’));//false
    console.log(reg2.test(‘B’));//false
    console.log(reg2.test(8));//false
    console.log(reg2.test(’!’));//true

量词符

  • 量词符用来设定某个模式出现的次数。

    量词 说明

    • 重复0次或更多次
      
    • 重复1次或更多次
      

    ? 重复0次或1次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次

  • 案例:用户名表单验证功能需求:

    • 如果用户名输入合法, 则后面提示信息为: 用户名合法,并且颜色为绿色
    • 如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为红色
  • 分析:

    • 用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为6~16位.
    • 首先准备好这种正则表达式模式 /5{6,16}$/
    • 当表单失去焦点就开始验证:
      • 如果符合正则规范, 则让后面的span标签添加 right类.
      • 如果不符合正则规范, 则让后面的span标签添加 wrong类.
  • 代码:

    请输入用户名

  • 括号总结

    • 大括号 {}量词符. 里面表示重复次数
    • 中括号 字符集合。匹配方括号中的任意字符.
    • 小括号 表示运算的优先级:JS
    • 正则表达式在线测试

预定义

  • 预定义类指的是某些常见模式的简写方式.

  • 案例:验证座机号码

    var reg = /^(\d{3}-\d{8}|\d{4}-\d{7})$/;

  • 案例:表单验证案例

    // 手机号验证:/^1[34578][0-9]{9}$/;
    //验证通过与不通过更换元素的类名与元素中的内容
    if (reg.test(this.value)) {
    // console.log(‘正确的’);
    this.nextElementSibling.className = ‘success’;
    this.nextElementSibling.innerHTML = ’ 恭喜您输入正确’;
    } else {
    // console.log(‘不正确’);
    this.nextElementSibling.className = ‘error’;
    this.nextElementSibling.innerHTML = '格式不正确,请从新输入 ';
    }

    //QQ号验证: /6\d{4,}KaTeX parse error: Can't use function '\u' in math mode at position 18: … //昵称验证: /^[\̲u̲4e00-\u9fa5]{2,…/
    // “\u4e00”和“\u9fa5”是unicode编码,并且正好是中文编码的开始和结束的两个值,
    / 所以这个正则表达式可以用来判断字符串中是否包含中文。

    //验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
    function regexp(ele, reg) {
    ele.onblur = function() {
    if (reg.test(this.value)) {
    // console.log(‘正确的’);
    this.nextElementSibling.className = ‘success’;
    this.nextElementSibling.innerHTML = ’ 恭喜您输入正确’;
    } else {
    // console.log(‘不正确’);
    this.nextElementSibling.className = ‘error’;
    this.nextElementSibling.innerHTML = ’ 格式不正确,请从新输入 ';
    }
    }
    };

    //密码验证:/7{6,16}$/
    //再次输入密码只需匹配与上次输入的密码值 是否一致

字符串.replace

  • 字符串的方法:replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。

    var str = ‘andy和red’;
    var newStr = str.replace(‘andy’, ‘baby’);
    console.log(newStr)//baby和red

    // 等同于 此处的andy可以写在正则表达式内
    var newStr2 = str.replace(/andy/, ‘baby’);
    console.log(newStr2)//baby和red

    // 替换一个
    var str = ‘abcabc’
    var nStr = str.replace(/a/,‘哈哈’)
    console.log(nStr) //哈哈bcabc

    // 全部替换 g
    var nStr = str.replace(/a/g,‘哈哈’)
    console.log(nStr) //哈哈bc哈哈bc

    // 忽略大小写i
    var str = ‘AAbcAba’;
    var newStr = str.replace(/a/i,‘哈哈’)//“哈哈AbcAba”

    // 忽略大小写i且 全部替换
    var str = ‘AAbcAba’;
    var newStr = str.replace(/a/ig,‘哈哈’)//“哈哈AbcAba”

  • 案例:过滤敏感词汇

    提交

老师笔记的正则代码

正则-介绍-使用

// 正则:是对象;

// 语法: /中间写规则/   遇到字母,不要加单双引号
// 对象:方法和属性集合体;
var reg = /123/; // 只要包含123就可以


// 方法:正则.test();
// 测试:参数数字和或者字符串,是否满足正则的要求;如果满足,方法返回true;
//      效果:获取用户输入的信息,是否满足正则!
var res = reg.test(112333);
console.log(res);

正则-边界符

// 字母:写abc不要写单双引号;
// ---------------------------------------- ^:必须以我们写的规则的文字开头:
//var rg = /^abc/;
// var res = rg.test("abcd");  true
//var res = rg.test("aabcd"); //false


// ----------------------------------------- $:必须以我们写的规则的文字结尾
var rg = /abc$/;
// console.log(rg.test("abcd")); //  false
// console.log(rg.test("ababc"));  // true


// ---------------------------------------  合起来用;必须以规则,必须以规则;只能是规则本身!
var rg = /^abc$/; // 必须以abc开头,以abc结尾;只能是abc这个三个字符;只能出现一次;
var res = rg.test("abcabc"); // false
console.log(res);

正则-小括号

// -----------------------------------------( | )  从()内选出一个组
// var rg = /^(abc|bbb|ccc)$/;
// console.log(rg.test("abc")); // true
// console.log(rg.test("abcbbbccc")); // false


var reg = /^(abc|aaa|bbb)(abc|aaa|bbb)$/;
console.log(reg.test("aaabbb")); // true
console.log(reg.test("aaa")); // false;

正则-中括号

  // []: 1.和前面数组没有关系  2.从[]选择出一个字符;3.可以多次使用
  // 范围:
  //       a-zA-Z0-9
  //       [^a-zA-Z0-9]  除去这个范围的取值;

// var reg = /^[abcde]$/;
// console.log(reg.test("a")); // true
// console.log(reg.test("aa")); // false


// var reg = /[abcde]/; // 不是严格要求,只要包含就OK
// console.log(reg.test("afff")); //  true



// 26个字母:小写
// var reg = /^[a-z]$/;
// console.log(reg.test("123456a"));

// 26个字母:大写
// var reg = /[A-Z]/;
// console.log(reg.test("abc")); //false

// 数字 0-9
// var reg = /^[0-9]$/;
// console.log(reg.test("123abc"));  //false


// 组合:
// var reg = /[a-zA-Z0-9]/;
// console.log(reg.test("中国"));  // false


// 在[^  ] 取对立面
var reg = /[^a-zA-Z0-9]/; //只要包含对立面就OK
console.log(reg.test("中国a")); // true;

var reg = /^[^a-zA-Z0-9]/;
console.log(reg.test("a中国")); // false;

var reg = /^[^a-zA-Z0-9]$/;
console.log(reg.test("-")); // true;

正则-量词符

  // *  :   出现的次数  >=0;
  // +  :   出现的次数  >=1;
  // ?  :   出现的次数  0 || 1; 
  // {n} :  必须出现的   n   次数;
  // {n,} :  必须出现的 >=n  次数;
  // {n,m} : 必须出现的 n~m  次数;

正则-预定义

  // 
  // \d   [0-9]
  // \w   字母数字_

  // 座机号:
  //    010-00001111;
  //    0352-0001111;
  // var reg = /^(\d{3}-\d{8}|\d{4}-\d{7})$/;
  //   \d{3}-\d{8}
  //   \d{4}-\d{7}

  // 手机号验证:/^1[34578][0-9]{9}$/;

  // QQ号验证: /^[1-9]\d{4,}$/;   
  // 昵称验证: /^[\u4e00-\u9fa5]{2,8}$/

  // 不需要:百度查;

正则-replace

  • trim():去除字符串两边的空格;

  • replace:经常用于和正则配合进行文本脱敏

    // --------------------------------------------------
    // 替换一次
    // var str = 'abcabc'
    // var nStr = str.replace(/a/, '哈哈')
    // console.log(nStr);
    
    
    // 全部:g   全球 global
    // var nStr = str.replace(/a/g, '哈哈');
    // console.log(nStr);
    
    
    // 忽略大小写  i  忽略 
    // var str = 'abcAbc'
    // var nStr = str.replace(/a/gi, '哈哈');
    // console.log(nStr);
    
  • 过滤敏感字:

    var btn = document.querySelector(“button”);
    var textarea = document.querySelector(“textarea”);
    var div = document.querySelector(“div”);
    btn.onclick = function() {
    var nStr = textarea.value.replace(/(激情|gay)/gi, “**”);
    div.innerText = nStr;
    };


  1. a-z0-9_- ↩︎

  2. abc ↩︎

  3. a-z ↩︎

  4. a-zA-Z0-9 ↩︎

  5. a-zA-Z0-9-_ ↩︎

  6. 1-9 ↩︎

  7. a-zA-Z0-9_- ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值