Code Showdown: Ruby gegen Javascript

Ruby und JavaScript stehen kurz davor, gegeneinander anzutreten. Beide Skriptsprachen sind dynamisch typisiert und unterstützen die objektorientierte Programmierung. Wir werden ihre Unterschiede oder Ähnlichkeiten in einigen ihrer allgemeineren Merkmale untersuchen.

Haftungsausschluss: Wir betrachten hier nur die moderne JavaScript ES6-Syntax.

Foto von Pramote Polyamate auf 500px

String-Interpolation

In der Computerprogrammierung wird bei der Zeichenfolgeninterpolation der Wert einer Variablen oder eines Ausdrucks in ein Zeichenfolgenliteral eingefügt.

In Ruby heißt das, wie Sie es erraten haben, String-Interpolation.

Rubin:

vorname = "martin"
last_name = "Riggs"
setzt "Hallo, ich bin # {Vorname} # {Nachname}."

In Javascript kann dasselbe mit Template-Literalen erreicht werden.

JavaScript:

const firstName = 'Martin';
const lastName = 'Riggs';
console.log (`Hi, ich bin $ {firstName} $ {lastName} .`);

Methoden und Funktionen

Wikipedia erklärt, dass in der Computerprogrammierung eine Unterroutine eine Folge von Programmanweisungen ist, die eine bestimmte Aufgabe ausführen und als Einheit zusammengefasst sind. Dieses Gerät kann dann in Programmen verwendet werden, in denen diese bestimmte Aufgabe ausgeführt werden soll.

In verschiedenen Programmiersprachen kann ein Unterprogramm eine Prozedur, eine Funktion, eine Routine, eine Methode oder ein Unterprogramm genannt werden.

Um verwendet zu werden, müssen diese Unterprogramme zuerst definiert und dann aufgerufen werden. In Ruby werden sie als Methoden und in JavaScript als Funktionen bezeichnet.

Rubin:

def full_name (vorname, nachname)
  "# {first_name.capitalize} # {last_name.capitalize}"
Ende
setzt full_name ("beatrix", "kiddo")

JavaScript:

Funktion fullName (Vorname, Nachname) {
  return `$ {firstName.capitalize ()} $ {lastName.capitalize ()}`;
};
console.log (fullName ("beatrix", "kiddo"));

Wenn Sie die obigen Beispiele ausführen, haben Sie wahrscheinlich bemerkt, dass das JavaScript-Beispiel nicht funktioniert, aber einen Fehler ausgibt: Uncaught TypeError: firstName.capitalize ist keine Funktion!

Dies liegt daran, dass JavaScript eine Großschreibung nicht nativ definiert. Ruby hat viele praktische und saubere idiomatische Methoden wie #capitalize, die wirklich praktisch sind. Damit das obige Beispiel funktioniert, müssen wir die Prototypenkette (Affen-Patch) für das JavaScript-String-Objekt verwenden:

String.prototype.capitalize = function () {
  return this.charAt (0) .toUpperCase () + this.slice (1);
}

Blöcke

In Ruby sind Blöcke im Grunde unbenannte Codestücke, die von innerhalb von Methoden übergeben und aufgerufen werden können. Viele der in Ruby integrierten Objektmethoden akzeptieren Blöcke, und dies ist eine bequeme Möglichkeit, das Verhalten solcher Methoden zu optimieren.

Rubin:

def timer
  start_time = Time.now
  setzt "Running block ..."
  
  Ausbeute
  setzt "Fertig!"
  end_time = Time.now - start_time
  "Ausführungszeit: # {end_time}"
Ende
setzt Timer {(0..10000000) .sort}

Hey, JavaScript hat keine Blöcke, daher ist die obige Implementierung nicht möglich und der Vergleich ist albern! Oder ist es? JavaScript-Funktionen können Rückruffunktionen als Argumente akzeptieren, und wenn wir Ruby-Blöcke als anonyme Methoden ansehen, können wir ein ähnliches Ergebnis erzielen.

JavaScript:

Funktions-Timer (Rückruf) {
  const startTime = new Date (). getTime ();
  console.log ("Callback wird ausgeführt ...");
  
  Rückrufen();
  console.log ("Fertig!");
  const endTime = new Date (). getTime ();
  return `Ausführungszeit: $ {endTime - startTime}`;
};
timer (() => Array.from (Array (10000000) .keys ()). sort ());

Hinweis: Im Gegensatz zu Ruby verfügt JavaScript nicht über ein integriertes Range-Objekt. Das Array.from (Number) .keys () oben gibt ein Array von 0 bis Number zurück.

Idiomatische Iterationen

Ruby ist dafür bekannt, sehr nette idiomatische Iteratoren zu haben, mit denen Arrays (und andere Enumerables oder iterative Strukturen) durchlaufen werden können.

Rubin:

names = ["Tango", "Cash", "Dalton", "Riggs"]
names.each do | name |
  setzt name
Ende

Mit ES6 wird das Durchlaufen eines Arrays in JavaScript zum Kinderspiel:

JavaScript:

const names = ['Tango', 'Cash', 'Dalton', 'Riggs'];
names.forEach (name => console.log (name));

Hinweis: Die Javascript forEach-Funktion kann auch auf den Index des Elements zugreifen. In Ruby verwenden wir einen anderen Iterator mit dem Namen each_with_index.

Klassen und Klassenvererbung

In der objektorientierten Programmierung sind Klassen Codevorlagen zum Erstellen von Objekten, zum Bereitstellen von Werten für den Status (die Eigenschaften oder Attribute des Objekts) und zum Implementieren von Verhalten (z. B. Get- und Setter-Funktionen zum Lesen und Schreiben solcher Eigenschaften oder Attribute).

Rubin:

Klasse Fahrzeug
  def initialize (Name, Typ)
    @name = name
    @type = Typ
  Ende
  def name
    @Name
  Ende
  def type
    @Art
  Ende
Ende
Klasse Auto 
diablo = Car.new ("Lamborghini")
Setzt diablo.name
setzt diablo.type

JavaScript:

Klasse Fahrzeug {
 
  Konstruktor (Name, Typ) {
    this.name = name;
    this.type = type;
  }
 
  getName () {
    return this.name;
  }
 
  getType () {
    return this.type;
  }
 
}
Klasse Auto erweitert Fahrzeug {
 
  Konstruktor (Name) {
    super (name, 'auto');
  }
}
const diablo = neues Auto ('Lamborghini');
console.log (diablo.getName ());
console.log (diablo.getType ());

Anmerkung: Im obigen Beispiel wird die Ruby Vehicle-Klasse normalerweise mit einem Attributleser implementiert, um die Getter-Methoden für die Instanzvariablen zu erstellen. Ich habe mich dafür entschieden, keinen Attribut-Reader zu verwenden, um die JavaScript-Implementierung ähnlicher zu gestalten.

Zerstörung

Modernes JavaScript hat dieses wirklich coole Ding namens Destructuring eingeführt, bei dem Sie Variablen Elemente in Arrays oder Objekten mit einer präzisen Syntax zuweisen können.

JavaScript:

Vorname, Nachname = 'James Bond'.split ();
console.log (`Mein Name ist $ {lastName}, $ {firstName} $ {lastName}`);

Dies ist in Ruby mit Sicherheit nicht möglich!

Rubin:

Vorname, Nachname = "James Bond" .split
setzt "Mein Name ist # {last_name}, # {first_name} # {last_name}"

Hinweis: Während wir Arrays in Ruby genauso wie in JavaScript destrukturieren können, gibt es kein Ruby-Äquivalent für die direkte Destrukturierung von Hashes.

Spread Operator

Modernes JavaScript hat auch den Spread-Operator eingeführt, mit dem iterierbare Ausdrücke erweitert werden können, wenn keine oder mehr Argumente oder Elemente erwartet werden.

JavaScript:

Funktionssumme (x, y, z) {
  return x + y + z;
};
konstante Zahlen = [1, 2, 3];
console.log (Summe (... Zahlen);
[a, b, ... rest] = [10, 20, 30, 40, 50];
console.log (a);
console.log (b);
console.log (rest); // rest ist ein Array!

In Ruby haben wir dafür den splat-Operator.

Rubin:

def sum (x, y, z)
  x + y + z
Ende
zahlen = [1, 2, 3]
setzt Summe (* Zahlen)
a, * rest, b = [10, 20, 30, 40, 50]
setzt ein
setzt b
Puts Rest # Rest ist ein Array!

Hinweis: Sie haben wahrscheinlich bemerkt, dass in Ruby * der Rest zwischen den anderen Variablen liegt. Das ist der Splat-Operator, der an einer beliebigen Stelle zwischen den Variablen platziert werden kann. In JavaScript muss der Spread-Operator an letzter Stelle stehen.

Ruby hat auch den Double-Splat-Operator **, um dasselbe mit Hashes zu tun. In der JavaScript ES2018-Spezifikation wird der Spread-Operator auch für Objekte eingeführt.

Letztes Wort

Wie Sie wahrscheinlich bemerkt haben, sind beide Sprachen doch nicht so unterschiedlich, und mit ES6 wird das Schreiben von JavaScript immer angenehmer. Sicher, JavaScript ist die Sprache des Browsers und seine Ereignisschleife sorgt für asynchrones Verhalten. Andererseits verfügt Ruby über sehr leistungsfähige Werkzeuge für die Metaprogrammierung und ist wegen seiner idiomatischen Syntax beliebt. Am Ende halte ich es für vorteilhaft, beide zu lernen und zu kennen, da die Kenntnis einer Programmiersprache Ihnen Anregungen gibt, wie Sie ein bestimmtes Problem in einer anderen programmieren oder angehen können.