继承

  • 让多个类之间建关系,便于代码的管理和复用
  • 继承方式
    • 原型继承,改变子类的原型对象
      • Student.prototype = new Person()
      • 缺点:如果父类中有引用数据类型,在子类生成的实例对象中改变该引用数据类型的值,就会影响子类其他实例对象,因为原型实例上的引用数据类型值会被所有实例共享
        function Person() {
        this.score = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    }
        let p1 = new Person()
        p1.score[0] = 2;
        let p2 = new Person()
        console.log(p2.score);// 这个不会影响,因为每new一次就创建一个新对象,this绑定到新对象上,引用数据指向不同的堆地址
        function Students() {
            this.ponit = [88, 99]
        }
        Students.prototype = new Person() //把students的原型对象指向Person类的一个实例对象
        let s1 = new Students()
        let s2 = new Students()
        s1.score[0] = 0
        console.log('s2:' + s2.score);  // 这里会影响,因为父类中引用数据类型前面的那个this,在原型继承时,已经确定为 new Person了,后面子类的实例对象不存在该引用数据this指向问题,所有子类实例中该引用数据都指向同一个堆地址,一旦一个实例对象修改,其他子类实例都会受影响
        s2.ponit[1] = 100;
        console.log('s1:' + s1.ponit); // 这里不会影响,这里的this.point在 new Students时才绑定,各个实例指向了不同的堆地址
        
    
  • 组合继承
    • 原型继承+call
      • 原型继承 继承原型的公有属性
      • call 继承原型的私有属性
    • 调用call会让父类构造函数执行多一次
    function Person(name,age){
        this.name = name;
        this.age = age
    }
    Person.prototype.say = function(){}
    Student.prototype = new Person()  // 原型继承 可以继承公有方法
    Student.prototype.constuctor = Student//原型继承后Student的constructor变成了Person,要重新指向
    function Student(name,age,className){
        Person.call(this,name,age)   //这里会让父类代码执行一次, 不能用bind(bind不执行代码,this.不能赋值)    
    } 
  • Object.create

    • 可以给创建出来的对象指定原型对象
    • Object.create(null) 创建一个没有原型对象的对象
  • 寄生组合继承

    • 通过 Object.create
    function Person(name,age){
        this.name = name;
        this.age = age
    }
    Person.prototype.say = function(){}
    //Student.prototype = new Person()  // 原型继承 可以继承公有方法
    Student.prototype = Object.create(Person.prototype) //把子类的原型指向父类的原型对象,不能拿到父类的私有属性,只能获取父类原型对象上的属性,也就是公有属性
    Student.prototype.constuctor = Student//原型继承后Student的constructor变成了Person,要重新指向
    function Student(name,age,className){
        Person.call(this,name,age)   //这里会让父类代码执行一次, 不能用bind(bind不执行代码,this.不能赋值)    
    } 
  • ES6中的继承
    • 使用class声明一个类
class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    say = () => { console.log('我的名字是' + this.name); }
}
class Student extends Person {
    constructor(name, age, className) {
        super(name, age)
        this.className = className
    }
}
let s1 = new Student('wc', 22, '1-2')
posted @ 2023-03-06 01:13  callAjax  阅读(12)  评论(0编辑  收藏  举报