Javascript ist objektorientiert. Jedes in js integrierte Objekt ist von Objekt abgeleitet, daher gibt es drei objektorientierte Funktionen: Vererbung, Polymorphismus und Rekonstruktion. Auch wenn js jetzt auf der Pseudovererbung von Prototypen basiert Die allgemeine Idee ist eine objektorientierte Sprache.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, JavaScript-Version 1.8.5, Dell G3-Computer.
Im Vergleich zu anderen Sprachen wirken „Objekte“ in JavaScript immer nicht so gesellig. Wenn einige Neulinge JavaScript objektorientiert lernen, haben sie oft Zweifel: Warum hat JavaScript (bis ES6) das Konzept von Objekten, aber nicht das Konzept von Klassen wie andere Sprachen? Warum können wir JavaScript-Objekten frei Eigenschaften hinzufügen, anderen Sprachen jedoch nicht?
Sogar in einigen Debatten betonten einige Leute, dass JavaScript keine „objektorientierte Sprache“, sondern eine „objektbasierte Sprache“ sei. Tatsächlich habe ich bisher Leute getroffen, die dies vertreten Die Frage „Wie definiert man objektorientiert und objektbasiert“ kann niemand beantworten.
Tatsächlich sind die beiden Adjektive objektbasiert und objektorientiert in verschiedenen Versionen des JavaScript-Standards aufgetaucht. Wir können uns zunächst die objektbasierte Definition des JavaScript-Standards ansehen. Der spezifische Inhalt dieser Definition lautet: „Die Infrastruktur der Sprache und des Hosts wird durch Objekte bereitgestellt, und das ECMAScript-Programm ist eine Sammlung von Objekten, die miteinander kommunizieren.“ ." Die Bedeutung besteht hier überhaupt nicht darin, die abgeschwächte objektorientierte Bedeutung auszudrücken, sondern darin, die Bedeutung von Objekten für die Sprache auszudrücken.
In diesem Artikel werde ich versuchen, Ihnen verständlich zu machen, was objektorientiert ist und was objektorientiert in JavaScript ist.
Lassen Sie uns zunächst darüber sprechen, was ein Objekt ist. Aus Übersetzungsgründen ist es für uns schwierig, die wahre Bedeutung von „Objekt“ im chinesischen Kontext zu verstehen. Tatsächlich ist Object (Objekt) der allgemeine Begriff für alles im Englischen, der etwas mit dem abstrakten Denken der objektorientierten Programmierung gemeinsam hat. Das chinesische „Objekt“ hat keine solche Universalität. Im Prozess des Programmierens verstehen wir es eher als einen Fachbegriff.
Aber egal was passiert, wir sollten uns darüber im Klaren sein, dass Objekte keine Konzepte sind, die im Computerbereich aus dem Nichts geschaffen wurden. Sie sind eine Abstraktion, die menschlichen Denkmustern folgt (so dass objektorientierte Programmierung auch als näher an menschlichen Denkmustern angesehen wird). ) ein Programmierparadigma).
Schauen wir uns also zunächst einmal an, was genau ein Objekt im menschlichen Denkmodell ist.
Das Konzept von Objekten wurde in der menschlichen Kindheit entwickelt, was viel früher ist als die Konzepte von Wert, Prozess und anderen, die üblicherweise in unserer Programmierlogik verwendet werden. In der Kindheit erkennen wir immer zuerst, dass ein bestimmter Apfel gegessen werden kann (ein bestimmter Apfel ist hier ein Objekt), dann erkennen wir, dass alle Äpfel gegessen werden können (alle Äpfel hier sind eine Klasse), und später erkennen wir, dass dies nur dann möglich ist Wir erkennen den Zusammenhang zwischen drei Äpfeln und drei Birnen und generieren dann das Konzept der Zahl „3“ (Wert).
In dem Buch „Object-Oriented Analysis and Design“ hat Grady Booch es für uns zusammengefasst. Er glaubt, dass ein Objekt aus menschlicher kognitiver Sicht eines der folgenden Dinge sein sollte:
Ein berührbares Objekt oder etwas, das kann gesehen werden;
Dinge, die von der menschlichen Intelligenz verstanden werden können;
Dinge, die das Denken oder Handeln leiten können (Handlungen vorstellen oder ausführen).
Mit der natürlichen Definition von Objekten können wir Objekte in Programmiersprachen beschreiben. In verschiedenen Programmiersprachen verwenden Designer auch verschiedene Sprachfunktionen, um Objekte abstrakt zu beschreiben. Die erfolgreichste Methode ist die Verwendung von „Klassen“ zur Beschreibung von Objekten, aus denen beliebte Programmiersprachen wie C++ und Java hervorgegangen sind. In den Anfangsjahren wählte JavaScript eine unbeliebtere Methode: Prototypen (ich werde mich im nächsten Artikel auf Prototypen konzentrieren, Sie können hier einfach einen Eindruck hinterlassen). Dies ist einer der Gründe, warum ich vorhin gesagt habe, dass es ungesellig ist.
Leider wurde JavaScript aus unternehmenspolitischen Gründen von der Geschäftsführung angewiesen, Java zu imitieren, als es eingeführt wurde. Daher führte JavaScript-Gründer Brendan Eich neue, diese und andere Sprachfunktionen ein, die auf der „Prototyp-Laufzeit“ basieren, und machte es zu „. eher wie Java aussehen".
Vor dem Aufkommen von ES6 versuchten viele JavaScript-Programmierer, JavaScript eher zu einer klassenbasierten Programmierung basierend auf dem Prototypsystem zu machen, was zu vielen sogenannten „Frameworks“ wie PrototypeJS und Dojo führte. Tatsächlich wurden sie zu einer Art seltsamem JavaScript-Dialekt und brachten sogar eine Reihe miteinander inkompatibler Communities hervor. Offensichtlich überwogen die bisherigen Vorteile die Verluste.
Wenn wir über Objekte aus der Laufzeitperspektive sprechen, diskutieren wir das tatsächliche Ausführungsmodell von JavaScript. Dies liegt daran, dass jede Codeausführung das Laufzeitobjektmodell nicht umgehen darf. Aus der Laufzeitperspektive sehen Sie jedoch nicht. Ich muss mich nicht um diese „klassenbasierten Funktionen“ kümmern, da das Konzept der Klassen in jeder Sprachlaufzeit verwässert wird.
Lassen Sie uns zunächst verstehen, wie JavaScript das Objektmodell entwirft.
Meiner Meinung nach sollten wir unabhängig von der verwendeten Programmiersprache zunächst die wesentlichen Eigenschaften von Objekten verstehen (siehe Grandy Boochs „Objektorientierte Analyse und Design“). Zusammenfassend weist das Objekt die folgenden Eigenschaften auf.
Objekte sind eindeutig identifizierbar: Selbst zwei Objekte, die genau gleich sind, sind nicht dasselbe Objekt.
Objekte haben einen Zustand: Objekte haben einen Zustand und dasselbe Objekt kann sich in unterschiedlichen Zuständen befinden.
Objekte haben Verhalten: Das heißt, der Zustand des Objekts kann sich aufgrund seines Verhaltens ändern.
Schauen wir uns zunächst das erste Merkmal an: Das Objekt ist eindeutig identifizierbar. Im Allgemeinen wird die eindeutige Identifizierung von Objekten in verschiedenen Sprachen durch Speicheradressen widergespiegelt. Daher wissen JavaScript-Programmierer, dass verschiedene JavaScript-Objekte nicht gleich sind. Wir können uns den folgenden Code ansehen: o1 und o2 , es sind zwei identische Objekte, aber das gedruckte Ergebnis ist falsch.
var o1 = { a: 1 }; var o2 = { a: 1 }; console.log(o1 == o2); // false
In Bezug auf die zweiten und dritten Merkmale von Objekten, „Zustand und Verhalten“, verwenden verschiedene Sprachen unterschiedliche Begriffe, um sie abstrakt zu beschreiben. In C++ werden sie beispielsweise „Mitgliedsvariablen“ und „Mitgliedsfunktionen“ genannt. Member-Funktionen“ in Java. Nennen Sie sie dann „Eigenschaften“ und „Methoden“.
In JavaScript werden Zustand und Verhalten als „Eigenschaften“ vereinheitlicht und abstrahiert. Da Funktionen in JavaScript als spezielle Objekte konzipiert sind (ich werde dies später ausführlich erläutern, ist es daher nicht erforderlich, hier näher darauf einzugehen). JavaScript Die Verhaltensweisen und Zustände in können mithilfe von Attributen abstrahiert werden.
Der folgende Code zeigt tatsächlich ein Beispiel für gewöhnliche Attribute und Funktionen als Attribute, wobei o ein Objekt, d ein Attribut und die Funktion f auch ein Attribut ist. Obwohl die Schreibmethode für JavaScript nicht dieselbe ist, d und f sind zwei gemeinsame Attribute.
var o = { d: 1, f() { console.log(this.d); } };
Zusammenfassend lässt sich also sagen, dass in JavaScript der Zustand und das Verhalten von Objekten tatsächlich in Eigenschaften abstrahiert werden. Wenn Sie Java verwendet haben, wundern Sie sich nicht. Obwohl es gewisse Unterschiede in den Designideen gibt, drücken beide die grundlegenden Eigenschaften von Objekten gut aus: Identität, Status und Verhalten.
Aufgrund der Erkenntnis der grundlegenden Eigenschaften von Objekten glaube ich, dass das einzigartige Merkmal von Objekten in JavaScript darin besteht, dass Objekte sehr dynamisch sind. Dies liegt daran, dass JavaScript Benutzern die Möglichkeit gibt, den Status und das Verhalten von Objekten zur Laufzeit hinzuzufügen .
Lassen Sie mich ein Beispiel geben: JavaScript ermöglicht beispielsweise das Hinzufügen von Eigenschaften zu Objekten zur Laufzeit, was sich völlig von den meisten klassenbasierten, statischen Objektdesigns unterscheidet. Wenn Sie Java oder andere Sprachen verwendet haben, werden Sie auf jeden Fall das gleiche Gefühl haben wie ich.
Der folgende Code zeigt, wie man einem Objekt zur Laufzeit Attribute hinzufügt. Nachdem die Definition abgeschlossen war, ist dieser Vorgang völlig in Ordnung. Das muss man verstehen.
var o = { a: 1 }; o.b = 2; console.log(o.a, o.b); //1 2
Um die Abstraktionsfähigkeiten zu verbessern, sind JavaScript-Eigenschaften komplexer als andere Sprachen. Es bietet zwei Arten von Dateneigenschaften und Accessor-Eigenschaften (Getter/Setter).
Für JavaScript sind Attribute nicht nur einfache Namen und Werte. JavaScript verwendet eine Reihe von Merkmalen, um Eigenschaften zu beschreiben.
Lassen Sie uns zunächst über die erste Art von Attributen sprechen, Datenattribute. Es ähnelt eher dem Attributkonzept anderer Sprachen. Datenattribute haben vier Eigenschaften.
Wert: Dies ist der Wert des Attributs.
beschreibbar: Legt fest, ob dem Attribut ein Wert zugewiesen werden kann.
enumerable: Bestimmt, ob for in dieses Attribut aufzählen kann.
konfigurierbar: Legt fest, ob das Attribut gelöscht oder der Merkmalswert geändert werden kann.
In den meisten Fällen ist uns nur der Wert des Datenattributs wichtig.
Der zweite Attributtyp ist das Accessor-Attribut (Getter/Setter), das ebenfalls vier Merkmale aufweist.
Getter: Funktion oder undefiniert, wird beim Abrufen des Attributwerts aufgerufen.
Setter: Funktion oder undefiniert, wird beim Festlegen des Eigenschaftswerts aufgerufen.
enumerable: Bestimmt, ob for in dieses Attribut aufzählen kann.
konfigurierbar: Legt fest, ob das Attribut gelöscht oder der Merkmalswert geändert werden kann.
Das Accessor-Attribut ermöglicht die Ausführung von Code beim Lesen und Schreiben des Attributs. Es ermöglicht Benutzern, beim Schreiben und Lesen des Attributs völlig unterschiedliche Werte zu erhalten. Es kann als syntaktischer Zucker für eine Funktion angesehen werden.
Der Code, den wir normalerweise zum Definieren von Attributen verwenden, generiert Datenattribute, von denen beschreibbar, aufzählbar und konfigurierbar alle standardmäßig auf „true“ gesetzt sind. Wir können die integrierte Funktion Object.getOwnPropertyDescripter verwenden, um sie anzuzeigen, wie im folgenden Code gezeigt:
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}
Wir verwenden hier zwei Syntaxen, um Eigenschaften zu definieren. Nach dem Definieren der Eigenschaften verwenden wir die JavaScript-API, um diese Eigenschaft anzuzeigen can find , die auf diese Weise definierten Attribute sind alle Datenattribute und der Standardwert von beschreibbar, aufzählbar und konfigurierbar ist wahr.
Wenn wir die Eigenschaften einer Eigenschaft ändern oder eine Accessor-Eigenschaft definieren möchten, können wir Object.defineProperty verwenden. Das Beispiel lautet wie folgt:
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高级教程】
Das obige ist der detaillierte Inhalt vonBasiert Javascript auf Objekten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!