原型、原型链
经典图解
四个规则
INFO
- 引用类型,都具有对象特性,即可自由扩展属性。
- 引用类型,都有一个隐式原型 proto 属性,属性值是一个普通的对象。
- 引用类型,隐式原型 proto 的属性值指向它的构造函数的显式原型 prototype 属性值。
- 当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 proto(也就是它的构造函数的显式原型 prototype)中寻找。
什么是原型对象?实例?构造函数?
创建一个对象
js
function M(name) {
this.name = name;
}
var o3 = new M("o3");
- 实例就是对象,在本例中 o3 就是实例,M 就是构造函数。
- 实例通过 new 一个构造函数生成的。
- 从上图中可以知道,实例的protpo指向的是原型对象。
- 实例的构造函数的 prototype 也是指向的原型对象。
- 原型对象的 construor 指向的是构造函数。
原型
JS 中的对象包含了一个 prototype 的内部属性,这个属性所对应的就是该对象的原型。
INFO
- 定义:原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖 先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
- 利用原型特点和概念,可以提取共有属性。
- 对象属性的增删和原型上属性增删改查。
- 对象如何查看原型 ==> 隐式属性 proto。
- 对象如何查看对象的构造函数 ==> constructor。
原型链
proto 是每个对象都有的属性,而 js 里万物皆对象,所以会形成一条 proto 连起来的链条,递归访问 proto 必须最终到头,且值为 null,当 js 引擎查找对象属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链中查找,但不会查找自身的 prototype。
简单理解就是原型组成的链,对象的proto它的是原型,而原型也是一个对象,也有proto属性,原型的proto又是原型的原型,就这样可以一直通过proto想上找,这就是原型链,当向上找找到 Object 的原型的时候,这条原型链就算到头了。
INFO
- 如何构成原型链?
- 原型链上属性的增删改查 原型链上的增删改查和原型基本上是一致的。只有本人有的权限,子孙是没有的。
- 谁调用的方法内部 this 就是谁-原型案例
- 绝大多数对象的最终都会继承自 Object.prototype
- Object.create(原型);
- 原型方法上的重写
MDN
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
- 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
原型以及原型链对应的关系
js
Object.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;
首先 js 里万物皆对象,每个对象都有
proto
的属性,所以会形成一条 proto 连起来的链条,递归访问 proto 必须最>终到头,且值为 null,当 js 引擎查找对象属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链中查找,但不会查找自身的 prototype。
补
js
var obj = Object.create(null);
// 不是所有的对象都继承 Object.prototype