- 原型链
- 别忘记默认的原型
- 确定原型和实例的关系
- 构造函数继承和原型继承
- Object.create()
ECMAScript将原型链作为实现继承的主要方法。其基本思路是让原型对象等于另一个类型的实例,实现的本质是重写原型对象
。
原型链的概念:假如我们让原型对象等于另一个类型的实例,此时的实例将包含一个指向原型对象的指针,相应地,原型对象又包含一个指向另一个原型对象的指针。假如另一个原型对象又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条,这就是所谓原型链的基本概念。例:
function SuperType () {
this.property = true
}
SuperType.prototype.getSuperValue = function () {
return this.property
}
function SubType () {
this.subproperty = false
}
// 继承了SuperType
SubType.prototype = new SuperType()
SubType.prototype.getSubValue = function () {
return this.subproperty
}
var instance = new SubType()
console.log(instance.getSuperValue()) // true
注意:这时候constructor指向SuperType,因为SubType的原型指向了另一个对象SuperType的原型,而这个原型对象的constructor属性指向的是SuperType。
别忘记默认的原型
所有引用各类型默认都继承了Object,而这个继承也是通过原型链实现的。大家要记住,所有函数的默认原型都是Object的实例,这也正是所有自定义类型都会继承toString()、valueOf()等默认方法的根本原因。
确定原型和实例的关系
可以通过两种方式来确定原型和实例之间的关系。第一种方法是使用instanceof操作符,用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,返回的是布尔值。例:
console.log(instance instanceof Object) // true
console.log(instance instanceof SuperType) // true
console.log(instance instanceof SubType) // true
第二种方式是使用isPrototypeOf()方法,用于判断某个对象的原型是否在另外一个对象的原型链上,返回的是布尔值。
console.log(Object.prototype.isPrototypeOf(instance)) // true
console.log(SuperType.prototype.isPrototypeOf(instance)) // true
console.log(SubType.prototype.isPrototypeOf(instance)) // true
构造函数继承和原型继承
构造函数继承优点是创建的实例都是一个单独的副本,不会互相影响,缺点是每创建一个实例就会创建一个副本,不能复用。
原型继承优点是所有的实例都可以共享原型所有的属性和方法,缺点是原型中某个属性的引用类型如果修改,其他实例中也会修改。
Object.create()
方法会使用指定的原型对象及其属性去创建一个新的对象。
语法:Object.create(proto[, propertiesObject])
参数:proto新创建对象的原型对象。
propertiesObject可选。可选。如果没有指定为undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。
返回值:在指定原型对象上添加新属性后的对象。
注意:如果proto参数不是null或者一个对象,则会报错。
网友评论