Sunny-117 / js-challenges

✨✨✨ Challenge your JavaScript programming limits step by step

Home Page:https://juejin.cn/column/7244788137410560055

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

寄生组合式继承

Sunny-117 opened this issue · 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
commented

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

commented

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

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

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

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

这其实也就是继承的本质

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

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

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

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