原型链做为实现继承的主要方法,其基本思路是利用原型让一个引用类型继承另外一个引用类型的属性和方法, 构造函数,原型和实例之间的关系经过一张图来解释一下,须要详细了解的能够看一下个人另一篇文章javascript
原型链继承的基本模式以下:git
function Parent() { this.name = "heyushuo"; } Parent.prototype.sayParentName = function() { console.log(this.name); }; function Child() { this.name = "kebi"; } //1.此时把Child的原型重写了,换成了Parent的实例 //2.换句话说,原来存在Parent的实例中的属性和方法,如今也存在Child.prototype中了 Child.prototype = new Parent(); //3.在继承了Parent实例中的属性和方法后基础上,又添加了属于本身的一个新方法(这里两个名字同样会覆盖) Child.prototype.sayChildName = function() { console.log(this.name); }; var Person = new Child(); console.log(Person); //因此如今Person指向Child的原型,Child的原型指向Parent的原型(由于Child的原型对象等于了Parent的实例,这个实例指向Parent的原型)
经过以下图打印的 Person 看一下他们的关系: 这里特别须要注意的是 Person.constructor 如今指向的是 Parent,由于 Child.prototype 中的 constructor 被重写了 能够经过以下代码改变 constructor 的指向github
//改变 constructor 的指向 Child.prototype.constructor = Child;
1. instanceof (实例对象是不是构造函数函数的实例)函数
console.log(Person instanceof Child); //true console.log(Person instanceof Parent); //true console.log(Person instanceof Object); //true //因为原型链的关系,能够说Person是他们三个中任何一个类型的实例
2.isPrototypeOf(Person) 只要原型链中出现过的原型,均可以说是该原型链派生的实例的原型(能够理解为是不是实例的原型) Object.prototype.isPrototypeOf(Person) //true Parent.prototype.isPrototypeOf(Person) //true Child.prototype.isPrototypeOf(Person) //truethis
再给 Child 添加新的方法的时候,必定要在原型继承父元素后添加,这样能够防止本身定义的方法,会和继承来的方法名字相同,致使 Child 本身定的方法被覆盖prototype
1.实例共享引用类型3d
虽然原型链继承很强大, 可是存在一个问题, 最主要的问题是包含引用类型值的原型, 由于包含引用类型值的原型属性会被全部的实例共享, 而在经过原型来实现继承的时候, 原型实际变成了另一个函数的实例(这里边就有可能存在引用类型)code
经过一个例子看一下对象
function Parent() { this.newArr = ["heyushuo", "kebi"]; } function Child() { this.name = "kebi"; } Child.prototype = new Parent(); var Person1 = new Child(); Person1.newArr.push("kuli"); console.log(Person1.newArr); // ["heyushuo","kebi","kuli"] var Person2 = new Child(); console.log(Person2.newArr); // ["heyushuo","kebi","kuli"]
2.在建立 Child 的子类的时候,没法像继承元素传递参数