说说自己的理解
-
我按照 js 的执行顺序说吧 感觉这样条理 清晰一点
-
但有一个 前提就是 引用数据类型是存在堆里面的 栈里面存的是指针
-
首先 函数内部会有一个 Objecrt 构造函数 (注意是构造函数 这个是内置的 也就是不用自己额外定义的)那么构造函数就会有 原型 他的原型 会指向 Object 的原型对象 这个原型对像就是原型链的尽头了 里面会有很多方法 像什么 tostring 什么的 都是在这上面 这个原型对象上面会有一个 隐式原型 _proto 但是这个隐式原型是指向 null 的 所以查找到最后 就是 null 嘛
-
那么当我们定义一个自己的构造函数的时候 首先还是指针存在栈里面 然后指向一个堆 堆里面是一个构造函数对象 对象有一个显示原型 prototype 然后这个显示原型有一个指针 指向一个 Object 空的实例对象 因为所有对象类型都是基于 Object 的嘛 这个空对象里面就有一个 隐式原型 _proto 这个隐式原型存一个地址 指向 Object 的原型
-
最后就是实例化对象了 实例化出来的对象 也是一个指针在栈里面 然后指向他的实例对象 那么上面就有一个隐式原型 指向他的构造函数的显示原型上面嘛 然后又因为之前 构造函数的显示原型 也就是之前的 object 空对象 然后他的 隐式原型 会指向 object 的原型嘛 也就是原型链的尽头了
-
那么查到的时候就是看 本身有没有该属性 没有的话就继续通过隐式原型一直向上 层查找就行了
-
这里面有一些注意的点
- 函数得 prototype 属性:是在定义得时候自动添加得 默认值为 null
- 作用域链查找的时候 跟显示原型没有关系 是通过隐私原型进行查找得
- 只是在 new 实例化得时候自动添加得 this._proto = Fn.prototype 把原型得地址赋值给了 _proto 才能查找到原型
- 实例对象的隐式原型指向构造函数的显示原型
-
另一个 就可以说一下这个函数的原型和原型链的关系
-
new 出来的函数实例 他也是有 隐式原型的
-
然后所有的函数隐式原型都是一样的 因为都是通过 new Function 得到的
-
function Foo() {} 等效于 var Foo = new Function() 函数对象就是大写 Function 实例
-
一个很有意思的点 就是构造函数的显示原型和 他的隐式原型指向的是同一个对象
-
说明什么呢 说明他他是 new 自己创建的
-
特殊的 Function = new Function() 普通的 var Foo = new Function() -
-
-
不是说那个 函数的显示原型会默认指向一个 空的 Object 实例对象嘛 (但是 Object 是不满足的)
- 1
-
所有函数都是 function 的实例(包含 Function )
-
Function._proto === Function.prototype
-
-
最后一点 就是 他为什么要这么设计
-
数据封装
-
构造函数
- new this constructor
-
prototype
-
-
instanceof
- 左边元素是否为 右边的 实例
- A(实例对象) instanceof B(构造函数)
- B 的显示原型对象在 A 对象的隐式原型链上 返回 true
-
原型链继承
- 子类的原型 绑定到父类的实例上 就形成了原型链
-
组合继承
- 原型链 + 构造函数继承
- 利用原型链
函数
- 函数对象是 函数实例
-
function Foo() {} 等效于 var Foo = new Function() 函数对象就是大写 Function 实例 所以 Foo 其实是函数实例 那么他也有 隐式原型属性 - 所有函数得隐式原型都是一样得 都指向他的显示原型 因为 他都是 通过 new Function 构造得
\