javascript活动对象的理解——伪单例模式

在本身研究javascript各类设计模式的过程当中,偶然写出的一段代码让本身理解的更深入了,之因此称之为伪单例模式,是由于这段代码形成的结果很想单例模式,可是其实是活动对象捣乱所形成的误会。javascript

代码很简单是这样的:html

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了呢?java

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

若是你对这个结果感到疑惑就接着看下吧,若是你一眼就看到其中的缘由,那你就不用在这里浪费时间咯~闭包

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

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

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

当咱们var a = new Person()后,状况是这样的:prototype

实例对象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,不懂得同窗多看看图哟。

相关文章
相关标签/搜索