0

I know this question has been asked for many times, however, most of them are either for the Node.js solutions or does not work in the browsers.

So, is it possible to implement a private method in browser javascript class?

    <html>
    <body>
        <script>
            class Happy
            {
                constructor()
                {
                }
                _leo()
                {
                    console.log("ff");
                }
            }       
            var h=new Happy();
            h._leo();
        </script>
    </body>
</html> 

However, the above code still outputs "ff" in the console, how can I fix it?

The KNVB
  • 3,588
  • 3
  • 29
  • 54
  • 4
    There are no private methods in JavaScript. You can hide a function in a closure; you can hide method's key (as a symbol) in a closure; you can't hide a method (though both ways are commonly used to fake it). – Amadan Sep 11 '18 at 02:31
  • There’s a [stage 3](https://kangax.github.io/compat-table/esnext/#test-instance_class_fields_private_instance_class_fields_basic_support) [proposal](https://github.com/tc39/proposal-class-fields#private-fields) to add a `#someMethod(){}` syntax. – Sebastian Simon Sep 11 '18 at 02:49
  • Is it possible to provide some examples for me? – The KNVB Sep 11 '18 at 03:11

1 Answers1

2

This illustrates how to hide a method name, effectively making the method uncallable outside the hiding closure:

const Klass = (function() {
  const privName = Symbol("priv");

  class Klass {
    publ() {
      console.log("in publ");
      this[privName]();
    }
    [privName]() {
      console.log("in priv");
    }
  }

  return Klass;
})()

let inst = new Klass();
inst.publ();
// => in publ
//    in priv

It uses the fact that Symbol() returns an entity that cannot be replicated, the fact that privName is not exposed anywhere outside the closure, and the fact that we can define properties with calculated names using the square bracket notation.

Unlike the function-hiding mechanism demonstrated by ultratoad, this is not just a helper function, it is a true method. Just note that you can't call it using the dot notation - dot notation only works when you know the name, and here, no-one does except privName.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • 4
    `privName` may not be exported, but you can always get the symbol with `Object.getOwnPropertySymbols(Klass.prototype)`. It is well hidden and can't collide, which are huge benefits, but it isn't technically private. – loganfsmyth Sep 11 '18 at 15:21
  • 1
    @loganfsmyth: Huh, didn't know that. On the other hand... Meh. Ruby's `private` is one `send` away; Pythonistas just trust other people will be too lazy to type an underscore. I'll take it. – Amadan Sep 11 '18 at 22:59
  • 1
    Totally, depending on your goal, this approach will be 100% acceptable. – loganfsmyth Sep 12 '18 at 00:28