JavaScript Object-Oriented Programming: Properties

JavaScript Object-Oriented Programming: Properties

Understanding properties in JavaScript object-oriented programming is key to creating rich and meaningful objects. Properties represent the data or state associated with an object or a class. Simply put, if a JavaScript object were a character in a story, its properties would describe who it is — its name, age, color, or any attribute that defines it. Properties give life and individuality to objects, making them more than just empty shells.

In JavaScript, properties can take many forms. They might belong to individual objects (instance properties), to the class itself (static properties), or be hidden from the outside world (private properties). Properties can even be dynamic, using computed names or controlled through getter and setter functions. This article will explore all these aspects of properties, showing you exactly how to define and use them with clear, executable examples that bring these concepts to life.

Defining Instance Properties in Classes

Instance properties are the most common kind you encounter. These are properties tied to each object created by a class. When you create a new object, it carries its own copy of these properties, allowing each instance to have unique values.

Here’s a fun example with a Cat class. Each cat has a name, age, and color. These values are set in the constructor, the special method that runs whenever we create a new cat.

class Cat {

  constructor(name, age, color) {
    this.name = name;
    this.age = age;
    this.color = color;
  }

}

const lucy = new Cat("Lucy", 3, "orange");
const smokey = new Cat("Smokey", 5, "gray");

console.log(lucy.name);  // Lucy
console.log(smokey.age); // 5

In this code, name, age, and color are instance properties. The keyword this refers to the object being created, and assigning values to this.name and others creates those properties. Each cat instance remembers its own data.

Adding and Modifying Properties Outside the Constructor

JavaScript is flexible — you don’t need to define all properties inside the constructor. You can add new properties or change existing ones anytime after the object is created.

Let’s create a Dog object and add a new property after creation:

class Dog {

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

}

const buster = new Dog("Buster");
buster.breed = "Beagle";  // Adding new property after creation

console.log(buster.name);  // Buster
console.log(buster.breed); // Beagle

buster.breed = "Labrador"; // Modifying property
console.log(buster.breed); // Labrador

Here, breed was not defined in the constructor but was added directly to the buster object later. This shows how properties are flexible and can be extended dynamically.

Using Static Properties

Static properties belong to the class itself, not to the instances. They are useful for values shared across all objects created by that class.

For example, consider a ChessPlayer class with a static property to keep track of total players:

class ChessPlayer {

  static totalPlayers = 0;

  constructor(name) {
    this.name = name;
    ChessPlayer.totalPlayers++;
  }

}

const harry = new ChessPlayer("Harry");
const ron = new ChessPlayer("Ron");

console.log(ChessPlayer.totalPlayers);  // 2

In this example, totalPlayers is a static property. It’s updated each time a new player is created. Notice you access it directly from the class ChessPlayer.totalPlayers, not from the individual player objects.

Computed Property Names in Classes

Sometimes property names depend on variables or expressions. JavaScript allows computed property names using square brackets [] to dynamically define properties.

Here’s a Movie class that uses a variable for a property name:

const dynamicProp = "rating";

class Movie {

  constructor(title, value) {
    this.title = title;
    this[dynamicProp] = value;  // Computed property name
  }

}

const inception = new Movie("Inception", 9);

console.log(inception.title);   // Inception
console.log(inception.rating);  // 9

This approach is helpful when the property names are not known until runtime or depend on other variables.

Private Properties Using Modern JavaScript Syntax

JavaScript recently introduced private properties, which use the # prefix. Private properties cannot be accessed directly outside the class, helping to hide internal data.

Let’s see a BankAccount class with a private balance:

class BankAccount {

  #balance;

  constructor(initialBalance) {
    this.#balance = initialBalance;
  }

  deposit(amount) {
    this.#balance += amount;
  }

  getBalance() {
    return this.#balance;
  }

}

const account = new BankAccount(1000);
account.deposit(500);

console.log(account.getBalance());  // 1500
// console.log(account.#balance);   // SyntaxError: Private field '#balance' must be declared in an enclosing class

Here, #balance is a private property. It can only be read or changed via public methods like getBalance and deposit. Trying to access it directly causes an error, showing encapsulation in action.

Using Getters and Setters for Property Access Control

Getters and setters allow you to control how properties are accessed or changed, often wrapping private data with custom logic.

Consider a Player class with a private _score and public getter/setter for score:

class Player {

  constructor(name) {
    this.name = name;
    this._score = 0;
  }

  get score() {
    return this._score;
  }

  set score(value) {

    if (value >= 0) {
      this._score = value;
    } else {
      console.log("Score must be positive.");
    }

  }

}

const hermione = new Player("Hermione");
hermione.score = 10;

console.log(hermione.score);  // 10

hermione.score = -5;          // Score must be positive.

console.log(hermione.score);  // 10 (unchanged)

Getters and setters provide a clean interface, allowing you to validate or transform values whenever properties are read or assigned.

Deleting Properties

JavaScript allows you to remove properties from objects using the delete keyword.

For instance, here is a Car object where we delete the color property:

const car = {
  make: "Toyota",
  model: "Corolla",
  color: "blue"
};

console.log(car.color);  // blue

delete car.color;

console.log(car.color);  // undefined

After delete car.color, the color property no longer exists on the car object. This can be useful when you need to clean up or modify objects dynamically.

Conclusion

Properties form the backbone of object-oriented programming in JavaScript. They allow objects to carry meaningful information and define their individual identities. Whether you are working with instance properties unique to each object, static properties shared across a class, or private properties hidden from outside access, mastering how to define and manipulate properties is essential.

This article covered the full spectrum — from basic property definitions and dynamic property names to modern private properties and access control through getters and setters. Armed with this knowledge, you can bring your JavaScript classes and objects to life with clear, flexible, and powerful data structures.

References

If you want to learn more about JavaScript properties and object-oriented programming, these resources are excellent starting points:

Scroll to Top