JavaScript原型链详细介绍 - Go语言中文社区

JavaScript原型链详细介绍


同事问了一个关于JavaScript 原型链、以及继承的本质的问题,探讨一番,决定将其写下来,为后人学习提供便利。要想搞清楚JavaScript 的原型链,就必须先搞定对象、原型对象、原型属性、构造函数、以及Function()  的概念。下面,我来一一讲解:

一、

开始之前先弄明白js中的 值类型 和引用类型。 值类型,存储的是数据本身,一些简单的数据,就是值类型,如number、string、boolean ,定义一个: var a=1; 就是值类型;而引用类型表示存在在某个存储区域的引用(像c 语言中的指针,不过js 是不能对地址进行操作的,所以一般都用引用一词来表示),引用指向数据的存储区域,像函数、对象、数组都是引用类型,比如 var arr=[1,2,3]  ,这个arr 就是引用类型 ,它存的就是[1,2,3] 的引用(指向) 。

讲白了就是引用类型的数据, 有两个存储区域, 一个存储数据本身, 一个变量存储引用。

下图就是对上面两个例子的解释:

                 

         接下来要讲明白__proto__、prototype、constructor  这三个属性。

         __proto__是站在对象的角度来说的,任何对象都有这个__proto__属性(结论),并且要声明的是,这个属性是非标准属性,还没写入ES标准中,不过目前火狐和谷歌浏览器已经开始支持。

         Prototype是站在构造函数的角度来说的, 凡是函数就有属性prototype 这是标准属性,由某一个函数new出来的对象,都会自动链接到该函数的prototype上。

比如:       var Fn1 = function ( ) { };  

                   varf1 = new Fn1( ) ;   //这个新的f1 对象就会自动的链接到 Fn1.prototype。

         constructor(构造器的意思)这个属性是每一个对象都可以访问到的,constructor 属性描述的是其构造函数。

比如:      function Fn( ) { }

                   varo= new Fn( ) ; 

                   console.log(o.constructor ===  Fn )  结果为true ; 

         原型对象概念是站在对象的角度来说的,即对象.__proto__  就是指向原型对象。

       原型属性概念是站在函数的角度来说的,即函数.prototype  就是指向原型属性。 本质上这两者指向的是同一个存储区 ,只是站在不同角度,说法不一样。

         有了这些概念,还差一个继承。继承,说白了,就是拿来主义,自己没有,把别人的东西拿过来,成为自己的。另外还有一个结论,对象继承自原型对象:对象没有的成员, 可以由原型对象提供。

还有一个推出的结论:原型对象也是对象,它也有原型对象的原型对象, 对象的原型对象一直往上找, 会找到一个Object.prototype ,再往上就是null 。

有了这些,假设我定义一个       function Fn(){ } 

                                                        varf1 = new Fn();

由这两行代码就要想到下面简化的原型链:

f1 -> Fn.prototype ->Object.prototype -> null 再比如:var o = new Object();  则它的原型链就是 o-> Object.prototype -> null 

下面我将通过画图的形式进行展示链结构:

假设我定义一个:                        function Fn(){ }    // 构造函数

                                                        varf1 = new Fn();   // 对象



图 1 是详细的画法,注意属性的箭头,红色就是原型链,下图是其他书本中常见的简式画法:



二、

弄看明白上面的两个原型链后,当new出新的对象时,同理就能画出类似这种的原型链,基于此,我们就要开始讨论另一个问题:函数也是对象、以及任何函数都是Function 的实例。那这些又该如何画呢?

开始之前先总结一下基本结论:

1、  对象都有原型对象, 对象默认继承自原型对象。

2、  函数被定义后, 默认就有原型属性, 原型属性也是对象。

3、  函数的原型属性默认继承自Object.prototype。

4、  原型对象中constructor 指向对应的构造函数。

5、  所有的函数都是Function 的实例。

6、  函数也是对象。


参考链接:

 http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html



基本的概念:

         prototype是函数的原型属性, 是该函数创建的对象的原型对象

         __proto__是对象的原型对象, 是创建该对象的构造函数的原型属性

 

由上面的基本结论和基本概念,推出:

         默认函数的原型属性继承自Object.prototype

         Function是函数, Function.prototype 是函数的原型属性

         Function.prototype继承自 Object.prototype

根据结论: Function, 和 函数, 和Function.prototype 之间的关系, 可以得到

         Array是 Function 的实例, 继承自 Fucntion.prototype

         Date是 Function 的实例, 继承自 Fucntion.prototype

         Object是 Function 的实例, 继承自 Fucntion.prototype

         Fucntion是 Function 的实例, 继承自 Fucntion.prototype

         结论Function.__proto__ 就是 Function.prototype

由此,就可等到下面的两幅图:



 


 

 

 

                                                                                                                                                                                                                                      By  Tuobo   beijing

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u010427666/article/details/51046118
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 22:08:19
  • 阅读 ( 1156 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢