原型和原型链的基础结论
1.函数与对象的关系
- 函数是对象,对象都是通过函数创建的。
- 函数与对象并不是简单的包含与被包含的关系。
2.原型的类别
- 显示原型: prototype, 是每个函数function独有的属性。
- 隐式原型:_ proto_ ,是每个对象都具有的属性。
3.原型和原型链
- 原型:一个函数可以看成一个类,原型是所有类都有的一个属性,原型的作用就是给这个类的一个对象都添加一个统一的方法。
- 原型链:每个对象都有一个_ proto_ ,它指向它的prototype原型对象; 它的prototype原型对象又有一个_proto_,指向它的prototype原型对象,就这样层层向上直到最终找到顶级对象Object的prototype,这个查询路径就是原型链。
4.JavaScript里最顶层的两个概念
- Function是JavaScript里最顶层的构造器,它构造了系统中的所有对象,包括用户定义对象、系统内置对象、甚至包括它自己。
- Object是最顶层的对象
: 所有对象都继承Object的原型
: Object也是被Function构造出来
5.instanceof
- obj instanceof F
- 描述: obj._ proto_ ._ proto_ … => F.prototype。 沿着对象obj的原型链查找是否存在对象F.prototype,若存在则返回true,若查找到原型链的终点Object. prototype仍未找到,则返回false。
经典原型和原型链的分析
(1)函数.prototype
前提结论:函数都是对象,每个函数都自带一个属性叫做prototype
例子:
详细的结构图:
最终结论:每个函数下其实有个prototype属性,prototype的属性值是一个对象,这个对象默认的只有一个叫做constructor的属性,指向这个函数本身。
(2)对象._ proto_
前提结论:每个对象都有一个隐藏的属性叫做_proto_
例子:
解释:
➢[[Prototype]]:是对象的一个内部属性, chrome的引擎通过_ proto_ 向外暴露了这个属性。实际上它可以看作就是对象的_ proto_属性
➢_proto_ 的值:等于构造该对象的函数的prototype属性。
testObj._ proto_ === testFn. prototype
结论:每个对象都有一个_ proto_ 属性,指向创建该对象的函数的prototype
详细图:
简化掉细节的通用图为:
(3)函数._ proto_
前提结论:在JavaScript中,函数都是对象,是对象就有隐藏的_proto_属性
解释:Function是最顶级的构造器,函数对象都是通过它来构造的
结论:函数._ proto_===Function.prototype
(4)函数.prototype._ proto_
解释:函数.prototype,它本质上是和 var obj={}是一样的,由new Object创造的 (在js中一切皆对象,它本质上就是一个空对象,空对象都是由new Object创造的 即每个函数都有一个prototype属性,它默认指向一个Object空对象前面我们说谁创建了它,那这个对象的隐式原型就指向了创建它的函数的一个显示原型)
结论:函数.prototype._ proto_===Object.prototype
(5)Object._ proto_
解释:Object是由顶层构造函数Function构造的(在js中所有的都是通过构造函数Function里进行构造的,所以我们的顶级对象也不例外)
结论:Object._ proto_===Function.prototype
(6)Object.prototype._ proto_
结论: Object. prototype较为特殊,它是顶级对象的原型,所以它的_ proto 指向是null。
(7)Function. proto_
解释:函数对象都是由被顶级构造函数Function创建。所以Function是被自身创建的
结论: Function. _proto _===Function.prototype
(8) Function.prototype._ proto_
解释:函数.prototype,它本质上是和var obj = {}是一样的,由new Object创建的
结论: Function.prototype._ proto_ ===Object.prototype
经典原型图:
原型链的作用
- 数据共享、节省内存空间
- 实现继承