JavaScript, un langage de types de données divers et flexibles, est fondamentalement divisé en deux catégories : les primitives et les objets . Cette distinction est cruciale à comprendre pour les développeurs de tous niveaux, car elle constitue la base sur laquelle JavaScript fonctionne. Revisitons ces concepts pour solidifier notre compréhension.
Valeurs primitives : les bases
"hello"
et "farewell"
sont encapsulées entre guillemets, servant de pierre angulaire à la manipulation textuelle en JavaScript.
-5
) ou de décimaux ( 3.14
), les nombres sont le fondement des opérations mathématiques dans le langage.
Les primitives sont immuables , ce qui signifie que leurs valeurs ne peuvent pas être modifiées une fois créées. Cette caractéristique prête souvent à confusion, surtout lorsque l'on confond une variable qui détient une valeur primitive avec la valeur elle-même.
Comprendre que les primitives sont immuables permet de clarifier de nombreux aspects du comportement de JavaScript, notamment dans les opérations de comparaison et d'affectation.
Au cours de notre parcours à travers JavaScript, même si nous n'utilisons pas directement certains de ces types, la reconnaissance et la compréhension de leurs rôles enrichissent notre boîte à outils de codage, ouvrant la voie à un code plus sophistiqué et plus efficace.
Au-delà du domaine des primitives, l'univers de JavaScript est dominé par les objets. Cette catégorie englobe un large éventail de structures de données, dont certaines pourraient vous surprendre, comme les Arrays . On rencontre principalement :
{}
pour les objets standards ou []
pour les tableaux, ces structures sont l'épine dorsale du regroupement des données et fonctionnalités associées.
x => x * 2
entre autres, les fonctions sont des citoyens de premier ordre en JavaScript, permettant d'attribuer du code à des variables, de le passer en arguments ou de le renvoyer depuis d'autres fonctions.
Les objets diffèrent fondamentalement des primitifs ; ils sont mutables et peuvent être directement manipulés dans notre code. Une idée fausse courante consiste à considérer tout ce qui est en JavaScript comme un objet. Cela est en partie vrai en raison de certains comportements de valeurs primitives, semblables à des objets. Par exemple, l'expression "hi".toUpperCase()
peut soulever des questions : comment une chaîne primitive peut-elle avoir des méthodes ?
Cela se produit via un processus connu sous le nom de « boxing » , dans lequel JavaScript encapsule temporairement les valeurs primitives dans des wrappers d'objet pour accéder aux méthodes, uniquement pour supprimer ces objets une fois l'opération terminée.
C'est un aspect fascinant de la conception de JavaScript, permettant aux primitives de bénéficier de méthodes de type objet sans être réellement des objets. Comprendre cette distinction est crucial à mesure que nous approfondissons la typologie de JavaScript.
typeof
d'opérateur JavaScript et le cas unique de null
Faire la distinction entre les différents types de données en JavaScript peut parfois sembler un peu magique. Entrez l'opérateur typeof
, un outil puissant de votre boîte à outils JavaScript qui révèle le type d'une valeur donnée. Voici comment cela fonctionne en pratique :
console.log(typeof(5)); // Outputs "number" console.log(typeof("hi")); // Outputs "string" console.log(typeof(undefined)); // Outputs "undefined" console.log(typeof({})); // Outputs "object" console.log(typeof([])); // Outputs "object" console.log(typeof(x => x * 2)); // Outputs "function"
Cependant, dans le domaine de JavaScript, tout ne semble pas être ce qu’il semble être. Prenons, par exemple, le traitement de null
par l'opérateur typeof
. Malgré les attentes, typeof null
renvoie "object"
, un résultat qui laisse perplexe de nombreux développeurs. Ce comportement n'est pas tant un bug qu'une bizarrerie du langage, ancrée dans les premières décisions de conception de JavaScript.
La valeur null
est censée représenter l’absence intentionnelle de toute valeur d’objet, mais la typeof
en tant qu’objet. Cette bizarrerie est bien connue et a persisté tout au long de l'évolution de JavaScript en raison de problèmes de compatibilité ascendante.
Il est essentiel de se rappeler que, contrairement à undefined
, qui signifie des valeurs qui n'ont pas été attribuées, null
est utilisé explicitement pour désigner l'attribution délibérée de « aucune valeur ». Bien que JavaScript n'impose pas la distinction d'utilisation entre null
et undefined
, l'adoption d'une approche cohérente de votre code peut aider à clarifier votre intention et à améliorer la lisibilité et la maintenabilité.
Dans le monde dynamique de JavaScript, écrire du code revient à poser des questions, et le langage répond par des réponses. Ces interactions sont capturées à travers ce que nous appelons des expressions . Une expression en JavaScript est toute unité de code valide qui se résout en une valeur.
Regardons un exemple simple :
console.log(5 + 5); // Outputs 10
Dans ce cas, 5 + 5
est une expression que javascript évalue avec la valeur 10
.
Les expressions sont les éléments constitutifs du code JavaScript, permettant des interactions et des calculs dynamiques au sein de vos programmes. Ils peuvent être aussi simples que l’exemple ci-dessus ou plus complexes. En fait, les expressions constituent votre ligne de communication directe avec le langage pour créer des applications Web interactives et dynamiques.
Alors que les types de données primitifs en JavaScript, tels que les chaînes, les nombres et les booléens, sont créés en tant qu'entités prédéfinies, les objets fonctionnent selon un principe différent. Chaque fois que nous utilisons {}
(accolades), nous ne faisons pas simplement référence à un plan existant ; nous donnons naissance à un tout nouvel objet. Considérons la création de deux objets simples :
const cat = {}; const dog = {};
Ici, cat
et dog
sont des objets distincts, chacun avec son propre espace en mémoire. Ce principe s'étend au-delà des simples littéraux d'objet pour englober toutes les structures de données complexes en JavaScript, y compris les tableaux, les dates et les fonctions.
Bien qu'il existe différentes méthodes pour créer ces entités, l'utilisation de {}
pour les objets, []
pour les tableaux et new Date()
pour les dates font partie des approches les plus directes pour créer des instances d'objet.
Mais qu’arrive-t-il à ces objets lorsqu’ils ne sont plus nécessaires ? Restent-ils indéfiniment dans l’univers JavaScript ? La réponse réside dans le mécanisme de récupération de place de JavaScript, un processus qui nettoie efficacement la mémoire qui n'est plus utilisée.
Le garbage collection est une opération automatique, ce qui signifie que les objets sont détruits et la mémoire qui leur est allouée récupérée une fois qu'il n'y a plus de référence à eux dans votre code.
En JavaScript, comparer des valeurs peut parfois donner l’impression de naviguer dans un labyrinthe, avec différents chemins vers la même destination : comprendre l’égalité. Il existe trois manières principales de comparer des valeurs :
Égalité stricte ( ===
) : Cette forme d'égalité est la plus précise, vérifiant à la fois la valeur et le type des deux opérandes. Cela revient à demander : « Ces deux valeurs sont-elles identiques en termes de type et de contenu ? »
Égalité lâche ( ==
) : moins stricte que l'égalité stricte, l'égalité lâche permet la coercition de type avant la comparaison. C'est comme demander : « Ces deux valeurs peuvent-elles être considérées comme identiques si l'on néglige leurs types ? »
Égalité de même valeur ( Object.is
) : cette méthode est similaire à l'égalité stricte mais avec quelques différences critiques, notamment dans la façon dont elle gère les cas JavaScript spéciaux.
Voyons Object.is
en action :
console.log(Object.is(2, 2)); // true console.log(Object.is({}, {})); // false
Pourquoi Object.is({}, {})
renvoie-t-il false ? Parce que chaque objet littéral {}
crée un objet unique en mémoire, ce qui amène Object.is
à les traiter comme des entités distinctes malgré leur similarité structurelle.
Bien que l'égalité stricte soit simple , elle présente ses propres particularités, notamment avec certaines valeurs JavaScript :
NaN === NaN
: Étonnamment, cette comparaison renvoie false
. En JavaScript, NaN
(Not-a-Number) est considéré comme inégal à lui-même, un trait rare destiné à signaler le résultat d'un calcul indéfini ou erroné.
-0
et 0
: -0 === 0
et 0 === -0
renvoient true
, bien que -0
et 0
soient des valeurs distinctes dans le système numérique de JavaScript. Cette égalité néglige le signe zéro et se concentre uniquement sur sa grandeur. Comprendre ces différences dans la vérification de l'égalité est primordial pour écrire du code JavaScript précis et sans bug. Bien que ===
et ==
aient leur rôle, savoir quand utiliser Object.is
peut être crucial, en particulier pour les cas extrêmes impliquant NaN
, 0
et -0
.
Ces connaissances permettent aux développeurs de prendre des décisions éclairées concernant les contrôles d'égalité, garantissant ainsi que leur code se comporte comme prévu dans un large éventail de scénarios.
Lorsqu'il s'agit de manipuler les propriétés d'un objet en JavaScript, vous disposez de deux outils principaux : la notation par points et la notation par crochets . Les deux méthodes offrent un chemin simple pour accéder et modifier le contenu d'un objet. Voici une introduction rapide :
object.key
).
object['key']
).
Ces techniques constituent la base de l’interaction avec les objets. Cependant, un aspect essentiel à comprendre est la façon dont JavaScript gère les références d'objets . Contrairement aux types de données primitifs, les objets en JavaScript sont des types référencés, ce qui signifie que lorsque vous manipulez un objet, vous travaillez avec une référence à l'emplacement de cet objet en mémoire, et non avec une copie directe de l'objet lui-même.
Pour donner vie à ce concept, considérons un scénario impliquant deux écrivains en herbe, Emily et Thomas, collaborant sur un roman. Ils décident d'utiliser des objets JavaScript pour structurer les personnages et les décors de leur histoire :
const project = { title: "Adventures in Code", characters: { protagonist: { name: "Alex", traits: ["brave", "curious"] } }, setting: { location: "Virtual World", era: "future" } };
Au fur et à mesure qu'ils développent leur histoire, Emily présente un personnage secondaire inspiré du protagoniste mais avec une touche unique :
const sidekick = project.characters.protagonist; sidekick.name = "Sam"; sidekick.traits.push("loyal");
Simultanément, Thomas décide d’élargir le cadre de leur roman :
const newSetting = project.setting; newSetting.location = "Cyber City"; newSetting.era = "2040";
À première vue, vous pourriez vous demander comment ces modifications affectent l'objet du project
d'origine. Voici le résultat :
sidekick
n'est pas un nouvel objet mais une référence à project.characters.protagonist
. La modification sidekick
a un impact direct sur l'objet du project
d'origine.
newSetting
est une référence à project.setting
, ce qui signifie que toute modification apportée à newSetting
affecte directement project.setting
.Cet exemple met en évidence un concept essentiel en JavaScript : travailler avec des objets signifie travailler avec des références, et lorsque vous affectez un objet à une variable, vous attribuez une référence à cet objet.
Toutes les modifications que vous apportez via cette référence sont reflétées dans toutes les références à cet objet. Ce comportement permet des structures de données complexes et interconnectées, mais nécessite également une gestion minutieuse pour éviter les effets secondaires involontaires.
Dans notre histoire, le processus collaboratif d'Emily et Thomas illustre magnifiquement comment les références d'objets peuvent servir les efforts créatifs de codage, permettant le développement partagé et dynamique de récits complexes ou, en termes plus pratiques, de structures de données complexes au sein de vos applications.
Lorsque vous travaillez avec des objets en JavaScript, l'affectation directe peut entraîner des modifications involontaires en raison de la nature de la copie des références. La création d'une copie de l'objet permet une manipulation sûre sans affecter l'objet d'origine ; de cette façon, nous atténuerons les modifications involontaires.
En fonction de vos besoins et des scénarios dont vous disposez, vous pouvez choisir entre une copie superficielle et une copie approfondie.
Object.assign : Cette méthode génère un nouvel objet en copiant les propriétés de la source vers l'objet cible ( {}
). Il est important de noter que Object.assign
effectue une copie superficielle, ce qui signifie que tous les objets ou tableaux imbriqués sont copiés par référence et non par leur valeur.
const original = { a: 1, b: { c: 2 } }; const copy = Object.assign({}, original); copy.bc = 3; // Affects both 'copy' and 'original'
Opérateur de propagation ( ...
) : analogue à Object.assign
, l'opérateur de propagation étend les propriétés de l'objet d'origine en un nouvel objet, ce qui entraîne une copie superficielle.
const copyUsingSpread = { ...original }; copyUsingSpread.bc = 4; // Also affects the 'original' object
JSON.parse et JSON.stringify : cette approche sérialise l'objet en une chaîne JSON, puis l'analyse à nouveau en un nouvel objet. Il crée effectivement une copie complète mais ne peut pas gérer les fonctions, les objets Date, les valeurs non définies et autres valeurs non sérialisables.
const deepCopy = JSON.parse(JSON.stringify(original)); deepCopy.bc = 5; // Does not affect the 'original' object
Bibliothèques : pour des scénarios plus complexes, des bibliothèques comme Lodash offrent des fonctions (par exemple, _.cloneDeep()
) qui peuvent cloner en profondeur des objets, notamment en gérant divers types de données plus efficacement que les méthodes JSON.
Reprenons notre exemple de projet d'écriture collaborative :
const project = { title: "Adventures in Code", characters: { protagonist: { name: "Alex", traits: ["brave", "curious"] } }, setting: { location: "Virtual World", era: "future" } };
Pour modifier le projet sans affecter l'original :
JSON.parse(JSON.stringify(project))
pour ajouter en toute sécurité un nouveau caractère ou modifier le paramètre.
Object.assign
ou l'opérateur de propagation pour les modifications de niveau supérieur où les structures imbriquées ne posent pas de problème.
Le choix entre une copie superficielle et profonde dépend de la complexité de l'objet et des exigences spécifiques de votre manipulation. Les copies superficielles sont plus rapides et plus adaptées aux objets simples, tandis que les copies profondes sont nécessaires pour les objets dotés de structures imbriquées, garantissant ainsi que l'objet d'origine reste intact.
En comprenant et en appliquant ces techniques d'adaptation, vous pouvez naviguer en toute confiance dans le système basé sur des références de JavaScript, garantissant ainsi que vos manipulations de données sont précises et intentionnelles.
Tout comme les personnages d’un roman héritent des traits de leurs ancêtres, les objets JavaScript héritent des propriétés et des méthodes de leurs prototypes. Ce concept reflète le métier de narrateur qu'Emily et Thomas ont exploré dans leur roman "Adventures in Code".
Pour approfondir notre compréhension des prototypes, poursuivons leur histoire en introduisant un nouvel arc de personnages qui reflète le modèle d'héritage en JavaScript.
Dans le monde de leur roman, il existe un scribe légendaire connu sous le nom de « L'Ancien Codeur », réputé pour sa sagesse et sa maîtrise des langues. Emily et Thomas décident de fonder un nouveau personnage, "Coder Leo", sur cette figure mythique, représentant la prochaine génération de codeurs.
// The Ancient Coder, known for his profound wisdom const ancientCoder = { wisdom: 100 }; // Coder Leo, a young scribe in training const coderLeo = { __proto__: ancientCoder, age: 15 };
Dans ce récit, Coder Leo est directement lié à The Ancient Coder par le biais d'un héritage magique connu sous le nom de « La chaîne prototype ». Cette connexion permet à Léo de puiser dans la sagesse de son ancêtre.
console.log(coderLeo.wisdom); // 100
Grâce à la chaîne prototype, Coder Leo peut accéder à la sagesse de The Ancient Coder malgré sa jeunesse. Mais que se passe-t-il lorsqu'ils rencontrent un défi ou un trait que The Ancient Coder ne possédait pas ?
console.log(coderLeo.courage); // undefined
Cette situation illustre un principe clé du système de prototypes JavaScript : si une propriété n'est pas trouvée sur l'objet, JavaScript recherchera la chaîne de prototypes pour la trouver. Si la propriété n'est toujours pas trouvée, undefined
est renvoyé, indiquant l'absence de ce trait.
Pour approfondir leur récit, Emily et Thomas explorent comment des traits uniques peuvent être ajoutés aux descendants, les différenciant de leurs ancêtres :
// Introducing a unique trait to Coder Leo coderLeo.courage = 50; console.log(ancientCoder.courage); // undefined console.log(coderLeo.courage); // 50
Ici, Coder Leo développe un trait de courage, distinct de The Ancient Coder. Ce changement n'altère pas les attributs de The Ancient Coder, illustrant comment les objets (ou personnages) peuvent évoluer indépendamment de leurs prototypes (ou ancêtres), grâce à la nature dynamique de JavaScript.
Cette histoire dans l'histoire fait non seulement progresser le roman d'Emily et Thomas, mais met également en lumière l'héritage basé sur le prototype de JavaScript. Comme les personnages d’un roman, les objets peuvent hériter des traits de leurs ancêtres. Pourtant, ils possèdent également la capacité de tracer leur propre chemin, en développant des propriétés uniques qui reflètent leur parcours individuel.
Alors qu'Emily et Thomas approfondissaient leur roman, "Adventures in Code", ils tombèrent sur un chapitre mystérieux : l'ancien tome de Protos. Ce tome, ont-ils découvert, n'était pas seulement un dispositif d'intrigue mais une métaphore pour comprendre les prototypes et les méthodes intégrées en JavaScript, des concepts qui ajouteraient une couche de magie au monde de leur histoire et à leur compréhension du codage.
Dans Scriptsville, le décor fictif de leur roman, chaque personnage et objet est imprégné des capacités du Tome de Protos. Ce livre magique est la source de toutes les connaissances et compétences, à l’image du prototype en JavaScript dont les objets héritent de propriétés et de méthodes.
// A seemingly ordinary quill in Scriptsville const quill = {};
Emily, à travers son personnage Ellie, explore cette plume, pour la découvrir liée au Tome des Protos via un fil magique – une analogie directe avec la propriété __proto__
des objets JavaScript, les connectant à leurs prototypes.
console.log(quill.__proto__); // Reveals the Tome's ancient scripts!
Cette révélation permet à Ellie d'accéder à la sagesse du Tome, y compris la possibilité d'invoquer hasOwnProperty
et toString
, démontrant les méthodes intégrées de JavaScript héritées du prototype Object.
Le récit présente ensuite le personnage de Thomas, Maître Donovan, un boulanger renommé connu pour ses beignets enchantés. Cherchant à partager son don culinaire, Donovan crée un sort, un peu comme définir une fonction constructeur en JavaScript :
function EnchantedDoughnut() { this.flavor = "magic"; } EnchantedDoughnut.prototype.eat = function() { console.log("Tastes like enchantment!"); };
Chaque beignet créé par Donovan porte l'essence de l'enchantement, permettant à quiconque le mange de faire l'expérience de la magie. Cette partie de l'histoire illustre comment les objets créés avec une fonction constructeur en JavaScript héritent des méthodes du prototype de leur constructeur, tout comme les beignets de Donovan héritent de la capacité d'être mangés.
À mesure que Scriptsville évolue, sa magie évolue également, passant des sorts anciens à l'art moderne de la syntaxe de classe. Emily et Thomas réinventent le métier de Donovan avec la nouvelle syntaxe, rendant sa magie plus accessible et s'alignant sur les pratiques contemporaines en JavaScript :
class ModernEnchantedDoughnut { constructor() { this.flavor = "modern magic"; } eat() { console.log("Tastes like modern enchantment!"); } }
Cette transition met non seulement à jour l'art culinaire de Donovan, mais reflète également l'évolution de JavaScript, mettant en évidence l'élégance et l'efficacité de la syntaxe de classe tout en préservant l'héritage sous-jacent basé sur le prototype.
Le parcours d'Emily et Thomas à travers la création de « Adventures in Code » devient une allégorie captivante pour comprendre les prototypes, les méthodes intégrées et l'évolution de JavaScript lui-même.
À travers leurs personnages et leurs histoires, ils éclairent des concepts complexes d'une manière engageante et profonde, montrant que chaque objet et personnage, tout comme chaque objet JavaScript, fait partie d'une tapisserie plus vaste et interconnectée d'héritage et d'innovation.
Leur histoire souligne une vérité fondamentale à la fois dans la narration et dans la programmation : comprendre le passé est essentiel pour maîtriser le présent et innover pour l’avenir.
Le monde magique de Scriptsville, avec ses tomes anciens, ses beignets enchantés et sa magie moderne, sert de toile de fond vivante pour explorer les profondeurs du système prototype de JavaScript et le pouvoir de l'héritage.
Au fur et à mesure qu'Emily et Thomas approfondissaient leur roman Adventures in Code, ils ont découvert la nécessité de trouver un moyen de gérer un monde complexe rempli de personnages, de décors et d'objets magiques.
Ils se tournèrent vers Ellie, une sage scribe de Scriptsville, connue pour son savoir-faire dans l'enchantement des objets et pour assurer l'harmonie dans tout le pays.
Ellie a partagé avec eux une formule magique, ensureObjectPath
, capable d'assurer l'existence de royaumes imbriqués au sein de leur monde :
function ensureObjectPath({obj, path}) { path.split('.').reduce((acc, part) => { if (!acc[part]) acc[part] = {}; return acc[part]; }, obj); return obj; } // Ensuring the path to a hidden forest in their novel const world = {}; ensureObjectPath({obj: world, path: 'hidden.forest.clearing'}); console.log(world); // Outputs: { hidden: { forest: { clearing: {} } } }
Ellie a expliqué que cet enchantement leur permet de créer n'importe quel endroit dans l'univers de leur roman, garantissant que chaque personnage puisse se lancer dans ses quêtes sans craindre de s'aventurer dans des royaumes inexistants.
De plus, Ellie leur a présenté un autre sort, checkForRequiredKeys
, conçu pour garantir que chaque personnage possède les attributs essentiels nécessaires à son voyage :
const REQUIRED_KEYS = ['age', 'address', 'gender']; function checkForRequiredKeys(obj) { REQUIRED_KEYS.forEach(key => { if (!Object.hasOwn(obj, key)) { obj[key] = {}; } }); } // Ensuring every character has the essential attributes const character = { name: "Ellie" }; checkForRequiredKeys(character); console.log(character); // Outputs: { name: "Ellie", age: {}, address: {}, gender: {} }
Ce sort a permis à Emily et Thomas d'intégrer la complexité à leurs personnages, en garantissant qu'aucun détail ne soit négligé, quelle que soit la complexité de leurs récits.
Au fur et à mesure que leur histoire se déroulait, les enchantements partagés par Ellie ont non seulement enrichi "Adventures in Code", mais ont également éclairé les principes sous-jacents de la manipulation et de la structure des objets en JavaScript.
Tout comme le sort ensureObjectPath
permettait la création de réalités imbriquées, les développeurs JavaScript disposent d'un pouvoir similaire pour structurer les données au sein de leurs applications.
De même, le sort checkForRequiredKeys
reflète les pratiques de programmation défensive essentielles pour garantir l’intégrité des données.
Au cours de nos pérégrinations à travers les royaumes enchantés de Scriptsville, Emily, Thomas, Ellie et de nombreux êtres magiques ont été nos compagnons, dévoilant les secrets de JavaScript d'une manière aussi captivante que la terre elle-même.
À travers des récits d'aventures et de découvertes, nous avons plongé au cœur de JavaScript, depuis sa syntaxe la plus simple jusqu'aux moteurs complexes qui palpitent sous sa surface.
Ce fut un voyage pas comme les autres, où la magie de la narration fusionne avec la logique de la programmation, révélant les merveilles de l'univers JavaScript.
===
), l'égalité lâche ( ==
) et l'utilisation d' Object.is
pour des comparaisons nuancées.
Propriétés des objets et prototypes : en fouillant dans les propriétés des objets, nous avons découvert la puissance de la notation par points et crochets pour accéder et modifier les propriétés, ainsi que le rôle central des prototypes dans l'héritage des objets.
Les histoires de fils d'héritage et de parchemins enchantés à Scriptsville ont donné vie à la chaîne de prototypes, montrant comment les objets héritent et remplacent les traits.
ensureObjectPath
et checkForRequiredKeys
, ont démontré des techniques pratiques pour travailler avec des objets imbriqués et garantir la présence de propriétés essentielles.
À travers le prisme du récit de Scriptsville, nous avons vu à quel point les fonctionnalités de JavaScript peuvent être à la fois magiques et logiques, offrant aux développeurs un vaste terrain de jeu pour la créativité et la résolution de problèmes.
Les histoires enchanteresses de Scriptsville sont bien plus que de simples contes ; ce sont des métaphores du talent artistique de la programmation, soulignant l'importance de comprendre les principes fondamentaux de JavaScript pour créer magistralement nos mondes numériques.
Alors que nous clôturons le livre de ce voyage, n'oubliez pas que l'aventure ne s'arrête pas là. Chaque concept que nous avons exploré est un tremplin vers une compréhension et une maîtrise plus approfondies de JavaScript.
Tout comme Emily et Thomas ont tissé leur histoire « Adventures in Code », vous pouvez également créer vos récits, vos objets enchantés et vos royaumes magiques dans l'univers sans limites de la programmation.