# Classes

## Création d'une classe

{% 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 %}

## Visibilité

En attendant la notion de [class fields](https://github.com/tc39/proposal-class-fields) qui sera probablement bientôt introduite en ECMAScript 2019 <http://kangax.github.io/compat-table/esnext/>, la notion de visibilité `private` se base sur la convention de nommage qui consiste à préfixer la propriété ou la méthode par le caractère underscore : `_`

```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';
    }

}
```

## Propriétés

```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" %}
Ne les utilisez pas.

L'implémentation de propriétés peut s'avérer pratique dans certains cas extrêmes tels que l'intégration d'une librairie "legacy", mocking, décoration pour "type checking" etc...

Autrement, cela introduit surtout de l'ambiguité dans le code.

Qui pourrait imaginer que le code suivant puisse lever une exception ?

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

Ou pire encore :

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

*Toute ressemblance avec du code existant est fortuite.*
{% endhint %}

## Héritage

```javascript
export class WishtackProduct extends Product {

    ...

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

}
```

{% hint style="warning" %}
Evitez l'héritage...

... et préférez la composition !
{% endhint %}

## Bonnes pratiques

{% hint style="success" %}
En l'absence de notion de "class fields", il est recommandé d'initialiser toutes les attributs dans le constructeur. Autrement, il est difficile de déterminer les attributs d'une classe et les attributs présents sur une instance dépendront alors des méthodes appelées.
{% endhint %}


---

# Agent Instructions: 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:

```
GET https://guide-angular.wishtack.io/ecmascript-6+/classes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
