Codeweergave: Ruby versus Javascript

Ruby en JavaScript staan ​​op het punt het tegen elkaar op te nemen. Beide scripttalen zijn dynamisch getypt en ondersteunen objectgeoriënteerd programmeren. We zullen hun verschillen of overeenkomsten onderzoeken voor een aantal van hun meer algemene kenmerken.

Disclaimer: we kijken hier alleen naar de moderne JavaScript ES6-syntaxis.

Foto door Pramote Polyamate op 500px

Stringinterpolatie

In computerprogrammering is stringinterpolatie het proces van het injecteren van de waarde van een variabele of een uitdrukking in een letterlijke tekenreeks.

In Ruby heet dit, je raadt het al, stringinterpolatie.

Robijn:

first_name = "Martin"
last_name = "Riggs"
zet "Hallo, ik ben # {first_name} # {last_name}."

In Javascript kan hetzelfde worden bereikt met sjabloonliteralen.

JavaScript:

const firstName = 'Martin';
const lastName = 'Riggs';
console.log (`Hallo, ik ben $ {firstName} $ {lastName} .`);

Methoden en functies

Wikipedia legt uit dat, bij computerprogrammering, een subroutine een reeks programma-instructies is die een specifieke taak uitvoert, verpakt als een eenheid. Deze eenheid kan vervolgens worden gebruikt in programma's waar die specifieke taak moet worden uitgevoerd.

In verschillende programmeertalen kan een subroutine een procedure, een functie, een routine, een methode of een subprogramma worden genoemd.

Om te worden gebruikt, moeten deze subroutines eerst worden gedefinieerd en vervolgens worden aangeroepen. In Ruby worden ze methoden genoemd en in JavaScript worden ze functies genoemd.

Robijn:

def volledige naam (voornaam, achternaam)
  "# {first_name.capitalize} # {last_name.capitalize}"
einde
zet volledige_naam ("beatrix", "kiddo")

JavaScript:

functie fullName (firstName, lastName) {
  retourneer `$ {firstName.capitalize ()} $ {lastName.capitalize ()}`;
};
console.log (fullName ("beatrix", "kiddo"));

Als je de bovenstaande voorbeelden uitvoert, heb je waarschijnlijk gemerkt dat het JavaScript-voorbeeld niet werkt, maar een foutmelding geeft: Uncaught TypeError: firstName.capitalize is geen functie!

Dit komt omdat JavaScript niet automatisch een hoofdletterfunctie definieert. Ruby heeft veel handige en nette idiomatische methoden zoals #kapitaliseren die erg handig zijn. Om het bovenstaande voorbeeld te laten werken, moeten we de prototypeketen (aap-patch) op het JavaScript String-object gebruiken:

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

Blocks

In Ruby zijn blokken in feite niet-genoemde stukjes code die kunnen worden doorgegeven en aangeroepen vanuit interne methoden. Veel van de ingebouwde objectmethoden in Ruby accepteren blokken en dit is een handige manier om het gedrag van dergelijke methoden aan te passen.

Robijn:

def timer
  start_time = Time.now
  zet "Lopend blok ..."
  
  opbrengst
  zet "Voltooid!"
  end_time = Time.now - start_time
  "Uitvoeringstijd: # {end_time}"
einde
zet timer {(0..10000000) .sort}

Hallo, JavaScript heeft geen blokken, dus de bovenstaande implementatie is niet mogelijk en de vergelijking is gek! Of is het? JavaScript-functies kunnen callback-functies als argumenten accepteren en als we denken dat Ruby-blokken erg op anonieme methoden lijken, kunnen we een soortgelijk resultaat bereiken.

JavaScript:

functietimer (terugbellen) {
  const startTime = new Date (). getTime ();
  console.log ("Terugbellen actief ...");
  
  terugbellen();
  console.log ( "Finished!");
  const endTime = new Date (). getTime ();
  retourneer `Uitvoeringstijd: $ {endTime - startTime}`;
};
timer (() => Array.from (Array (10000000) .keys ()). sort ());

Opmerking: in tegenstelling tot Ruby heeft JavaScript geen ingebouwd bereikobject. De Array.from (Number) .keys () hierboven retourneert een Array van 0 naar Number.

Idiomatische iteraties

Ruby staat erom bekend zeer mooie idiomatische iterators te hebben om Arrays (en andere Enumerables of iteratieve structuren) te doorlopen.

Robijn:

names = ["Tango", "Cash", "Dalton", "Riggs"]
names.each do | name |
  zet naam
einde

Met ES6 wordt het doorlopen van een array in JavaScript een fluitje van een cent:

JavaScript:

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

Opmerking: De Javascript voor elke functie heeft ook toegang tot de index van het element. In Ruby zouden we hiervoor een andere iterator gebruiken die each_with_index wordt genoemd.

Klassen en klassenvererving

In Object-Oriented Programming zijn klassen codesjablonen voor het maken van objecten, die waarden bieden voor de status (eigenschappen of attributen van het object) en implementatiegedrag (zoals getters en setters om dergelijke eigenschappen of attributen te lezen en te schrijven).

Robijn:

klasse voertuig
  def initialiseren (naam, type)
    @naam = naam
    @type = type
  einde
  def naam
    @naam
  einde
  def type
    @type
  einde
einde
class Car 
diablo = Car.new ("Lamborghini")
zet diablo.name
zet diablo.type

JavaScript:

klasse voertuig {
 
  constructor (naam, type) {
    this.name = name;
    this.type = type;
  }
 
  getName () {
    terug this.name;
  }
 
  getType () {
    retourneer dit.type;
  }
 
}
class Car verlengt voertuig {
 
  constructor (naam) {
    super (naam, 'auto');
  }
}
const diablo = new Car ('Lamborghini');
console.log (diablo.getName ());
console.log (diablo.getType ());

Opmerking: In het bovenstaande voorbeeld zou de Ruby Vehicle-klasse doorgaans worden geïmplementeerd met een attribuutlezer om de getter-methoden voor de instantievariabelen te maken. Ik heb ervoor gekozen geen attribuutlezer te gebruiken om een ​​meer vergelijkbaar uiterlijk te hebben met de JavaScript-implementatie.

destructurering

Modern JavaScript introduceerde dit echt coole ding genaamd destructuring, waarbij je elementen in arrays of objecten aan variabelen kunt toewijzen met een beknopte syntaxis.

JavaScript:

firstName, lastName = 'James Bond'.split ();
console.log (`Mijn naam is $ {lastName}, $ {firstName} $ {lastName}`);

Je kunt dit toch niet doen in Ruby!

Robijn:

first_name, last_name = "James Bond" .split
zet "Mijn naam is # {last_name}, # {first_name} # {last_name}"

Opmerking: Hoewel we arrays in Ruby net zo goed kunnen vernietigen als in JavaScript, is er geen Ruby equivalent aan direct vernietigende hashes.

Gespreide operator

Modern JavaScript heeft ook de spread-operator geïntroduceerd waarmee iterabele expressies kunnen worden uitgebreid waar nul of meer argumenten of elementen worden verwacht.

JavaScript:

functiesom (x, y, z) {
  retourneer x + y + z;
};
const nummers = [1, 2, 3];
console.log (sum (... nummers);
[a, b, ... rest] = [10, 20, 30, 40, 50];
console.log (a);
console.log (b);
console.log (rust); // rest is een array!

In Ruby hebben we hiervoor de splat-operator.

Robijn:

def som (x, y, z)
  x + y + z
einde
nummers = [1, 2, 3]
zet som (* getallen)
a, * rust, b = [10, 20, 30, 40, 50]
zet een
zet b
zet rust # rust is een array!

Opmerking: je hebt waarschijnlijk gemerkt dat in Ruby * rust tussen de andere variabelen ligt. Dat is de splat-operator die overal tussen de variabelen kan worden geplaatst. In JavaScript moet de spread-operator als laatste komen.

Ruby heeft ook de dubbele splat-operator ** om hetzelfde te doen op hashes. De JavaScript ES2018-specificatie introduceert de spread-operator ook op objecten.

Laatste woord

Zoals u waarschijnlijk wel besefte, zijn beide talen toch niet zo verschillend en met ES6 is JavaScript steeds aangenamer geworden om te schrijven. Natuurlijk, JavaScript is de taal van de browser en de event-lus biedt asynchroon gedrag. Aan de andere kant heeft Ruby zeer krachtige tools om metaprogrammering te doen en is hij geliefd om zijn idiomatische syntaxis. Aan het einde van het einde denk ik dat het nuttig is om te leren en beide te weten, omdat kennis van de ene programmeertaal je ideeën geeft over hoe je een bepaald probleem in een ander kunt coderen of aanpakken.