Checkout my CSS Grid By Example and Getting Started With React video courses on Skillshare. Sign up now and get one free month of Skillshare.

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.

Home Screencasts Best of Newsletter Search X