js高级 面向对象 学习笔记

系列文章目录


对象Object

对象 是一组无序相关属性和方法的集合
变量 属性 区别
共同点:都是用来储存数据
变量:单独声明赋值 单独存在
属性 :对象里的变量称为属性 ,不需要声明,用描述对象的特征 对象名.属性名来调用

函数 方法 区别
共同点:都是用来实现某种功能
函数:单独存在 函数名()可直接调用
方法:对象里的函数称为方法,方法不需要声明。对象.方法名()调用。用来描述对象的行为和功能

创建对象的三种方式

  1. 字面量 { }
 //字面量
  var obj = {} //空对象
  var obj1 = {
    name: "ss",
    age: 18,
    sayHi: function () {
      console.log('hello');
    }
  }
  //使用对象  调用属性 对象名.属性名
  console.log(obj1.age);
  //使用对象  调用属性 对象名['属性名']
  console.log(obj1['name']);
  //调用方法  对象名.  方法名  记得小括号
  obj1.sayHi()
  1. new object
//new Object 创建对象
//等号赋值添加属性和方法
var obj2 = new Object();//创建对象
obj2.name='w';
obj2.age='18';
obj2.sex='男';
obj2.sayHey=function(){
   console.log('hey');
 }
 console.log(obj2.name);
 obj2.sayHey()
  1. 构造函数创建
    前两种的构造函数一次只能创建一个对象,构造函数可以提高代码复用性
//构造函数  对象的公共的属性和方法抽取出来 封装到函数里
 //语法格式  构造函数名首字母大写 ,不需要return 调用必须要用new 属性方法必须加this
//  function 构造函数名(){
//   this.属性=值
//   this.方法=function()
// }
function Star(age,name,sex){
  this.age=age
  this.name=name
  this.sex=sex
  this.sing =function(singName){
    console.log(name+'唱'+singName);
  }
}
var ldh = new Star(55,'刘德华','男')//返回对象
var zxy = new Star(55,'张学友','男')//返回对象
var gfc = new Star(55,'郭富城','男')//返回对象
console.log(ldh);
console.log(ldh.name);
ldh.sing('冰雨')
console.log(zxy.name);
zxy.sing('吻别')
console.log(gfc.name);
gfc.sing('对你爱不完')

构造函数:泛指某一大类(class) 抽取了对象的公共部分,封装到函数
对象:特指某一个具体事务
利用构造函数来创建对象的过程 称为对象的实例化

new关键字执行过程

  1. 在内存中创建一个新的空对象
  2. this指向这个空对象
  3. 执行构造函数里的代码,给这个新对象添加属性和方法
  4. 返回这个新对象

遍历对象

for in 循环用于数组或对象属性循环遍历

// 遍历对象
var  ooo={
  name:'o',
  age:88,
  sex:'男',
  fn:function(){
    console.log('函数');
  }
}
//for in 
for (const key in ooo) {
  console.log(key);//输出属性名
  console.log(ooo[key]);//输出 值
}

一、面向对象开发

面向过程 POP(Process-oriented programming)
:分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一 个的依
次调用就可以了。

面向对象 OOP (Object Oriented Programming)
:把事务分解成为一个个对象,然后由对象之间分工与合作。
优点 :灵活性 代码复用 容易维护和开发,适合多人开的大型项目
特性:
封装性
继承性
多态性

区别

二、es6中类与对象

1.类 Class

抽取了对象的公共部分 ,泛指某一大类。通过类实例化一个对象

创建类

constructor 函数:
接受传递参数,返回实例对象,new生成实例时自动调用,不写 也会自动生成constructor 函数

注意语法规范,创建类类名后面不要加小括号,生成实例类名后面加小括号,构造函数不需

//创建类
  class Star{
    //构造函数
    constructor(name,age){
      this.name=name
      this.age=age
    }
    //类中添加方法  不需要写function 函数方法之间不需要逗号
    sing(singsName){
      console.log(this.name+'唱'+singsName);
    }
  }
  //类创建对象
 var ldh= new Star('刘德华',18)
 console.log(ldh.name);
 console.log(ldh.age);
 var zxy= new Star('张学友',27)
 console.log(zxy.name);
 console.log(zxy.age);
 ldh.sing('忘情水')
 zxy.sing('烦恼歌')

类的继承

extends 子类继承父类的属性和方法
super 访问和调用父类的构造函数和普通函数
继承中属性或方法查找原则:就近原则先找子类再找父类
super() super.name()
子类可继承父类方法 也可扩展自己方法
super 必须在子类this前调用

  //类的继承
    class Dad{
      constructor(x,y){
      this.x=x;
      this.y=y
      }
      money(){
        console.log(1000);
      }
      sum(){
        console.log(this.x+this.y);
      }
      say(){
        console.log('我是爸爸');
        return "dddd"
      }
    }
    //继承
    class Son extends  Dad{
      constructor(x,y){
        //子类调用父类的构造方法
        //super 必须在子类this前调用
        super(x,y)

        this.x=x
        this.y=y
      }
      say1(){
        // console.log('我是儿子');
       console.log( this.say() +'sss');

      }
      sub(){
        console.log(this.x-this.y);
      }
    }
    var  son = new Son(1,2)
    var son1 =new Son(15,28)
    son.money()
    son.sum()
    son1.sum()
    son.say1()
    son.sub()

注意 ★

  1. es6中类没有变量提升,必须先定义类在实例化对象 否则会报错(ReferenceError)
  2. 类里共有的属性和方法要加this使用
  3. 类中this的指向问题 ★★
    constructor中this指向的创建的对象实例
    方法中 this指向调用该函数的对象

2.对象 Object

是一组无序相关属性和方法的集合
由属性和方法组成。
代码如下(示例):

三、构造函数与原型

一般情况 公共属性定义到构造函数中
公共方法定义到原型对象上

构造函数

成员:构造函数中属性和方法,成员可以添加
实例成员:构造函数内部通过this添加的成员,
实例成员只能通过实例化的对象来访问
静态成员:在构造函数本身上添加的成员,
静态成员只能通过构造函数来访问

存在问题
1 浪费内存

原型

构造函数原型对象 prototype

prototype是一个对象。
作用:共享方法
每个构造函数都有一个原型对象prototype,指向另一个对象
构造函数通过原型分配的函数是所有对象所共享的

对象原型__proto__

非标准属性,实际开发在不能使用
对象有一个属性__proto__指向构造函数的prototype 原型对象

对象.proto ===原型.prototype 等价的

方法查找规则:
1先看对象是否存在该方法,如果有执行对象上的该方法
2 没有,就通过__proto__去构造函数原型对象prototype查找

对象为什么可以使用原型对象中的方法

constructor 构造函数

指回构造函数本身
作用:记录该对象引用于哪个构造函数

如果我手动的修改了原来的原型对象,给原型对象赋值为一个对象,则必须要手动使用constructor 指回原来的构造函数

<script>
    //构造函数
    function Star(name ,age) {
      this.name=name
      this.age=age
      
    }
    //手动利用constructor属性指回原来构造函数
    // Star.prototype.sing=function(name){
    //   console.log(name+'sing');
    // }
    // Star.prototype.movie=function(){
    //   console.log('电影');
    // }
    Star.prototype={
      constructor:Star,
      sing:function(){
        console.log('唱歌');
      },
      movie:function(){
        console.log('电影');
      },
      dance:function(){
        console.log('跳舞');
      },
    }
    let wf =new Star('王菲','暧昧')
    let ny =new Star('那英','征服')
    console.log(wf);
    console.log(ny);
    wf.sing('红豆')
    ny.sing('默')
    //静态成员 只能通过构造函数来访问
    Star.sex='女'
    console.log(Star.sex);
    console.log(wf.sex);
    console.dir(Star)
    console.dir(wf)
    console.log(wf.sing=== ny.sing);
    console.log(wf.__proto__ ===Star.prototype);
    console.log(wf.__proto__);
    console.log(Star.prototype);
    console.log(Star.prototype.constructor);
    console.log(wf.__proto__.constructor);
  </script>

构造函数,实例,原型对象三者关系

在这里插入图片描述

四、原型链

每个对象都有一个原型对象
原型对象的原型对象是Object
Object的原型对象是null
原型链

js成员查找机制

按照原型链查找,返回结果遵循就近原则

  1. 当访问一个对象的属性或方法时,首先查找对象本身有没有该属性
  2. 如果没有就查它的原型(__proto__指向的prototype原型对象)
  3. 无则查找原型对象的原型(Object原型对象)
  4. 一直找到Object的原型(null)

原型对象中this指向问题

构造函数中this 指向实例对象
原型对象里的函数 this 指向实例对象

原型对象的应用

扩展内置对象

通过原型对象,对内置对象进行自定义的方法
数组或字符串等内置对象中不能给原型对进行覆盖操作 Array.prototype={}
只能是添加操作 Array.prototype.sum=function(){}
例:给数组添加求和方法

  <script>
console.log(Array.prototype);
 Array.prototype.sum=function(){
   let sum=0
   for (let i = 0; i < this.length; i++) {
    sum +=this[i]
   }
   return sum
 }
  let arr=[1,58,97,67,35,84,66,74]
  console.log(arr.sum());
  </script>

五、继承

call()

修改函数运行时的this指向
thisArg :当前调用函数this指向的对象
,arg1,arg2:传递的其他参数

fun.call(thisArg,arg1,arg2)

 //call方法
    function fn(x,y){
     console.log('牛奶咖啡');
     console.log(this);
     console.log(x+y);
    }
    let  o ={
      name:'sdq'
    }
    //1调用函数
    // fn.call()
    //2 改变this指向
    fn.call(o,1,5)

组合继承

构造函数+原型对象模拟实现继承

借助构造函数继承父类型属性

核心原理:通过call() 把父类型的this指向子类型的this

  //借助构造函数继承父类型属性
    //1 父构造函数
    function Father(name,age){
      //this指向父构造函数的实例
     this.name=name
     this.age=age
    }
    //2 子构造函数
    function Son(name ,age,sex){
      //this指向字构造函数的对象实例 
      Father.call(this,name,age)
      this.sex=sex
    }
    let s= new Son('aaa',18,'女')
    console.log(s);

借用原型对象继承父类方法

//借助构造函数继承父类型属性
    //1 父构造函数
    function Father(name,age){
      //this指向父构造函数的实例
     this.name=name
     this.age=age
    }
    //方法
    Father.prototype.money=function(){
      console.log(10000);
    }
    //2 子构造函数
    function Son(name ,age,sex){
      //this指向字构造函数的对象实例 
      Father.call(this,name,age)
      this.sex=sex
    }
    //直接赋值错误,修改子元素的原型对象 父原型会一起修改
    //Son.prototype=Father.prototype
    //如果利用对象的形式修改了原型对象,利用constructor 指回原来的原型对象
    Son.prototype=new Father()
    Son.prototype.constructor=Son
    //子原型对象的方法
    Son.prototype.test=function(){
      console.log('测试'); 
    }
    console.log(Father.prototype);
    console.log(Son.prototype.constructor);
    let s= new Son('aaa',18,'女')
    console.log(s);

原型对象继承方法

六、es5新增方法

数组方法

迭代(遍历)方法:forEach(),map(),some(),every()
forEach 遍历数组 return true 不会终止迭代

//forEach 遍历数组
    let arr = [1, 2, 3]
    let sum = 0
    arr.forEach(function (value, index, array) {
      console.log('数组元素' + value);
      console.log('数组下标' + index);
      console.log('数组本身' + array);
      sum += value
    })
    console.log(sum);

filter() 创建一个新数组,新数组的元素通过指定数组中符合条件元素 用于筛选数组
查询多个元素适用 return true 不会终止迭代

  let arr1 = [88, 66, 84, 97, 15, 34, 62, 12]
    let arr2 = arr1.filter(function (value, index, array) {
      return value  % 2===0
      // return value > 50
    })
    console.log(arr1);
    console.log(arr2);

some 方法 检测数组中条件是否有满足条件的元素 返回值布尔值 找到第一个元素就终止循环
查询唯一元素适用
遇到 return true 就终止迭代,查询效率更高

let arr3=[10,20,60,80,55,33]
    let flag=arr3.some(function(value){
      // return value=20
      return value<10
    })
  console.log(flag);

字符串方法

trim ()去除字符串两侧空格

 let str ='   255dd   '
    console.log(str);
    console.log(str.trim());

对象方法

Object.keys(obj)
:用于获取对象自身属性 类似于for …in
返回由属性名组成的数组

//用于获取对象自身属性 object.key()
    var obj={
      id:1,
      name:'小米',
      price:'4777',
      num:'56'
    }
    let arr=Object.keys(obj)
    console.log(arr);
    arr.forEach(function(value){
      console.log(value);
    })

Object.defineProperty()定义对象中新属性 或修改原有属性
Object.defineProperty(obj,prop,descriptor)
descriptor {}
value 设置属性值 默认undifined
writable 是否可以重新写 默认false
enmerable 属性是否可以被枚举 (能不能遍历出来) 默认false
configurable 属性是否可以删除或再次修改第三个属性中的特性 默认false

obj.boos='雷军'
    obj.price='1987'
   
    Object.defineProperty(obj,'logo',{value:'MI'})
    Object.defineProperty(obj,'num',{value:99})
    //id不允许重写
    Object.defineProperty(obj,'id',{
      writable:false
    })
    obj.id=2
    console.log(obj);
    //密码不可枚举 遍历不出来
  Object.defineProperty(obj,'password',{
    enumerable:false,
    value:'10jqkA'
  })
  console.log(obj);
 console.log(Object.keys(obj)); 
 //价格不允许删除
 Object.defineProperty(obj,'price',{
   configurable:false
 })
 delete obj.price;
 console.log(obj);

七 函数

函数定义方式

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

function fn(){}

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

var fun =function(){]

3 利用new Function(‘agr1’,‘agr1’,‘函数体’)
执行效率较低 使用较少
Function内参数都必须是字符串格式
所有函数都是Function的实例(对象)
函数也属于对象

console.dir(foo)
console.log(foo instanceof Object);//true
//new function 构造函数
    let foo= new Function('console.log(123)')
    foo()

函数原型关系

函数调用方式

  1. 普通函数
  // 1. 普通函数
    function fn(){
      console.log('offer offer');
    }
    fn()
    fn.call()
  1. 对象的方法
var o={
    say:function() {
      console.log('ei');
    }
  }
  o.say()
  1. 构造函数
 function Star(){}
 new Star()
  1. 绑定事件函数
  <button class="btn">点击</button>

let btn =document.querySelector('.btn')
  btn.onclick=function(){
    console.log('我被点了');
  }//触发事件调用
  1. 定时器函数
 // 5. 定时器函数
  setTimeout(() => {
    console.log('dsq');
  }, 1000);
  //根据定时器间隔时间自行调用
 
  1. 立即执行函数
(function(){
    console.log('立即执行');
  })()
  //自动调用

八 this

函数内this指向

调用方式this指向
普通函数window
构造函数实例对象,原型对象里的方法指向实例对象
对象方法方法所属对象
事件绑定函数绑定事件对象
定时器函数window
立即执行函数window

改变函数内部this指向

  • call方法
    调用函数
    改变函数this指向
    实现继承
function Father(name,age,sex){
      this.name=name
      this.age=age
      this.sex=sex
    }
    Father.prototype.money=function(){
      console.log('我没钱');
    }
    function Son(name,age,sex){
      Father.call(this,name,age,sex)
    }
    Son.prototype=new Father()
    Son.prototype.test=function(){
    console.log('我要考试');
    }
    let  kk =new Son('KK',18,'女')
    kk.money()
    kk.test()
    console.log(Father.prototype);
    console.log(Son.prototype);
  • bind方法
    不调用函数,但能改变函数内部指向
    返回值由指定this值和初始化参数改造的原函数拷贝
    应用场景:有的函数不需要立即调用,但又想改变函数内部的this指向,就使用bind
    按钮,点击之后就禁用该按钮,3秒钟后开启
  var o= {
      name:"ss",
      age:18
    }
     //bind方法 (捆绑的意思)不调用函数 改变函数内部this指向
     function fn(a,b){
       console.log(this);
       console.log(a+b);
     }
    let f= fn.bind(o,1,2)
     f()  
    // 应用场景:有的函数不需要立即调用,但又想改变函数内部的this指向,就使用bind
    //按钮,点击之后就禁用该按钮,3秒钟后开启
    let btn =document.querySelector('button')
     btn.onclick=function(){
       this.disabled=true//this 指向当前按钮
      //2 let that=this
       setTimeout(function() {
      //1  this.disabled=false//当前this指向window
       //2  that.disabled=false//当前that 指向按钮
       this.disabled=false//3 bind 改变this后 指向btn
       }.bind(this), 3000);//this指向btn对象
     }
  • apply方法
    apply 方法 参数是数组形式
    apply 的主要应用:例如利用apply 借助于数学对象求最值
 var o= {
      name:"ss",
      age:18
    }
    function fn(arr){
      console.log(this);
      console.log(arr);//'pink'
    }
    //apply 方法  参数是数组形式
     fn.apply(o,['pink'])
    //apply 的主要应用:例如利用apply 借助于数学对象求最值
    //Math.max()
    let arr =[12,57,68,88,24]
    // let max=Math.max.apply(null,arr)
    let max=Math.max.apply(Math,arr)
    let min=Math.min.apply(Math,arr)
    console.log(max,min);

call apply bind 区别总结

相同点:
都可以改变函数内部this指向
区别:

  • call和apply会调用函数,并改变函数内部this指向
  • call和apply 传递参数不一样,call传递arg1,arg2。apply必须是数组形式[arg]
  • bind 不会调用函数,可以改变函数内部this指向
    主要应用场景:
    call常用于继承
    apply 常用于数组
    bind 不调用函数,可改变定时器内部this指向

九 严格模式 strict mode

严格模式

开启严格模式

严格模式到整个应用到整个脚本或个别函数。
为脚本开启严格模式
所有语句前放置一句

<script>
    'use strict'
    //下面的就是代码会按照严格模式执行代码
  </script>
  <script>
    (function(){
      'use strict'
    })
  </script>

为函数开启严格模式

 <script>
    //为当前函数开启严格模式
    function fn(){
      'use strict'
    }
  </script>

严格模式的变化

1 变量名必须先声明再使用

  num =10
   console.log(num); // 

2严禁删除已经声明的变量

    let num =10 
     console.log(num);
    delete num// 报错

3 严格模式下this指向问题
全局作用域中 函数中的this是undefined

  //全局作用域中 函数中的this是undefined
      function fn(){
       console.log(this);//undefined
      }
      fn()

4构造函数不加new调用,this指向undefined,如果赋值会报错

 function Star(){
       this.name='代号'
    }
  Star()//报错 this为undefined 无法添加属性name
  var dc = new Star()
  console.log(dc.name);

5 定时器 this还是指向 window

 setTimeout(function() {
    console.log(this);//window
  }, 1000);

6 函数变化 函数参数不允许重名

 function dd(a,a){
  // 'use strict'
   console.log(a+a);
 }
  dd(1,3)//6 后面的值会覆盖前面的值 非严格 ,严格模式会报错

十 高阶函数

:对其他函数进行操作的函数,
接收函数作为参数或者 将函数作为返回值输出
最典型是作为回调函数

 //高阶函数 -函数可以作为参数传递
    function  fn(a,b,callback){
      console.log(a+b);
      callback&& callback();
    }
    fn(4,6,function(){
      console.log('我是最后调用的');
    })

十一 闭包

变量作用域

变量根据作用域分为:全局变量和局部变量

  1. 函数内部可以使用去全局变量
  2. 函数外部不可能使用局部变量
  3. 函数执行完毕,函数作用域内的局部变量会销毁

闭包

:有权访问另一个函数作用域中变量的函数(一个作用域可以访问另一个函数内部的局部变量)
被访问的变量所在的函数称为闭包函数

闭包的作用:延伸了变量的作用范围

 //闭包 fu函数作用域访问另一个函数f中的变量 num
     //f 作用域外访问 f内部的局部变量
    function f(){//闭包函数
      let num =10
     // function fu(){
    //    console.log(num);
     // }
      // fu()  //1
      //return fu //2
       return function(){
        console.log(num);
      }//3
    }
  let fun   =   f()
  fun()

在这里插入图片描述

十二 递归

:一个函数在内部调用其本身,那么这个函数就是递归函数

递归很容易发生‘栈溢出’ (stack overflow)
必须要加退出条件 return

递归求解数学题

求 n的阶乘

    //1-n的阶乘
    function fn(n){
      if (n == 1) {
        return 1
      }
      return n * fn(n-1);
    }
    console.log( fn(6));

求斐波那契数列 (兔子序列 )1 1 2 3 5 8 13 21…
在这里插入代码片规律:前两项(n-1,n-2)是第三项n的和

  function fb(n){
      if(n === 1 || n === 2){
        return 1
      }
      return fb(n - 1) + fb(n - 2)
    }
    console.log(fb(14));//377

深拷贝和浅拷贝

浅拷贝:只拷贝一层,更深层次级别(对象或者数组)的只拷贝引用 (传址)
es6新增方法可以浅拷贝
Object.assign(target,…sources)
(修改o.msg.age了,obj.msg.age会一起改变)

 let obj ={
      id:1,
      name:'we',
      msg:{
        age:18
      }
    }
    let o={}
    //for循环浅拷贝
    // for (const k in obj) {
    //   //K 是属性名   obj[k]是属性值
    //   o[k]=obj[k]
    // }
  //es6的浅拷贝语法糖
    Object.assign(o,obj)
    console.log(o);
    o.msg.age=20
    console.log(obj);

深拷贝:拷贝多层,每一层数据都会拷贝
利用函数递归完成深拷贝
判断属性值属于哪种数据类型 把值给属性 数组也属于object 先判断数组再判断对象最后是普通类型

 let obj ={
      id:1,
      name:'we',
      msg:{
        age:18
      },
      color:['pink','red','blue']
    }
    let ob={}
    //利用函数递归完成深拷贝
    function deepCopy(newobj,oldobj){
     for (const k in oldobj) {
        //判断属性值属于哪种数据类型 把值给属性 数组也属于object
        //1 获取属性值 oldobj[k]
        var item =oldobj[k]
        //2 判断该值是否为数组
        if(item instanceof Array){
          newobj[k]=[];
          deepCopy(newobj[k],item)

        }else if( item instanceof Object){
            //3 判断该值是否为对象
          newobj[k]={}
          deepCopy(newobj[k],item)
        }else{
           //4 判断该值是否为简单数据类型
          newobj[k]=item
        }
     }
    }
    deepCopy(ob,obj)
    ob.msg.age=20;
    ob.color[1]='green';
    console.log(ob);
    console.log(obj);
  

十三 正则表达式

什么是正则表达式?

正则表达式( Regular Expression ) 是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象
作用:匹配,替换,提取 。表单验证

特点

正则特点

创建正则表达式

1 通过调用RegExp对象的构造函数创建

   let regxp=new RegExp(/123/);

2 利用字面量创建 正则表达式

let rg=/123/

测试正则表达式 test

test() :用于检测字符串是否符合该规则,返回布尔值

let rg=/123/
rg.test(123)//ture

正则表达式的组成

1 边界符
^ :以什么开头
$:以什么结尾
^ $在一起就是精确匹配

//
     //正则表达式不需要加引号的 不管是数字型还是字符串型
     let reg=/abc/ //包含abc字符
     console.log(reg.test('abc'));//true
     console.log(reg.test('aaabc'));//true
     console.log(reg.test('abcdd'));//true
     console.log("——————————————————————————————————————————————");
     let r1=/^abc/ //abc开头
     console.log(r1.test('abc'));//true
     console.log(r1.test('aaabc'));//false
     console.log(r1.test('abcdd'));//true
     console.log("——————————————————————————————————————————————");
     let r2=/^abc$/ //abc开头,abc结尾 只能是abc三个字符
     console.log(r2.test('abc'));//true
     console.log(r2.test('aaabc'));//false
     console.log(r2.test('abcdd'));//false

2 字符类
[] : 一系列字符供选择,只需要匹配其中一个

  let r1=/[abc]/
   console.log(r1.test('sss'));//false
   console.log(r1.test('baby'));//true
   console.log(r1.test('okla'));//true

[-] :方括号内范围符

   //
   let r3 =/^[a-z]$/ //26个英文字母 任意一个返回ture
   console.log(r3.test('sb'));//false
   console.log(r3.test('x'));//true
   console.log(r3.test('y'));//true

[^ ] 中括号里有^ 表示取反

 //字符组合
   let r4 =/^[a-zA-Z0-9-_]$/ //26个英文字母大小写和数字 任意一个返回ture
   console.log(r4.test('Z'));//true
   console.log(r4.test('x'));//true
   console.log(r4.test('Sy'));// false
   console.log(r4.test(5));// true
   console.log(r4.test('-'));// true
   console.log(r4.test('_'));// true
   console.log(r4.test('!'));// false

   //[^] 中括号有^ 表示取反
   let r5 =/^[^a-zA-Z0-9-_]$/ //取反 不能包含26个英文字母大小写和数字 返回ture
   console.log(r5.test('_'));//  false
   console.log(r5.test('!'));// true
   console.log(r5.test('!Sy!'));// false

3 量词符
:用于设定某个模式出现的次数

// * 相当于出现次数>=0
   let r6 =/^a*$/
   console.log(r6.test('asb'));//false
   console.log(r6.test('a'));//true
   console.log(r6.test('aaaa'));//true

     // +  相当于出现次数>=1
     let r7 =/^a+$/
   console.log(r7.test(''));//false
   console.log(r7.test('a'));//true
   console.log(r7.test('aaaa'));//true

   
     // ? 相当于出现次数 1||0
     let r8 =/^a?$/
   console.log(r8.test(''));// true
   console.log(r8.test('a'));//true
   console.log(r8.test('aaaa'));//false


     // {3} 相当于出现次数 3次
     let r9 =/^a{3}$/
   console.log(r9.test('aaass'));// false
   console.log(r9.test('a'));//false
   console.log(r9.test('aaa'));// true
    // {3,} 相当于出现次数 >=3次
    let r10 =/^a{3,}$/
   console.log(r10.test('aaaaaa'));// ture
   console.log(r10.test('a'));//false
   console.log(r10.test('aaa'));// true

   // {3,5} 相当于出现次数 >=3次 <=5次
   let r11 =/^a{3,5}$/ 
   console.log(r11.test('aaaaaa'));//  false
   console.log(r11.test('aaaa'));//ture
   console.log(r11.test('aaa'));// true

用户名表单验证的表达式

   //用户名表单验证的表达式 {6,16}大括号内不能有空格
 <style>
    .right{
      color: green;
    }
    .wrong{
      color: red;
    }
  </style>
</head>
 用户名:<input type="text" class="uname" placeholder="请输入用户名"><span></span>
<body>
  <script>
    let reg =/^[a-zA-Z0-9_-]{6,16}$/
    let uname =document.querySelector('.uname')
    let span=document.querySelector('span')
    uname.onblur=function(){
      if(reg.test(this.value)){
       span.className='right'
       span.innerHTML='用户名输入正确'
      }else{
        span.className='wrong'
       span.innerHTML='用户名格式错误'
      }
    }
 
  </script>
</body>

括号总结
中括号 字符集合 匹配方括号中任意字符
大括号 量词符 表示重复次数
小括号表示优先级

// 中括号
    let  r1 =/^[0-9]$/
    console.log(r1.test('8'));
   // 大括号
   let  r2 =/^abc{3}$/ //ab 让c 重复三次
    console.log(r2.test('ccc'));//false
    console.log(r2.test('accc'));//false
    console.log(r2.test('abccc'));//true
   // 小括号 优先级
   let  r3 =/^(abc){3}$/ //让abc 重复三次
   console.log(r3.test('ccc'));//false
    console.log(r3.test('accc'));//false
    console.log(r3.test('abcabcabc'));//true

预定义类:常见模式的简写方式
在这里插入图片描述
正则表达式的替换 replace
/g:全局匹配
/i: 忽略大小写
/gi:全局匹配+忽略大小写

<textarea name="" id="msg" cols="30" rows="10"></textarea>
  <button>提交</button>
  <div></div>
  <script>
    let  text = document.querySelector('textarea')
    let  btn = document.querySelector('button')
    let  div = document.querySelector('div')
    btn.onclick=function(){
      div.innerHTML= text.value.replace(/激情|gay/g,'**')
    }
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页