如果你此时此刻按下f12 ,就会打开浏览器的控制台;
在控制台 输出一个函数:
就会发现,在ff 函数上挂着两个属性:__proto__和protoype
__proto__ : 函数也是普通对象,指向Function类上的prototype对象;
prototype: 函数的原型;
为什么函数身上会有 proto 属性呢?
__proto__属性对于js初学者来说,最初认识它是通过构造函数;
构造函数生成的实例上有__proto__属性,指向该构造函数的原型;该 构造函数的原型对象有constructor指向该构造函数;
那么,现在请跟我念:
js 里面所有对象都是Object构造函数的实例;
js 里面所有函数,都是Function构造函数的实例;
既然,所有函数都是Function构造函数的实例,那么所有函数身上都有__proto__指向Function构造函数的原型对象
同时,所有函数,只要前面有new,就从普通函数变成了构造函数,所以所有函数的身上都有prototype 属性指向自己的原型
现在还是比较好理解的,那么,下面请更加大声的朗读:
一切构造函数也是函数,也是Function类的实例
Object类也是构造函数,只要是函数,就是Function类的实例,所以Object类身上的__proto__指向其构造函数(Function类)的原型
那么,问题来了,Function类的原型也是对象吧,对象就有__proto__吧,那么这个__proto__指向谁呢?
原型对象的__proto__指向Object类的原型,Object类的原型对象,没有__proto__属性
看懂下面这张图,基本上算是理解了:
总结,js中,函数扮演了三个角色:
1、作为普通函数,形如 fn() 执行
2、作为类(构造函数),函数作为类时,有prototype属性,指向自己的原型对象;通过new 操作符可以生成自己的实例(该实例是个对象数据类型),该实例的__proto__指向该类的原型
3、作为对象,自身的__proto__指向Funtion类的原型,Funtion类的原型的__proto__指向Object类的原型,Object类的原型没有__proto__;函数作为对象有自己的私有属性;