本系列作为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. eclipse中调出android sdk manager和android virtual device manager图标

    有时候在安装ADT插件后,eclipse菜单栏上不会显示android sdk manager和android virtual device manager两个图标, 这个时候,如果安装ADT插件的步 ...

  2. Mirantis Fuel fundations

    Mirantis Nailgun is the most important service a RESTful application written in Python that contains ...

  3. Java DES 加密和解密源码(转)

    原文地址:http://www.oschina.net/code/snippet_727646_18383 Java密码学结构设计遵循两个原则: 1) 算法的独立性和可靠性. 2) 实现的独立性和相互 ...

  4. HDOJ1166 敌兵布阵

    赤裸裸的线段树,借个模板,改写一下即可. 代码: #include<iostream> #include<cstdio> #include<stdio.h> #in ...

  5. 用代码场景Spine人物

    在使用Spine动画的时候可能会需要用代码创建,所以就小小的研究了一下 /// <summary> /// 加载一个spine的骨骼动画 /// </summary> /// ...

  6. Mongo散记--聚合(aggregation)&amp; 查询(Query)

    mongo官网:http://www.mongodb.org/ 工作中使用到Mongo,可是没有系统的学习研究过Mongo,仅对工作过程中,在Mongo的使用过程中的一些知识点做一下记录,并随时补充, ...

  7. globalCompositeOperation 学习

    globalCompositeOperation globalCompositeOperation即Canvas中的合成操作. 1.source-over 这是默认值,他表示绘制的图形将画在现有画布之 ...

  8. css黑魔法

    多行文本溢出显示省略号(...)的方法 p { overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-li ...

  9. 解压tomcat后一闪而过的问题

    解压tomcat压缩包后,直接点击startup会出现一闪而过. 免安装的tomcat双击startup.bat后,启动窗口一闪而过,而且tomcat服务未启动. 原因是:在启动tomcat是,需要读 ...

  10. lightoj 1030

    递推,倒着递推. #include<stdio.h> #define maxn 1010 #define min(a,b) (a)>(b)?(b):(a) int main() { ...