GithubHelp home page GithubHelp logo

Comments (11)

angelbeatsying avatar angelbeatsying commented on May 31, 2024 2

寄生组合式继承的基本**是为了解决组合继承的缺点,组合继承调用了两次父构造函数,生成了两个实例属性,只不过实例上的覆盖了原型上的属性。用了寄生式继承的方法,将子类原型指向父类原型,一般是Object.create() 与 Object.setPrototype()
缺点: 感觉还是父类原型中的引用类型值会被所有下面的实例共享,一个改变,其它都变了,,

from step-by-step.

clark-maybe avatar clark-maybe commented on May 31, 2024 2

显式混入模式的一种变体被称为‘寄生继承’,他即是显式的又是隐式的。

//传统的js类 vehicle
function Vehicle() {
    this.engines = 1;
}

Vehicle.prototype.ignition = function () {
    console.log('turning on my engine.')
}
Vehicle.prototype.drive = function () {
    this.ignition();
    console.log('steering and moveing forword.')
}

//寄生类 Car
function Car() {
    //首先,car是一个Vehicle
    var car = new Vehicle();

    //接着我们对car进行定制
    car.wheels = 4;
    var vehDrive = car.drive;

    //重写Vehicle::drive()
    car.drive = function () {
        vehDrive.call(this);
        console.log(`rolling on all ${this.wheels}wheels!`)
    }
    return car;
}

var myCar = new Car();
myCar.drive();
//turning on my engine.
// steering and moveing forword.
// rolling on all 4wheels!

如你所见,首先我们复制一份vehicle父类的定义,然后混入子类的定义,然后用这个复合对象构建实例。

摘自《你不知道的JavaScript上》

from step-by-step.

jodiezhang avatar jodiezhang commented on May 31, 2024

组合继承是JavaScript最常用的继承模式。组合继承最大的问题是,无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。
组合式继承

function SuperType(name){
   this.name=name
   this.color=["red","blue","green"]
}
SuperType.prototype.sayName=function(){
     console.log(this.name)
}
function SubType(name,age){
    SuperType.call(this,name)//第二次调用SuperType,又有了实例属性name和color了
    this.age=age
}
//第一次调用SuperType,实例属性name和color和SuperType的prototype属性都给了SubType的prototype对象
SubType.prototype=new SuperType() 
SubType.prototype.constructor=SubType
SubType.prototype.sayAge=function(){
   console.log(this.age)
}

寄生组合式继承

function inheritPrototype(subType,superType){
    var prototype=Object.create(superType.prototype)
    prototype.constructor=subType
    subType.prototype=prototype
}
function SuperType(name){
   this.name=name
   this.colors=["red","blue","green"]
}
SuperType.prototype.sayName=function(){
   console.log(this.name)
}

function SubType(name,age){
    SuperType.call(this,name)
    this.age=age
}
inheritPrototype(SubType,SuperType)
SubType.prototype.sayAge=function(){
     console.log(this.age)
}

这种方式的高效率体现在它只调用了一次SuperType构造函数,并且因此避免了SubType.prototype上面创建不必要,多余的属性。与此同时原型链还能保持不变还能用instanceof和isPrototypeOf.

from step-by-step.

YvetteLau avatar YvetteLau commented on May 31, 2024

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,基本思路:

不必为了指定子类型的原型而调用超类型的构造函数,我们需要的仅是超类型原型的一个副本,本质上就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下所示:

function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType;//增强对象
    subType.prototype = prototype;//指定对象
}
  • 第一步:创建超类型原型的一个副本
  • 第二步:为创建的副本添加 constructor 属性
  • 第三步:将新创建的对象赋值给子类型的原型

至此,我们就可以通过调用 inheritPrototype 来替换为子类型原型赋值的语句:

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
//...code
function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SuberType.prototype = new SuperType();
inheritPrototype(SuberType, SuperType);
//...code

优点:

只调用了一次超类构造函数,效率更高。避免在SuberType.prototype上面创建不必要的、多余的属性,与其同时,原型链还能保持不变。

因此寄生组合继承是引用类型最理性的继承范式。

from step-by-step.

chongyangwang avatar chongyangwang commented on May 31, 2024
   寄生组合式继承   类似于组合式继承   只不过组合式继承在实现时调用了两次超集  即实例化两次父类型,而寄生组合式继承只需调用一次超集,即利用构造函数继承属性  利用原型式继承方法。

组合式继承实现如下:

function Super(text){
   this.text = text
   this.like = ['唱','调','rap','篮球']
}
Super.prototype.say=function(){
  console.log(this.text)
}
function Suber(text){
  Super.call(this,text)
}

Suber.prototype=new Super('cccccccccccc');
console.log(Suber.prototype.constructor);   // Super
Suber.prototype.constructor= Suber;  //  Suber
Suber.prototype.say();
// var sub1 = new Suber();
// sub1.like.push('小姐姐')
// console.log(sub1.like);

// var sub2 = new Suber2();
// console.log(sub2.like);

寄生组合式继承实现如下:

function clonePrototype(Super,Suber){
   var prototype = Object.create(Super.prototype);
   prototype.constructor = Suber;
   Suber.prototype = prototype;
}

function Super(name){
  this.name = name
  this.like = ['sing','dance','rap','basketball']
}
Super.prototype.sayName=function(){
   console.log(this.name)
}

function Suber(name,age){
   Super.call(this,name)      //  继承属性
   this.age=age
}
clonePrototype(Super,Suber);
Suber.prototype.sayAge=function(){
  console.log(this.age)
}

var sub1 = new Suber('sss',45);
console.log(sub1.name);
sub1.sayName();
sub1.sayAge();

image

image

image

为什么要贴上面的三张图?

其实最下面的那张图可以帮助理解 new 操作符到底干了啥?

1.创建了一个空对象。
2.将空对象的__proto__属性=要实例化对象的prototype。
3.为此对象添加属性 name age like等 只针对例子。
4.返回此对象。

from step-by-step.

ziyi2 avatar ziyi2 commented on May 31, 2024

https://github.com/ziyi2/js/blob/master/JS%E7%B1%BB%E5%92%8C%E7%BB%A7%E6%89%BF.md

包含ES5和ES6对于类的继承的不同

from step-by-step.

yelin1994 avatar yelin1994 commented on May 31, 2024

寄生组合继承

function CreateDog(obj) {
    function Dog () {
        
    }
    Dog.prototype = obj
    return new Dog()
}
function Animal () {
    this.type = ['aniaml']
}
Animal.prototype.sayType = function () {
    console.log(this.type)
}
function Wolve () {
    Animal.call(this)
    this.hitType = 'hit'
}
function Addextend(wolve, animal) {
    const prototype = CreateDog(animal.prototype)
    prototype.constructor = wolve
    wolve.prototype = prototype
    wolve.prototype.sayHittype = function () {
        console.log(this.hitType)
    }
}
Addextend(Wolve, Animal)
const wolve = new Wolve()
// const wolve2 = new Wolve()
wolve.sayType()
wolve.sayHittype()

如名字所示,就是组合和寄生的结合:

  • 相比寄生,他继承的数据属性不会互相影响
  • 相比组合又少了一次Animal 的调用

from step-by-step.

MissNanLan avatar MissNanLan commented on May 31, 2024
  • 基本**:和组合继承有点类似,不过它解决组合继承调用两次父类的构造函数,就是在子类的原型调用父类的构造函数时做下改变,用寄生式继承来做这步操作,我们想要无非不就是父类原型的一个副本而已
  • 优点: 解决了组合继承两次调用父类的构造函数,普遍人员认为这是最理想的一种方式
function inheritPrototype(child,parent){
  var prototype = Object(parent.prototype);  //  创建对象
  prototype.constructor = child;   // 增强对像
  child.prototype = prototype;      // 指定对象
}

function Animal(speices){
  this.speices = speices;
  this.skills = ["jump","climb","catch","run"];
}

Animal.prototype.getSpeices = function(){
  console.log(this.speices)
}

function Dog(species,color){
  Animal.call(this,species);
  this.color = color;
}

inheritPrototype(Dog,Animal); 
// 在组合继承里面,这句是 Dog.prototype = new Animal()

var dog1 = new Dog('牧羊犬','black');
dog1.getSpeices(); // 牧羊犬

from step-by-step.

hefeng6500 avatar hefeng6500 commented on May 31, 2024

寄生组合式继承的基本**是为了解决组合继承的缺点,组合继承调用了两次父构造函数,生成了两个实例属性,只不过实例上的覆盖了原型上的属性。用了寄生式继承的方法,将子类原型指向父类原型,一般是Object.create() 与 Object.setPrototype()
缺点: 感觉还是父类原型中的引用类型值会被所有下面的实例共享,一个改变,其它都变了,,

这位兄台,对于 “父类原型中的引用类型值会被所有下面的实例共享” 这个缺点,你可以在父类原型上定义一个函数 return 出一个对象就可以了吧,这样每次修改子类实例中继承来子父类原型共享属性都不会其他子实例的修改而变化了

from step-by-step.

Sonirjodxpro avatar Sonirjodxpro commented on May 31, 2024

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,基本思路:

不必为了指定子类型的原型而调用超类型的构造函数,我们需要的仅是超类型原型的一个副本,本质上就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下所示:

function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType;//增强对象
    subType.prototype = prototype;//指定对象
}
  • 第一步:创建超类型原型的一个副本
  • 第二步:为创建的副本添加 constructor 属性
  • 第三步:将新创建的对象赋值给子类型的原型

至此,我们就可以通过调用 inheritPrototype 来替换为子类型原型赋值的语句:

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
//...code
function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SuberType.prototype = new SuperType();
inheritPrototype(SuberType, SuperType);
//...code

优点:

只调用了一次超类构造函数,效率更高。避免在SuberType.prototype上面创建不必要的、多余的属性,与其同时,原型链还能保持不变。

因此寄生组合继承是引用类型最理性的继承范式。

写错了点吧。最后那应该不需要再new 一次父类了。

from step-by-step.

fashen007 avatar fashen007 commented on May 31, 2024

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,基本思路:

不必为了指定子类型的原型而调用超类型的构造函数,我们需要的仅是超类型原型的一个副本,本质上就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下所示:

function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType;//增强对象
    subType.prototype = prototype;//指定对象
}
  • 第一步:创建超类型原型的一个副本
  • 第二步:为创建的副本添加 constructor 属性
  • 第三步:将新创建的对象赋值给子类型的原型

至此,我们就可以通过调用 inheritPrototype 来替换为子类型原型赋值的语句:

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
//...code
function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SuberType.prototype = new SuperType();
inheritPrototype(SuberType, SuperType);
//...code

优点:

只调用了一次超类构造函数,效率更高。避免在SuberType.prototype上面创建不必要的、多余的属性,与其同时,原型链还能保持不变。

因此寄生组合继承是引用类型最理性的继承范式。

是不是写错了,为啥还需要调用inheritPrototype 前还需要
SuberType.prototype = new SuperType();

from step-by-step.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.