es6 class类和继承

class类

类 基类(BaseClass) 父类(子类的爸爸,爷爷,祖父等) 子类 超类(SuperClass 就是子类的爸爸)
子类继承父类的所有方法和属性

1、下面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法
   class Box{//类名首字母必须大写,驼峰式命名
   		a=1;//描述改对象的属性值,ES7支持,不需要let或者var
       constructor(a,b){// 构造函数
           console.log(a+b);//8
       }
       play(){
           console.log(this===b)//this 就是通过构造函数实例化对象b,谁调用该方法,this就是谁
       }
   }
   let b=new Box(5,3)  //实例化,当实例化时执行构造函数constructor
   b.play()
   console.log(b.constructor === Box)//true  
    //对象的构造函数就是当前的类名
    
   console.log(b.constructor === Box.prototype.constructor)//true  
   //b是Box类的实例,它的constructor方法就是Box类原型的constructor方法
  • 类名首字母必须大写,驼峰式命名
  • 如果不继承任何类别,意味着自动继承Object,Object就是js所有类别的基类
  • 对象的构造函数就是当前的类名 ,构造函数是通过该类创建对象的唯一入口函数
  • 如果不写constructor构造函数,类别会自动添加这个函数默认没有内容或者执行超类的构造函数
  • 在其他语言中类名和构造函数名称一样,因为这个类需要实例化对象 ,必须先执行构造函数,有些语言的构造函数可以有多个
  • 原生js构造函数只能有一个,并且所有类的构造函数写为construstor函数,这个构造函数实际就是当前的类名
2、因为js中构造函数就是类名,因此我们可以根据对象的构造函数是否是某个类名来判断它是否属于该类

//通过实例化创建的对象就是一个类,可以根据构造函数判断是否属于该类
	var arr=new Array(1,2,3);
	console.log(arr.constructor.name);//Array
	//单独打印constrctor是一个函数
	//构造函数有一个name属性就是这个类的类名
	console.log(arr.constructor===Array);//true
	
	var date=new Date();
	console.log(date.constructor===Date);//true
	
	var reg=/a/g;
	console.log(reg.constructor===RegExp);//true
	
	var div=document.createElement("div");
	console.log(div.constructor===HTMLDivElement);//true

3、类中除了函数中的局部变量就是类中的属性,类中的this就是实例化对象
//以下代码只为解释定义一个人类的类,并且去如何使用它,中文编程万万不可以
   class man{
       eyes=2;
       mouse=1;
       ear=2;
       hands=2;
       foots=2;
       name;//创建了一个man的类,有以上属性
       constructor(_name){
          this.name=_name;
       }
       walk(){//man的类有walk() run()  eat() fire()的方法
           console.log(this.name+"走")
       }
       run(){
           console.log(this.name+"跑")
       }
       eat(){
           console.log(this.name+"吃")
       }
       fire(){
           console.log(this.name+"生火")
       }
   }

  var xiaoming=new man("小明");
  //创建一个xioaming的实例化对象,具备这个man的类的所有方法和属性,可以直接使用
  xiaoming.eat();
  xiaoming.run();
  var xiaohua=new man("小花");
  //创建了一个xioahua的实例化对象
  xiaohua.run();
  xiaohua.fire();
  1. 通过构造函数实例化的对象,就是这个类的实例对象(比如上述代码xiaohua就是通过构造函数实例化的对象,它就是这个类的实例对象)
  2. 因此这个实例对象就具备了类所有属性和方法,比如上述代码xiaohua就具备man这个类的所有属性和方法
  3. 这个实例对象就可以调用他自身的方法和属性了
  4. 因为构造函数默认生成实例化对象,因此不能在构造函数中使用return 返回其他内容,构造函数不允许写return
  5. 谁调用方法,在类的函数中this就是那个实例对象

4、这里进行一个小练习,习惯一下面向对编程的思维,下面有生成10个随机小方块的两个不同的代码,看看有什么不同

第一种:

 function randomColor(){
         var col="#";
         for(var i=0;i<6;i++){
             col+=Math.floor(Math.random()*16).toString(16);//随机生成颜色
         }
         return col;
     }

  class Rect{//类名首字母大写,驼峰式命名
      elem;
      constructor(w,h,c){
          this.elem=this.createRect(w,h,c);//这里的this指该类
      }
      createRect(w,h,c){//创建div的方法
          let div=document.createElement("div");
          Object.assign(div.style,{
              width:w+"px",
              height:h+"px",
              backgroundColor:c,
              float:'left'
          });
          return div;
      }
      appendTo(parent){//把创建的div添加到父元素中
          parent.appendChild(this.elem);
      }
      play(){
          console.log("aaa");
      }
      run(){
          console.log("1");
      }
  }

  
  for(var i=0;i<10;i++){
      var w=Math.floor(Math.random()*50+50);
      let rect=new Rect(w,w,randomColor());//实例化10个对象,随机生成宽高和颜色
      rect.appendTo(document.body);//添加到body中
  }

第二种:

function randomColor(){
        var col="#";
        for(var i=0;i<6;i++){
            col+=Math.floor(Math.random()*16).toString(16);//随机生成颜色
        }
        return col;
    }
class Rect1{
    elem;
    w=50;
    h=50;
    c="red";
    constructor(){
        this.elem=this.createRect();
    }
    createRect(){
        let div=document.createElement("div");
        Object.assign(div.style,{
            width:this.w+"px",
            height:this.h+"px",
            backgroundColor:this.c
        });
        return div;
    }
    appendTo(parent){
        parent.appendChild(this.elem);
    }
    setWH(w,h){
        this.elem.style.width=w+"px";
        this.elem.style.height=h+"px";
    }
    setBg(color){
        this.elem.style.backgroundColor=color;
    }
    
}

for(var i=0;i<10;i++){
    var w=Math.floor(Math.random()*50+50);
    let rect=new Rect1();//实例化10个对象,随机生成宽高和颜色
    rect.setWH(w,w);
    rect.setBg(randomColor())
    rect.appendTo(document.body);//添加到body中
}

两种实现的效果都一样,第一种已经算是半个面向对象的编程方式了,第二种把每个变量当成属性放在类中,更能体现面向对象的编程思想
生成十个随机div

5、继承

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

比如,要继承Rect1类,只需要使用extends就可以继承过来Rect1的属性和方法了,继承父类后,必须在构造函数中使用super()调用超类的构造函数,超类的是什么,这个就执行的是什么

class Circle1 extends Rect1{
       constructor(r){
           // 继承父类后,必须在构造函数中调用超类的构造函数
           super();//超类的构造函数,超类是什么,这个就是什么
           //超类的构造函数如果有参数的,在这里子类中必须传入这个需要参数

       }
   }

比如,现在我要创建十个圆形,只需在上述创建的10的方块的代码中添加部分属性就可以做到,那就不用新写一个类了,可以在原有的类上继承它的属性,然后再添加新的属性就可以做到

上述代码第一种方法

//随机生成颜色函数
function randomColor(){
    var col="#";
    for(var i=0;i<6;i++){
        col+=Math.floor(Math.random()*16).toString(16);//随机生成颜色
    }
    return col;
}


//创建父类
class Rect{
	    elem;
	    constructor(w,h,c){
	        this.elem=this.createRect(w,h,c);//这里的this指该类
	    }
	    createRect(w,h,c){//创建div的方法
	        let div=document.createElement("div");
	        Object.assign(div.style,{
	            width:w+"px",
	            height:h+"px",
	            backgroundColor:c,
	            float:'left'
	        });
	        return div;
	    }
	    appendTo(parent){//把创建的div添加到父元素中
	        parent.appendChild(this.elem);
	    }
	    play(){
	        console.log("aaa");
	    }
	    run(){
	        console.log("1");
	    }
	}


//继承
class Circle extends Rect{
      constructor(w,h,c,r){
          super(w,h,c);//超类的构造函数是有参数的,因此在这里子类中必须传入这个需要参数
          this.elem.style.borderRadius=r+"%";
      }
      setBorder(w,c){
          this.elem.style.border=w+"px solid "+c;
      }
      // 因为子类的方法与父类的方法相同,因此会覆盖
      play(){
          console.log("bbb");
      }
      run(){
          super.run();//执行超类的run方法,在继续执行下面的内容
          console.log("2");
      }
  }

//实例化
for(var i=0;i<10;i++){
    var w=Math.floor(Math.random()*50+50);
     let c=new Circle(w,w,randomColor(),50);
     c.setBorder(2,"red")
     c.appendTo(document.body);
     c.play();
     c.run();
 }

上述代码第二种方法

//随机生成颜色函数
function randomColor(){
    var col="#";
    for(var i=0;i<6;i++){
        col+=Math.floor(Math.random()*16).toString(16);//随机生成颜色
    }
    return col;
}

//创建父类
class Rect1{
      elem;
      w=50;
      h=50;
      c="red";
      constructor(){
          this.elem=this.createRect();
      }
      createRect(){
          let div=document.createElement("div");
          Object.assign(div.style,{
              width:this.w+"px",
              height:this.h+"px",
              backgroundColor:this.c
          });
          return div;
      }
      appendTo(parent){
          parent.appendChild(this.elem);
      }
      setWH(w,h){
          this.elem.style.width=w+"px";
          this.elem.style.height=h+"px";
      }
      setBg(color){
          this.elem.style.backgroundColor=color;
      }
      play(){
          console.log("aaa");
      }
      run(){
      console.log('1');
      }
      
  }

//继承
 class Circle extends Rect1{
      constructor(){
          super();//使用super()调用超类的构造函数
      }
      borderR(r){
          this.elem.style.borderRadius=r+"%";
      }
      setBorder(w,c){
          this.elem.style.border=w+"px solid "+c;
      }
      // 因为子类的方法与父类的方法相同,因此会覆盖
      play(){
          console.log("bbb");
      }
      run(){
	       super.run();//执行超类的run方法,在继续执行下面的内容
	       console.log("2");
   	  }
  }

  //实例化
 for(var i=0;i<10;i++){
	    let cir=new Circle();//创建对象实例
	    cir.borderR(50);//子类中的方法设置border-radious
	    var w=Math.floor(Math.random()*5+1);
	    cir.setBorder(w,randomColor());//子类中的方法设置border
	    cir.setBg(randomColor());//父类中的方法随机生成颜色
	    cir.appendTo(document.body)//父类中的方法添加元素到页面上
 }

实现效果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡萝卜大王驾到通通闪开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值