• (nodebb)

    Of course, TypeScript compiles down into JavaScript, so those private keywords don’t really matter. JavaScript doesn’t have private.

    One could propose the same argument about cfront style C++ compilation (compiles C++ to C then compiles the C with a C compiler), on the grounds that C doesn't have private either, except that in C++, private matters a lot, even if you compile with cfront.

  • (author) in reply to Steve_The_Cynic

    The key difference here is that TypeScript is a superset of JavaScript, so all valid JavaScript is valid TypeScript and JavaScript doesn't enforce types. So even in TypeScript, it's trivial to get around private protections, so private doesn't matter that much to TypeScript.

  • Robin (unregistered)

    Actually, JS does allow you to have "private" properties/functions/methods. Even in old-style JS it's easy to make a "class" with a closure and keep some details private:

    (apologies in advance if the formatting is messed up, it's my first time trying to put code on these forums and there's no "preview")

    function makeObject(privateVar) {
      return {
        getVar: function() {
          return privateVar;
        }
      };
    } 
    

    And then you can do var obj = makeObject("foo"); and call obj.getVar()as often as you want to get the value, knowing nothing can ever change it or even access it directly.

    Javascript certainly has major flaws, to do with its weak typing - but I hate seeing people assert things about it that just aren't true. No, it's not a traditional OO language like Java or C# - but for all JS's flaws I think it's a good thing that it avoids that kind of dogmatism. (And you don't have to be like those language either to get strong, static typing - just look at Haskell, or Rust - but I'm getting off topic.)

  • Foo AKA Fooo (unregistered) in reply to Robin

    What you just emulated is const/final, not private. Private would mean the outside cannot even read the value, while other methods of the class can read and write it (unless it's also const/final).

    Anyway, Remy obviously meant that JS doesn't support this particular "private" keyword as used in the code. Even if privateness can also be emulated, that wouldn't help that code.

    IMHO, it's like saying C is an OOP language. Yes, with some tricks and a lot of discipline, you can implement things that work like classes and methods, but the language does not support you in that. Otherwise, you could say that even binary machine code is OOP (and FP and everything else), since everything can be compiled down to machine code, but that's not the point when talking about language features.

  • (nodebb)

    So.... TRWTF is TypeScript...?

    Addendum 2020-10-28 09:57: Or just the compiler...???

  • Yehuda R (unregistered) in reply to Robin

    Javascript certainly has major flaws, to do with its weak typing - but I hate seeing people assert things about it that just aren't true.

    Repeat after me: Javascript is the scourge of the world. Javascript is the scourge of the world. It is one big flaw, I wish it would die already, and take typescript with it. And yes, I have extensive experience with both.

    And it is cute what we can do with closures, but ultimately it does have a performance cost. Even if it's minor, why should declaring a variable private have a performance cost?? Here are some references.

  • David Mårtensson (unregistered) in reply to Bananafish

    Not really, typescript, used correctly, is a very good help.

    But in by itself its just a superset that does not enforce anything.

    But if you include a linter as part of the compile pipeline (using webpack or similar) you can select to get any problems as warnings or errors that could prevent a checkin.

    But then you have those that consider any such obstacles as a personal affront and try to circumvent any safety.

  • Robin (unregistered) in reply to Foo AKA Fooo

    I don't see the difference. No external code can access the value directly - I illustrated with a simple "getter" which accesses it, but no setter (although I could have included that too), which is more or less what the original code is trying (badly!) to do. I could instead have had no getter at all, but had other "public" methods that use, and alter, the private internal variable(s).

    Functionally, there is zero difference between this and what OO languages do with "public" and "private" declarations. (OK you can't emulate "protected", at least not without involving prototypes and so on and generally making a mess. I admit I'm not an OO programmer and, while I certainly appreciate the importance of having things be private, I don't really understand "protected" and dislike inheritance in general.)

  • Naomi (unregistered) in reply to Foo AKA Fooo

    What you just emulated is const/final, not private. Private would mean the outside cannot even read the value, while other methods of the class can read and write it (unless it's also const/final).

    Not to defend Javascript, but this isn't actually true: in their example, privateVar is private; it just happens to have a getter. But perhaps this is a clearer example:

    function makeObject(privateVar) {
        return {
            sayHello: function() {
                console.log("Hello, " + privateVar + "!");
            }
        };
    }
    
    let foo = makeObject("bar");
    foo.sayHello(); // "Hello, bar!"
    console.log(foo.privateVar); // undefined
    

    It's stupid, but it works... sort of. The thing is, you have to declare any methods that want to use the private "member" in that factory function as well (and the performance penalty @Yehuda R alluded to grows with each one). Those "private members" aren't members at all. The member functions are closures that close over the "private members", which is how they can see them when nothing else can, but this means you're creating a new closure per member function that needs to access a "private member" per factory call, which... I mean, it's Javascript, so you're probably not running it in a high-performance context anyway, but it's still kind of icky.

    And, of course, none of that plays nicely with Javascript's (already quirky) notion of inheritance. This is getting a little outside what I'm comfortable speaking to, and there may be a workaround I'm not aware of, but even so...

    With all those caveats, Remy's right. Javascript doesn't have private members. You can fake them under certain circumstances, but there's a real trade-off to doing so.

  • Risk Adverse (unregistered)

    Have you taken a look at fp-ts? Just don't build things that have state.

    I can't think of a more accessible programming experience then just opening a browser, hit F12, and go to the console. If it has the internet, it has a browser. My bet is the world dies long before JavaScript does. Peer to peer Relay, GraphQL in the browser, no more servers.

  • (nodebb)

    I once turned on warnings and despaired.

    Seriously though, if you do that on our code base you won't get far. Thankfully we have "tests" that catch entirely avoidable runtime crashes...

  • Multihuntr (unregistered)

    I like the part where the doc refers to the second parameter as "date", but the implementation refers to it as "data". Really makes my day.

Leave a comment on “A Type of Useless”

Log In or post as a guest

Replying to comment #:

« Return to Article