最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 继承的那些事

    正文概述 掘金(喀喀)   2021-04-10   473

    前言

    最近在学习继承的一些东西,写这篇文章也是为了让自己的学习更加贯彻一下吧!
    学习过程是通过 死磕36JS手写题这篇文章来学习的,所以有些代码可能应用了上面的,感兴趣的可以去看一下那篇文章!

    原型链继承

    先来看一下代码吧!

    function Animal() {
        this.colors = ['black', 'white']
    }
    Animal.prototype.getColor = function() {
        return this.colors
    }
    function Dog() {}
    Dog.prototype =  new Animal()
    
    let dog1 = new Dog()
    dog1.colors.push('brown')
    let dog2 = new Dog()
    console.log(dog2.colors)  // ['black', 'white', 'brown']
    

    我知道光看这代码可能有点蒙,所以根据自己的理解我画了一下里面的“恩爱情仇”,如有不足的地方希望大家帮我指出

    继承的那些事 我就就着图给大家简单的解释一下吧!

    1. Animal的原型Animal.prototype的getColor属性等于function()函数,就相当于Animal的原型获得了返回colors的能力
    2. Animal的实例化对象等于Dog.prototype,相当于Dog的原型继承了Animal的属性
    3. Dog的实例化对象dog1在colors数组了新加入了一个颜色brown,所以Dog里面也有了brown属性
    4. Dog再一次实例化了一个对象dog2,所以dog2里面的colors数组有了三种颜色。
    5. 原型链继承存在的问题:

    问题1:原型中包含的引用类型属性将被所有实例共享;
    问题2:子类在实例化的时候不能给父类构造函数传参;


    借用call

    老规矩,先看代码!

      function Parent1(){
        this.name = 'parent1';
      }
      function Child1(){
        Parent1.call(this);
        this.type = 'child1'
      }
      console.log(new Child1); //parent1,child1
    

    什么是call()?
    call() 方法是预定义的 JavaScript 方法。

    它可以用来调用所有者对象作为参数的方法。

    通过 call(),您能够使用属于另一个对象的方法。

    所以这就是为什么call可以实现继承的原因。
    但是还有个问题:这样写的时候子类虽然能够拿到父类的属性值,但是问题是父类原型对象中一旦存在方法那么子类无法继承

    组合继承

    组合继承结合了原型链和盗用构造函数,将两者的优点集中了起来。基本的思路是使用原型链继承原型上的属性和方法,而通过call继承实例属性。这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。

    先看代码!

    function Animal(name) {
        this.name = name
        this.colors = ['black', 'white']
    }
    Animal.prototype.getName = function() {
        return this.name
    }
    function Dog(name, age) {
        Animal.call(this, name)
        this.age = age
    }
    Dog.prototype =  new Animal()
    Dog.prototype.constructor = Dog
    
    let dog1 = new Dog('奶昔', 2)
    dog1.colors.push('brown')
    let dog2 = new Dog('哈赤', 1)
    console.log(dog2) 
    // { name: "哈赤", colors: ["black", "white"], age: 1 }
    
    1. Dog函数里 Animal.call(this,name)继承Animal()函数的name属性
    2. Dog.prototype = new Animal()让Dog继承了Animal的colors属性以及getName方法
    3. Dog.prototype.constructor = Dog 让Dog.prototype的构造函数是Dog。
    4. 这样就实现了继承

    寄生式组合继承

    组合继承虽然解决了问题,已经算是比较完善了,但是它也产生了新的问题,就是调用了2次父类构造函数,第一次是new Animal(),第二次是在Animal.call()这里,所以我们可以再优化一下。 解决办法就是我们不让父构造函数给子类原型赋值,而是创建一个第三方,让第三方函数获取父类原型的副本

      function Parent5 () {
        this.name = 'parent5';
        this.play = [1, 2, 3];
      }
      function Child5() {
        Parent5.call(this);
        this.type = 'child5';
      }
      Child5.prototype = Object.create(Parent5.prototype);
      Child5.prototype.constructor = Child5;
    

    这种方法可以说是最完美的啦(撒花),所有的问题都被完美解决了
    在这里我们小小的解释一下
    Child5.prototype = Object.create(Parent5.prototype);
    这句代码的意思就是:基于Parent5.prototype创建一个新的原型(此原型会有Parent5原型的所有属性)赋值给Child5.prototype。
    在这里,我们就成功的把两次调用父类构造函数变成了一次。

    class 实现继承

    先上代码!

    class Animal {
        constructor(name) {
            this.name = name
        } 
        getName() {
            return this.name
        }
    }
    class Dog extends Animal {
        constructor(name, age) {
            super(name)
            this.age = age
        }
    }
    

    class继承其实和原型链继承没啥区别,但是它可比原型链要香一点(在我看来)!
    香在哪里呢?

    1. 极大地简化了原型链代码。 看见了上面原型链继承有时候是不是有点绝望啊?我也是,但是没关系,我们有class,它大大的简化了原型链代码,是不是有点拨云见日的感觉啊,哈哈!
    2. class应用起来也是非常方便的,它在定义对象和方法的时候就可以用extends来实现继承。(香香)

    总结

    老师告诉我,学习必须要想苦行僧般的徒步旅行,每一步要走踏实,每一次都不能停下!加油,自己。


    起源地下载网 » 继承的那些事

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元