JavaScript 原型继承开端
1.原型继承本质
就javascript对象系统的实现来讲,对象并没有原型,而构造器有原型(构造器.prototype指向其原型)。对象只有构造自某个原型的说法,并没有持有某个原型的说法。原型其实也是一个对象实例。原型的含义是指:如果构造器有一个原型对象A,则由该构造器创建的实例都必然复制自A。
2.空的对象是所有对象的基础
来看看以下代码:
<html>
<head>
<meta http-equiv="content-type" charset="utf-8"/>
<script type="text/javascript">
var proto = Object.prototype; var count = 0;
for(var n in proto)
{
count++;
}
alert(count);//return 0;
</script>
</head>
<body>
</body>
</html>
由上边代码我们知道Object()构造器的原型就是一个空的对象。下边的两行代码无非就是从Object.prototype复制出的一个映像,也是空的对象
obj1 = new Object();
obj2 = {};
构建过程可以简单理解为”复制”

图 2.1 对象构建
3.构造复制---写复制---读遍历
由图 2.1可以看出,每构造出一个实例,都需要从原型中复制出一个相应的实例出来,但这种构造复制会产生一个问题:内存空间的急剧消耗。
因此我们的另一个策略就是写时复制,先看下图:

图 3.1 写时复制
在系统中只要将obj1和obj2的引用指向对象的原型,这样在读取的时候顺着引用读取即可。只有当需要修改对象obj1或obj2的属性时才复制一个映像出来,以后就操作该映像。写时复制的优点是只在第一次写的时候用一些代码来分配内存,带来一些代码和内存上的开销,以后就没有这种开销了。但如果需要经常写操作,则这种方式与上一种没有什么区别。
第三种策略就是把写复制的粒度再次变小,从原型变成成员,仅当写某个实例的成员时,将成员信息复制到实例映像中。

图 3.2 成员复制
我们发现obj2仍旧指向原型,在写操作时也没有与原型相同大小的实例被创建出来,不会导致大量的内存分配,因此在内存使用上更加经济。但obj2需要维护一张成员列表,列表中存放修改了的成员,列表中的成员是否与原型中的成员是否一致并不重要,只需要遵循两条规则。
1)保证读取时先被访问到。我们访问obj2.value时,得到10.但对于obj1.value,这时读遍历规则就起作用了:
2)如果对象中没有指定属性,则会尝试遍历对象的整个原型链,知道找到該值或者为空。
假设原型也持有一张成员列表,如下:

图 3.3 读遍历
那么,obj2.value为10,而obj1.value自然为’abc’。我们也发现原型带来的另外一个效果:obj1.value与obj2.value的类型并不相同。如果原型链上没有维护value这个成员,那么obj1.vlaue的值就是undefined。
ps:从上图可以看到存取实例中的属性比存取原型中的属性效率要高,即obj2.value比obj1.value少一个指针访问....
JavaScript 原型继承开端的更多相关文章
- 再谈javascript原型继承
Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...
- 彻底理解Javascript原型继承
彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...
- [转]Javascript原型继承
真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...
- JavaScript原型继承工作原理
原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...
- 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象
JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...
- 浅析Javascript原型继承(转)
引自: http://blog.csdn.net/kittyjie/article/details/4380918 原作者解释的浅显易懂,非常不错的JavaScript prototype总结 JS没 ...
- Javascript原型继承容易忽略的错误
编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...
- javascript原型继承圣杯模式
javascript纯面向对象开发需要使用到的一个模式,来对对象之间原型继承做中间层代理避免重复继承与代码杂乱 <!DOCTYPE html> <html lang="en ...
- javascript原型继承
在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由 ...
随机推荐
- 中国海洋大学第四届朗讯杯高级组 A 2718 Rocky(模拟)
题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2718 题意:优先直走,右 左 后.... ...
- poj 3126 Prime Path( bfs + 素数)
题目:http://poj.org/problem?id=3126 题意:给定两个四位数,求从前一个数变到后一个数最少需要几步,改变的原则是每次只能改变某一位上的一个数,而且每次改变得到的必须是一个素 ...
- UVa 201 Squares
题意: 给出这样一个图,求一共有多少个大小不同或位置不同的正方形. 分析: 这种题一看就有思路,最开始的想法就是枚举正方形的位置,需要二重循环,枚举边长一重循环,判断是否为正方形又需要一重循环,复杂度 ...
- Ejabberd源码解析前奏--调试
一.日志文件 一个ejabberd节点写两个日志文件: ejabberd.log ejabberd 服务日志, 由 ejabberd 节点汇报的消息erlang.log Erlang/OTP 系 ...
- Entity Framework 增删改查和事务操作
1.增加对象 DbEntity db = new DbEntity(); //创建对象实体,注意,这里需要对所有属性进行赋值(除了自动增长主键外),如果不赋值,则会数据库中会被设置为NULL(注意是否 ...
- ViewPager onPageChangeListener总结
今天在做项目的时候,由于要处理viewPager页面滑动的事件,所以对其进行了一个小小的研究: 首先ViewPager在处理滑动事件的时候要用到OnPageChangeListener OnPageC ...
- [Everyday Mathematics]20150101
(1). 设 $f(x),g(x)$ 在 $[a,b]$ 上同时单调递增或单调递减, 试证: \[ (b-a)\int_a^b f(x)g(x)\mathrm{\,d}x \geq \int_a^b ...
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.3.1
Let $A=A_1\oplus A_2$. Show that (1). $W(A)$ is the convex hull of $W(A_1)$ and $W(A_2)$; i.e., the ...
- CXF之三 Tomcat中发布Web Service
服务接口及实现类请参考CXF之一 创建Maven Web项目,在pom.xml中添加CXF和spring Web的引用,由于CXFServlet需要Spring Web的支持. <project ...
- PHP 进行蜘蛛访问日志统计
$useragent = addslashes(strtolower($_SERVER['HTTP_USER_AGENT'])); if (strpos($useragent, 'googlebot' ...