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

JavaScript原型链详细介绍

2016-04-02 23:25 411 查看
同事问了一个关于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、 函数也是对象。

基本的概念:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: