js-challenges icon indicating copy to clipboard operation
js-challenges copied to clipboard

寄生组合式继承

Open Sunny-117 opened this issue 2 years ago • 13 comments

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

function Son(name, age) {
  // 这里其实就等于 this.name = name
  Parent.call(this, name)
  this.age = age
}

Son.prototype.getAge = function () {
  return this.age
}
Son.prototype.__proto__ = Object.create(Parent.prototype)

const son1 = new Son('shao', 20)

console.log(son1.getName()) // shao
console.log(son1.getAge()) // 20

Sunny-117 avatar Nov 03 '22 08:11 Sunny-117

不改constructor么,为什么给__proto__设置原型?

hnustwjj avatar Nov 03 '22 10:11 hnustwjj

Object.setPrototypeOf() 是 ECMAScript 6 最新草案中的方法,相对于 Object.prototype.proto,它被认为是修改对象原型更合适的方法

hnustwjj avatar Nov 03 '22 10:11 hnustwjj

Object.setPrototypeOf() 是 ECMAScript 6 最新草案中的方法,相对于 Object.prototype.proto,它被认为是修改对象原型更合适的方法

佬,可以写一个完美的,然后pr合并一下

Sunny-117 avatar Nov 03 '22 11:11 Sunny-117

佬,可以写一个完美的,然后pr合并一下

其实就是像下面这样改就好了

//Son.prototype.__proto__ = Object.create(Parent.prototype)
Reflect.setPrototypeOf(Son.prototype, Parent.prototype);
Reflect.setPrototypeOf(Son, Parent);

因为 setPrototype的实现是下面这样的

Reflect.setPrototype = function(obj, proto) {
     obj.__proto__ = proto;
     return obj
}

所以上面其实就相当于

Son.__proto__ = Parent;
Son.prototype.__proto__ = Parent.prototype;

这其实也就是继承的本质

23olddog avatar Nov 22 '22 06:11 23olddog

function Parent(value) {
	this.a = value;
}
Parent.prototype.getValue = function () {
	console.log(this.val);
};
function Child(value1, value2) {
	Parent.call(this, value1);
    this.b = value2;
}
Child.prototype = Object.create(Parent.prototype, {
    construcotr:{
        value:Child,
        enumerable:false,
        writable:true,
        configurable:true
    }
});

Child.prototype[Symbol.toStringTag]="Child.prototype";
Parent.prototype[Symbol.toStringTag]="Parent.prototype";
console.log(new Child(1,2))

veneno-o avatar Jan 24 '23 12:01 veneno-o

function Person(name, age) {
  this.name = name;
  this.age = age;
}
function Son(name, age, skills) {
  Parent.call(this, name, age);
  this.skills = skills;
}

Son.prototype = Object.create(Person.prototype);
Son.prototype.constructor = Son;

// Object.create原理
function myCreate(obj) {
  function F() {}
  F.prototype = obj;
  return new F();
}

bearki99 avatar Feb 02 '23 15:02 bearki99

function Animal(name) {
  this.name = name;
  this.type = 'mammal';
}

Animal.prototype.sayName = function() {
  console.log('My name is ' + this.name);
};

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

// 使用寄生式继承继承Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.sayBreed = function() {
  console.log('I am a ' + this.breed);
};

let myDog = new Dog('Max', 'Golden Retriever');
myDog.sayName(); // 'My name is Max'
myDog.sayBreed(); // 'I am a Golden Retriever'

kangkang123269 avatar Mar 02 '23 16:03 kangkang123269

function SuperType(_name) {
  this.colors = ["red", "blue", "green"];
  this.name = _name;
}
SuperType.prototype.getName = function () {
  console.log(this.name);
};
function SubType(_name, age) {
  SuperType.call(this, _name);
  this.age = age;
}
//Object.create()返回一个空对象,函数参数将作为空对象的原型对象
SubType.prototype = Object.create(SuperType.prototype);
SubType.prototype.constructor = SubType;

SubType.prototype.getAge = function () {
  console.log(this.age);
};

let instance1 = new SubType("lbw", 18);
instance1.colors.push("black");
console.log(instance1.colors); //[ 'red', 'blue', 'green', 'black' ]
instance1.getName(); //lbw
instance1.getAge(); //18

let instance2 = new SubType("white", 28);
console.log(instance2.colors); //[ 'red', 'blue', 'green' ]
instance2.getName(); //white
instance2.getAge(); //28

YMnotafraid avatar Mar 05 '23 05:03 YMnotafraid

// 原型链继承 function f() { this.f1 = 1; this.f2 = 20; }

        function s() {}
        s.prototype = new f();
        // 缺点:构造多个子类时,父类的属性会同步修改

// 组合继承 function f() { this.f1 = 1; this.f2 = 20; }

        function s() {
            f.call(this)
        }
        s.prototype = new f();
        // 优点:解决了修改父类属性会同步的问题
        // 缺点:调用了两次父类

// 寄生组合继承(继承原型、静态属性、实例属性) function f() { this.f1 = 1; this.f2 = 20; } function s() { // 子类继承父类实例属性 f.call(this); } function inheritPrototype(f, s) { let prototype = Object.create(f.prototype); prototype.constructor = s; // 子类继承父类原型 s.prototype = prototype; // 子类继承父类静态属性 s.proto = f; } inheritPrototype(f, s);

cscty avatar Jun 17 '23 17:06 cscty

  // 实现继承的核心函数
  function inheritPrototype(subType,superType) {
     function F() {};
     //F()的原型指向的是superType
     F.prototype = superType.prototype; 
     //subType的原型指向的是F()
     subType.prototype = new F(); 
     // 重新将构造函数指向自己,修正构造函数
     subType.prototype.constructor = subType; 
  }
  // 设置父类
  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);
  }
  var instance = new SubType("Taec",18)
  console.dir(instance)

RoyDust avatar Jul 24 '23 08:07 RoyDust

function inherit(target, origin) { function Fn() {} Fn.prototype = origin.prototype target.prototype = new Fn() Object.defineProperty(target.prototype, 'constructor', { writable: false, enumerable: false, configurable: true, value: target }) }

Coolxieyuyuyu avatar Apr 17 '24 13:04 Coolxieyuyuyu

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

function Son(name, age) {
  // 这里其实就等于 this.name = name
  Parent.call(this, name)
  this.age = age
}

Son.prototype.getAge = function () {
  return this.age
}
Son.prototype.__proto__ = Object.create(Parent.prototype)

const son1 = new Son('shao', 20)

console.log(son1.getName()) // shao
console.log(son1.getAge()) // 20

为什么要Son.prototype.proto = Object.create(Parent.prototype),而不是Son.prototype.proto=Parent.prototype?

skyler-developer avatar Aug 15 '24 10:08 skyler-developer

// 组合继承
function parentClass(name){
    this.name = name;
}
function childClass(name,age){
    parentClass.call(this,name);
    this.age = age;
}
childClass.prototype = Object.create(parentClass.prototype);
childClass.prototype.constructor = childClass;

// 寄生组合式继承
function inherit(parent,child){
    const fn = function(){};
    fn.prototype = parent.prototype;
    child.prototype = new fn();
    child.prototype.constructor = child;
}
function parentClass(name){
    this.name = name;
}
function childClass(name,age){
    parentClass.call(this,name);
    this.age = age;
}
inherit(parentClass,childClass);

jianxingyao avatar Sep 15 '24 09:09 jianxingyao