es5继承 es6继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /**
         * 原型链继承
         * 优点:
         * 1、非常纯粹的继承关系,实例是子类的实例,也是父类的实例
         * 2、父类新增原型方法/原型属性,子类都能访问到
         * 3、简单,易于实现
         * 缺点:
         * 1、创建子类的时候无法向父类构造函数传参
         * 2、无法实现多继承
         * 3、来自原型对象的所有属性被所有实例共享
        */
        // 原型链继承

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

        function Sub(){}
        Sub.prototype = new Super('李先生');
        let a = new Sub();
        console.log(a.getName())
        
        /**
         * 原型链继承
         * 优点:
         * 1、解决原型链继承中子类实例共享父类引用属性的问题
         * 2、创建子类实例时,可以向父类传递参数
         * 3、可以实现多继承(call多个父类对象)
         * 缺点:
         * 1、实例并不是父类的实例,只是子类的实例
         * 2、只能继承父类的实例属性和方法,不能继承原型属性/方法
         * 3、无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
        */
        // 构造函数继承 apply和call

        function Super(name){
            this.name = name;
            // this.getName = function(){
            //     return this.name;
            // }
        }
        Super.prototype.getName = function(){
            return this.name;
        }
        function Sub(){
            Super.apply(this, arguments);
        }

        let a = new Sub('李先生');
        console.log(a)
        console.log(a.getName()); // 报错

        /**
         * 实例继承
         * 优点:不限调用方式
         * 缺点:1、实例是父类的实例 不是子类的实例
         * 2、不支持多继承
        */
        function Sub(){
            var instance = new Super();
            instance.name = name || 'xx';
            return instance;
        }

        /**
         * 拷贝继承
         * 优点:支持多继承
         * 缺点:1、效率低,内存占用高因为要拷贝父类的属性
         * 2、无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
        */
        function Sub(){
            var instance = new Super();
            for(let p in instance){
                Cat.prototype[p] = instance[p];
            }
        }

        /**
         * 组合继承
         * 优点:
         * 1、弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
         * 2、既是子类的实例,也是父类的实例
         * 3、不存在引用属性共享问题
         * 4、可传参
         * 5、函数可复用
         * 缺点:
         * 1、调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
        */
        function Sub(){
            Super.apply(this, arguments);
            this.name = name;
        }

        Sub.prototype = new Super();
        /**
         * 组合寄生式继承
         * 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
        */
        function Sub(){
            Super.apply(this, arguments);
            this.name = name;
        }

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

        /**
         * es6 class extends继承
         * es5中apply和call底层也是通过prototype来实现继承的
         * 区别:
         * 1、class 声明会提升,但不会初始化赋值
         * 2、class 声明内部会启用严格模式。
         * 3、class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
         * 4、class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
         * 5、必须使用 new 调用 class。
         * 6、class 内部无法重写类名。
         * 最主要的区别:
         * 1、ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))
         * 2、ES6的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this
         * 3、.ES5的继承时通过原型或构造函数机制来实现。
         * 4、.ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。
         * 因为子类没有自己的this对象,而是继承了父类的this对象,然后对其进行加工。如果不调用super方法,子类得不到this对象。
         * 
      * 
        */

        class Super {
            constructor(name){
                this.name = name;
            }
            getName(){
                return this.name;
            }
        }

        class Sub extends Super {
            constructor(name, age){
                super(name);
            }
        }

        let son = new Sub();



    </script>
</body>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值