构造函数、原型、实例之间的关系
每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型
原型链
当构造函数的原型同时也是另一个构造函数的实例时,那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链
例如:
function Person () {
this.name = '人'
}
// 在人原型里添加getPersonName方法
Person.prototype.getPersonName = function () {
console.log(this.name + 'getPersonName');
}
// 创建了黄种人
function YellowPeople () {
this.name = '黄种人'
}
YellowPeople.prototype = new Person()
// 通过YellowPeople生成gxPerson实例对象
var gxPerson = new YellowPeople()
gxPerson.getPersonName()
当YelowPeople 的实例对象gxPeople想要调用Person.prototype原型对象里面的getPersonName方法时,按照常规的理解它们之间没有联系所以是使用不了的,这时候就需要一个桥梁将它们串联起来,YellowPeople.prototype = new Person(),就起到了桥梁作用,YellowPeople.prototype 是YelowPeople 的原型对象同时也是Person的实例,至此形成了原型链,gxPeople就可以继承使用getPersonName方法了
注意:由于 YellowPeople.prototype = new Person()改变了YellowPeople.prototype的constructor的指向,所以gxperson的constructor的指向也随之改变,变成了Person
原型链的经典继承
Animal 构造函数定义了两个属性,name 和 categorys,而它的原型上也定义了一个方法叫 sayName()。Dog 构造函数调用了 Animal 构造函数,传入了 name 参数,然后又定义了自己的属性 age。此外,Dog.prototype 也被赋值为 Animal 的实例。原型赋值之后,又在这个原型上添加了新方法 sayAge()。这样,就可以创建两个 Dog 实例,让这两个实例都有自己的属性,包括 categorys,同时还共享相同的方法
function Animal(name) {
this.name = name;
this.categorys = ["cat", "rabbit"];
}
Animal.prototype.sayName = function () {
console.log(this.name);
};
function Dog(name, age) {
// 继承属性
Animal.call(this, name);
this.age = age;
}
// 继承方法
Dog.prototype = new Animal();
Dog.prototype.sayAge = function () {
console.log(this.age);
};
var d1 = new Dog("zhangsan", 29);
d1.categorys.push("dog");
console.log(d1.categorys); // [ 'cat', 'rabbit', 'dog' ]
d1.sayName(); // zhangsan
d1.sayAge(); // 29
var d2 = new Dog("lisi", 27);
console.log(d2.categorys); // [ 'cat', 'rabbit' ]
d2.sayName(); // lisi
d2.sayAge(); // 27