本系列作为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修饰)。

总结:

  1. 当在prototype对象上存放可变数据时,可能会带来问题。

  2. 普通情况下,每一个实例特有的可变属性须要被存放在实例本身上。

Effective JavaScript Item 36 实例状态仅仅保存在实例对象上的更多相关文章

  1. Effective JavaScript Item 35 使用闭包来保存私有数据

    本系列作为EffectiveJavaScript的读书笔记. JavaScript的对象系统从其语法上而言并不鼓舞使用信息隐藏(Information Hiding).由于当使用诸如this.name ...

  2. [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法

    前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...

  3. Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复

    效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...

  4. Effective JavaScript Item 34 在prototype上保存方法

    本系列作为EffectiveJavaScript的读书笔记. 不使用prototype进行JavaScript的编码是全然可行的,比如: function User(name, passwordHas ...

  5. Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数

    作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...

  6. Effective JavaScript Item 37 认识this的隐式指向

    本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...

  7. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  8. Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合

    本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...

  9. Effective JavaScript Item 51 在类数组对象上重用数组方法

    Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...

随机推荐

  1. JavaMail回复

    JavaMail邮件回复 http://blog.csdn.net/o_darling/article/details/17558049 http://blog.csdn.net/xiyang_199 ...

  2. LED发光二极管

    半导体发光器件包括半导体发光二极管(简称LED).数码管.符号管.米字管及点阵式显示屏(简称矩阵管)等.事实上,数码管.符号管.米字管及矩阵管中的每个发光单元都是一个发光二极管. 一. 半导体发光二极 ...

  3. ASP 代码当前记录集不支持更新问题的解决办法。

    错误类型: ADODB.Recordset (0x800A0CB3) 当前记录集不支持更新.这可能是提供程序的限制,也可能是选定锁定类型的限制. /Model/manage/Admin_Admin.a ...

  4. Java - 字符串和Unicode互转 - 解析小米pm.min.js

    小米JS地址: http://p.www.xiaomi.com/zt/20130313/huodong/pm.min.js 上面这个JS是小米抢手机页面的代码.和抢手机有直接关联.. 虽然我3次都没抢 ...

  5. 大数据为什么要选择Spark

    大数据为什么要选择Spark Spark是一个基于内存计算的开源集群计算系统,目的是更快速的进行数据分析. Spark由加州伯克利大学AMP实验室Matei为主的小团队使用Scala开发开发,其核心部 ...

  6. Codeforces 325D

    #include <cstdio> #include <algorithm> #include <cstring> #include <cstdlib> ...

  7. 探究adroid活动

    Intent用处 隐式使用intent,在被启动的activity的manifest文件配置该活动 在出发活动建立intent时就写好和 网页浏览器用new intent 时用Intent.ACTIO ...

  8. jquery Ztree v3.5 实例2 自定义显示在节点前的图片

    显示效果如下: 代码如下: <html> <head><title></title></head> <script type=&quo ...

  9. 【玩转Ubuntu】01. Ubuntu上配置JDK

    一.安装JDK 提示:这里我们使用jdk1.6,因为android开发要求使用1.6.如果不信你可以打开android studio,它会提示你选择JDK6的路径 下载地址: http://www.o ...

  10. linux下的进程、网络、性能监控命令

    进程监控 端口   1)netstat -anp | grep xxx   2)lsof  -i:<port> 句柄    lsof  -n | grep xxxx 线程栈   1)gst ...