寄生组合式继承
Sunny-117 opened this issue · 12 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
不改constructor么,为什么给__proto__设置原型?
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))
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'
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
// 原型链继承
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
})
}
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?