每个构造函数都有一个原型对象,原型对象都包含一个指向函数的指针,而实例都包含一个指向原型对象的内部指针。此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针,假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型对象的链条。也就是原型链。简单实例如下:
function Persion(name) { this.name = name;}Persion.prototype.sayName = function() { console.log(this.name);}function ChildPersion(name) { this.name = name;}// 继承了PersionChildPersion.prototype = new Persion();var child = new ChildPersion('bill')child.sayName() // bill复制代码
以上实例中,ChildPersion继承了Persion,Persion是object的实例,因此,Persion的原型都会指向一个内部指针指向object.prototype。
instanceof()
用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
// 定义构造函数function C(){} function D(){} var o = new C();o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototypeo instanceof D; // false,因为 D.prototype不在o的原型链上o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回trueC.prototype instanceof Object // true,同上C.prototype = {};var o2 = new C();o2 instanceof C; // trueo instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.D.prototype = new C(); // 继承var o3 = new D();o3 instanceof D; // trueo3 instanceof C; // true复制代码
isPrototypeOf()
用于测试一个对象是否存在于另一个对象的原型链上。
function Foo() {}function Bar() {}function Baz() {}Bar.prototype = Object.create(Foo.prototype);Baz.prototype = Object.create(Bar.prototype);var baz = new Baz();console.log(Baz.prototype.isPrototypeOf(baz)); // trueconsole.log(Bar.prototype.isPrototypeOf(baz)); // trueconsole.log(Foo.prototype.isPrototypeOf(baz)); // trueconsole.log(Object.prototype.isPrototypeOf(baz)); // true复制代码
注意
在通过原型实现继承时,不能使用对象字面量创建原型方法,因为这样会重写原型链。如:
function Persion(name) { this.name = name;}Persion.prototype.sayName = function(){ console.log(this.name)}function ChildPersion(name) { this.name = name;}ChildPersion.prototype = new Persion();var child = new ChildPersion('bill');child.sayName() // bill// 重写ChildPersion.prototypeChildPersion.prototype = { getName: function(){ console.log(this.getName) }}var child2 = new ChildPersion('bill');child2.sayName() // Uncaught TypeError: child2.sayName is not a function复制代码
原型链的问题
- 包含引用类型的原型属性会被所有实例共享,因此,我们如果一个实例中修改了这个原型属性,那么,其他实例的对应属性也会改变
- 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
如有侵权,请发邮箱至wk_daxiangmubu@163.com 或留言,本人会在第一时间与您联系,谢谢!!