Fixing the TypeError: Cannot read private member #value from an object whose class did not declare it

Using private properties can trigger some unexpected Javascript errors.

We have seen in the previous article how to declare private properties on Javascript classes using the # synax. While this is a great addition it can lead us to unexpected results.

Let's take the following example, where we try to access a private property from a static method:

class Employee {
  #salary

  constructor(s = 0) {
    this.#salary = s
  }

  static showPrivateData(obj) {
    return `Salary is = ${obj.#salary}`
  }
}

It works fine if we pass an object that has the private property:

// 👍 this will work
const joe = new Employee(20)
const data = Employee.showPrivateData(joe)
console.log(data) //Salary is = 20

However, if we try to access the private property on an object that does not has it:

// ⛔️ this will throw an error
const data = Employee.showPrivateData({})
console.log(data)

We will get the below error:

Uncaught TypeError: Cannot read private member #salary from an object whose class did not declare it

We can fix this error in 2 ways.

Solution 1. using the in JS operator to fix the Cannot read private member error

Using the Javascript in operator we can check if a given object has a given property. This works now also for private properties:

class Employee {
  #salary

  constructor(s = 0) {
    this.#salary = s
  }

  static showPrivateData(obj) {
    if (!(#salary in obj)) {
      return `No private data here!`;
    }
    return `Salary is = ${obj.#salary}`;
  }
}

const data = Employee.showPrivateData({})
console.log(data) // "No private data here!"

Solution 2. using the instanceof JS operator to fix the Cannot read private member error

One other alternative is to use the instanceof operator and check if the given object is from a class that we know it has the given private property:

class Employee {
  #salary

  constructor(s = 0) {
    this.#salary = s
  }

  static showPrivateData(obj) {
    if (!(obj instanceof Employee)) {
      return `No private data here!`;
    }
    return `Salary is = ${obj.#salary}`;
  }
}

const data = Employee.showPrivateData({})
console.log(data) // "No private data here!"

Overall I prefer the first approach as it is more specific and direct.

📖 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.

📖 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.


Leave a Reply

Your email address will not be published. Required fields are marked *

Home Screencasts Best of Newsletter Search X

📖 50 Javascript, React and NextJs Projects

Hi friend! Before you go, just wanted to let you know about the 50 Javascript, React and NextJs Projects FREE ebook.

One of the best ways to learn is by doing the work. Choose from 8 project categories and get started right away:

  • Business & Real-World
  • Games & Puzzles
  • Fun & Interesting
  • Tools & Libraries
  • Personal & Portfolio
  • Project Add-Ons
  • Productivity
  • Clones

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects complete with project briefs and wireframes!

Keep building and level up! Get all projects as an ebook right to your inbox!

X