Home > database >  Are JavaScript private fields private per class or per instance?
Are JavaScript private fields private per class or per instance?

Time:03-24

JavaScript recently added private class fields, named with a hash prefix.

(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)

I'm looking for a clear answer on whether this form of privacy is 'per class' or 'per instance.'

Say a Person class is defined with a private field named '#secret'.

I use 'new' to construct two instances of Person class: person1 and person2.

Does person1 have access to inspect and modify #secret field of person2?

class Person {
  #secret;
  constructor(secret) {
    this.#secret = secret;
  }
  getSomebodyElsesSecret(somebody) {
    return somebody.#secret;
  }
  setSomebodyElsesSecret(somebody, value) {
    somebody.#secret = value;
  }
}

CodePudding user response:

They're per class - an instance can view and modify another instance.

class Person {
  #secret;
  constructor(secret) {
    this.#secret = secret;
  }
  getSomebodyElsesSecret(somebody) {
    return somebody.#secret;
  }
  setSomebodyElsesSecret(somebody, value) {
    somebody.#secret = value;
  }
}

const a = new Person('a');
const b = new Person('b');
console.log(a.getSomebodyElsesSecret(b))
a.setSomebodyElsesSecret(b, 'c');
console.log(a.getSomebodyElsesSecret(b))

One way to look at it is that private fields are similar to variables scoped only to the class - they can be referenced however you want by anything inside the class's {}, and can't be referenced outside.

In terms of scope, it's a bit like a WeakMap that defines the private variables and an IIFE that returns the class:

const Person = (() => {
    const secrets = new WeakMap();
    return class Person {
        constructor(secret) {
            secrets.set(this, secret);
        }
        getSomebodyElsesSecret(somebody) {
            return secrets.get(somebody);
        }
        setSomebodyElsesSecret(somebody, value) {
            secrets.set(somebody, value);
        }
    }
})();

const a = new Person('a');
const b = new Person('b');
console.log(a.getSomebodyElsesSecret(b))
a.setSomebodyElsesSecret(b, 'c');
console.log(a.getSomebodyElsesSecret(b))

CodePudding user response:

No. If it was public, you can access it as person2.secret but it is private now which means you cannot directly access it outside the class.

  • Related