JS的原型和原型链

2019-12-06  本文已影响0人  饥人谷_小霾

原型/共用属性

所有对象都有 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
}

根据下面内存图分析原型

image.png

图中红色的箭头所连成的线,就组成了一条原型链

//对象的__proto__指向Object对象的prototype
obj.__proto__ === Object.prototype


//数值的__proto__指向Number对象的共用属性
n1.__proto__ === Number.prototype;

//Number对象的共用属性的__proto__指向Object对象的共用属性。
n1.__proto__.__proto__ === Object.prototype;

其他对象也可以得出类似的等式

__proto__ 与 prototype

image

当我们写了一句代码var s = new String(' hello ') 以后:

image

我们创建的对象的__proto__ 会用来指向原有的String对象,使得我们可以调用String对象的公有属性。

总结:

一些烧脑的等式

通过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__互相引用。

image.png

注:
Object.__proto__ === Function.prototype,因为 Function 是 Object 的构造函数。

上一篇 下一篇

猜你喜欢

热点阅读