Ich frage mich, woran das liegt. Beide verwenden das Schlüsselwort function. Gibt es einen offensichtlichen Unterschied zwischen diesen beiden?
Antworten
Zu viele Anzeigen?Technisch gesehen gibt es keine Klasse, beide sind nur Funktionen. Jede Funktion kann als Konstruktor aufgerufen werden mit dem Schlüsselwort new
und die Prototypeigenschaft dieser Funktion wird für das Objekt verwendet, von dem die Methoden geerbt werden.
Der Begriff "Klasse" wird nur begrifflich verwendet, um die oben beschriebene Praxis zu beschreiben.
Wenn also jemand zu Ihnen sagt: "Machen Sie eine Farbklasse" oder was auch immer, würden Sie das tun:
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
Color.prototype.method1 = function() {
};
Color.prototype.method2 = function() {
};
Wenn Sie es aufschlüsseln, gibt es einfach eine Funktion und einige Zuweisungen zu einer Eigenschaft namens prototype
dieser Funktion, alle generische Javascript-Syntax, nichts Ausgefallenes vor sich geht.
Es wird alles ein wenig magisch, wenn Sie sagen var black = new Color(0,0,0)
. Sie würden dann ein Objekt mit folgenden Eigenschaften erhalten .r
, .g
y .b
. Dieses Objekt hat auch einen versteckten [[Prototyp]]-Link zu Color.prototype
. Das heißt, Sie können sagen black.method1()
auch wenn .method1()
existiert nicht in der black
Objekt.
JavaScript ist die beliebteste Implementierung des ECMAScript-Standards. Die Kernfunktionen von Javascript basieren auf dem ECMAScript-Standard, aber Javascript hat auch andere zusätzliche Funktionen, die nicht in den ECMA-Spezifikationen/Standard enthalten sind. Jeder Browser verfügt über einen Javascript-Interpreter.
Overview
" ECMAScript wurde ursprünglich als Web-Skriptsprache entwickelt, die einen Mechanismus zur Belebung von Webseiten in Browsern und zur Durchführung von Serverberechnungen als Teil einer webbasierten Client-Server-Architektur bietet. Eine Skriptsprache ist eine Programmiersprache, die zur Manipulation, Anpassung und Automatisierung der Funktionen eines bestehenden Systems verwendet wird.
ECMAScript ist eine objektorientierte Programmiersprache für die Durchführung von Berechnungen und die Bearbeitung von Rechenobjekten in einer Host-Umgebung. Ein Webbrowser bietet eine ECMAScript-Host-Umgebung für clientseitige Berechnungen, z. B. Objekte, die Fenster, Menüs, Pop-ups, Dialogfelder, Textbereiche, Anker, Frames, Verlauf, Cookies und Eingabe/Ausgabe darstellen.
ECMAScript ist objektbasiert ECMAScript: Die grundlegenden Sprach- und Host-Funktionen werden von Objekten bereitgestellt, und ein ECMAScript-Programm ist eine Ansammlung von kommunizierenden Objekten.
Objekte "
-
Jeder Konstruktor ist eine Funktion, die über eine Eigenschaft namens
“prototype”
die zur Umsetzung der prototypenbasierten Vererbung und der gemeinsamen Eigenschaften verwendet wird. -
Jedes Objekt, das durch einen Konstruktor erzeugt wird, hat einen impliziten Verweis (den sogenannten Prototyp des Objekts) auf den Wert seiner
constructor’s “prototype”
Eigentum. Außerdem kann ein Prototyp einen impliziten Verweis auf seinen Prototyp haben, der nicht null ist, usw.; dies wird alsprototype chain
.
Funktion
JavaScript behandelt Funktionen als Objekte erster Klasse. Da sie ein Objekt sind, können Sie einer Funktion Eigenschaften zuweisen.
Hoisting ist die Aktion des JavaScript-Interpreters, alle Variablen- und Funktionsdeklarationen an den Anfang des aktuellen Bereichs zu verschieben. Function Hoisting, declarations & expressions
FunctionDeclaration : function BindingIdentifier ( FormalParameter ) { FunctionBody } FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
ES5-Funktion:
function Shape(id) { // Function Declaration
this.id = id;
};
// prototype was created automatically when we declared the function
Shape.hasOwnProperty('prototype'); // true
// Adding a prototyped method to a function.
Shape.prototype.getID = function () {
return this.id;
};
var expFn = Shape; // Function Expression
console.dir( expFn () ); // Function Executes and return default return type - 'undefined'
Zu einer Funktion, wenn der Rückgabewert nicht angegeben ist, dann undefined
zurückgegeben wird. Wird die Funktion aufgerufen mit new
und der Rückgabewert ist kein Objekt, dann wird dies (das neue Objekt) zurückgegeben.
HINWEIS: Für jede Funktion wird automatisch eine Prototypeigenschaft erstellt, um die Möglichkeit zu berücksichtigen, dass die Funktion als Konstruktor verwendet wird.
constructor
"Funktionsobjekt, das Objekte erstellt und initialisiert.prototype
"Objekt, das gemeinsame Eigenschaften für andere Objekte bereitstellt.__proto__
" Die proto Eigenschaft, die auf den Prototyp des Superobjekts verweist. Wenn Sie es öffnen, werden Sie sehen, dass proto verweist auf die Variablen und Funktionen seines Superobjekts.
Um auf die Prototyp-Methoden der oben beschriebenen Funktion zuzugreifen, müssen wir ein Objekt mit new
Schlüsselwort zusammen mit constructor function
. wenn Sie Folgendes erstellen Shape - Object
mit new
Schlüsselwort, dann hat es ein internal (or) private link
zum Prototyp der Funktion Shape
.
ES5 Konstrukteur-Funktions-Klassen: Funktionsobjekte, die mit Function.prototype.bind erstellt werden
Shape.prototype.setID = function ( id ) {
this.id = id;
};
var funObj = new Shape( );
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 )
console.dir( funObj );
console.log( funObj.getID() );
/*
expFun funObj
name: "Shape" id: 10
prototype:Object
constructor: function Shape(id)
getID: function()
setID: function( id )
__proto__: function () __proto__: Object
constructor: function Shape(id)
getID: function()
setID: function( id )
<function scope>
*/
ES6 führte die Funktion Arrow ein : Ein Pfeilfunktionsausdruck hat eine kürzere Syntax als ein Funktionsausdruck und bindet nicht sein eigenes this, arguments, super oder new.target. Diese Funktionsausdrücke sind am besten für Nicht-Methodenfunktionen geeignet und können nicht als Konstruktoren verwendet werden. ArrowFunction-Grammerzeugung haben keine Prototyp-Eigenschaft.
ArrowFunction : ArrowParameters => ConciseBody
a => (a < 10) ? 'valid' : 'invalid' const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; }; console.log( fn(2) ); // Even console.log( fn(3) ); // Odd
Klasse
In einer klassenbasierten objektorientierten Sprache wird der Zustand im Allgemeinen von Instanzen getragen, die Methoden werden von Klassen getragen, und die Vererbung bezieht sich nur auf Struktur und Verhalten. In ECMAScript werden der Zustand und die Methoden von Objekten getragen, und Struktur, Verhalten und Zustand werden alle vererbt.
Babel ist ein JavaScript-Compiler. Verwenden Sie ihn zum Transformieren
ES6
aES5
FormatBABEL JS
(oder)ES6Console
.
ES6-Klassen : ES2015 classes
sind ein einfacher Zucker für das prototypenbasierte OO-Muster. Eine einzige, praktische deklarative Form macht die Verwendung von Klassenmustern einfacher und fördert die Interoperabilität. Klassen unterstützen prototypenbasierte Vererbung, Superaufrufe, Instanz- und statische Methoden und Konstruktoren.
class Shape {
constructor(id) {
this.id = id
}
get uniqueID() {
return this.id;
}
set uniqueID(changeVal) {
this.id = changeVal;
}
}
Shape.parent_S_V = 777;
// Class Inheritance
class Rectangle extends Shape {
constructor(id, width, height) {
super(id)
this.width = width
this.height = height
}
// Duplicate constructor in the same class are not allowed.
/*constructor (width, height) { this._width = width; this._height = height; }*/
get area() {
console.log('Area : ', this.width * this.height);
return this.width * this.height
}
get globalValue() {
console.log('GET ID : ', Rectangle._staticVar);
return Rectangle._staticVar;
}
set globalValue(value) {
Rectangle._staticVar = value;
console.log('SET ID : ', Rectangle._staticVar);
}
static println() {
console.log('Static Method');
}
// this.constructor.parent_S_V - Static property can be accessed by it's instances
setStaticVar(staticVal) { // https://sckoverflow.com/a/42853205/5081877
Rectangle.parent_S_V = staticVal;
console.log('SET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
}
getStaticVar() {
console.log('GET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
return Rectangle.parent_S_V;
}
}
Rectangle._staticVar = 77777;
var objTest = new Rectangle('Yash_777', 8, 7);
console.dir( objTest );
ES5 Funktionsklassen : verwendet Object.defineProperty ( O, P, Attributes )
_En
Object.defineProperty()
Methode definiert eine neue Eigenschaft direkt für ein Objekt oder ändert eine vorhandene Eigenschaft für ein Objekt und gibt das Objekt zurück._Funktionsinstanzen, die als Konstruktor verwendet werden können, haben eine Prototypeigenschaft .
Diese Eigenschaft hat die Attribute { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.
'use strict';
var Shape = function ( superClass ) {
var currentClass = Shape;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
// Instance Variables list.
this.id = id; return this;
}
var staticVariablesJOSN = { "parent_S_V" : 777 };
staticVariable( currentClass, staticVariablesJOSN );
// Setters, Getters, instanceMethods. [{}, {}];
var instanceFunctions = [
{
key: 'uniqueID',
get: function get() { return this.id; },
set: function set(changeVal) { this.id = changeVal; }
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Object);
var Rectangle = function ( superClass ) {
var currentClass = Rectangle;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
this.width = width;
this.height = height; return this;
}
var staticVariablesJOSN = { "_staticVar" : 77777 };
staticVariable( currentClass, staticVariablesJOSN );
var staticFunctions = [
{
key: 'println',
value: function println() { console.log('Static Method'); }
}
];
staticMethods(currentClass, staticFunctions);
var instanceFunctions = [
{
key: 'setStaticVar',
value: function setStaticVar(staticVal) {
currentClass.parent_S_V = staticVal;
console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
}
}, {
key: 'getStaticVar',
value: function getStaticVar() {
console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
return currentClass.parent_S_V;
}
}, {
key: 'area',
get: function get() {
console.log('Area : ', this.width * this.height);
return this.width * this.height;
}
}, {
key: 'globalValue',
get: function get() {
console.log('GET ID : ', currentClass._staticVar);
return currentClass._staticVar;
},
set: function set(value) {
currentClass._staticVar = value;
console.log('SET ID : ', currentClass._staticVar);
}
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Shape);
// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
console.log(target, ' : ', props);
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function staticMethods( currentClass, staticProps ) {
defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
// Get Key Set and get its corresponding value.
// currentClass.key = value;
for( var prop in staticVariales ) {
console.log('Keys : Values');
if( staticVariales.hasOwnProperty( prop ) ) {
console.log(prop, ' : ', staticVariales[ prop ] );
currentClass[ prop ] = staticVariales[ prop ];
}
}
};
function _inherits(subClass, superClass) {
console.log( subClass, ' : extends : ', superClass );
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype,
{ constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
if (superClass)
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);
Unten Code-Schnipsel ist zu testen, über Jede Instanz hat ihre eigene Kopie der Instanz Mitglieder und gemeinsame statische Mitglieder.
var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 ); // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area; // Area : 1000
obj1.globalValue; // GET ID : 77777
obj1.globalValue = 88; // SET ID : 88
obj1.globalValue; // GET ID : 88
var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 ); // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area; // Area : 350
obj2.globalValue; // GET ID : 88
obj2.globalValue = 999; // SET ID : 999
obj2.globalValue; // GET ID : 999
console.log('Static Variable Actions.');
obj1.globalValue; // GET ID : 999
console.log('Parent Class Static variables');
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 777
obj1.setStaticVar(7); // SET Instance Method Parent Class Static Value : 7
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 7
Die Hauptunterschiede zwischen Funktionen und Klassen sind:
- Funktionsdeklarationen get
Hoisted
an den oberen Rand des Kontexts, während Klassendeklarationen und Funktionsausdrücke nicht hochgezogen werden.- Funktionsdeklarationen, Ausdrücke können sein
Overridden
denn sie sind wie eine Variable -var
wenn mehrere Deklarationen verfügbar sind, hat sie Vorrang vor ihrem übergeordneten Bereich . Während die Klassen nicht überschrieben werden, sind sie wielet
|const
, let lässt nicht zu, dass mehrere Deklarationen mit demselben Namen innerhalb des Geltungsbereichs deklariert werden.- Function's / classes erlaubt nur einen einzigen Konstruktor für seinen Objektbereich.
Computed method names
sind für ES6-Klassen mit dem Schlüsselwort class erlaubt, aber für das Schlüsselwort function ist es nicht erlaubtfunction myFoo() { this.['my'+'Method'] = function () { console.log('Computed Function Method'); }; } class Foo { ['my'+'Method']() { console.log('Computed Method'); } }
In javascript gibt es keine Klassen. javascript verwendet Prototyp Vererbung eher als Klasse basierte Vererbung. Viele Menschen werden auf Klassen in Javascript verweisen, weil es einfacher zu verstehen ist, aber es ist nur eine Analogie.
Bei der klassenbasierten Vererbung erstellen Sie eine Klasse (eine "Blaupause", wenn Sie so wollen) und instanziieren dann Objekte aus dieser Klasse.
Bei der Vererbung von Prototypen wird ein Objekt direkt von einem anderen übergeordneten Objekt instanziiert, ohne dass jemals ein "Bauplan" benötigt wird.
Véase die wikipedia-Seite für weitere Informationen zur Vererbung von Klassen und Prototypen.
Unterschied zwischen einem Konstruktor function
y class
En class
Schlüsselwort in Javascript ist sehr ähnlich zu einer Konstruktor-Funktion in der folgenden Weise:
- Sie verwenden beide das prototypische Vererbungssystem von Javascript
- Sie werden beide zur Erstellung von Objekten mit der folgenden Syntax verwendet:
new myObj(arg1, arg2)
Konstruktorfunktionen und Klassen sind sich sehr ähnlich und können oft austauschbar verwendet werden, je nach Vorliebe. Allerdings ist Javascript private Felder zu Klassen Funktionalität, die nicht durch Konstruktor-Funktionen implementiert werden kann (ohne Scope-Hacks)
Ejemplo:
class PersonClass {
constructor(name) {
this.name = name;
}
speak () { console.log('hi'); }
}
console.log(typeof PersonClass);
// logs function, a class is a constructor function under the hood.
console.log(PersonClass.prototype.speak);
// The class's methods are placed on the prototype of the PersonClass constructor function
const me = new PersonClass('Willem');
console.log(me.name);
// logs Willem, properties assinged in the constructor are placed on the newly created object
// The constructor function equivalent would be the following:
function PersonFunction (name) {
this.name = name;
}
PersonFunction.prototype.speak = function () { console.log('hi'); }
Klasse
Eine Klassendeklaration ist auf den sie enthaltenden Block beschränkt. Es ist ein Fehler einen Klassennamen zweimal im selben Block zu deklarieren. Klassendefinitionen sind nicht gehostet.
Funktionen
Die Funktionsdeklaration ist im Strict-Modus ein Blockbereich.
Die folgende Tabelle fasst den Unterschied zwischen Klasse und Funktion zusammen
- See previous answers
- Weitere Antworten anzeigen