原型和原型链

在Javascript中,我们创建的每一个函数都有一个 Prototype(原型) 属性,这个属性是一个指针,指向一个对象。 而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。 使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

原型对象

新建一个函数,根据规则就会为该函数创建一个 prototype 属性,这个属性指向函数的原型对象。 默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数) 属性,这个属性是一个指向 prototype 属性 所在函数的指针。列如上面的那个列子:Person.prototype.constructor 指向 Person。
对于创建的自定义函数(构造函数)其原型对象默认只会取得 constructor 属性,对于其他的方法,则都是从 Object 继承而来的。 当调用构造函数创建一个实例后,该实例的内部将包含一个( [[Prototype]] )指针(内部属性)指向构造函数的原型对象。对于 Chrome、 Firefox等浏览器都支持一个 _proto_ 属性。虽然无法访问到 [[Prototype]] 属性,但可以通过 isPrototypeOf() 方法来确定对象之间 是否存在这种关系。如果 [[Prototype]] 指向调用 isPrototypeOf() 方法的对象(Person.prototype),就会返回true。 从ECMAScript6开始,[[Prototype]] 可以通过 Object.getPrototypeOf()来访问
当需要读取某个对象的某个属性时,都会执行一次搜索,目标是给定名字的属性。首先先从对象实例本身开始,如果找到了给定名字的属性就返回属性值, 如果没找到,就继续搜索指针指向的原型对象,在原型对象中查找给定名字的属性。如果找到该属性就返回属性值。前面提到:原型最初只包含 constructor 属性,其它方法都是继承而来的,而该属性也是共享的。
虽然可以通过对象实例访问保存在原型中的值,却不能通过对象实例重写原型中的值。在实例中添加一个属性,而该属性与 实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。因为在对象实例上搜索到给定名字的属性时,就会返回该属性值, 而不再去原型搜索了。当然可以 通过delete操作符则可以完全删除该实例属性( delete xxx.xxx )。还可以通过 hasOwnProperty() 方法可以测试一个属性是存在于实例中,还是原型中(该方法是从 Object 继承而来的 ),只有给定的 属性存在于对象的实例中,才会返回true。

原型链

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实例都包含一个指向原型对象的内部指针。如果原型对象等于另一个类型的实例, 原型对象将包含一个指向另一个原型对象的指针,相应的以此类推,层层递进,就构成了实例与原型的链条,就是原型链。换句话说就是:每个实例都有一个属性 (内部指针)指向它的构造函数的原型对象。该原型对象也有一个自己的原型对象,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为 这个原型链中的最后一个环节(Object的原型)。
实现原型链:
posted @ 2020-10-25 19:11  攻城Alone  阅读(77)  评论(0编辑  收藏  举报