继承的理解
一、原型继承
Child.prototype = new Parent(); //Parent实例有父类所有属性和方法 //将Child原型指向Parent实例,Child实例就能访问父类的属性和方法
弊端:
1.继承来的引用类型的属性被所有实例共享
2.在创建 Child 的实例时,不能向Parent传参
3.继承单一
封装成函数:
function createObj(o) {
function F(){}
F.prototype = o;
return new F();
}
var person1 = createObj(new Parent()); //拿到父类实例并继承
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:1、所有实例都会继承原型上的属性。
2、无法实现复用。(新实例属性都是后面添加的)给person1
添加了 name 值,并非修改了父类原型上继承来的 name 值。
二、构造函数继承
function Parent () { } function Child () { Parent.call(this); //Parent.apply(this, arguments) } // 使用call或apply方法,将父对象的构造函数绑定在子对象上 //优点: 1.避免了引用类型的属性被所有实例共享 2.可以在 Child 中向 Parent 传参
3.可以继承多个,call多个 //缺点: 方法都在构造函数中定义,每个新实例都有父类构造函数的副本,臃肿
只能继承父类构造函数的属性
三、组合继承
function Parent (name) { this.name = name; } function Child (name, age) { Parent.call(this, name); this.age = age; } Child.prototype = new Parent(); //Child.prototype.constructor 的指向是Parent Child.prototype.constructor = Child; //指向指回Child
//优点:可以继承父类原型上的属性,可以传参,可复用。
每个新实例引入的构造函数属性是私有的
//缺点:调用了两次父类构造函数(耗内存)