ES3 en détails

Tutoriel pour apprendre à utiliser la valeur de this en JavaScript

Dans ce tutoriel, nous allons discuter d'une propriété supplémentaire liée aux contextes d'exécution : le mot-clé this.

14 commentaires Donner une note à l'article (5)

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Beaucoup de développeurs associent le mot-clé this à ce qu'il est dans la programmation orientée objet, à savoir, une référence à un objet nouvellement créé par un constructeur. En JavaScript ce concept existe aussi, cependant il ne se limite pas uniquement à la référence d'un objet instancié.

Comme la pratique le montre, ce sujet est assez difficile et trouver quelle est la valeur de this à travers les différents contextes d'exécution est bien souvent problématique.

Voyons plus en détail toutes les possibilités offertes par le mot-clé this en JavaScript.

II. Définitions

this est une propriété du contexte d'exécution. C'est un objet spécial du contexte dans lequel le code est exécuté.

Pseudo-code
Sélectionnez
1.
2.
3.
4.
5.
6.
activeExecutionContext = {
    VO: {
        <...>
    },
    this: <objet dédiée ou GO>
}

Il y a l'objet des variables (dont la forme abrégée sera VO pour « variable object ») dont nous avons discuté dans le chapitre précédent.

Quant à this, il est directement lié aux déclinaisons de codes exécutables des contextes. La valeur de this est déterminée pendant la phase d'entrée dans le contexte et est immuable pendant que le code du contexte est exécuté.

Examinons les différents cas en détail.

III. La valeur de this dans le code global

Dans le code global, la valeur de this est toujours l'objet global (dont la forme abrégée sera GO pour « global object »). Il est donc possible d'y faire référence indirectement comme suit :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
// Définition explicite d'une propriété de `this`
this.jack = 10; // === (GO.jack = 10)
console.log(jack); // `10`

// Définition implicite via l'assignation d'une propriété de l'objet global
sally = 20;
console.log(this.sally); // `20`

// Définition implicite via la déclaration d'une variable
// car l'objet des variables du contexte global est l'objet global lui-même
var zero = 30;
console.log(this.zero); // `30`

IV. La valeur de this dans le code des fonctions

Les choses sont plus intéressantes quand this est utilisé à l'intérieur d'une fonction. Ce cas est le plus compliqué et est la cause de beaucoup de peines.

La première (et sûrement la plus importante) chose à savoir sur le mot-clé this dans cette déclinaison de code est qu'ici elle n'est pas statiquement liée à la fonction.

Comme mentionné plus haut, la valeur de this est déterminée pendant la phase d'entrée dans le contexte et dans le cas d'une fonction, cette valeur peut être complètement différente à chaque fois (à chaque appel).

Cependant, une fois la phase d'exécution du code en cours, la valeur de this est immuable. C'est-à-dire qu'il n'est pas possible de lui affecter une nouvelle valeur, car ce n'est pas une variable (par opposition au langage de programmation Python, par exemple, dont l'objet self est explicitement défini et peut donc être redéfini à souhait pendant la phase d'exécution) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
var nightmare = { gift: 10 };

var christmas = {
    gift: 20,
    party: function () {

        console.log(this === christmas); // `true`
        console.log(this.gift); // `20`

        this = nightmare; // « erreur : cette valeur ne peut être changée »

        // console.log(this.gift); // `20`
        // S'il n'y avait pas eu d'erreur, cette valeur aurait pu être `10` à la place

    }

};

// pendant la phase d'entrée dans le contexte la valeur de `this`
// est déterminée comme se référant à `christmas` ; pourquoi ?
// nous en discuterons plus en détail plus bas

christmas.party(); // `true`, `20`

nightmare.party = christmas.party;

// cependant juste après, la valeur de `this` se réfère
// à `nightmare`, même si nous appelons la même fonction

nightmare.party(); // `false`, `10`

Alors qu'est-ce qui fait varier la valeur de this dans le code d'une fonction ? Sa façon d'être activée.

Dans une fonction appelée de manière standard, this est fourni par l'appelant (« caller ») qui active le code du contexte, c'est-à-dire le contexte parent qui appelle la fonction. Et la valeur de this est déterminée par la forme de l'expression appelante (en d'autres mots, par la forme syntaxique avec laquelle la fonction est appelée).

C'est réellement un point important, aussi, nous allons encore insister sur ce point une nouvelle fois afin de déterminer sans problèmes la valeur de this dans chaque contexte. La forme de l'expression appelante, c'est-à-dire la manière dont la fonction est appelée, est la seule chose qui influence la valeur de this dans le contexte appelé.

Cela signifie donc que si vous avez pu lire ceci dans différents articles (ou même des livres) sur le JavaScript :

« La valeur de this dépend de la manière dont la fonction est définie. Si c'est une fonction global, this se réfère à l'objet global, et si cette fonction est la méthode d'un objet, la valeur de this est toujours cet objet ».

Hé bien ces articles se trompaient.

Nous allons voir que même une fonction globale peut être activée avec différentes formes d'expression appelante qui influencent tout autant la valeur de this :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function gift() {
    console.log(this);
}

gift(); // `GO`

console.log(gift === gift.prototype.constructor); // `true`

// mais en exécutant notre fonction sous une forme d'expression appelante différente,
// pour la même fonction, la valeur de `this` est différente

gift.prototype.constructor(); // vaut le prototype de la fonction soit `gift.prototype`.

Autre exemple. Il est aussi possible d'appeler une fonction définie en tant que méthode d'un objet, mais que la valeur de this ne fasse pas référence à cet objet :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var gift = {
    toy: function () {
        console.log(this);
        console.log(this === gift);
    }
};

gift.toy(); // `gift`, `true`

var exampleFunc = gift.toy;

console.log(exampleFunc === gift.toy); // `true`

// cependant une fois encore sous une nouvelle forme d'expression appelante
// à partir de la même fonction, nous avons une valeur de `this` différente

exampleFunc(); // `GO`, `false`

Maintenant que la vérité est (r)établie, voyons comment concrètement la forme de l'expression appelante influence la valeur de this.

Afin d'y répondre, il faut d'abord comprendre par quel mécanisme interne est déterminée la valeur de this. Pour cela, il est nécessaire de voir plus en détail un type interne du JavaScript — le type Reference.

IV-A. Le type Reference

En utilisant du pseudocode, une valeur de type Reference peut être représentée comme un objet avec deux propriétés : la base (c'est-à-dire l'objet auquel appartient la propriété) et le nom de la propriété pour cette base :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
valueOfReferenceType = {
    base: <objet de la propriété>,
    propertyName: <nom de la propriété>
}

Notons que depuis ES5, une référence contient également une propriété nommée strict qui est une valeur indiquant si la référence doit être résolue en mode strict ou non.

 
Sélectionnez
'use strict';

// Accès à `jack`.
jack;
Pseudo-code
Sélectionnez
// Référence pour `jack`.
jackReference = {
    base: GO,
    propertyName: 'jack',
    strict: true,
}

La valeur d'un type Reference peut seulement être de deux sortes :

  1. Récupérée à partir d'un identifiant,
  2. Récupérée à partir d'un accesseur de propriété.

IV-A-1. Les identifiants

Les identifiants sont pris en charge par le processus de résolution d'identifiant qui sera vu plus en détail dans le chapitre sur la chaîne des portées. Nous allons tout de même voir ici que cet algorithme de résolution retourne toujours une valeur de type Reference (qui est un élément important pour trouver la valeur de this).

Les identifiants sont des noms de variables, des noms de fonctions, des noms de paramètres et des noms de propriétés non qualifiées (des propriétés de l'objet global accédées sans préfixe). Par exemple, en ce qui concerne les valeurs des identifiants suivants :

 
Sélectionnez
1.
2.
3.
var jack = 10; // variable
function sally() {}; // fonction
zero = 'ghost'; // propriété non qualifiée

un résultat intermédiaire des opérations de résolution correspondant au type Reference serait le suivant :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
jackReference = {
    base: GO,
    propertyName: 'jack'
}

sallyReference = {
    base: GO,
    propertyName: 'sally'
}

zeroReference = {
    base: GO,
    propertyName: 'zero'
}

Et pour obtenir la valeur réelle d'un objet depuis sa valeur de type Reference, il y a une méthode interne GetValue qui peut-être décrite en pseudocode comme suit :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
function GetValue(value) {

    // Quand on ne demande pas la valeur d'un type Reference
    if (Type(value) != Reference) {
        return value;
    }

    // Obtenir ce sur quoi pointe la référence
    base = GetBase(value);

    // Vérifier qu'elle ne pointe pas dans le vide
    if (base === null) {
       throw new ReferenceError;
    }

    // Obtenir cette valeur
    return base.[[Get]](GetPropertyName(value));

}

Il y a une méthode interne [[Get]] qui retourne la valeur réelle de la propriété d'un objet, incluant au préalable l'analyse de l'héritage de cette valeur vis-à-vis de la chaîne des prototypes :

Pseudo-code
Sélectionnez
1.
2.
3.
GetValue(jackReference) // `10`
GetValue(sallyReference) // `function sally() {}`
GetValue(zeroReference) // `'ghost'`

IV-A-2. Les accesseurs de propriété

Les accesseurs de propriété utilisent aussi ce mécanisme et il y en a deux déclinaisons : la notation point (« dot ») (quand la propriété a un nom correct et connu à l'avance), ou la notation crochet droit (« bracket ») :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
var barrel = {
    lock: function shock() {}
}

// accesseurs
barrel.lock();
barrel['lock']();

Dont un retour de calcul intermédiaire de type Reference est :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
5.
6.
barrelLockReference = {
    base: barrel,
    propertyName: 'lock'
}

GetValue(barrelLockReference) // `function shock() {}`

IV-A-3. Détermination de this

Donc, reposons la question une dernière fois : en quoi la valeur de type Reference est liée à la valeur de this du contexte de la fonction ? C'est parti pour la révélation principale de cet article.

La règle générale de la détermination de la valeur de this dans un contexte de fonction est la suivante :

La valeur de this dans un contexte de fonction est fournie par l'appelant et déterminée en fonction de la forme de l'expression appelante (la manière dont la fonction est syntaxiquement appelée).

Si sur la partie à gauche des parenthèses appelantes (...), il y a une valeur de type Reference alors la valeur de this associée est celle contenue dans la base de cette valeur de type Reference.

Dans tous les autres cas (c'est-à-dire avec n'importe quelle autre valeur qui n'est pas un type Reference), la valeur de this est toujours mise à null. Mais comme il n'y a pas de sens à ce que la valeur de this soit null, cette valeur est implicitement remplacée par l'objet global.

Notons qu'en mode strict en ES5, la valeur de this n'est pas associée à l'objet global mais est mise à undefined.

Montrons un exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
function barrel() {
    return this;
}

barrel(); // `this` vaut `GO`

Nous voyons que dans la partie gauche des parenthèses appelantes, il y a une valeur de type Reference (car barrel est un identifiant) :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
barrelReference = {
    base: GO,
    propertyName: 'barrel'
}

Donc, la valeur de this est définie comme étant celle de la base de la valeur du type Reference, c'est-à-dire l'objet global.

Voyons que cela est similaire avec un accesseur de propriété :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
var barrel = {
    lock: function shock() {
        return this;
    }
};

barrel.lock(); // `this` vaut `barrel`

Nous avons de nouveau une valeur de type Reference avec pour base l'objet barrel qui va donc être utilisé comme valeur de this lors de la phase d'activation :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
barrelLockReference = {
    base: barrel,
    propertyName: 'lock'
}

Cependant, activer la même fonction avec une autre forme d'expression appelante, nous montre que l'on a une autre valeur de this :

 
Sélectionnez
1.
2.
var oogieBoogie = barrel.lock;
oogieBoogie(); // `this` vaut `GO`

car oogieBoogie étant un identifiant, il produit une autre valeur de type Reference utilisée comme base (l'objet global) et donc pour la valeur this :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
oogieBoogieReference = {
    base: GO,
    propertyName: 'oogieBoogie'
}

Maintenant, nous pouvons exactement dire pourquoi la même fonction activée sous différentes formes d'expression appelante a différentes valeurs de this. La réponse est qu'il y a une valeur intermédiaire de type Reference différente :

Cas des identifiants :

 
Sélectionnez
1.
2.
3.
4.
5.
function barrel() {
    console.log(this);
}

barrel(); // `GO`

Car,

Pseudo-code
Sélectionnez
1.
2.
3.
4.
barrelReference = {
    base: GO,
    propertyName: 'barrel'
}

Cas des accesseurs de propriété :

 
Sélectionnez
1.
2.
3.
4.
5.
console.log(barrel === barrel.prototype.constructor); // true

// autre forme d'expression appelante

barrel.prototype.constructor(); // `barrel.prototype`

Car,

Pseudo-code
Sélectionnez
1.
2.
3.
4.
barrelPrototypeConstructorReference = {
    base: barrel.prototype,
    propertyName: 'constructor'
}

Voici encore un autre exemple classique avec une détermination dynamique de la valeur de this en fonction de la forme de l'expression appelante :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function barrel() {
    console.log(this.lock);
}

var nightmare = { lock: 10 };
var christmas = { lock: 20 };

nightmare.gift = barrel;
christmas.gift = barrel;

nightmare.gift(); // `10`
christmas.gift(); // `20`

IV-B. Appel de fonctions et types sans Reference

Nous avons noté plus haut que dans le cas où la partie gauche des parenthèses appelantes est une valeur qui n'est pas de type Reference (mais de n'importe quel autre type), la valeur de this est automatiquement mise à null et, par conséquent, remplacée par l'objet global.

Imaginons un exemple avec une telle expression :

 
Sélectionnez
1.
2.
3.
(function () {
    console.log(this); // `null` => `GO`
})();

Dans ce cas, nous avons une fonction de type Object (d'instance Function) mais pas un type Reference (il n'y a aucun identifiant ou accesseur de propriété à résoudre), et donc la valeur de this est finalement remplacée par celle de l'objet global.

Voici des exemples plus complexes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var barrel = {
    lock: function () {
        console.log(this);
    }
};

barrel.lock(); // Premier cas
(barrel.lock)(); // Deuxième cas
(barrel.lock = barrel.lock)(); // Troisième cas
(false || barrel.lock)(); // Quatrième cas
(barrel.lock, barrel.lock)(); // Cinquième cas

Nous avons un accesseur de propriété dont la valeur intermédiaire devrait normalement être une valeur de type Reference nous fournissant en base l'objet barrel (premier cas), mais qui pourtant, dans certains cas, nous donne pour this une base valant GO (Autres cas ?).

Le point ici, c'est que les trois derniers appels (qui ont bien une partie à gauche des parenthèses appelantes) après l'application de certaines opérations ne retournent pas une valeur de type Reference.

  • Avec le premier cas, tout est clair. Il n'y a sans l'ombre d'un doute un type Reference qui est résolu, et par conséquent, la valeur de this est la base de cette référence, c'est-à-dire barrel.
  • Dans le deuxième cas, il y a un opérateur de groupement qui n'applique pas, comme nous l'avons vu plus haut, la méthode pour aller chercher la valeur réelle d'un objet depuis une valeur de type Reference, c'est-à-dire qui n'applique pas GetValue. Sachant cela, après l'évaluation de l'opérateur de groupement qui dans ce cas retourne simplement barrel.lock, nous obtenons de nouveau une expression à gauche dont la valeur sera de type Reference et dont la base sera pour this l'objet barrel.
  • Dans le troisième cas, l'opération dans l'opérateur de groupement se fait avec l'opérateur d'affectation, à la différence d'une opération réalisée uniquement avec un opérateur de groupement, l'opérateur d'affectation appelle la méthode GetValue. La conséquence est que cela nous ramène, une fois l'expression complètement évaluée, une fonction de type Object (mais pas une valeur de type Reference). Dans ce cas this vaut null et, par conséquent, vaut l'objet global.
  • De la même manière pour les quatrième et cinquième exemples, l'opérateur virgule et l'opérateur d'expression logique OR font appel à la méthode interne GetValue. Ils perdent leurs valeurs de type Reference pour retourner une valeur de type Object (une fonction). Donc this finit par valoir l'objet global.

IV-C. Le type Reference et la valeur null de this

Nous avons vu qu'il y a des cas où l'appel de l'expression se situant sur la partie gauche des parenthèses retourne bien une valeur intermédiaire de type Reference, mais qu'il y a aussi des cas où la valeur de this est à null (et donc remplacée par l'objet global). C'est ce qui arrive quand la base de la valeur du type Reference est un objet d'activation (dont la forme abrégée sera AO pour « activation object »).

Nous pouvons mettre en évidence cela dans un exemple avec une fonction interne à une fonction parente appelante. Comme nous l'avons vu dans le deuxième chapitre ; les variables locales, les fonctions internes et les paramètres formels sont stockés dans l'objet d'activation, ce qui donne :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
function jack() {
    function sally() {
        console.log(this);
    }
    sally(); // Comme la base de `sally` est `AO(jack)`, `this` est remplacé par `GO`
}

L'objet d'activation retourne toujours une valeur de this équivalente à null (c'est-à-dire que le pseudocode AO(jack) est équivalent à null). Ici encore, nous en revenons à la description précédente indiquant que la valeur de this dans le cas où elle est null est l'objet global.

Une exception demeure cependant avec une fonction qui serait appelée dans la structure de contrôle with dans le cas où with contiendrait un nom de propriété de fonction. La structure de contrôle with ajoute ses objets en amont de la chaîne de portées, c'est-à-dire avant l'objet d'activation. Par conséquent, la base de la valeur de type Reference (par un identifiant ou un accesseur de propriété) n'est pas l'objet d'activation, mais l'objet de la structure de contrôle with. Au passage, cela n'est pas vrai uniquement pour des fonctions internes, mais également aux fonctions globales, car l'objet with masque les objets les plus hauts (objet global ou objet d'activation) dans la chaîne des portées :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var gift = 10;

with ({

    jack: function () {
        console.log(this.gift);
    },
    gift: 20

}) {

    jack(); // 20

}

Car,

Pseudo-code
Sélectionnez
1.
2.
3.
4.
jackReference = {
    base: __withObject,
    propertyName: 'jack'
}

Une situation similaire intervient en appelant une fonction qui serait le premier argument de la structure de contrôle catch : dans ce cas, l'objet catch est aussi ajouté en amont de la chaîne des portées c'est-à-dire avant l'objet d'activation ou l'objet global. Cependant, ce comportement est reconnu comme un bug dans ECMA-262-3, car la nouvelle version du standard ECMA-262-5 rectifie cela. C'est-à-dire que la valeur de this pour un objet d'activation doit être équivalente à l'objet global et non plus à l'objet catch :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
try {
    throw function () {
        console.log(this);
    };
} catch (nightmare) {
    nightmare(); // `__catchObject` en ES3, `GO` dans la version ES5
}

c'est-à-dire en ES3 :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
eReference = {
    base: __catchObject,
    propertyName: 'nightmare'
}

mais en ES5 :

Pseudo-code
Sélectionnez
1.
2.
3.
4.
eReference = {
    base: GO,
    propertyName: 'nightmare'
}

On a également la même situation avec un appel récursif d'une expression de fonction nommée (plus de détails à propos des fonctions seront donnés dans un prochain tutoriel). Au premier appel de la fonction, la base de la valeur intermédiaire de type Reference est l'objet d'activation parent (soit l'objet global), mais dans les appels récursifs — la base devrait être un objet spécial stockant le nom optionnel de l'expression de fonction. Cependant, dans ce cas, la valeur de this associée est toujours l'objet global :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
(function nightmare(jack) {

    console.log(this);

    !jack && nightmare(1); // « devrait » être un objet spécial, mais est toujours l'objet global

})(); // `GO`

IV-D. La valeur de this dans une fonction appelée en tant que constructeur

Il y a un cas de plus en rapport avec la valeur de this dans un contexte de fonction. On le nomme appel de fonction en tant que constructeur :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
function Happy() {
    console.log(this); // objet nouvellement créé plus bas et nommé `happy`
    this.halloween = 10;
}

var happy = new Happy();
console.log(happy.halloween); // `10`

Dans ce cas, l'opérateur new appelle la méthode interne [[Construct]] de la fonction Halloween qui va appeler à son tour la méthode interne [[Call]] après chaque création d'un nouvel objet pour fournir une nouvelle valeur de this pour chacun d'eux.

IV-E. Manuellement affecter la valeur de this à l'appel d'une fonction.

Il y a deux méthodes définies dans Function.prototype (et donc accessibles par toutes les fonctions), permettant de spécifier la valeur de this manuellement lors de l'appel d'une fonction. Ces méthodes sont apply et call.

Chacune d'entre elles accepte en premier argument la valeur que va prendre this dans le contexte créé lors de l'appel. La différence entre ces deux méthodes est vraiment minime. Pour apply, le second argument est obligatoirement un objet sous forme de tableau (ou un objet s'en rapprochant comme la propriété arguments de l'objet d'activation) dont chaque élément dans l'ordre sera associé à chaque paramètre de la fonction de gauche à droite. Pour call, la méthode accepte n'importe quels arguments. Le seul paramètre obligatoire pour ses deux méthodes est le premier, c'est-à-dire la valeur que prendra this.

Exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var sally = 10;

function halloween(jack) {
    console.log(this.sally);
    console.log(jack);
}

halloween(20); // `this === GO`, `this.sally === 10` et `jack === 20`

halloween.call({ sally: 20 }, 30); // `this === <premier argument>`, `this.sally === 20` et `jack === 30`
halloween.apply({ sally: 30 }, [40]) // `this === <premier argument>`, `this.sally === 30` et `jack === 40`

V. Conclusion

Dans ce tutoriel, nous avons discuté des fonctionnalités du mot-clé this en JavaScript (qui est vraiment une fonctionnalité par comparaison au C++ ou au Java). Dans le prochain chapitre de cette série, nous allons éclaircir un point plusieurs fois mentionné dans ce tutoriel : la chaîne des portées.

VI. Remerciements

Nous remercions Bruno Lesieur qui nous a autorisés à publier ce tutoriel.

Nous remercions également Laethy pour la mise au gabarit et Fabien pour la correction orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2018 Nom Auteur. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.