在自己研究javascript各种设计模式的过程中,偶然写出的一段代码让自己理解的更深刻了,之所以称之为伪单例模式,是因为这段代码造成的结果很想单例模式,但是实际上是活动对象捣乱所造成的误会。

代码很简单是这样的:

function Person(){
var money = 0;
Person.prototype.getMoney = function (){
return money;
}
Person.prototype.addMoney = function (m){
money += m;
}
}
var a = new Person();
var b = new Person();
a.addMoney(20); console.log(a.getMoney());//打印20
console.log(b.getMoney());//打印20

这里有些同学可能会感觉很奇怪了,a和b完全是两个不同的对象,每次new的时候都会把私有变量money初始化成0,为什么a对象使用addMoney()方法后,同时b对象的money也变成20了呢?

这个时候会造成一种假象,就是通过new实例化多个对象的结果都是产生了同一个对象,仿佛就像单例模式那样。

如果你对这个结果感到疑惑就接着看下吧,如果你一眼就看到其中的原因,那你就不用在这里浪费时间咯~

我们从这个构造函数说起,这里我我使用了var来创造一个私有变量money,并在这个构造函数中提供了两个匿名函数给构造函数的原型对象的getMoney和addMoney,即通过闭包的方式来提供对money变量的访问权限,如果你把原型对象的写在外面是访问不到money这个私有变量的。

事实上恰恰因为我这个行为导致了伪单例的发生,我们接下来用图来剖析一下当我们new对象的时候,函数的活动对象发生了怎样的变化。

如果对函数的活动对象、执行环境不太理解,给个传送门http://www.docin.com/p-509501990.html,讲解的十分清楚。

当我们var a = new Person()后,情况是这样的:

实例对象a通过原型链可以调用原型对象中的两个属性指向那两个匿名函数(迷之圆圈),他们在闭包的帮助下访问活动对象一的money属性。此时money属性初始化为0。

当我们var b = new Person()后,情况变成了这样:

现在可以很清楚的看到,真正改变的是原型对象中属性所指向的匿名函数,也就是说现在实例a和实例b通过原型中的访问所访问的money变量都是位于活动对象2中的,活动对象1已经被玩坏后抛弃了。

再看下一句的a.addMoney(20)实际上就是将活动对象2中的money变成了20,这就很明白了,最后他俩getMoney访问到的都是活动对象2里面的money,自然都会返回20了。则就造成了伪单例的效果。

总结要注意的几点:

1,要达成伪单例的效果,必须将构造函数中的变量设为私有变量而不是通过this设置为实力属性,因为那样访问的就不是通过闭包了。

2,给原型对象添加在构造函数内部才能访问私有变量,不明白?还不去好好看闭包!

3,最后所有的对象访问的都是最后new时,构造函数所形成的活动对象,对此有疑问的同学可以交换一下代码执行的顺序,比如改成这样:

var a = new Person();
a.addMoney(20);//写在前面
var b = new Person(); console.log(a.getMoney());//返回0
console.log(b.getMoney());//返回0

这是很自然的,因为被你你添加的20的那个money在活动对象一中,当你创造活动对象2时,实例对象a已经移情别恋了,a和b现在都指向活动对象2了,其中money被初始化成0,不懂得同学多看看图哟。

javascript活动对象的理解——伪单例模式的更多相关文章

  1. javascript系列学习----对象相关概念理解

    1.构造函数(相对于面向对象编程语言里面的类) 2.对象实例(它是由构造函数构造出来的对象,使用到关键字 new) 3.this关键字(往往是指我们的对象本身) 下面我们来看一个实例: var Per ...

  2. JavaScript:理解执行环境、作用域链和活动对象

    作用域的原理,对JS将如何解析标识符做出了解答.而作用域的形成与执行环境和活动对象紧密相关. 我们对于JS标识符解析的判断,存在一个常见误区 首先,看一个关于JS标识符解析的问题 ,源于风雪之隅提出的 ...

  3. 自己理解的javascript 的对象和类理解

    首先需要先理解类和对象的意义,我个人理解如下: 类:对象的抽象化: 对象:类的实体: javascript中没有class关键字和类的用法,只能用伪类来做类的,所以要用function来定义累的名字: ...

  4. javascript中函数的执行环境、作用域链、变量对象与活动对象

    javascript高级程序设计中:对执行环境.作用域链.变量对象.活动对象的解释: 1.执行环境: 执行环境:有时也叫环境:是JavaScript中最为重要的一个概念:执行环境定义了变量或函数有权访 ...

  5. 03.JavaScript 面向对象精要--理解对象

    JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...

  6. 谈谈对Javascript构造函数和原型对象的理解

    对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅..(哔!).   常用的几种对象创 ...

  7. 转载:Javascript面向对象编程原理 -- 理解对象

    源地址:http://www.html-js.com/article/1717 虽然JavaScript中已经自带了很多内建引用类型,你还是会很频繁的需要创建自己的对象.JavaScript编程的很大 ...

  8. 1--面试总结-js深入理解,对象,原型链,构造函数,执行上下文堆栈,执行上下文,变量对象,活动对象,作用域链,闭包,This

    参考一手资料:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/中文翻译版本:https://zhuanlan.zhihu.com/p ...

  9. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

随机推荐

  1. PAT-乙级-1001. 害死人不偿命的(3n+1)猜想 (15)

    1001. 害死人不偿命的(3n+1)猜想 (15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 卡拉兹(Ca ...

  2. Qt官网变更【2012】

    Qt最近被Digia完全收购,诺基亚这两年的不理不睬,没有魄力,不仅断送了他的手机霸主地位,也耽误了Qt这两年的快速发展. 希望Digia能让Qt真正实现 run everywhere. 最近Qt的官 ...

  3. ubuntu装机

    备份: .bashrc profile .vimrc exports defults/ 各种workspace中的源码 goagent/ 重转后安装: apt-get install openjdk- ...

  4. ServletContext对象

    **1 ServletContext对象   1)在web应用中,由服务器创建的唯一的一个对象是ServletContext   2)ServletContext对象在每一个Servlet中取得都是相 ...

  5. NPAPI插件开发

    1.插件是什么 插件是一种遵循一定规范的应用程序接口编写出来的程序.插件必须依附于一个宿主程序,为宿主程序提供增强功能.插件的种类有很多,这里主要讨论浏览器插件. IE下利用OLE和COM技术开发的浏 ...

  6. 【TopCoder】SRM 680 DIV 2

    1. BearPair之bigDistance1.1 题目概述在 <= 50的字符串中找位置i,j 满足(1) s[i] != s[j];(2) abs(i-j)尽可能大.若不存在返回-1, 否 ...

  7. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  8. [ffmpeg 扩展第三方库编译系列] 关于libvpx mingw32编译问题

    在编译libvpx的时候遇到挺多的问题, 1.[STRIP] libvpx.a < libvpx_g.a strip: Bad file number   这个错误也是比较难搞的,一开始以为只是 ...

  9. Android开发之json解析

    目前正在尝试着写app,发现看懂代码和能写出来差距很大,最关键的是java基础比较的差,因为只会python,java基础只学习了一个礼拜就过了.感觉java写出来的代码不如python简单明了. 上 ...

  10. BZOJ_1020_[SHOI2008]_安全的航线flight_(计算几何+二分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1020 给出一条航线(折线),给出\(c\)个陆地(多边形).求航线上距离陆地的最近距离最远的距 ...