每个构造函数都有一个原型对象,原型对象都包含一个指向函数的指针,而实例都包含一个指向原型对象的内部指针。此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针,假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型对象的链条。也就是原型链。简单实例如下:
function Persion(name) {
this.name = name;
}
Persion.prototype.sayName = function() {
console.log(this.name);
}
function ChildPersion(name) {
this.name = name;
}
// 继承了Persion
ChildPersion.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.prototype
o instanceof D; // false,因为 D.prototype不在o的原型链上
o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.
D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 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)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.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.prototype
ChildPersion.prototype = {
getName: function(){
console.log(this.getName)
}
}
var child2 = new ChildPersion('bill');
child2.sayName() // Uncaught TypeError: child2.sayName is not a function
原型链的问题
- 包含引用类型的原型属性会被所有实例共享,因此,我们如果一个实例中修改了这个原型属性,那么,其他实例的对应属性也会改变
- 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
网友评论