原型链
通过原型链继承:Child.prototype = new Father(); // Child.prototype.__proto__ === Father.prototype
- 缺点:
- 原型链中的引用类型会被所有实例共享
- 无法向父级构造函数传参 ```javascript // Father.proto === Function.prototype // Father.prototype.proto === Object.prototype function Father(){ } Father.prototype.name = “baba”;
Child.prototype = new Father(); // Child.prototype.proto === Father.prototype
function Child(){
}
var child = new Child();
console.log(child.name); // “baba”
<a name="tGYtP"></a>### 借用构造函数在子构造函数中通过 call()、apply() 调用父级造函数,可以向父级构造函数传参<br />缺点:每个实例都创建了共有属性的副本,破坏了代码的复用性,浪费空间```javascriptfunction Father(name) {this.name = name;}function Child(name) {Father.call(this, name);}var child1 = new Child("baba");var child2 = new Child("mama");console.log(child1.name); // "baba"console.log(child2.name); // "mama"child2.name = "me"console.log(child1.name); // "baba"console.log(child2.name); // "me"
组合继承
原型链 + 借用构造函数,共享属性用原型链继承,非共享属性借用父级构造函数
缺点:需要调用两次父级构造函数,耗内存
function Father(name) {this.name = name;}Father.prototype.getName = function() {console.log(this.name); // 共享属性通过原型链继承}function Child(name) {Father.call(this, name); // 非共享属性借用父级构造函数}Child.prototype = new Father(); // 与寄生组合继承不同之处Child.prototype.constructor = Child; // Child.prototype.__proto__ === Father.prototypevar child1 = new Child("baba");var child2 = new Child("mama");child1.getName(); // "baba"child2.getName(); // "mama"child2.name = "me";child1.getName(); // "baba"child2.getName(); "me"
原型式继承
// 以 obj 作为原型构建对象function creatObject(obj) {function F(){};F.prototype = obj;return new F();}var parent = {name: "baba"}var child = creatObject(parent);console.log(child.name); // "baba"
该方法类似通过 Object.create() 创建对象
// 创建对象:Object.create(原型)var person = Object.create(Person.prototype);var obj = Object.create(null); //创建没有原型的对
寄生继承
function object(obj) {var clone = Object.create(obj);clone.sayHi = function(){console.log("Hi " + this.name);}return clone;}var parent = {name: "baba"}var child1 = object(parent);var child2 = object(parent);console.log(child1.sayHi === child2.sayHi); // false
寄生组合式继承
组合继承改进版,不需要调用两次父级构造函数
function Parent(name) {this.name = name;}Parent.prototype.getName = function() {console.log(this.name);}function Child(name) {Parent.call(this, name);}function inheritPrototype(Parent, Child) {Child.prototype = Object.create(Parent.prototype); // 与组合继承不同之处Child.prototype.constructor = Child;}inheritPrototype(Parent, Child);var child = new Child('baba');child.getName(); // "baba"
圣杯模式
function inherit(Target, Origin) {function F() {};F.prototype = Origin.prototype;Target.prototype = new F();Target.prototype.constructor = Target;Target.prototype.uber = Origin.prototype; // 记录继承原型}var inherit = (function() {function F() {};return function(Target, Origin) {F.prototype = Origin.prototype;Terget.prototype = new F();Terget.prototype.constructor = Target;Target.prototype.uber = Origin.prototype;}}());
Class 继承
ES6 extends 继承,与 java 类似
class Parent{constructor(name){this.name = name;}getName(){console.log(this.name);}}class Child extends Parent{constructor(name, age){super(name);this.age = age;}getAge(){console.log(this.age);}}let child = new Child("baba", 18);child.getName(); // "baba"child.getAge(); // 18
