1

I know that everything is private in node.js unless you export it.

I couldn't find other ways of exporting a whole class, but my goal is to make the privateMethod() inaccessible from where the class is imported to and instantiated.

#!/usr/bin/env node

'use strict'

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {}
    privateMethod() {}
}

Is there a solution to this, or do I have to just leave it public?

Thanks in advance for any help.

Boba0514
  • 181
  • 1
  • 3
  • 15

1 Answers1

5

Edit in 2021:

Javascript has a proposal (currently at Stage 3 as of early 2021) for private members/methods. See this description on MDN for more details. Portions of this are implemented in Chrome and Nodejs, not yet in Safari and Firefox.

To use this feature, you prefix the method with # as in:

class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world'
  }

  getPrivateMessage() {
    return this.#privateMethod()
  }
}

This will be a syntax error in a Javascript engine that does not support this feature.


Original answer from 2019.

Work-arounds for private members.

Javascript does not, by itself, have the notion of private methods. So, if you define a method on a class, then any code that has a reference to an instance of that class can call that method. There is no such thing as a method definition that is private in Javascript.

That said, there are numerous work-arounds that can give you code that operates on an object that is private and not callable from outside your module. Here's an example:

'use strict'

// declare privateMethod as a local function that can only be called from within this module
function privateMethod(obj, args) {
   // private code here
   // reference instance with obj.method() or obj.data
   obj.otherPublicMethod()
}

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {
        // call code for private method
        privateMethod(this, ...);
    }
    otherPublicMethod() {}
}

This is truly private because the code for the method is not on the prototype and thus is not discoverable or callable from outside this module. Of course, you have to call it slightly differently because it's not a "real" method. But, that's because all "real" methods are discoverable and callable from the outside.


If you want the private method itself to use this to reference the current object, then you just change how you call the method:

'use strict'

// declare privateMethod as a local function that can only be called from within this module
function privateMethod(args) {
   // private code here
   // can reference this as in any normal method this.method() or this.data
   this.otherPublicMethod()
}

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {
        // call code for private method using .call()
        privateMethod.call(this, ...);
    }
    otherPublicMethod() {}
}

FYI, TypeScript supports both private methods and properties. Here's an article that gives you a look at how that works. Of course, this means buying into the whole TypeScript syntax and type checking and transpiling your code.


There's also a closure-based method of implementing private methods and private instance variables described here: http://crockford.com/javascript/private.html. but that means you can't put any methods that wish to access the private methods in the class definition or on the prototype. But, it does work.

jfriend00
  • 683,504
  • 96
  • 985
  • 979