js 面向对象 实现继承的几种方式

1.原型链继承

1.1 原理:将父类的实例添加到子类的原型上

1.2 缺点:父类新增原型方法/原型属性,子类都可以访问到,父类一变子类都会改变

function Person (name) {
            this.name = name;
        };
        Person.prototype.getName = function () {    //对原型进行扩展
            return this.name;
        };
        function Parent (age) {
            this.age = age;
        };
        Parent.prototype = new Person('老明');
        Parent.prototype.getAge = function () {
            return this.age;
        };
        var result = new Parent(22);

2.构造继承

2.1 原理:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

2.2 缺点:方法都在构造函数中定义, 只能继承父类的实例属性和方法,不能继承原型属性/方法,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能


function Person (name) {
            this.name = name;
            this.friends = ['小李','小红'];
            this.getName = function () {
                return this.name;
            }
        };

//        Person.prototype.geSex = function () {    //对原型进行扩展的方法就无法复用了
//            console.log("男");
//        };

        function Parent = (age) {
            Person.call(this,'老明');  //这一句是核心关键
            //这样就会在新parent对象上执行Person构造函数中定义的所有对象初始化代码,
            // 结果parent的每个实例都会具有自己的friends属性的副本
            this.age = age;
        };

        var result = new Parent(23);
        console.log(result.name);    //老明
        console.log(result.friends);  //["小李", "小红"]     console.log(result.getName());  //老明     console.log(result.age);    //23     console.log(result.getSex());  //这个会报错,调用不到父原型上面扩展的方法

           

           

3.组合继承

所有的实例都能拥有自己的属性,并且可以使用相同的方法,组合继承避免了原型链和借用构造函数的缺陷,结合了两个的优点,是最常用的继承方式

3.1.原理:通过调用父类构造,继承父类的属性并保留传参的优点,再通过将父类实例作为子类原型,实现函数复用

        function Person  (name) {

            this.name = name;

            this.friends = ['小李','小红'];

        };

        Person.prototype.getName = function () {

            return this.name;

        };

        function Parent (age) {

            Person.call(this,'老明');  //这一步很关键

            this.age = age;

        };

        Parent.prototype = new Person('老明')  //这一步也很关键


4.寄生组合继承

4.1 原理: 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免了组合继承的缺点

function Person(name) {
            this.name = name;
            this.friends = ['aa','bb'];
        }

        Person.prototype.getName = function () {
            return this.name;
        };

        function Parent(age) {
            Person.call(this,"cc");
            this.age = age;
        }

        (function () {
            var Super = function () {};    // 创建一个没有实例方法的类
            Super.prototype = Person.prototype;
            Parent.prototype = new Super();    //将实例作为子类的原型
        })();
        var result = new Parent(23);

你可能感兴趣的:(js 面向对象 实现继承的几种方式)