function A(){ this.a='a'; this.arr=[1,2]; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(){ this.b='b'; } B.prototype.funB=function(){ console.log("我是B的方法"); } B.prototype=new A(); var b1=new B();
因为A的实例可以访问A.prototype
,因此咱们能够设置B.prototype
指向A的实例。因此B的实例能够访问A的实例以及A.prototype
,实现继承app
1.因为对象类型的赋值是引用赋值,若是父类A实例化过程当中有引用类型,那么子类B的实例的这个属性都指向同一内存空间。函数
function A(){ this.a='a'; this.arr=[1,2]; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(){ this.b='b'; } B.prototype.funB=function(){ console.log("我是B的方法"); } B.prototype=new A(); var b1=new B(); var b2=new B(); b1.arr.push(3); console.log(b1.arr); // [1, 2, 3] console.log(b2.arr); // [1, 2, 3]
2.若是父类的实例须要传入一些参数,那么两个子类实例初始化时某一属性值相同this
function A(year){ this.year=year; } function B(){ this.b='b'; } B.prototype=new A(18); var b1=new B(); var b2=new B(); console.log(b1.color); // 18 console.log(b2.color); // 18
3.B.prototype
中constructor指向不正确,由于B.prototype
指向了一个A的实例,因此本应指向B的constructor指向了Aprototype
function A(year){ this.year=year; } function B(){ this.b='b'; } B.prototype=new A(18); var b1=new B(); b1.constructor===A // true
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color){ A.call(this,color); } B.prototype.funB=function(){ console.log("我是B的方法"); } var b1=new B("red"); console.log(b1) // {a: "a", arr: Array(2), color: "red"}
解决了引用赋值问题,也能够自定义一些属性了,constructor也指向B了,即解决了类式继承的第一个、第二个问题以及第三个问题code
很明显,B除了调用了A这个函数外并无和A扯上什么关系,原型链是不通的(没法访问到应该做为父类的A的prototype属性),我甚至并不以为这是一种继承方式,但它为下面两种方法奠基了基础对象
b1.__proto__===B.prototype // true b1.__proto__.__proto__===Object.prototype // true
说白了,就是将上述两种方法的长处组合到一块儿,利用原型链实现原型属性和方法的继承,经过借用构造函数实现对实例属性的继承继承
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color,age){ // 经过借用构造函数实现对实例属性的继承 A.apply(this,[color]); this.age=age; } // 利用原型链实现原型属性和方法的继承 B.prototype=new A(); B.prototype.constructor=B; var b1=new B('red',18);
既经过在原型上定义方法实现了函数复用,又可以保证每一个实例都有它本身的属性内存
调用了两次父类的构造函数原型链
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color,age){ A.apply(this,[color]); this.age=age; } B.prototype=Object.create(A.prototype); B.prototype.constructor=B; var b1=new B('red',18);
只需访问一次父类的构造函数,避免了在子类的prototype上建立没必要要、多余的属性原型