JavaScript原型链的理解

一、原型链的概念

JavaScript是一门面向对象的编程语言,JavaScript 中的所有事物都是对象,并且对象与对象之间不是彼此独立的,而是有“继承”关系的。

这种“继承”关系与Java或者C#中的继承不同。Java或C#中是有类的概念的,子类继承父类,通过extends关键字实现;而JavaScript中没有真正意义上的class(类),但有与之类似的概念——原型对象;A继承B,则A的“__proto__”属性会指向B的“prototype”属性,从而有以下示意图:

A与B的关系为: A.__proto__   ---------->   B.prototype  , 这句话的意思就是,A的原型(__proto__) 指向 B的原型对象(prototype)。

从A继承B的示意图中,我们看到一条具有指向关系的链,那么这是不是就是今天的主题——原型链 呢?答案是:不是

原型链要求末尾节点为null,B.prototype 不等于null,谁的原型会为null呢?答案是:Object对象的原型对象——Object.prototype,所以有以下示意图:

 

所以,我把原型链的定义概括为:一群具有继承关系的对象,通过__proto__属性建立指向关系,并最终指向null,从而形成一条指向关系链,我们称之为原型链。

二、为什么会有这样的指向关系

现在,虽然知道了什么是原型链,但是为什么是这样的指向关系,形成这样的一条链,下面我们继续来探讨:

首先,了解概念:

①、对象的分类    如上文所说,JavaScript中所有的事物都是对象,而这些对象,可以分为两大类:函数对象普通对象。分类的依据是:是否具有原型对象(prototype),或者是否具有prototype属性。函数对象具有prototype属性,而普通对象没有;

②、prototype    原型对象,对象中的所有属性和方法,将继承给子对象,由子对象们共享;

③、__proto__    原型。任何由继承而来的对象,都有且仅有一个原型,并且由其__proto__属性指明。

由于JavaScript中一切皆对象,并且这些对象最终都继承自Object对象,所以在原型链中末尾的两个节点,一定是Object.prototype和null。

三、对象

前文中,我们无数次提到了一个概念,那就是对象,什么是对象?对象即属性和方法的集合,最典型的

var obj = {
        name: 'hjx',
        age: 24,
        sayHello: function() {
            console.log('Hello!');
        }
}

obj既为一个对象,此对象有属性name,age,有方法sayHello()。仅以“属性和方法的集合”这几个字的解释,我们还很难理解JavaScript中的继承关系和原理,所以,引入一下概念:

、隐式属性   由__proto__属性指向的属性和方法。

、显示属性    非__proto__属性指向的属性和方法,显示属性分为共享属性和非共享属性

③、共享属性    继承给子对象,由子对象共享的属性和方法。(共享:所有子对象的公共资源,一旦改变,所有子对象访问时均已改变。本质上是在继承的时候,所有子对象的__proto__属性指向它,在内存中此属性仅此一份,子对象和父对象均可去读写)

④、非共享属性(本地属性)    继承给子对象时,由子对象单独享有的属性和方法,也成为本地属性。(单独享有:继承时,在每个子对象的内存空间中都复制了一份,在子对象中各自独立)

用一个等式来表达对象: 对象  =  显示属性(共享属性 + 本地属性) + 隐式属性

四、关系图

关系图总结:

①、子对象的__proto__属性指向父对象的prototype属性(子对象的原型指向父对象的原型对象);

②、Object对象的__proto__属性指向Function对象的prototype属性(Object对象的原型指向Function对象的原型对象);

③、Function对象的__proto__属性指向自己的prototype属性(Function对象的原型指向自己的原型对象);

④、Function对象的prototype属性的__proto__属性指向Object的prototype属性(Function对象的原型对象的原型指向Object对象的原型对象,因为,Function对象的原型对象是一个对象,由Object对象继承而来)

⑤、Object对象的prototype属性的__proto__属性指向null(Object对象的原型对象的原型指向null,因为,一切对象的原型最终都指向Object对象的原型对象,然而Object对象的原型对象又是一个对象,JavaScript规定它指向null,所以Object对象的原型对象Object.prototype总是在原型链上,除null意外的顶端位置)

完~

猜你喜欢

转载自www.cnblogs.com/hjx-blog/p/9188526.html