> For the complete documentation index, see [llms.txt](https://web-dev-guide.wishtack.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://web-dev-guide.wishtack.io/ecmascript/classes.md).

# Classes

## ES6 Classes

{% tabs %}
{% tab title="ES6 Class" %}

```javascript
class Customer {

    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    getName() {
        return this.firstName;
    }

}
```

{% endtab %}

{% tab title="Legacy Prototype" %}

```javascript
var Customer = function(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Customer.prototype = {
    getName: function () {
        return this.firstName;
    }
}
```

{% endtab %}
{% endtabs %}

## Visibility

Meanwhile [class fields](https://github.com/tc39/proposal-class-fields) get supported, visibility rules are just based on a common naming convention where properties and methods get prefixed with the underscore character `_` if they are private.

```javascript
class Customer {

    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = null;
        this._isBadPayer = this._tellIfBadPayer();
    }
    
    getName() {
        return this.firstName;
    }
    
    _tellIfBadPayer() {
        return this.firstName === 'foo';
    }

}
```

## Properties

```javascript
class Customer {

    constructor(firstName, lastName) {
        this.firstName = firstName;
    }

    get firstName() {
        return this._firstName;
    }
    
    set firstName(value) {
        this._firstName = value;
    }
    
}

/* @HACK: Last time we use var, I promise! */
var customer = new Customer();

customer.firstName = 'Foo';

console.log(customer.firstName); // Foo
```

{% hint style="danger" %}
Avoid using properties.

Properties can become handy in some extreme cases like the integration of some legacy library, mock, implementing a runtime type checking decorator or something fancy like that etc...

Otherwise, properties will only introduce ambiguity.

Who would imagine that this code might trigger a runtime exception?

```javascript
var customer = new Customer();
element.textContent = customer.name;
```

Or even worse, things might end up like this:

```javascript
/* @HACK: Do not remove this useless line as it initializes
 * the user eagerly instead of running it lazily. */
request.user;
```

{% endhint %}

## Inheritance

This is inheritance:

```javascript
export class WishtackProduct extends Product {

    ...

    getProductId() {
        return 'wishtack-' + this._wishtackId;
    }

}
```

{% hint style="warning" %}
Now, avoid it...

... and prefer composition!
{% endhint %}

## Best practices

{% hint style="success" %}
Meanwhile we get the class fields in JavaScript, it is recommended to initialize all the attributes in the constructor. Otherwise, it's hard to figure out which attributes are available on a class. In addition to this, the available attributes will depend on the methods that have been called.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://web-dev-guide.wishtack.io/ecmascript/classes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
