Private Methods in ECMAScript 6 (ECMAScript 2015)

Georgi Razsolkov • May 12, 2020

In this short article I want to show you a cool trick about how to protect your methods in ES6 classes. All properties in ES6 classes are public and can be examined or modified outside the class.

//test.js
export class Test {
    print() {
        console.log('Hello!');
    }
}
//demo.js
import { Test } from './Test.js';

const test = new Test();
test.print(); //output: 'Hello!'

In the example above, print() is a public method and if you create an instance of Test class, you will be able to call it from everywhere.

Fortunately there is a way to 'hide' this method.

We will use Symbol() - cool Javascript feature which allows us to create a primitive data type of type Symbol.

Every value returned from Symbol() is unique.

console.log(Symbol('print') === Symbol('print'));
//output: false

So if we create Symbol, assign this Symbol to be a method name and export the class - the only place where you can access this method will be inside the file where the class is located. Outside of the file we don't have access to the Symbol, therefore we won't be able to call the method.

//Test.js
const PRINT = Symbol('print');

export class Test {
    [PRINT]() {
        console.log('Hello!');
    }
}

//const test = new Test();
//test[PRINT](); //output: 'Hello!'

//demo.js
import { Test } from './Test.js';
const PRINT = Symbol('print');

const test = new Test();
test[PRINT](); //output: error: Uncaught TypeError: test[PRINT] is not a function
test.print(); //output: error: Uncaught TypeError: test.print is not a function

There is an official proposal to include private class fields in ESNext, you can read more about this proposal here.