ES6中class的基本使用和继承

1.ES6中类

类是由ES6中新引入的的一个新概念,可以用class关键字声明一个类,类的首字母大写
基本用法

class Test{}

用new关键字来实例化一个类,获取一个对象。

//创建类
class Test {
	constructor(num1, num2) {
	     this.num1 = num1
	     this.num2 = num2
	 }
	 sum() {
	     console.log(this.num1 + this.num2)
	 }
}
//通过new实例化类,获取一个对象
let test = new Test(1, 2)
//调用类里面的方法
test.sum()
  1. constructor函数是一个类的默认函数,通过new命令生成对象实例,自动调用constructor函数。一个类里面必须要有constructor函数,如果没有定义,一个空的constructor函数会默认添加;
  2. constructor函数默认返回实例对象(即this),也可以指定返回另一个对象;
  3. 类的数据类型就是函数,类本身就指向构造函数;
  4. 类的所有的构造方法都是定义在类的prototype属性上的。
 class Test {
//构造函数,默认必须存在,可以不定义
    constructor() {

    }
    test1() {
        //...
    }
    test2() {
        //...
    }
}
// 上面的写法和下面的是一样的
Test.prototype = {
    constructor() { },
    test1() { },
    test2() { },
};

在类的实例上调用方法,其实就是调用原型上的方法。

注意点
  1. 类不存在变量提升
new Test()
class Test{
     
 }
 //Uncaught ReferenceError: Cannot access 'Test' before initialization

上面代码中,Test类是使用在前,定义在后,这样就报错,因为 ES6 不会把类的声明提升到代码头部。这个跟后面的继承有关系,必须保证子类在父类之后定义。
2. 类的name属性

class Test{}
Test.name
//name

name属性总是返回紧跟在class关键字后面的类名。
3.this 的指向
类的方法内部如果含有this,它默认指向类的实例。

class Test{
  method(){
        console.log(this) 
     }
 }
 console.log(new Test())

this指向Test实例对象。但是如果在class的方法内部使用this,在外部单独去调用这个方法就会报错

class Test{
 method(){
        this.method1()
     }
     method1(){
         console.log('11111111111')
     }
 }
 const test = new Test()
 const {method } = test
 method()
 // Cannot read property 'method1' of undefined

上面代码中,method方法中的this,默认指向Test类的实例。但是,如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境(由于 class 内部是严格模式,所以 this 实际指向的是undefined),从而导致找不到method1方法而报错。

解决方法在构造方法中绑定this

 class Test{
 	//构造函数
  constructor(){
       //绑定this
           this.method = this.method.bind(this);
       }
       method(){
          this.method1()
       }
       method1(){
           console.log('11111111111')
       }
   }
   const test = new Test()
   const {method } = test
   method()

2.类的继承

Class 可以通过extends关键字实现继承,基本用法

//父类
class Father{
}
//子类继承父类extends 
class Child extends Father{
}

上面代码定义了一个Child类,该类通过extends关键字,继承了Father类的所有属性和方法。但是由于没有部署任何代码,所以这两个类完全一样,等于复制了一个Father类。

class Father{
	constructor(){
	}
	test(){
		console.log('父类方法')
	}
}

class Child extends Father{
}
//实例化后,子直接继承了父类的属性和方法
let child = new Child()
//直接调用父类的方法
child.test()//1000

super关键字
调用父类的普通函数

class Father {
	test() {
	          return '父类的方法'
	      }
 }
 class Child extends Father {
     test(){
     	  //调用父类的方法
          return super.test()
      }
 }
 var child = new Child()
 console.log(child.test())//父类的方法

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例

class Father {
   constructor(){
        this.price =10
    }
    test1() {
        console.log(this.price)
    }
}
class Child extends Father {
    constructor(){
        //super表示父类的构造函数,用来新建父类的this对象
        super()//调用父类的constructor
        this.price =20
    }
    test2() {
        //调用父类的方法
         super.test1()
    }
}
var child = new Child()
child.test2()//20

上面代码中,super.test1()虽然调用的是Father.prototype.test1(),但是Father.prototype.test1()内部的this指向子类Child 的实例,导致输出的是2,而不是1。也就是说,实际上执行的是super.test1.call(this)。

调用父类的构造函数

class Father {
   constructor(price, count) {
       this.price = price;
       this.count = count;
   }
   test() {
       console.log(this.price+this.count)
   }
}
class Child extends Father {
   constructor(){
   	//super表示父类的构造函数,用来新建父类的this对象
       super(20,10)//调用父类的constructor
   }
}
var child = new Child()

你可能感兴趣的:(web)