• 【学习笔记】六种继承详解


    六种继承的学习,敲得源码和注释都在下面,可以直接运行,方便更加直观的了解想继承

    一、原型链继承

    通过prototype去继承

    注意事项
    1、给原型添加方法的代码一定要放在替换原型的语句之后。
    2、存在内存空间共享的问题,当存在属性为数组的时候,一个改变,另一个也会改变

        
        function Animal(name){
            this.friend=["ahua","amao"]
            this.name = name
            this.color = "yellow"
            this.eat = function (food) {
                console.log(this.name + "正在吃:" + food)
            }
        }
        Animal.prototype.master = "小明"
    
        function Dog() {
            // this.color = "white"
    
         }
        
        function Cat() { }
        // Dog.prototype.color = "AJJAJA"
        Dog.prototype = new Animal()
        Dog.prototype.name = "大黄"
        
        var dog = new Dog()
        dog.friend.push("aaa")
        
        var dog2 = new Dog()
        dog.eat('大骨头') //大黄正在吃:大骨头
        
        console.log(dog.master)//小明
        cat.eat('鱼儿')
        Cat.prototype.color = "dsakdkjad"
        Cat.prototype = new Animal()
        Cat.prototype.name = "小咪"
        var cat = new Cat()
        console.log(dog.color)
        console.log(dog instanceof Animal)
        console.log(dog instanceof Dog)
        onsole.log(cat instanceof Animal)
        console.log(cat instanceof Cat)
    	
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    构造函数继承

    二、构造函数继承 主要就是使用call实现的 ,call可以改变函数this的指向

        // -----------------------------分割线---------------------------------------
    	function Animal(name){
            this.friend=["ahua","amao"]
            this.name = name
            this.color = "yellow"
            this.eat = function (food) {
                console.log(this.name + "正在吃:" + food)
            }
        }
        Animal.prototype.master = "小明"
         
        function Fox(){
            Animal.call(this)
            this.color = "red"
            this.name = "小狐狸"
        }
        
        let fox = new Fox()
        let fox1 = new Fox()
    
        // 解决了内存空间共享的问题
        fox1.color="green"
        console.log(fox.friend,fox1.friend)
    
        //父类原型上新增的属性和方法不会被继承
        console.log(fox.master,fox1.master)
    
        // -----------------------------分割线---------------------------------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    组合继承

    思路就是使用原型链实现对原型属性和方法的继承
    而通过借用构造函数来实现对实例属性的继承。
    即通过在原型上定义方法实现了函数复用,又能够保证每个实例都有他自己的属性
    解决了内存空间共享的问题,相较于构造函数,父类原型上的方法和属性都可以被继承

    
    
    
        function Animal(name){
            this.friend=["ahua","amao"]
            this.name = name
            this.color = "yellow"
            this.eat = function (food) {
                console.log(this.name + "正在吃:" + food)
            }
        }
        Animal.prototype.master = "小明"
    
        function Tiger (name,age){
            Animal.call(this,name) //第二次调用
            this.weight = age
        }
        Tiger.prototype = new Animal()  //第一次调用
        Tiger.prototype.sayName = function(){
            alert(this.weight)
        }
    
        var littleTiger = new Tiger("xiaolaohu","dklsajdlk")
        littleTiger.friend.push("xiaolaohu")
        console.log(littleTiger.friend)
        littleTiger.eat("DJSKAHD")
    
        var littleTiger1 = new Tiger("xiaol大萨达aohu","dklsajdlk")
        littleTiger1.friend.push("xiaol大萨达aohu")
        console.log(littleTiger1.friend)
        littleTiger1.eat("DJSKAHD")
    
        // 组合继承也有缺点 父类执行了两次 多构造一次就会多一次开销,(性能问题)
        // new了一次,call的时候一次
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    原型式继承

    主要使用的是ES5的方法, Object.create(proto[,propertiesObject])
    传入一个目标对象作为create的参数,会生成一个新对象。而这个新对象的__proto__是由目标对象提供的。

      
            let Person = {
                name:"xiaobei",
                friends:["angel","xiaoxiao"]
            }
    
            // let aPerson = Object(Person)
            let aPerson = Object.create(Person)
            aPerson.name = "goushi"
            aPerson.friends.push("dshaj")
    
            // let Person1 = Object(Person)
            let Person1 = Object.create(Person)
            Person1.name = "PI"
            Person1.friends.push("DKSAHD")
    
            console.log(aPerson,Person1)  
            
            // 可以继承父类的属性和方法,还是存在空间共享的问题
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    寄生式继承

    创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回一个对象

        
        function createAnother(original){
            let clone = Object.create(original)
            clone.sayHi = function(){
                console.log("hi")
            }
            return clone
        }
    
        let persopn = {
            name:"dhjsa",
            friends:["dsahk","shajd"]
        }
    
        let ontherPerson = createAnother(persopn)
        // ontherPerson.friends.push("dhsakj")
        ontherPerson.name = "dshakd hads"
    
        let ontherPerson1 = createAnother(persopn)
        // ontherPerson1.friends.push("111")
        ontherPerson1.name = "dshakd"
    
        console.log(ontherPerson,ontherPerson1)
    
        //缺点,依旧存在空间共享的问题
        //适用于关注对象,不在乎类型和构造函数的场景,Object()函数不是寄生式继承所必须的
        //任何返回新对象的函数都可以在这里使用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    寄生式组合继承

    寄生式组合继承
    通过借用构造函数继承属性,但使用混合式原型链继承方法
    基本思路就是 取得父类原型的一个副本,使用寄生式继承来继承父类原型,
    然后将返回的新对象赋值给子类原型,解决了内存共享的问题

        
        function inheritPrototype(subType, superType) {
            let prototype = Object.create(superType.prototype);  // 创建对象,创建父类原型的一个副本
            prototype.constructor = subType;                     // 增强对象,弥补因重写原型而失去的默认的constructor 属性
            subType.prototype = prototype;                       // 指定对象,将新创建的对象赋值给子类的原型
        }
    
        // 父类初始化实例属性和原型属性
        function superType(name) {
            this.name = name;
            this.colors = [1, 2, 3, 4, 5];
        }
        superType.prototype.saySuper = function () {
            console.log("super");
        };
    
        // 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
        function subType(name, age) {
            superType.call(this, name);
            this.age = age;
        }
        subType.prototype.saySub = function () {
            console.log("sub");
        };
    
        // 将父类原型指向子类
        inheritPrototype(subType, superType);
    
        let instance1 = new subType("zs", 10);
        instance1.colors.push(10);
        let instance2 = new subType("ls", 20);
        instance2.colors.push(100);
    
        console.log(instance1);
        console.log(instance2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    ArduPilot开源飞控之Copter任务
    Mysql事务隔离机制
    权重向量介绍
    Open3D 二维凸包计算
    通过vuex存储token,通过前置路由守卫完成对登录操作之后的token值验证,完成登录状态的保持
    计算机毕业设计django基于Python的学校财务管理系统(源码+系统+mysql数据库+Lw文档)
    【软件安装】Windows系统中使用miniserve搭建一个文件服务器
    Python 模拟超市收银抹零行为
    WebRTC目录结构
    语言模型编码中/英文句子格式详解
  • 原文地址:https://blog.csdn.net/xh1506101064/article/details/125606915