JS 继承方式

119 阅读2分钟

通过原型链实现继承

` function Person(name, age, sex) { this.arr = [33, 44, 55]; this.name = name this.age = age this.sex = sex }

    Person.prototype.sayHello = function () {
        console.log(`你好,我是${this.name}今年${this.age}岁了,我是${this.sex}生`);
    }

    function Student(name, age, sex, address) {
        this.name = name
        this.age = age
        this.sex = sex
        this.address = address
    }

    // 原型链实现继承
    Student.prototype = new Person()

    // 子类可以重写父类方法
    Student.prototype.sayHello = function () {
        console.log(`敬礼!,你好,我是${this.name}今年${this.age}岁了,我是${this.sex}生,我家在${this.address}`);
    }

    var xm = new Student('小明', 6, '男', '翻斗花园')
    xm.sayHello()

    var xh = new Person('小红', 7, '女')
    xh.sayHello()

    console.log(xh.arr);
    xm.arr.push(123)
    console.log(xm.arr);

`

通过原型链实现继承的问题

  • 问题1: 如果父类属性中有引用类型属性 则会被所有子类共享
  • 问题2: 子类中重复定义父类定义过的属性
  • 使用组合式继承即可解决以上问题

组合式继承

`

function People(name, sex, age) { this.name = name this.age = age this.sex = sex }

    People.prototype.sayHello = function () {
        console.log(`你好,我是` + this.name + '今年' + this.age + '岁了');
    }
    
    People.prototype.sleep = function () {
        console.log(this.name + '睡觉');
    }
    
    function Student(name, sex, age, school, sid) {
        // 借助构造函数
        People.call(this, name, sex, age)
        this.school = school
        this.sid = sid
    }
    
    Student.prototype = new People()

    Student.prototype.exam = function () {
        console.log(this.name + '正在考试');
    }

    Student.prototype.sayHello = function () {
        console.log('敬礼!你好我是' + this.name + '我今年' + this.age + '岁了,我是' + this.sex + '生,我的学校是' + this.school + '我的学号是' + this.sid);
    }

    var xiaoming = new Student('小明', '男', 12, 'pk学校', 10086)
    xiaoming.sayHello()
    xiaoming.sleep()
    xiaoming.exam()

`

组合式继承缺点

  • 会调用两次父类的构造函数 造成效率浪费

通过Object.create()实现寄生组合式继承

  function inheritPrototype(subType, superType) {
            var prototype = Object.create(superType.prototype)
            subType.prototype = prototype
        }

        function People(name, sex, age) {
            this.name = name
            this.age = age
            this.sex = sex
        }
        People.prototype.sayHello = function () {
            console.log(`你好,我是` + this.name + '今年' + this.age + '岁了');
        }
        People.prototype.sleep = function () {
            console.log(this.name + '睡觉');
        }
        //寄生式组合继承
        inheritPrototype(Student, People)

        function Student(name, sex, age, school, sid) {
            // 借助构造函数
            People.call(this, name, sex, age)
            this.school = school
            this.sid = sid
        }
        Student.prototype.exam = function () {
            console.log(this.name + '正在考试');
        }

        Student.prototype.sayHello = function () {
            console.log('敬礼!你好我是' + this.name + '我今年' + this.age + '岁了,我是' + this.sex + '生,我的学校是' + this.school + '我的学号是' + this.sid);
        }

        var xiaoming = new Student('小明', '男', 12, 'pk学校', 10086)

        xiaoming.sayHello()
        xiaoming.sleep()
        xiaoming.exam()
        console.log(Student.prototype.__proto__ === People.prototype);//true

Object.create()方法

  • 创建一个新的对象 可以将原有对象设置为新对象的原型
  • 参数1 被设置为新对象原型的 原对象
  • 参数2 设置新对象内的属性值 与原对象重复则会被新对象覆盖

        var obj1 = {
            a: 33,
            b: 45,
            c: 12,
            test: function () {
                console.log(this.a + this.b);
            }
        }
        var obj2 = Object.create(obj1, {
            d: {
                value: 99
            },
            a: {
                value: 10
            }
        })


        console.log(obj2.__proto__ === obj1); //true

        console.log(obj2.a); //10
        console.log(obj2.b); //99
        console.log(obj2.c); //12
        console.log(obj2.d); //45

        /*
           原型式继承
        */
        obj2.test()