function Universe() {
// 缓存的实例
var instance = this;
// 其它内容
this.start_time = 0;
this.bang = "Big";
// 重写构造函数
Universe = function () {
alert(1)
return instance;
//改成return this,uni2.bang是undefined
};
}
// 测试
var uni = new Universe();
var uni2 = new Universe();
uni.bang = "123";
console.log(uni === uni2); // true
console.log(uni2.bang); // 123
这里new了两次Universe(),只alert了一次1,为什么呢?
然后重写构造函数里,把 return instance;
改成return this
,uni2.bang是undefined,两个有什么区别呢?
大家讲道理2017-04-11 12:36:59
你return instance 的时候,返回的是上面那个 Universe() 作用域内的this,所以可以获取到 this.bang
Universe = function () {
alert(1)
// 这里返回的this 是当前这个 function作用域内的 this。没有任何属性
return instance;
};
阿神2017-04-11 12:36:59
第一次运行,返回了重写前的构造函数的实例————这种事普通的构造函数,只是函数内部重写了Universe,并且形成了一个闭包
第二次运行,如果返回instance,就跟调用普通函数一样(这种方式类似于稳妥构造函数模式)。
如果返回this,则就是又调用了一次普通的构造函数,返回一个{},其没有任何实例属性。
天蓬老师2017-04-11 12:36:59
不知道题主知道原因没有,小白试着理解一波...
首先,是var uni = new Universe();
这一步先是用instance保存了Universe这个函数的this指向,instance一直留在内存里面,重写构造函数的时候不会执行alert(1)。这个重写相当于重新给一个已经声明了的变量赋值嘛,平时写完
first:var a = function(){
//do sth
};
second:a = function(){
alert('sth');
};
也不会alert出东西吧。
接着是var uni2 = new Universe();
这个时候new的直接就是重写部分
function Universe () {
alert(1)
return instance;
};
了,1
也就因为Universe被new,如UKer所说“跟调用普通函数一样”alert出来了,然后接下来无论var uni[3456] = new Universe();
1
也都会alert出来。
而第二个问题,把instance改成this,uni还可以拿到指向原Universe的this,uni2因为重写之后this并不是指向原Universe,指向的是重写后的空的Universe {}
。所以uni === uni2 //false
。你uni.bang = "123";
是给原Universe.bang赋值,而uni2
里面啥都没有,所以无论uni2.start_time
还是uni2.bang
都是undefined
。
表达能力一般,希望题主看完能理解~O(∩_∩)O~
黄舟2017-04-11 12:36:59
为什么没人去质疑题主写的单例模式很奇怪呢?
要是我希望内存只有一份数据,这样不是更简单吗?
var Universe = {
start_time: 0,
bang: 'Big'
};
如果你觉得不够用,要加几个动作,可以这样:
var Universe = {
start_time: 0,
bang: 'Big',
doing: function() {}
};
假如你认为需要一些内部私有变量,可以写个标准的闭包。
var Universe = (function() {
var _name;
function _getName() {
}
return {
start_time: 0,
bang: 'Big',
doing: function() {},
getName: _getName
};
})();
优雅的语言,别整复杂了。