javascript - js的单例模式,重写构造函数,为什么new了两次只执行了一次重写的那个构造函数
ringa_lee
ringa_lee 2017-04-11 12:34:59
0
4
319
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,两个有什么区别呢?

ringa_lee
ringa_lee

ringa_lee

Antworte allen(4)
大家讲道理

你return instance 的时候,返回的是上面那个 Universe() 作用域内的this,所以可以获取到 this.bang

Universe = function () {
    alert(1)
    // 这里返回的this 是当前这个 function作用域内的 this。没有任何属性
    return instance;
};
阿神

第一次运行,返回了重写前的构造函数的实例————这种事普通的构造函数,只是函数内部重写了Universe,并且形成了一个闭包

第二次运行,如果返回instance,就跟调用普通函数一样(这种方式类似于稳妥构造函数模式)。
如果返回this,则就是又调用了一次普通的构造函数,返回一个{},其没有任何实例属性。

Peter_Zhu

不知道题主知道原因没有,小白试着理解一波...
首先,是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~

黄舟

为什么没人去质疑题主写的单例模式很奇怪呢?

要是我希望内存只有一份数据,这样不是更简单吗?

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
    };

})();

优雅的语言,别整复杂了。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage