JavaScript之原型链(一)

就JavaScript的语言和对象系统的实现来讲,对象(Object Instance)并没有原型,而构造器(Constructor)有原型。对象只有“构造自某个原型”的问题,并不存在“持有(或拥有)某个原型”的问题。“原型也是对象实例”是一个最关键的性质,这是它与“类继承体系”在本质上的不同。——《JavaScript语言精粹与编程实践》

翻了好几本书,其中就有周爱民老师的《JavaScript语言精粹与编程实践》。看过一些章节之后感叹真是难得的佳作,可惜最近事情不少,还没能静下心来细细体会全部吃透,但总算有所心得,不管对错先记下来日后有机会再修改。

一、原型复制与原型链

先来个看图说话(说话内容摘自上述《JavaScript语言精粹与编程实践》):

原型复制

原型链的最上层是一个空的Object对象实例,通过构造器生成的对象实例obj1和obj2其实分别就是一个指向构造出他们的原型的引用。图中原型和obj2又分别有各自的属性。对象属性的查找就是遍历该对象的原型链,直到原型为空或找到改属性。

二、原型链

JavaScript被作为一种扩展语言而设计,需要在内建对象的宿主环境中运行。JavaScript从宿主环境获取的对象树就被称为宿主对象,宿主对象的根节点就是全局对象。通过使用全局对象,可以访问所有其他预定义的对象、函数和属性。全局对象不是任何对象的属性,所以它没有名称。全局对象只是一个对象而不是类,既没有构造函数,也无法实例化一个新的全局对象。

预定义对象中有两个比较重要:Object对象和Function对象。JavaScript的普通对象(new Object()创建的实例)是Object对象的实例,JavaScript的函数是Function对象的对象实例。如果用原型继承的相关术语来解释,即JavaScript中的普通对象的原型对象是Object.prototype,JavaScript中的函数的原型对象是Function.prototype。当然,Function.prototype与一个普通对象并没有本质区别。还有,当一个函数的prototype有意义之后,这个函数就摇身一变成了一个“构造器”。

OK,接下来通过分析一段简单的代码来搞清楚原型链到底是什么东东。

1、全局对象与函数

首先是如下一段函数声明与赋值:

var Language = function (name) {
    this.name = name;
};

该代码运行后,JavaScript的内部环境应该如下图所示:

图示1

上图中需要说明的是,每个构造器都会有一个prototype属性指向构造器的原型,每个对象实例都会有一个constructor属性指向它的构造器,以此形成原型链的链状结构。接下来用在上一篇博客中搭好的编译环境验证一下上图的准确性:

图示2

2、对象的属性

上一小节中的Language是在全局上下文中定义的变量,所以,由之前的图中可以看出,Language成为了全局对象的一个属性。其实Language也有prototype,因为Language可以成为其他对象的构造器。Language的prototype是Object对象实例。

接下来在上一小节的代码之后增加一行:

var Language = function (name) {
    this.name = name;
};

Language.prototype.a ='aaa';

代码运行后JavaScript的内部环境如下图所示:

图示3

接下来是验证:

图示4

可以看到运行本小节追加的赋值语句之后,Language.prototype多了一个a属性。

3、对象的属性与原型链

继续追加代码:

var Language = function (name) {
    this.name = name;
};

Language.prototype.a ='aaa';

var lan1 = new Language('JavaScript');

代码运行后JavaScript的内部环境如下图所示:

图示5

接下来是验证:

图示6

上图中通过方法hasOwnProperty()可以知道某属性是否是对象自身的属性。可以看出a不是lan1自身的属性,因为它是lan1的原型的属性。但是在遍历lan1属性的for循环中,a也出现在了遍历结果之中,这正是“如果在对象中没有指定属性,则尝试遍历对象的整个原型链,直到原型为空或找到该属性”规则的体现。

三、未待续完

关于JavaScript的原型链,写到这里并未结束。下回再继续研究下所谓的“内部原型链”。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值