带有闭包解释的Javascript单例
简介:我开始阅读Javascript模式书,但一个例子都抓不住。它相当大,所以在给你一个代码之前,我会试着简单地解释一下 示例说明:所以他们试图通过闭包来定义单例。第一段代码非常简单,但它有一个显著的缺点——在创建了带有闭包解释的Javascript单例,javascript,design-patterns,singleton,closures,Javascript,Design Patterns,Singleton,Closures,简介:我开始阅读Javascript模式书,但一个例子都抓不住。它相当大,所以在给你一个代码之前,我会试着简单地解释一下 示例说明:所以他们试图通过闭包来定义单例。第一段代码非常简单,但它有一个显著的缺点——在创建了宇宙的第一个实例之后,我们无法重新定义原型 问题:有人能给我解释一下第二个示例('Good'singleton)代码在第一次构造函数调用后是如何改变原型的吗 “坏”单身汉: function Universe() { var instance = this; this
宇宙的第一个实例之后,我们无法重新定义原型
问题:有人能给我解释一下第二个示例('Good'singleton)代码在第一次构造函数调用后是如何改变原型的吗
“坏”单身汉:
function Universe() {
var instance = this;
this.start_time = 0;
this.bang = "Big";
Universe = function () {
return instance;
};
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing; // true
uni2.nothing; // true
//AS YOU CAN SEE ALL CHANGES TO UNIVERSE PROTOTYPE HAVE NO RESULT AFTER FIRST CONSTRUCTOR CALL
uni.everything; // undefined
uni2.everything; // undefined
function Universe() {
var instance;
Universe = function Universe() {
return instance;
};
Universe.prototype = this;
instance = new Universe();
instance.constructor = Universe;
instance.start_time = 0;
instance.bang = "Big";
return instance;
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
//QUESTION: how does it manage to change the prototype of singleton?!
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing && uni.everything && uni2.nothing && uni2.everything; // true
然后他们用下面的代码解决问题:
好的单身汉:
function Universe() {
var instance = this;
this.start_time = 0;
this.bang = "Big";
Universe = function () {
return instance;
};
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing; // true
uni2.nothing; // true
//AS YOU CAN SEE ALL CHANGES TO UNIVERSE PROTOTYPE HAVE NO RESULT AFTER FIRST CONSTRUCTOR CALL
uni.everything; // undefined
uni2.everything; // undefined
function Universe() {
var instance;
Universe = function Universe() {
return instance;
};
Universe.prototype = this;
instance = new Universe();
instance.constructor = Universe;
instance.start_time = 0;
instance.bang = "Big";
return instance;
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
//QUESTION: how does it manage to change the prototype of singleton?!
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing && uni.everything && uni2.nothing && uni2.everything; // true
换言之,同样的问题是:为什么在第一个代码段中uni.earthing==false
和uni2.earthing==false
,但在第二个代码段中uni.earthing==true
和uni2.earthing==true
?至于我,在这两种情况下,它们都应该是false
注意:请随意改写这个答案,让它听起来更好,我可能没有解释清楚
示例1(“坏”单例)
在您的第一个示例中:
function Universe() {
var instance = this;
this.start_time = 0;
this.bang = "Big";
Universe = function () {
return instance;
};
}
第二次调用new Universe()
时,它返回从第一次(替换全局Universe
构造函数时)存储的实例,而不是新对象。这就是为什么对Universe.prototype
的任何更改都没有效果
示例2(“好的”单例)
你的第二个例子有点复杂。第一次调用它时,this
指的是最初创建的对象,这意味着它具有带有nothing
属性的原型。由于该对象现在是返回实例的原型,因此继承了nothing
属性
因为现在,当您第二次调用newuniverse()
时,它将返回第一次调用的instance=newuniverse()
的结果,对它所做的任何更改也会随之保留
因为您在原始的Universe
函数中返回了instance
,uni
是与uni2
相同的对象
这与执行此操作具有相同的效果:
var Universe2;
function Universe() {
Universe2 = function () {
return instance;
};
Universe2.prototype = this;
var instance = new Universe2();
instance.constructor = Universe2;
instance.start_time = 0;
instance.bang = "Big";
return instance;
}
Universe.prototype.nothing = true;
var uni = new Universe();
Universe2.prototype.everything = true;
var uni2 = new Universe2();
最后一个物体看起来像这样:
==========================
= Object.prototype =
= - hasOwnProperty: ... =
= - toString: ... =
= - ... =
==========================
^
|
|
|
|
==========================
= Universe.prototype: =
= - nothing: true =
==========================
^
|
|
|
|
==========================
= Instance of Universe: =
= - everything: true =
==========================
^
|
|
|
|
==========================
= Instance of Universe2: =
= - start_time: 0 =
= - bang: "Big" =
==========================
当然是,它总是返回第一次创建的实例。@Qantas94Heavy您刚才回答了哪个问题?