Skip to main content

JavaScript Classes

JavaScript Class Fields

Written by Published

Class fields declare properties directly in the class body.

Before fields existed, every property had to be assigned in the constructor.

A field states the default up front, where it is easy to see.

Example

Example

javascript

class Counter {
  count = 0;

  up() {
    this.count++;
    return this.count;
  }
}

console.log(new Counter().up());

The output is 1, starting from the field's default of 0.

What is a Class Field?

A field is a property written directly in the class body.

It is set on every instance before the constructor body runs.

Fields end with a semicolon, not a comma.

Syntax

Syntax

javascript

class Name {
  property = value;
}

No let, const or this in the declaration.

Fields Are Per-Instance

Each instance gets its own copy, so arrays are not shared.

Example

Example

javascript

class Basket {
  items = [];
}

const a = new Basket();
const b = new Basket();

a.items.push("Book");

console.log(a.items.length + " and " + b.items.length);

The output is 1 and 0.

Fields Run Before the Constructor

The constructor can rely on the field already having its default.

Example

Example

javascript

class Person {
  greeting = "Hello";

  constructor(name) {
    this.message = this.greeting + " " + name;
  }
}

console.log(new Person("Ada").message);

The output is Hello Ada.

A Constructor Can Override a Field

An assignment in the constructor happens after the field is set.

Example

Example

javascript

class Box {
  size = 1;

  constructor(size) {
    if (size) {
      this.size = size;
    }
  }
}

console.log(new Box().size + " then " + new Box(5).size);

The output is 1 then 5.

Arrow Function Fields Keep this

An arrow function field is bound to the instance permanently.

That makes it safe to pass around as a callback.

Example

Example

javascript

class Person {
  name = "Ada";

  greet = () => {
    return "Hello " + this.name;
  };
}

const greet = new Person().greet;

console.log(greet());

A normal method here would have lost this.

The Cost of Arrow Fields

Each instance gets its own copy, unlike a shared prototype method.

Use them when you need the binding, not by default.

Example

Example

javascript

class Person {
  arrow = () => "hi";
  normal() {
    return "hi";
  }
}

const a = new Person();
const b = new Person();

console.log(a.arrow === b.arrow);
console.log(a.normal === b.normal);

The arrow is false and the method is true: one is copied, the other shared.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Class Fields</title>
</head>
<body>

  <h1>Class Fields</h1>

  <p id="out"></p>
  <button id="btn">Add one</button>

  <script>
    class Counter {
      count = 0;

      up = () => {
        this.count++;
        document.getElementById("out").textContent = "Count: " + this.count;
      };
    }

    const counter = new Counter();

    document.getElementById("btn").addEventListener("click", counter.up);
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try a normal method:

Change up to a normal method and see the click handler break.

Important Points

  • A field declares a property in the class body.
  • Fields are set before the constructor body runs.
  • Each instance gets its own copy.
  • An arrow function field keeps this bound to the instance.
  • Arrow fields are copied per instance, so use them deliberately.

Conclusion

Class fields put an object's shape where you can see it at a glance.

The arrow function field is the standard fix for callbacks losing this.

Just remember it trades sharing for binding.