Javascript est basé sur les objets ; c'est un langage de script basé sur les objets qui peut non seulement créer des objets, mais également utiliser des objets existants. La définition basée sur les objets du standard JavaScript : l'infrastructure du langage et de l'hôte est fournie par des objets, et un programme JavaScript est un ensemble d'objets qui communiquent entre eux.
L'environnement d'exploitation de ce tutoriel : système Windows 7, JavaScript version 1.8.5, ordinateur Dell G3.
Bonjour, je suis Winter, l'ancien responsable front-end d'Alibaba Mobile Taobao. Cet article est issu de mon explication de JavaScript dans la rubrique "Réapprendre le Front-End" de Geek Time.
Par rapport à d'autres langages, les "objets" en JavaScript semblent toujours moins grégaires. Certains nouveaux arrivants ont souvent des doutes lors de l'apprentissage du JavaScript orienté objet : Pourquoi JavaScript (jusqu'à ES6) a-t-il le concept d'objets, mais pas le concept de classes comme les autres langages ? Pourquoi pouvons-nous ajouter librement des propriétés aux objets JavaScript, mais pas à d’autres langages ?
Même dans certains débats, certaines personnes ont souligné que JavaScript n'est pas un "langage orienté objet", mais un "langage basé sur les objets". Cette affirmation a déjà été largement diffusée, mais en fait, j'en ai les détenteurs. rencontrés jusqu'à présent Personne qui fait cette déclaration ne peut répondre à la question "Comment définir l'orientation objet et l'orientation objet".
En fait, les deux adjectifs orientés objet et orienté objet sont apparus dans différentes versions du standard JavaScript. Nous pouvons d'abord examiner la définition basée sur les objets du standard JavaScript. Le contenu spécifique de cette définition est le suivant : "L'infrastructure du langage et de l'hôte est fournie par des objets, et le programme ECMAScript est un ensemble d'objets qui communiquent entre eux. ". Le sens ici n’est pas du tout d’exprimer la signification orientée objet affaiblie, mais d’exprimer l’importance des objets pour le langage.
Donc, dans cet article, je vais essayer de vous faire comprendre ce que sont l'orienté objet et l'orienté objet en JavaScript.
Parlons d'abord de ce qu'est un objet. Pour des raisons de traduction, il nous est difficile de comprendre le vrai sens du terme « objet » dans le contexte chinois. En fait, Object est le terme général désignant tout en anglais, ce qui a quelque chose en commun avec la pensée abstraite de la programmation orientée objet. L'« objet » chinois n'a pas une telle universalité. Dans le processus d'apprentissage de la programmation, nous l'entendons davantage comme un terme professionnel.
Mais quoi qu'il en soit, nous devons réaliser que les objets ne sont pas des concepts créés à partir de rien dans le domaine informatique. Ils sont une abstraction qui suit les schémas de pensée humains (c'est pourquoi la programmation orientée objet est également prise en compte : plus proche de A. paradigme de programmation de l'esprit humain).
Alors, jetons d’abord un coup d’œil à ce qu’est exactement un objet dans le modèle de pensée humaine.
Le concept d'objets se forme dans la petite enfance humaine, bien avant les concepts tels que les valeurs et les procédures couramment utilisés dans notre logique de programmation. Dans l'enfance, nous réalisons toujours d'abord qu'une certaine pomme peut être mangée (une certaine pomme ici est un objet), puis nous réalisons que toutes les pommes peuvent être mangées (toutes les pommes ici sont une classe), et ensuite Ce n'est que plus tard que nous réaliser le lien entre trois pommes et trois poires, conduisant au concept du chiffre « 3 » (valeur).
Dans le livre "Object-Oriented Analysis and Design", Grady Booch nous l'a résumé. Il pense que d'un point de vue cognitif humain, un objet devrait être l'une des choses suivantes :
Grâce à la définition naturelle des objets, nous pouvons décrire des objets dans des langages de programmation. Dans différents langages de programmation, les concepteurs utilisent également diverses fonctionnalités du langage pour décrire de manière abstraite les objets. L'école la plus réussie consiste à utiliser des « classes » pour décrire les objets, ce qui a donné naissance à des langages de programmation populaires tels que C++ et Java. Dans les premières années, JavaScript a choisi une méthode plus impopulaire : les prototypes (je me concentrerai sur les prototypes dans le prochain article, vous pouvez simplement laisser une impression ici). C'est une des raisons pour lesquelles j'ai dit plus tôt qu'il était insociable.
Malheureusement, pour des raisons politiques de l'entreprise, la direction a ordonné à JavaScript d'imiter Java lors de son lancement. Par conséquent, le fondateur de JavaScript, Brendan Eich, a introduit de nouvelles fonctionnalités, ainsi que d'autres, qui le font "ressembler davantage à Java". .
Avant l'émergence d'ES6, un grand nombre de programmeurs JavaScript ont essayé de faire en sorte que JavaScript ressemble davantage à une programmation basée sur les classes basée sur le système prototype, ce qui a abouti à de nombreux "frameworks", tels que PrototypeJS et Dojo. . En fait, ils sont devenus une sorte de dialecte étrange de JavaScript et ont même engendré une série de communautés mutuellement incompatibles. De toute évidence, les gains obtenus jusqu'à présent ont dépassé les pertes.
Si nous parlons d'objets du point de vue de l'exécution, nous discutons du modèle d'exécution réel de JavaScript. En effet, toute exécution de code ne doit pas contourner le modèle objet d'exécution. Cependant, heureusement, du point de vue de l'exécution, vous ne le faites pas. Je n'ai pas à être dérangé par ces "fonctionnalités basées sur les classes", car le concept de classes dans n'importe quel environnement d'exécution de langage est affaibli.
Tout d’abord, comprenons comment JavaScript conçoit le modèle objet.
À mon avis, quel que soit le langage de programmation que nous utilisons, nous devons d'abord comprendre les caractéristiques essentielles de l'objet (se référer à "Object-Oriented Analysis and Design" de Grandy Booch " 》). Pour résumer, l'objet présente les caractéristiques suivantes.
Regardons d'abord la première caractéristique, l'objet est identifiable de manière unique. D'une manière générale, l'identification unique des objets dans différents langages se reflète dans les adresses mémoire. Par conséquent, les programmeurs JavaScript savent que les différents objets JavaScript ne sont pas égaux les uns aux autres. Nous pouvons regarder le code suivant, o1 et o2. , ce sont deux objets identiques, mais le résultat imprimé est faux.
var o1 = { a: 1 }; var o2 = { a: 1 }; console.log(o1 == o2); // false
Concernant les deuxième et troisième caractéristiques des objets, "état et comportement", différents langages utiliseront des termes différents pour les décrire de manière abstraite. Par exemple, C++ les appelle "variables membres" et "fonctions membres". ", Java les appelle "propriétés" et "méthodes".
En JavaScript, l'état et le comportement sont unifiés et abstraits en tant que "propriétés". Considérant que les fonctions sont conçues comme un objet spécial en JavaScript (j'expliquerai cela en détail plus tard), ce n'est pas nécessaire. pour entrer dans les détails ici), afin que les comportements et les états en JavaScript puissent être abstraits à l'aide d'attributs.
Le code suivant montre en fait un exemple d'attributs et de fonctions ordinaires en tant qu'attributs, où o est un objet, d est un attribut et la fonction f est également un attribut. Bien que la méthode d'écriture ne soit pas la même, il convient à JavaScript. Par exemple, d et f sont deux attributs communs.
var o = { d: 1, f() { console.log(this.d); } };
Donc, pour résumer, en JavaScript, l'état et le comportement des objets sont en fait résumés en attributs. Si vous avez utilisé Java, ne soyez pas surpris. Bien qu'il existe certaines différences dans les idées de conception, les deux expriment bien les caractéristiques fondamentales des objets : identité, statut et comportement.
Sur la base de la prise de conscience des caractéristiques de base des objets, je crois que les caractéristiques uniques des objets en JavaScript sont : Les objets sont très dynamiques car JavaScript donne aux utilisateurs la possibilité d'effectuer des actions au moment de l'exécution. capacité d'un objet à ajouter un état et un comportement.
Permettez-moi de vous donner un exemple. Par exemple, JavaScript permet d'ajouter des propriétés aux objets au moment de l'exécution, ce qui est complètement différent de la plupart des conceptions d'objets statiques basées sur des classes. Si vous avez utilisé Java ou d’autres langages, vous aurez certainement le même ressenti que moi.
Le code suivant montre comment ajouter des attributs à un objet au moment de l'exécution. Au début, j'ai défini un objet o Une fois la définition terminée, j'ai ajouté son attribut b. Vous devez comprendre cela.
var o = { a: 1 };o.b = 2;console.log(o.a, o.b); //1 2
Afin d'améliorer les capacités d'abstraction, les propriétés JavaScript sont conçues pour être plus complexes que les autres langages. Elles fournissent deux types de propriétés de données et de propriétés d'accesseur (getter/setter).
Pour JavaScript, les attributs ne sont pas de simples noms et valeurs. JavaScript utilise un ensemble de caractéristiques pour décrire les propriétés.
Commençons par le premier type d'attributs, les attributs de données . Il est plus proche du concept d'attribut d'autres langues. Les attributs de données ont quatre caractéristiques.
Dans la plupart des cas, nous nous soucions uniquement de la valeur de l'attribut data.
Le deuxième type d'attribut est l'attribut accesseur (getter/setter) , qui a également quatre caractéristiques.
L'attribut accesseur permet d'exécuter du code lorsque l'attribut est lu et écrit. Il permet aux utilisateurs d'obtenir des valeurs complètement différentes lors de l'écriture et de la lecture de l'attribut. Il peut être considéré comme un sucre syntaxique. pour une fonction.
Le code que nous utilisons habituellement pour définir les attributs générera des attributs de données , dans lesquels les attributs inscriptibles, énumérables et configurables sont tous définis par défaut sur true. Nous pouvons utiliser la fonction intégrée Object.getOwnPropertyDescripter pour le voir, comme indiqué dans le code suivant :
var o = { a: 1 };o.b = 2;//a和b皆为数据属性 Object.getOwnPropertyDescriptor(o,\u0026quot;a\u0026quot;) // {value: 1, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor(o,\u0026quot;b\u0026quot;) // {value: 2, writable: true, enumerable: true, configurable: true}
我们在这里使用了两种语法来定义属性,定义完属性后,我们用JavaScript的API来查看这个属性,我们可以发现,这样定义出来的属性都是数据属性,writeable、enumerable、configurable都是默认值为true。
如果我们要想改变属性的特征,或者定义访问器属性,可以使用 Object.defineProperty,示例如下:
var o = { a: 1 }; Object.defineProperty(o, \u0026quot;b\u0026quot;, {value: 2, writable: false, enumerable: false, configurable: true});//a和b都是数据属性,但特征值变化了 Object.getOwnPropertyDescriptor(o,\u0026quot;a\u0026quot;); // {value: 1, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor(o,\u0026quot;b\u0026quot;); // {value: 2, writable: false, enumerable: false, configurable: true} o.b = 3;console.log(o.b); // 2
这里我们使用了Object.defineProperty来定义属性,这样定义属性可以改变属性的writable和enumerable,我们同样用Object.getOwnPropertyDescriptor来查看,发现确实改变了writable和enumerable特征。因为writable特征为false,所以我们重新对b赋值,b的值不会发生变化。
在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:
var o = { get a() { return 1 } }; console.log(o.a); // 1
访问器属性跟数据属性不同,每次访问属性都会执行getter或者setter函数。这里我们的getter函数返回了1,所以o.a每次都得到1。
这样,我们就理解了,实际上JavaScript 对象的运行时是一个“属性的集合”,属性以字符串或者Symbol为key,以数据属性特征值或者访问器属性特征值为value。对象是一个属性的索引结构(索引结构是一类常见的数据结构,我们可以把它理解为一个能够以比较快的速度用key来查找value的字典)。我们以上面的对象o为例,你可以想象一下“a”是key。
这里{writable:true,value:1,configurable:true,enumerable:true}是value。我们在前面的类型课程中,已经介绍了Symbol类型,能够以Symbol为属性名,这是JavaScript对象的一个特色。
讲到了这里,如果你理解了对象的特征,也就不难理解我开篇提出来的问题。
你甚至可以理解为什么会有“JavaScript不是面向对象”这样的说法:JavaScript的对象设计跟目前主流基于类的面向对象差异非常大。而事实上,这样的对象系统设计虽然特别,但是JavaScript提供了完全运行时的对象系统,这使得它可以模仿多数面向对象编程范式(下一节课我们会给你介绍JavaScript中两种面向对象编程的范式:基于类和基于原型),所以它也是正统的面向对象语言。
JavaScript语言标准也已经明确说明,JavaScript是一门面向对象的语言,我想标准中能这样说正因为JavaScript的高度动态性的对象系统。
所以,我们应该在理解其设计思想的基础上充分挖掘它的能力,而不是机械地模仿其它语言。
要想理解JavaScript对象,必须清空我们脑子里“基于类的面向对象”相关的知识,回到人类对对象的朴素认知和面向对象的语言无关基础理论,我们就能够理解JavaScript面向对象设计的思路。
在这篇文章中,我从对象的基本理论出发,和你理清了关于对象的一些基本概念,分析了JavaScript对象的设计思路。接下来又从运行时的角度,介绍了JavaScript对象的具体设计:具有高度动态性的属性集合。
很多人在思考JavaScript对象时,会带着已有的“对象”观来看问题,最后的结果当然就是“剪不断理还乱”了。
【相关推荐:javascript学习教程】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!