原型与原型链

133 阅读3分钟

原型与原型链:

1.所有原型链的终点都是Object函数的prototype属性
2.每个构造函数都拥有一个prototype属性,此属性指向一个对象,也是原型对象
3.原型对象默认拥有一个constructor属性,指向指向他的那个构造函数
4.每个对象都拥有一个隐藏的属性_proto_,指向它的原型对象

在JS中,每一个函数都有原型,函数被实例化以后,实力对象通过prototype属性可以访问原型,实现继承机制

定义原型:

原型实际上就是一个普通对象,继承于Object类,由JavaScript自动创建并依附于每个函数身上,原型在JavaScript对象系统中的位置和关系如图: 

访问原型的方法:

1. obj._proto_
2. Obj.constructor.prototype
3. Object.getPrototypeOf(obj)

其中obj表示一个实例对象,constructor表示构造函数。proto(前后各两个下划线)是一个私有属性,可读可写,与prototype属性相同,都可以访问原型对象,Object.getPrototypeOf(obj)是一个静态对象,参数为示例对象,返回值是参数对象的原型对象

_proto_属性是一个私有属性,存在浏览器兼容性问题,以及缺乏非浏览器环境的支持。使用obj.constructor.prototype也存在一定的风险,如果obj对象的constructor属性值被覆盖,则obj.constructor.prototype将会失效。因此,比较安全的用法是使用Object.getPrototypeOf(obj)

设置原型的方法:

1.obj._proto_ = prototypeObj,
2.Object.setPrototypeOf(obj,prototypeObj)
3.Object.create(prototypeObj)

其中,obj表示一个实例对象,prototypeObj表示原型对象。注意,IE不支持前两种方法。

检测原型:

使用isPrototypeOf()方法可以判断该对象是否为参数对象的原型。isPrototypeOf()是一个原型方法,可以在每个实例上调用

原型链:

  在JS中,实例对象在读取属性时总是先检查私有属性。如果存在,则会返回私有属性;否则就会检索prototype原型;如果找到同名属性,则会返回prototype原型的属性值
  prototype原型允许引用其他对象,如果在prototype原型中没有找到指定的属性,则JS将会根据引用关系,继续检索prototype原型对象的prototype原型,以此类推。

原型继承:

原型继承是一种简化的继承机制,也是 JavaScript 原生支持的继承模式。在原型继承中,类和实例概念被淡化了,一切都从对象的角度来考虑。原型继承不再需要使用类来定义对象的结构,直接定义对象,并被其他对象引用,这样就形成了一种继承关系,其中引用对象被称为原型对象。JavaScript 能够根据原型链来查找对象之间的这种继承关系。

原型继承的缺点:

1.每个类型只能有一个原型,所以不支持多继承
2.不能友好的支持带参数的父类
3.使用不灵活,在原型声明阶段实例化父类,并把它作为当前类型的原型,这限制了父类实例化的灵活性,无法确定父类实例化的时机和场合
4.prototype属性固有的副作用