Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

寄生组合式继承 #59

Open
Sunny-117 opened this issue Nov 3, 2022 · 13 comments
Open

寄生组合式继承 #59

Sunny-117 opened this issue Nov 3, 2022 · 13 comments

Comments

@Sunny-117
Copy link
Owner

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
@hnustwjj
Copy link

hnustwjj commented Nov 3, 2022

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

@hnustwjj
Copy link

hnustwjj commented Nov 3, 2022

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

@Sunny-117
Copy link
Owner Author

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

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

@23olddog
Copy link

23olddog commented Nov 22, 2022

佬,可以写一个完美的,然后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;

这其实也就是继承的本质

@veneno-o
Copy link
Contributor

veneno-o commented Jan 24, 2023

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))

@bearki99
Copy link

bearki99 commented Feb 2, 2023

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();
}

@kangkang123269
Copy link

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'

@YMnotafraid
Copy link

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

@cscty
Copy link

cscty commented Jun 17, 2023

// 原型链继承
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);

@RoyDust
Copy link

RoyDust commented Jul 24, 2023

  // 实现继承的核心函数
  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)

@Coolxieyuyuyu
Copy link

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
})
}

@skyler-developer
Copy link

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?

@jianxingyao
Copy link

// 组合继承
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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests