原型/共用属性
所有对象都有 toString 和 valueOf 属性,那么我们是否有必要给每个对象一个 toString 和 valueOf 呢?答案是不需要的。因为JS每次声明一个对象都要写一次这些方法这样写的话会非常占用内存,而且内存还那么贵,所以JS 的做法是把所有的对象共用的属性全部放在heap堆内存的一个对象(共用属性组成的对象),然后让每一个对象的 __proto__
存储这个「共用属性组成的对象」的地址。而这个共用属性,就是传说中的原型
原型的目的:可以减少不必要的内存浪费
如:
var s1 = new String('hi');
var s2 = new String('he');
var n1 = new Number(1);
var n2 = new Number(2);
var b1 = new Boolean(true);
var b2 = new Boolean(false);
var o1 = {
name: 'xiao',
age: 6
}
var o2 = {
name: 'ming',
age: 18
}
根据下面内存图分析原型
![](https://img.haomeiwen.com/i3237223/3088e1861079017d.png)
图中红色的箭头所连成的线,就组成了一条原型链。
-
__proto__
就是这些共用属性的引用。 - 声明Number对象、String对象、Boolean对象时,如声明Number对象,在stack栈内存中存储着该对象的内存地址,对象的内容存储在heap堆内存中。对象的内容里面有
__proto__
,它指向的Number的共用属性(Number.prototype)。
某些等式:
//对象的__proto__指向Object对象的prototype
obj.__proto__ === Object.prototype
//数值的__proto__指向Number对象的共用属性
n1.__proto__ === Number.prototype;
//Number对象的共用属性的__proto__指向Object对象的共用属性。
n1.__proto__.__proto__ === Object.prototype;
其他对象也可以得出类似的等式
__proto__
与 prototype
![](https://img.haomeiwen.com/i11616333/2a4e4a828437a102.png)
当我们写了一句代码var s = new String(' hello ')
以后:
![](https://img.haomeiwen.com/i11616333/3bc16aa4edcdb750.png)
我们创建的对象的__proto__
会用来指向原有的String对象,使得我们可以调用String对象的公有属性。
总结:
-
__proto__
是某对象的共用属性的引用,是为了用户使用其共用属性中的方法而存在的 。(使用的) -
prototype
是浏览器写的,本身就存在,是某对象的共同属性的引用,为了不让对象的共用属性因没有被调用而被垃圾回收而存在。(防止回收)
一些烧脑的等式
通过var 对象 = new 函数;推出其他烧脑的等式
var n = new Number(1);
//var 对象 = new 函数;
//对象的__proto__最终指向某对象的共用属性,构造某对象的函数的prototype也指向某对象的共用属性
//__proto__ 是对象的属性,prototype是函数的属性
对象.__proto__ === 函数.prototype
//函数的prototype是对象,这个对象对应的就是最简单的函数Object
函数.prototype.__proto__ === Object.prototype
//由于函数本身即是函数(最优先被视为函数),也是对象,而函数的构造函数是Function
函数.__proto__ === Function.prototype
//Function即是对象,也是函数,但他优先是个函数
Function.__proto__ === Function.prototype
//Function.prototype也是对象,是普通的对象,所以其对应的函数是Object
Funciton.prototype.__proto__=== Object.prototype
奇葩的Function
我们经过上面的推导,发现Function,他即是函数,也是对象,所以他有函数的prototype,也有对象的__proto__
,即Function.prototype 与Funciton.__proto__
互相引用。
![](https://img.haomeiwen.com/i3237223/e632777eedcad4a7.png)
注:
Object.__proto__ === Function.prototype
,因为 Function 是 Object 的构造函数。
网友评论