Effective JavaScript Item 36 实例状态仅仅保存在实例对象上
本系列作为EffectiveJavaScript的读书笔记。
一个类型的prototype和该类型的实例之间是”一对多“的关系。那么,须要确保实例相关的数据不会被错误地保存在prototype之上。
比方,对于一个实现了树结构的类型而言,将它的子节点保存在该类型的prototype上就是不对的:
function Tree(x) {
this.value = x;
}
Tree.prototype = {
children: [], // should be instance state!
addChild: function(x) {
this.children.push(x);
}
};
var left = new Tree(2);
left.addChild(1);
left.addChild(3);
var right = new Tree(6);
right.addChild(5);
right.addChild(7);
var top = new Tree(4);
top.addChild(left);
top.addChild(right);
top.children; // [1, 3, 5, 7, left, right]
当状态被保存到了prototype上时。全部实例的状态都会被集中地保存,在上面这样的场景中显然是不对的:本来属于每一个实例的状态被错误地共享了。例如以下图所看到的:
正确的实现应该是这种:
function Tree(x) {
this.value = x;
this.children = []; // instance state
}
Tree.prototype = {
addChild: function(x) {
this.children.push(x);
}
};
此时,实例状态的存储例如以下所看到的:
可见。当本属于实例的状态被共享到prototype上时,或许会产生问题。在须要在prototype上保存状态属性前。一定要确保该属性是可以被共享的。
整体而言,当一个属性是不可变(无状态)的属性时,就能将它保存在prototype对象上(比方方法可以被保存在prototype对象上就是由于这一点)。当然,有状态的属性也可以被放在prototype对象上,这要取决于详细的应用场景,典型的比方用来记录一个类型实例数量的变量。
使用Java语言作为类比的话,这类可以存储在prototype对象上的变量就是Java中的类变量(使用statickeyword修饰)。
总结:
- 当在prototype对象上存放可变数据时,可能会带来问题。
- 普通情况下,每一个实例特有的可变属性须要被存放在实例本身上。
Effective JavaScript Item 36 实例状态仅仅保存在实例对象上的更多相关文章
- Effective JavaScript Item 35 使用闭包来保存私有数据
本系列作为EffectiveJavaScript的读书笔记. JavaScript的对象系统从其语法上而言并不鼓舞使用信息隐藏(Information Hiding).由于当使用诸如this.name ...
- [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法
前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...
- Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复
效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- Effective JavaScript Item 34 在prototype上保存方法
本系列作为EffectiveJavaScript的读书笔记. 不使用prototype进行JavaScript的编码是全然可行的,比如: function User(name, passwordHas ...
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...
- Effective JavaScript Item 51 在类数组对象上重用数组方法
Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...
随机推荐
- Linux07--Shell程序设计03 通配符与正则表达式
通配符 通配符可用于代替字符. 通常地,星号“*”匹配0个或以上的字符,问号“?”匹配1个字符. 使用情况: 1.文件和目录 在CP/M.DOS.Microsoft Windows和类Unix操作系统 ...
- Delphi下重载窗体CreateParams翻转关闭按钮
type TForm1 = class(TForm) private { Private declarations } public { Public declarations } ...
- Unix/Linux环境C编程入门教程(18) kali-linuxCCPP开发环境搭建
1. Kali linux是BT5的晋级版本,用于信息安全.基于Debian7内核.新建虚拟机. 2. 选择默认虚拟机 3. 选择稍后安装操作系统 4.选择Linux Debian7 64位,因为Ka ...
- MPAndroidChart绘制图形表
最近一个项目需要用到表格进行统计显示,本来用的是的achartengine,后来发现一个更加强大的开源框架MPAndroidChart. 下面简单介绍下MPAndroidChart,MPAndroid ...
- 此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行
错误提示:此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行.若要将此服务器连接到服务器场,请使用 SharePoint 产品配置向导,该向导可从 ...
- 无法加载协定为“XXXWebServiceSoap”的终结点配置部分,因为找到了该协定的多个终结点配置
错误描述:无法加载协定为“XXXWebServiceSoap”的终结点配置部分,因为找到了该协定的多个终结点配置.请按名称指示首选的终结点配置部分. 错误原因:该webservce在web.confi ...
- vs2010快捷方式
[窗口快捷键] Ctrl+W,W: 浏览器窗口 Ctrl+W,S: 解决方案管理器 Ctrl+W,C: 类视图 Ctrl+W,E: 错误列表 Ctrl+W,O: 输出视图 trl+W,P: ...
- poj 1149 pigs ---- 最大流
题意以及分析:http://ycool.com/post/zhhrrm6#rule3 主要是建图,简化图,然后在套最大流的模板. #include <iostream> #include& ...
- MySQL管理一些基础SQL语句
.进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; .查询所有数据的大小: ),),'MB') as data from i ...
- Mysql中文乱码问题完美解决方案[转]
原文地址 MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如还停留在latin12.table的语系设定问题(包含character与collation)3.客户端程式( ...