文章导读
https://github.com/mqyqingfeng/Blog/issues/16
继承
原型链继承、借用构造函数、组合继承、原型式继承
继承的方式
-
原型链继承:child构造函数的prototype指向parent的实例
function Parent() { this.name = 'lili'; } function Child() {} Child.prototype = new Parent();
缺点:
-
引用类型的属性被所有实例共享
function Parent() { this.names = ['lili']; }
function Child() {}
Child.prototype = new Parent();
const child1 = new Child(); const child2 = new Child(); child1.names.push(‘kevin’); console.log(child1.names); // [‘lili’,‘kevin’]; child2.names.push(‘moli’); console.log(child2.names); // [‘lili’,‘kevin’,‘moli’];
2. 在创建child实例时,不能向parent传参 ---
-
-
借用构造函数(经典继承):在child构造函数中执行Parent的call
function Parent(name) { this.name = name; } function Child(name) { Parent.call(this, name); } const child1 = new Child('lili'); console.log(child1.name); // lili const child2 = new Child('kevin'); console.log(child2.name) // kevin
优点:
- 避免引用类型的属性被所有实例共享
- 可以向parent传参
缺点: 方法在构造函数中执行,每次创建实例都会创建一遍方法
-
组合继承: 融合原型链继承和构造函数
function Parent(name) { this.name = name; this.colors = ['green']; } function Child(name, age) { Parent.call(this, name); this.age = age; } Child.prototype = new Parent(); Child.prototype.constructor = Child; // 修正Child.prototype,不然会是Parent const child1 = new Child('lili', 18); console.log(child1.name, child1.age, child1.colors);
-
原型式继承:用object.create的模拟实现,将传入的对象作为创建的对象的原型
function createObj(o) { function F() {}; F.prototype = o; return new F(); } var person = { name: 'kevin', friends: ['daisy', 'kelly'] } var person1 = createObj(person); var person2 = createObj(person); console.log(person1, person2) // {} {} person1.name = 'person1'; console.log(person2.name); // kevin person1.friends.push('taylor'); console.log(person2.friends); // ["daisy", "kelly", "taylor"]
-
寄生式继承:创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象
function createObj(o) { const F = Object.create(o); F.getName = function() { return 'kevin'; } return F; }