原型和原型链的基础结论
1. 函数和对象的关系
- 函数是对象,对象都是通过函数创建的;
- 函数与对象并不是简单的包含与被包含的关系;
2. 原型的类型
- 显示原型:prototype,是每个函数 function 独有的属性;
- 隐式原型: proto,是每个对象都具有的属性;
3. 原型和原型链
- 原型:一个函数可以看成一个类,原型是所有类都有的一个属性,原型的作用就是给这个类的一个对象都添加一个统一的方法;
- 原型链: 每个对象都有一个_proto_,它指向它的peototype原型对象;它的prototype原型对象又有一个_proto_,指向它的 prototype 原型对象,就这样层层向上直到最终找到顶级对象Object的prototype,这个查询路径就是原型链;
4. JavaScript 里最顶层的两个概念
- Function是最顶层的构造器
Function是JavaScript里最顶层的构造器,它构造了系统中的所有对象,包括用户定义对象、系统内置对象、甚至包括它自己。
A. 自定义对象:
function fun() {};
var obj = new fun();
B. 系统内置对象:
var arr = new Array(1,2,3);
console.log(arr);
输出:[1,2,3]
- Object是最顶层的对象
所有对象都集成 Object 的原型;
Object 也是被 Function 构造出来;
5. instanceof
obj instanceof F
- 常见的不够正确描述:用来判断一个对象是否是某个构造函数的实例,比如我们创建一个函数,并且将它实例化;
function fun() {};
var obj = new fun();
console.log(obj instanceof fun);
输出:true
- 正确的描述:
obj.proto.proto...=> F.prototype。沿着对象 obj 的原型链查找是否存在对象 F.prototype,若存在则返回 true,若查找到原型链的终点 Object.prototype 仍未找到,则返回 false;
6. 函数.prototype
- 前提结论:函数都是对象,每个函数都自带有一个属性叫做 prototype;

- 最终结论:
每个函数下其实都有一个 prototype 属性, prototype 的属性值是一个对象,这个对象默认的只有一个叫做constructor的属性,指向这个函数本身;
7. 对象.proto
- 前提结论:每个对象都有一个隐藏的属性叫做_proto_;

- 结论:每个对象都有一个_proto_属性,指向创建该对象的函数的 prototype;

7. 函数.proto
- 前提结论:在JavaScript 中,函数都是对象,是对象就有隐藏的_proto_属性;
- 解释: Function是最顶级的构造器,函数对象都是通过它构造的;

8.函数.prototype.proto
- 解释:函数.prototype,它本质上是和 var obj = {} 是一样的,由 new Object 创建的;
- 结论:函数.protype.proto === Object.prototype

9. Object.proto
- 解释: Object是由顶层函数 Function 构造的;
- 结论: Object.proto === Function.prototype;

10. Object.prototype.proto
- 结论: Object.prototype 较为特殊,它是顶级对象的原型,所以它的_proto_指向是null;

11. Function.proto
- 解释:函数对象都是由被顶级构造函数Function创建,所以Function是被自身创建的;
- 结论:Function.proto === Function.prototype

12. Function.prototype.proto
- 解释: 函数.prototype,它本质上是和var obj = {}是一样的,由 new Object创建的;
- 结论:Function.prototype.proto === Object.prototype;

13. 经典原型图

14. 原型链的作用