首先在我们一行代码也没写的时候,在js分到的内存中,数据区内存是什么样的呢?

浏览器会有一个全局变量window,里边存的是浏览器提供给我们的属性。window有很多属性 ,上图选了三个来进行说明。图中的xxx.prototype就是原型(prototype)。__proto__是引用的原型对象的地址。
只有构造函数才有prototype属性,所有的对象都有__proto__属性。
函数也是对象,所有函数也有__proto__属性。
当我们输入以下代码的时候,在内存中发生了什么?
var n1 = new Number(1)

js会在堆内存中新建一个n1对象,并给它一些属性。n1会有一个隐藏的属性__proto__。该属性指向构造n1的函数的prototype,比如上面代码中的n1,它是由Number函数来构造的,所以n1的__proto__属性就指向了Number.prototype。
综上,当我们输入
n1.toString()
浏览器是怎么做的呢?
首先先找到n1对象,并遍历n1的key,看有没有toString,
如果发现没有,就去__proto__引用的对象(prototype)中去找。//n1.__proto__.toString
如果还没有,就去n1.__proto__.__proto__.toString中去找。//n1.__proto__.__proto__.toString
以此类推。
把上面的寻找过程中,遇到的每个对象当作一个节点,连接起来就是原型链。
最后总结一条公式
对象.__proto__ === 函数.prototype
其中函数是说构造该对象的函数。
比如:Object.__proto__ === Function.prototype

Object是一个函数,所以由Function函数构造。
再比如:fn.__proto__ === Function.prototype

fn也是一个函数,所以由Function函数构造。
再再比如:Function.__proto__ === Function.prototype

Function自己也是一个函数,所以由Function函数构造。
网友评论