类是由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()
class Test {
//构造函数,默认必须存在,可以不定义
constructor() {
}
test1() {
//...
}
test2() {
//...
}
}
// 上面的写法和下面的是一样的
Test.prototype = {
constructor() { },
test1() { },
test2() { },
};
在类的实例上调用方法,其实就是调用原型上的方法。
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()
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()