DEV Community

Discussion on: Hiding details in JavaScript classes with symbols

Collapse
 
joelnet profile image
JavaScript Joel

Symbol only changes the property key it does not add any privacy.

The first example is equivalent to this:

// here the key is type 'string'
p['s_firstname'] = 'Nana'; 
Enter fullscreen mode Exit fullscreen mode

The 2nd example is equivalent to this:

// here the key is type 'Symbol'
p[s_firstname] = 'Nana'; 
Enter fullscreen mode Exit fullscreen mode

Using the symbol will still allow you to set the firstname.

let s_firstname  = Symbol();

class Person {
    constructor(firstName) {
        this[s_firstname] = firstName;
    }

    log() {
        console.log('I am', this[s_firstname]);
    }

}

let p = new Person("Oliver")
p.log(); // I am Oliver
p[s_firstname] = "Nana";
p.log()// I am Nana
Enter fullscreen mode Exit fullscreen mode
Collapse
 
olivermensahdev profile image
Oliver Mensah

Well noted.

Collapse
 
joelnet profile image
JavaScript Joel

You can also enumerate property-symbols with this command:

Object.getOwnPropertySymbols(p)

So if you do not know the symbol, you can still set the property using code like this:

let p = new Person("Oliver")
// set first property-symbol to 'Nana'
p[Object.getOwnPropertySymbols(p)[0]] = 'Nana'
p.log() // I am Nana

Collapse
 
joelnet profile image
JavaScript Joel

Alternatively, you can also achieve privacy by switching from using a Class to using a closure.

// firstname cannot be modified!
const person = (firstName) => ({
  log: () => console.log('I am', firstName)
})

let p = person("Oliver")
p.log(); // I am Oliver
Enter fullscreen mode Exit fullscreen mode
Collapse
 
olivermensahdev profile image
Oliver Mensah

I am concerned about the classical way of preventing outside modification of class properties. I have been finding means to do that until I tried using symbols. In my approach, it works and that is why I wanted to share with others but I did not know that they modified using another approach as you have stated. I like how you have outlined the process. But can you help in the classical way of hiding details in JavaScript?

Thread Thread
 
joelnet profile image
JavaScript Joel • Edited

I am not a fan of classes in JavaScript. As a matter of fact, I never create code with classes. I have found that functions will serve the same purpose. I prefer using the revealing module pattern over JavaScript classes.

Here's an example:

const createPerson = (firstName) => {
  var s_firstname = firstName

  const log = () =>
    console.log('I am', s_firstname)
  const setName = firstName =>
    (s_firstname = firstName)

  return {
    log,
    setName
  }
}

const me = createPerson('unknown')
me.setName('Joel')
me.log()

I added a setName function to demonstrate how to set the private var s_firstname.

Thread Thread
 
olivermensahdev profile image
Oliver Mensah

That's cool

Collapse
 
olivermensahdev profile image
Oliver Mensah

Okay. Thanks for the feedback