A problem about JS singleton pattern

function Demo(name) {
    this.name = name;
}
var getSingle = function(fn) {
    var result;
    return function() {
        console.log(arguments.length);
        return result || (result = fn.apply(this, arguments));
    }
};
const aa = new getSingle(Demo)("a");
const bb = new getSingle(Demo)("b");
console.log(aa === bb); //true
console.log(aa.name); // TypeError: aa is undefined
console.log(bb); // undefined

Why aa.name and bb are not defined?


const aa = new (getSingle (Demo)) ('a'); parentheses can solve the undefined problem,
but the singleton is not written this way:
result = fn.apply (this, arguments): result is always undefined, which is obviously a mistake;
and var result, every time getSingle is executed, you can see that this is definitely not a singleton


function Demo(name) {
        this.name = name;
    }
    var getSingle = function(fn) {
        var result;
        return function() {
            console.log(arguments.length);
            return result || (result = fn.apply(this, arguments));
        }
    };
    const ss=getSingle(Demo);
    const aa = new ss('a');
    const bb = new ss('b');
    console.log(aa === bb);
    console.log(aa.name);
    console.log(bb);
    const m=new (getSingle(Demo))('m');
    console.log(m.name);
    const m2=new (getSingle(Demo))('m2');
    console.log(m==m2);

1. Operator precedence
2. Every time you go to getSingle, you will redefine result and return a new function, so even if you succeed in that way, it will not be equal

.

-update
need to borrow ES6 syntax, ES5 , I really can't think of

function Demo(name) {
    this.name = name;
}

let getSingleBuilder = function (fn) {
    let result;
    return function () {
        return result || (result = new fn(...arguments));
    }
};

let SingleDemo = getSingleBuilder(Demo);

const aa = new SingleDemo('a');
const bb = new SingleDemo('b');
console.log(aa === bb); // true

-original answer

For the precedence problem of the

operator, just add two parentheses, otherwise you will treat getSingle as a constructor.
operator precedence

const aa = new (getSingle(Demo))('a');
const bb = new (getSingle(Demo))('b');

this is the result typed on the terminal, the Chinese translation, you think the name can not be read,

Menu