原型 - 原型链
ps:假设
function Person(){};
var per = new Person();
很重要:js里面的面向对象是基于原型(prototype)实现的
-
在原型上定义的属性(方法),通过“继承”使得:实例也拥有了这个属性(方法);
-
构造函数在函数申明时,就会产生一个
prototype
属性(默认指向一个空的Object对象)
,构造函数可以通过prototype
访问到原型对象。 -
实例通过
__proto__
访问到与构造函数prototype
所指向的同一个原型对象。- per.proto === Person.prototype // true
- 其中 :
- prototype : 又称之为“显示原型”;
- proto : 又称之为“隐式原型”
- 注意 : ES6之前:只能操作显示原型,不能操作隐式原型。
-
constructor:原型可以通过构造器
constructor
访问到构造函数
// 实例访问构造函数
per.__proto__.constructor === Person; //true
- 实例读取属性过程:
1. 现在自身的属性查找
2. 然后沿着 "__proto__" 隐式原型链查找
3. 如果都没有则返回 undefined
- 原型继承 :实例对象自动拥有构造函数原型对象的属性(方法) ———— 原理:原型链
instanceof
A instanceof B : B函数的显示原型,是否存在于,A实例的隐式原型链上。
还有一些重要点
Function = new Function(); // Function 是由自身 new 出来的!牛掰吧!自己生了自己,有意思
// 所以
Function.__proto__ === Function.prototype; // true
// Object 是由Function new出来的,也就是说 Object.__proto__ === Function.prototype;
// 但是"__proto__"隐式原型链的最终指向还是会到达Object, 很绕对吧!!!
Object = new Function();
// 所以
Object.__proto__ === Function.prototype;
关于原型链的三个点:(原型链又称之为:隐式原型链)
1. 子类(实例)的 '__proto__' 指向父类(构造函数)的 'prototype'
2. 原型链(隐式原型链)的最终指向是 "Object.prototype"
3. Object.prototype.__proto__ === null 原型链的尽头
综上所述:然后就构成了这样一张图