1

I'm reading typescript output now. It converts modern ES21 to the older versions. I am wondering why It's this way, I mean why devs used to create a whole variable _this and set it to this keyword. Like it's easier to just put this instead of create a new variable... Any ideas?

Input (TypeScript)

const Singleton = () => {
  
  if (Singleton._instance) return Singleton._instance;

  Singleton._instance = this;

  return this;
};

const a = new Singleton();
const b = new Singleton();

console.log(a === b);

Output (JavaScript)

// BUT WHY ?
var _this = this;

var Singleton = function () {
    if (Singleton._instance)
        return Singleton._instance;
    Singleton._instance = _this;
    return _this;
};
var a = new Singleton();
var b = new Singleton();
console.log(a === b);

  • 1
    Because [the way the `this` keyword works](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) its value is not static but determined at call time. [If you want to use the correct `this`](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) you need to capture it. – VLAZ Mar 11 '21 at 19:45
  • 1
    That singleton pattern looks wrong.. `const Singleton = () => {` There will be no `this`, it will just be the same as `globalThis` or `window` in old money.. It should really be `const Singleton = function () {` for it to be valid. IOW: `console.log(a === b);` Is equivalent to `window === window`, and of course it is. – Keith Mar 11 '21 at 19:58
  • 1
    @VLAZ His problem is not that of capturing `this`, it's because he's not even getting one.. ` () => {} ``,, no `this` – Keith Mar 11 '21 at 20:01
  • 1
    @Keith there are many things I'd say are wrong with this singleton. However, I take it it's a question about *why* `_this` exists, where the code is more of an illustration. – VLAZ Mar 11 '21 at 20:02
  • 1
    Exactly! That's what I wanted to hear! An arrow function doesn't have its own `this`. Great job! – user15328189 Mar 11 '21 at 20:03
  • @VLAZ What's wrong with my singleton pattern? Like it gives me what I want. What would you change there ? – user15328189 Mar 11 '21 at 20:04
  • 1
    1. You have a public static property exposing the instance, so anybody is free to manipulate it. It's not even `readonly` although it should *really* be `private`, 2. Speaking of properties, this should be a *class* rather than a function. 3. With the existence of modules, the singleton pattern is largely obsolete. Just use `export const instance = new Singleton();` and you don't really need to ever call `new`. All imports will be the same. 4. Even without modules or classes, this could have been an IIFE that creates and stores an instance. – VLAZ Mar 11 '21 at 20:11
  • 1
    To add to @VLAZ list: No. 3. Your creating an object every place you access this Singleton (apart from the first), that immediately will get disposed of. It 's not a massive performance memory hit / but like mentioned Singletons are very easy to do with modules, and that would be a nicer way to do them. – Keith Mar 11 '21 at 20:18
  • @VLAZ. Yeah, I agree that it's better to keep the _instance property private. by the way, like JS doesn't support private stuff if I am not mistaken, `#` I don't use just now, but maybe... What about if I just create a readonly property as you said using `Object.createProperty()` ? – user15328189 Mar 11 '21 at 20:37
  • 1
    `JS doesn't support private stuff` There are lots of ways of doing private stuff in JS. Take this -> `var x = (function () { var private = 'hello'; return () => console.log(private); })()` There is no access to `private` here, another option for private in modern JS is also the `WeakMap` – Keith Mar 11 '21 at 20:43
  • 1
    @Keith Thank you for helping me! – user15328189 Mar 11 '21 at 20:52
  • 1
    "*JS doesn't support private stuff if I am not mistake*" but you're writing TypeScript code. You can have an access modifier in TS. – VLAZ Mar 11 '21 at 21:02

0 Answers0