在自己研究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. [转载]JQuery获取元素文档大小、偏移和位置和滚动条位置的方法集合

    在ajax中经常需要对元素的位置进行精确的定位,此时不仅需要获取元素自身的大小位置等属性.还需要知道页面.浏览器.滚动条等的长度和宽度.因为浏览器的兼容问题,如果使用javascript获取这些数值是 ...

  2. [转载]jquery tmpl使用方法

    动态请求数据来更新页面是现在非常常用的方法,比如博客评论的分页动态加载,微博的滚动加载和定时请求加载等. 这些情况下,动态请求返回的数据一般不是已拼好的 HTML 就是 JSON 或 XML,总之不在 ...

  3. 团体程序设计天梯赛-练习集L1-001. Hello World

    L1-001. Hello World 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 这道超级简单的题目没有任何输入. 你只需要在一行中输 ...

  4. hdu 4665

    转载一下  用的搜索   竟然过了 ............代码 ....... #include<stdio.h> #include<string.h> #include&l ...

  5. Akka的fault tolerant

    要想容错,该怎么办? 父actor首先要获知子actor的失败状态,然后确定该怎么办, “怎么办”这回事叫做“supervisorStrategy".   // Restart the st ...

  6. 到底该不该熟悉掌握struts2的ONGL呢?

    其实,在学习网站开发过程中,其实不掌握ONGL也是可以的.我们完全可以使用JSTL和EL来代替OGNL. 只要存在要往页面传输内容,我们直接把对象放在request范围即可,这样我们就可以在jsp中使 ...

  7. struts2 request内幕 为什么在struts2用EL表达式可以取值

    不知道大家有没有想过这样一个问题:为什么在action中的实例变量,没有使用request.setAttribute()方法将值添加到request范围内,却能在jsp中用EL表达式取出? 众所周知, ...

  8. tortoisesvn › prefer local prefer repository

    tortoisesvn › prefer local prefer repository

  9. 利用VC/VS的安装目录找到C/C++库函数实现的源代码

    2013-07-03 20:08:57 大多开发软件的装目录下都有很多有价值的东西,比如help文档.user guide.src文件等.今天在VS的安装目录下发现了库函数的源文件,这些文件中有对所有 ...

  10. JavaScript DOM高级程序设计 7.向应用程序加入Ajax--我要坚持到底!

    有时候,或许是因为理解能力,也或许是因为浮躁,看东西总是不入心,而且还老是想跳过本节,或者赶紧看完本节,这样的恶性循环,让我在即没有真正的学习到知识,又打击我的学习信心,还浪费了我很多事件,我想,当遇 ...