跟着coderwhy学习JavaScript高级(十三)

542 阅读2分钟

类的声明

class Person {}

function Person1() {}

// 上面两种写法本质上是一样的
console.log(typeof Person)
console.log(typeof Person1)

类的构造函数

class Person {

    // 一个类只能有一个构造函数
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

类的方法和静态方法

class Person {
    // 构造函数
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    
    // 普通的实例方法
    // 创建出来的对象进行访问
    // var p = new Person()
    // p.sayName()
    sayName(){
        console.log(this.name)
    }
    
    // 静态方法
    // Person.sayAge()
    static sayAge(){
        console.log(this.age)
    }
    
    // 类的访问器,也就是Object.defineProperty中的 get 和 set
    get Name() {
        return name;
    }
    
    set Name(newValue) {
        this.name = newValue;
    }
}

class实现继承

    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
      // 普通方法
      sayName() {
        console.log(`我是父类的方法我是person,我叫${this.name}`)
      }
      // 普通方法
      sayAge() {
        console.log(`我是父类的方法${this.age}`)
      }

      // 静态方法
      static say() {
        console.log(`我是父类的静态方法,你直接调用,也可以在子类重写`)
      }
    }

    // 子类继承父类
    class Student extends Person {
      constructor(name, age, sId) {
        super(name, age)
        this.sId = sId;
      }

      // 重写父类的方法
      sayName() {
        // 保留父类的逻辑,在子类重写父类的方法
        super.sayName()
        console.log(`子类重写父类的方法,年龄是 ${this.name}`);
      }

      sayId() {
        // 子类调用父类的方法
        super.sayAge()
        // 在执行子类的方法
        console.log(`我是子类方法,id是${this.sId}`)
      }

      // 重写父类的静态方法
      static say() {
        // 先调用一次父类的方法, 如果需要保留父类的逻辑就调用一次
        // 如果需要全部推翻重写, 那么不需要
        super.say()

        console.log(`我在子类重写了父类的静态方法,并且保留父类静态方法原来的代码逻辑`)
      }
    }

    var stu = new Student('malong', 18, 001)
    // 调用普通方法
    stu.sayName()
    stu.sayId()
    // 调用静态方法
    Student.say()

创建继承内置类

基本不会被用到

    // 创建继承的内置类
    class myArray extends Array {
      fristItem() {
        return this[0]
      }
      lastItem() {
        return this[this.length - 1]
      }
    }

    var arr = new myArray(1, 2, 3, 4)
    console.log(arr.fristItem(), arr.lastItem())

类的混入

JavaScript只支持单继承,不支持多继承。

    class Person { }
    class Student extends Person { }

    function mixinRunner(baseClass) {
      return class extends baseClass {
        running() {
          console.log('mixinRunner..')
        }
      }
    }

    function mixinEater(baseClass) {
      return class extends baseClass {
        eating() {
          console.log('eating...')
        }
      }
    }

    var NewStudent = new mixinEater(mixinRunner(Student))
    var stu = new NewStudent()
    console.log(stu)

多态

不同的数据类型进行同一个操作,表现出不同的行为,这就是多态。

    // 传统意义面向对象实现多态的三个前提
    // 1.子类继承父类 (必须有继承)
    // 2.子类重写父类的方法 (必须有重写)
    // 3.必须有父类引用指向子类对象
    
    // 传统意义上的多态
    class Person {
      doSomeThing() {}
    }
    // 1.子类继承父类
    class Student extends Person {
      // 2.子类重写父类的方法 
      doSomeThing() {
        console.log('我是学生,我要读书')
      }
    }

    class Teacher extends Person {
      doSomeThing() {
        console.log('我是老师,我教学生')
      }
    }

    var stu = new Student();
    var tea = new Teacher();

    function foo(person: Person) {
      person.doSomeThing()
    }
    
    // 3.父类引用指向子类对象
    foo(stu);
    foo(tea);
  • JavaScript中的多态
    function doSomeThing(foo) {
        foo.getName()
    }
    
    var obj = {
        name: "malong",
        getName() {
            console.log(this.name)
        }
    }
    
    class Person {
        getName() {
            console.log("Person getName")
        }
    }
    var p = new Person()
    
    // 不同的数据类型进行同一个操作,表现出不同的行为,这就是多态。
    doSomeThing(p)
    doSomeThing(obj)