原型链的基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法。
构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部函数。
实现原型链的代码:
function SuperType(){
this.prototype=true;
}
SuperType.prototype.getSuperValue=function(){
return this.prototype;
}
function SubType(){
this.subprototype=false;
}
// 继承了SuperType
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function(){
return this.subprototype;
}
var instance=new SubType();
alert(instance.getSuperValue()); //true
![](https://i-blog.csdnimg.cn/blog_migrate/759454706b4f2f245480190a2ef3fe8c.png)
上图根据:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部函数这句话进行理解
ps:构造函数的首字母大写。
但以读取模式访问一个实例属性时,首先会在实例中搜索该属性。如果没有找到该属性,这回继续搜索实例的原型。上面的例子:instance.getSuperValue()会尽力三个搜索步骤:1)搜索实例;2)搜索SubType.prototype;3)搜索SuperType.prototype,最后一步找到了该方法。
默认的原型
还是上面的例子,给他们添加默认的原型:
剩余部分不变。
当调用instance.toString()时,实际上调用的是保存在Object.prototype中的方法。
确定原型和实例的关系:
第一种 instanceOf,由于原型链的关系得出下面结果:
alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true
第二种 isPrototypeOf(),只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型,
alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true
补充:
首先声明一个函数保存在一个变量里,按照编程习惯,一般将这个代表类的变量名首字母大写,然后在这个函数的内部通过对this(函数内部自带的一个变量,用于指向当前这个对象)变量添加属性后者方法来实现对类添加属性或者方法:
var Book=function(id,bookname,price){
this.id=id;
this.bookname=bookname;
this.price=price;
}
也可以通过类的原型上添加属性和方法,两种方式:一种是一一为原型对象属性赋值,一种是将一个对象赋值给类的原型对象:
Book.prototype.display=function(){
// 展示这本书
};
// 或
Book.prototype={
display:function(){}
};
当使用功能方法是,我们不能直接用book类,需要new关键字来实例化新的对象,使用实例化对象的属性或方法,可以通过点语法访问。
var book=new Book(10,'设计模式',50);
console.log(book.bookname()); //设计模式
问题:通过this添加的属性和方法同在prototype中添加的属性和方法有什么区别呢?
通过this 添加的属性和方法是在当前对象上添加的,然而js是一种基于原型prototype的语言,所以每创建一个对象时,他都会有一个原型prototype用于指向其继承的属性、方法。通过prototype继承的方法并不是对象自身的,所以使用这些方法时,需要通过prototype一级一级查找的来。通过this定义的属性或者方法是对象自身拥有的,所以我们每次通过创建一个新对象时,this指向的属性和方法都会得到相应的创建,而通过prototype继承的属性或方法是每个对象通过prototype访问到,所以每次通过类创建一个新对象是这些属性和方法不会再次创建。
问题:Book.prototype中的constructor又是指向什么呢?
constructor是一个属性,当创建一个函数或者对象时都会为其创建一个原型对象prototype,在prototype对象中就又会像函数中创建this一样创建一个constructor属性,这个属性指向的就是拥有整个原型对象的函数或对象,所以Book.prototype中的constructor指向的对象就是Book类对象。