Skip to content

JavaScript Tutorial Classes and Object-Oriented JavaScript

Class Fields and Private Fields

Lesson 191 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

Class fields

Instead of setting every property in the constructor, you can declare fields directly in the class body.

script.js
JS
class Product {
  name;
  price = 0;
  inStock = true;

  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}

const pen = new Product("Pen", 2);
console.log(pen);  // → Product { name: Pen, price: 2, inStock: true }

Fields keep the shape of the object visible at the top of the class.

Private fields: #name

A name that starts with # is private: it can only be used inside the class body. Code outside cannot read or change it, and trying is an error.

script.js
JS
class BankAccount {
  #balance = 0;

  deposit(amount) {
    if (amount <= 0) throw new Error("Amount must be positive");
    this.#balance += amount;
  }

  getBalance() {
    return this.#balance;
  }
}

const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance());   // → 100
console.log(account.balance);        // → undefined (there is no public "balance")

#balance is enforced by the language itself, not just by convention. That is real encapsulation: the only way to change the balance is through methods that check the rules.

If you try to read it from outside the class, the script does not even start. Writing account.#balance in the code above fails with a SyntaxError (Private field ‘#balance’ must be declared in an enclosing class), because the engine checks this when it reads the file.

Private methods

script.js
JS
class Validator {
  #isEmail(text) {
    return /^[^\s@]+@[^\s@]+$/.test(text);
  }

  check(value) {
    return this.#isEmail(value) ? "valid" : "invalid";
  }
}

console.log(new Validator().check("maya@example.com")); // → valid

Checking for a private field

Inside the class, #field in object tells you whether an object has it.

script.js
JS
class Secret {
  #value = 42;
  static isSecret(obj) {
    return #value in obj;
  }
}

console.log(Secret.isSecret(new Secret())); // → true
console.log(Secret.isSecret({}));           // → false

The old convention: _underscore

Before private fields, developers wrote _balance to say “do not touch”. It is only a convention. Anyone can still read it. Use # when you want true privacy.

Private is not “secret”

Private fields protect against other code in your program changing your data. They do not hide data from the user: everything in browser JavaScript can be inspected in developer tools. Never keep passwords or API keys in JavaScript expecting them to be safe.

Field initialisation order

Fields are initialised before the constructor body runs (in the base class), so you can use them in the constructor.

Support

Class fields and private fields are standard (ES2022) and work in all current browsers.