Js对象之原型链详解

在刚开始接触js的时候,一直对js中的原型链一知半解,只知道对象的最顶层是Object。Array,Number等类是Object原型链下的子类。下面将以Function对象为例子来说。在使用类的一些公共方法 | 属性 的时候,会使用Funciton.方法名|属性名来进行调用,如果在函数的原型上自定义了一些方法,后期在实例化的对象中可以随便调用定义在Function原型上的方法。而且实例化的对象不但可以调用Function原型上的方法,也可以调用Object原型上对应方法。

其实上面一段话已经js的原型链概念和优点讲述出来了。下面我们就按照上面这段话的逻辑,将js中的原型链剖析一下。包括用户经常会迷惑的prototype和__proto__的关联和区别。

1,原型链的延伸。

在原型链的上述延伸中,我们所使用最多的就是Number,String,Array前面这几个类。

2,以Function为例,是因为Function这个比较特殊。而且函数js的实际操作中又三种角色。在下面的三种角色中,类的操作就是上面最开始那段话讲述的操作。

(1)普通函数:在作为普通函数的操作中,涉及到堆栈内存释放,变量提升和作用域链的操作。

在使用function来创建函数的时候,会将在堆内存中申请一处空间,用来存储函数体内的代码,并将堆内存的地址返回给函数名方便后期调用地址,来拿取函数体的操作字符串。在代码自上而下运行到函数的时候,函数会将字符串取出,在当前的栈内存中,重新开辟一个私有的栈内存并在栈内存中运行当前代码:运行顺序---->形参赋值-------->变量提升---------->再自上而下运行代码,返回函数的返回值。当前栈内存在代码运行结束后,自动销毁。

(2)普通对象操作:在作为一个普通对象的操作的时候,和正常的obj没什么区别,只用key-value形式来操作。

(3)类:在类的实际操作用,会涉及到原型(prototype)和原型链(__proto__)操作。

在讲述原型操作的时候,应用别人一句非常经典的话。1.每个对象都具有一个名为__proto__的属性;2.每个构造函数(构造函数标准为大写开头,如Function(),Object()等等JS中自带的构造函数,以及自己创建的)都具有一个名为prototype的方法(注意:既然是方法,那么就是一个对象(JS中函数同样是对象),所以prototype同样带有__proto__属性);3.每个对象的__proto__属性指向自身构造函数的prototype;

上面就是大概原型链的指向了,下面附上我一张手绘图,反正我是理解了,如果有不理解的可以私聊

在js中万物皆对象,1.所有的函数数据类型都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存。2.在浏览器给prototype开辟的堆内存中有一个天生自带的属性:constructor,这个属性存储的值是当前函数本身。3.每一个对象都有一个__proto__的属性,这个属性指向当前实例所属类的prototype(如果不能确定它是谁的实例,都是Object的实例)所以以Function为例:Function.prototype有一个__proto__,Function也有一个__proto__属性,但是两者的属性是不同的。

Function.__proto__ ----> Function.prototype

Function.prototype.__proto__ ------> Object.prototype

Object.prototype.__proto__ -----> null

注意一下:Object也是有__proto__属性的,而且:Object.__proto__ -----> Function.prototype

猜你喜欢

转载自blog.csdn.net/swimming_in_IT_/article/details/88416189