简介:我开始阅读Javascript Patterns一书并且无法掌握一个例子。它非常大,所以我会在给你一个代码之前先简单解释一下。
示例说明:所以他们尝试做的是在Closure的帮助下定义单例。第一段代码非常简单,但它有一个明显的缺点 - 我们无法在创建Universe
的第一个实例后重新定义原型。
问题: 有人可以解释一下,第一个构造函数调用之后,第二个示例(“好”单例)代码如何设置更改原型?
'坏'单身:
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.everything == false
和uni2.everything == false
中,但在第二个uni.everything == true
和uni2.everything == true
?至于我,在两种情况下都应该false
答案 0 :(得分:4)
注意:请随意改写此答案以使其听起来更好,我可能还没有解释清楚。
在你的第一个例子中:
function Universe() {
var instance = this;
this.start_time = 0;
this.bang = "Big";
Universe = function () {
return instance;
};
}
第二次调用new Universe()
时,它会返回第一次存储的instance
(替换全局Universe
构造函数时),而不是新对象。这就是Universe.prototype
的任何更改都没有效果的原因。
你的第二个例子有点复杂。第一次调用它时,this
引用最初创建的对象,这意味着它具有nothing
属性的原型。由于此对象现在是返回实例的原型,因此继承了nothing
属性。
因为现在当您第二次致电new Universe()
时,它会从第一次返回instance = new Universe()
的结果,所以对它的任何更改都会保留。
由于您在原始instance
函数中返回了Universe
,因此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" =
==========================