在自己研究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. hibernate简介(Session,几种状态,方法······等)

    1.Hibernate是什么?          Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数 ...

  2. jquery 对 Json 的各种遍历

    grep <script type='text/javascript' src="/jquery.js"></script> <script type ...

  3. Bypass Preventing CSRF

    CSRF在过去的n年(n>2)一直都火,在bh/defcon/owasp等会议上多次探讨CSRF的攻防[具体你可以看看以往的那些pp].前 段时间PLAYHACK.net上发表了一个总结性的pp ...

  4. http://jingyan.baidu.com/article/e4511cf33479812b855eaf67.html

    http://jingyan.baidu.com/article/e4511cf33479812b855eaf67.html

  5. html--offsetLeft,Left,clientLeft的关键--动态获取计算元素位置关系

    动态计算元素位置关系的时候,必备... http://www.cnblogs.com/panjun-Donet/articles/1294033.html

  6. uEditor独立图片上传

    项目中.上传图片,非常希望有一款比较兼容的查件. 网上找了一些,图片上传立刻显示的js代码,还有uploadify.都会碰到这样那样的不兼容和其它头疼的问题. 后来想,干脆就用php的上传类最干脆.但 ...

  7. spring事物的传播行为

    1.spring事物的传播行为,主要是用来解决业务层拥有事物的方法,相互调用的问题. 2.声明事物, 在代码执行前,开启事务.代码执行完,提交事务 3.spring并没有提供事务具体的处理,而只是调用 ...

  8. Android:使用ViewPager实现左右滑动切换图片 (简单版)

    ViewPager,它是google SDk中自带的一个附加包的一个类, 可以使视图滑动. 步骤: 1.引入android-support-v4.jar包,在主布局里加入 <android.su ...

  9. CSS+DIV 布局三种定位方式

    一.普通流 普通流中元素框的位置由元素在HTML中的位置决定.块级元素从上到下依次排列,框之间的垂直距离由框的垂直margin计算得到.行内元素在一行中水平布置. 二.定位 1.相对定位 被看作普通流 ...

  10. python学习笔记三--字典的使用

    一.基本使用: 1. 赋值:{key:value} 1.1 与列表相同处:会改变索引(键)相关联的值的改变 1.2 与列表不同处:不用考虑值的长度,而列表是有序的需要考虑末尾偏移量,超过末尾偏移量的会 ...