您的位置:首页 > Web前端 > JavaScript

原型(3) JavaScript原型链详细介绍

2016-04-14 22:53 441 查看
同事问了一个关于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 ( ) { } ;   
                var f1 = new Fn1( ) ;   //这个新的f1 对象就会自动的链接到 Fn1.prototype 。
        constructor (构造器的意思) 这个属性是每一个对象都可以访问到的,constructor 属性描述的是其构造函数。
比如:  function Fn( ) { } 
                var o= new Fn( ) ;  
                console.log( o.constructor ===  Fn )  结果为true ;  
        原型对象概念是站在对象的角度来说的,即对象.__proto__  就是指向原型对象。
        原型属性概念是站在函数的角度来说的,即函数.prototype  就是指向原型属性。 本质上这两者指向的是同一个存储区 ,只是站在不同角度,说法不一样。
        有了这些概念,还差一个继承。继承,说白了,就是拿来主义,自己没有,把别人的东西拿过来,成为自己的。另外还有一个结论,对象继承自原型对象:对象没有的成员, 可以由原型对象提供。
还有一个推出的结论:原型对象也是对象,它也有原型对象的原型对象, 对象的原型对象一直往上找, 会找到一个Object.prototype ,再往上就是null 。 
有了这些,假设我定义一个  function Fn(){ }  
                                            var f1 = new Fn(); 
由这两行代码就要想到下面简化的原型链:
f1 -> Fn.prototype -> Object.prototype -> null 再比如:var o = new Object();  则它的原型链就是 o -> Object.prototype -> null  
下面我将通过画图的形式进行展示链结构: 
假设我定义一个:         function Fn(){ }    // 构造函数
                                     var f1 = new Fn();   // 对象



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



二、
弄看明白上面的两个原型链后,当new出新的对象时,同理就能画出类似这种的原型链,基于此,我们就要开始讨论另一个问题:函数也是对象、以及任何函数都是Function 的实例。那这些又该如何画呢?
开始之前先总结一下基本结论:
1、        对象都有原型对象, 对象默认继承自原型对象。
2、        函数被定义后, 默认就有原型属性, 原型属性也是对象。
3、        函数的原型属性默认继承自 Object.prototype。
4、        原型对象中 constructor 指向对应的构造函数。
5、        所有的函数都是 Function 的实例。
6、        函数也是对象。

基本的概念:
        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
由此,就可等到下面的两幅图:





                                                                                                             
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  原型 js