Afisare cod: Ruby vs Javascript

Ruby și JavaScript sunt pe cale să meargă din cap. Ambele limbaje de script sunt tastate dinamic și acceptă programarea orientată pe obiecte. Vom examina diferențele sau asemănările cu unele dintre caracteristicile lor mai comune.

Disclaimer: Ne uităm aici doar la sintaxa modernă JavaScript ES6.

Fotografie de Pramote Polyamate pe 500px

Interpolarea corzilor

În programarea computerului, interpolarea șirurilor este procesul de injectare a valorii unei variabile sau a unei expresii într-un text literal.

În Ruby, așa se numește, ai ghicit, interpolarea șirului.

Rubin:

prenumele = "Martin"
last_name = "Riggs"
pune „Bună, sunt # {prenumele} # {prenumele}."

În Javascript, același lucru poate fi obținut cu literale de șablon.

JavaScript:

const firstName = 'Martin';
const lastName = 'Riggs';
console.log (`Bună, sunt $ {firstName} $ {lastName} .`);

Metode și funcții

Wikipedia explică faptul că, în programarea computerului, o subrutină este o secvență de instrucțiuni de program care îndeplinește o sarcină specifică, ambalată ca unitate. Această unitate poate fi apoi utilizată în programe oriunde ar trebui să se efectueze acea sarcină specială.

În diferite limbaje de programare, o subrutină poate fi numită procedură, funcție, rutină, metodă sau subprogram.

Pentru a putea fi utilizate, aceste subrutine trebuie definite mai întâi și apoi numite. În Ruby, ele sunt cunoscute sub numele de metode și în JavaScript, sunt denumite funcții.

Rubin:

def nume_ nume (prenumele, prenumele)
  "# {first_name.capitalize} # {last_name.capitalize}"
Sfârșit
pune nume_complet ("beatrix", "kiddo")

JavaScript:

function fullName (firstName, lastName) {
  returnare $ $ firstName.capitalize ()} $ {lastName.capitalize ()} `;
};
console.log (nume complet ("beatrix", "kiddo"));

Dacă executați exemplele de mai sus, probabil ați observat că exemplul JavaScript nu funcționează, dar aruncă o eroare: Uncaught TypeError: firstName.capitalize nu este o funcție!

Acest lucru se întâmplă deoarece JavaScript nu definește nativ o funcție de capitalizare. Ruby are multe metode idiomatice la îndemână și îngrijite, cum ar fi #capitalizarea, care sunt cu adevărat convenabile. Pentru ca exemplul de mai sus să funcționeze, va trebui să utilizăm lanțul de prototipuri (patch-ul maimuță) pe obiectul String JavaScript:

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

blocuri

În Ruby, blocurile sunt, practic, bucăți de cod nenumite care pot fi transmise și apelate din metode interioare. Multe dintre metodele de obiect încorporate în Ruby acceptă blocuri și acestea sunt o modalitate convenabilă de a modifica modul în care se comportă astfel de metode.

Rubin:

cronometru def
  start_time = Time.now
  pune „Run block ...”
  
  Randament
  pune "Terminat!"
  end_time = Time.now - start_time
  "Timp de execuție: # {end_time}"
Sfârșit
pune cronometrul {(0..10000000) .sort}

Hei, JavaScript nu are blocuri, deci implementarea de mai sus nu este posibilă și comparația este o prostie! Sau este? Funcțiile JavaScript pot accepta ca argumente funcțiile de apelare și dacă ne gândim la blocurile Ruby ca fiind foarte asemănătoare unor metode anonime, putem obține un rezultat similar.

JavaScript:

funcție cronometru (callback) {
  const startTime = data nouă (). getTime ();
  console.log ("Se rulează apelul invers ...");
  
  suna inapoi();
  console.log ( "A terminat!");
  const endTime = data nouă (). getTime ();
  returnare „Timp de execuție: $ {endTime - startTime}`;
};
timer (() => Array.from (Array (10000000) .keys ()). sort ());

Notă: Spre deosebire de Ruby, JavaScript nu are un obiect Range încorporat. Array.from (Number) .keys () de mai sus returnează o matrice de la 0 la număr.

Iterații idiomatice

Ruby este cunoscut pentru faptul că are iteratori idiomatici foarte drăguți care să se bucure prin Array-uri (și alte Enumerabile sau structuri iterative).

Rubin:

names = ["Tango", "Cash", "Dalton", "Riggs"]
nume.each do | nume |
  pune numele
Sfârșit

Cu ES6, iterarea printr-un tablou în JavaScript devine o briză:

JavaScript:

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

Notă: Funcția Javascript forEach poate accesa și indexul elementului. În Ruby, am folosi un iterator diferit pentru cel numit fiecare_cu_index.

Clasele și moștenirea clasei

În programarea orientată pe obiecte, clasele sunt șabloane de cod pentru crearea obiectelor, furnizând valori pentru starea (proprietățile sau atributele obiectului) și implementarea comportamentului (cum ar fi getters și setters pentru a citi și scrie astfel de proprietăți sau atribute).

Rubin:

Vehicul de clasă
  def inițializare (nume, tip)
    @ nume = nume
    @type = tip
  Sfârșit
  nume def
    @Nume
  Sfârșit
  tip def
    @tip
  Sfârșit
Sfârșit
clasa Mașină 
diablo = Car.new ("Lamborghini")
pune diablo.name
pune diablo.type

JavaScript:

Vehicul de clasă {
 
  constructor (nume, tip) {
    this.name = nume;
    this.type = tip;
  }
 
  getName () {
    returna acest nume
  }
 
  getType () {
    returnează acest tip;
  }
 
}
Clasa Mașină extinde Vehicul {
 
  constructor (nume) {
    super (nume, „mașină”);
  }
}
const diablo = new Car („Lamborghini”);
console.log (diablo.getName ());
console.log (diablo.getType ());

Notă: În exemplul de mai sus, clasa vehiculului Ruby ar fi de obicei implementată cu un cititor de atribute pentru a crea metodele getter pentru variabilele de instanță. Am ales să nu folosesc un cititor de atribute pentru a avea un aspect mai similar cu implementarea JavaScript.

Destructurarea

JavaScript modern a introdus acest lucru cu adevărat interesant, numit distrugere, unde puteți atribui elemente din tablouri sau obiecte variabilelor cu o sintaxă concisă.

JavaScript:

firstName, lastName = 'James Bond'.split ();
console.log (`Numele meu este $ {lastName}, $ {firstName} $ {lastName}`);

Cu siguranță că nu poți face asta în Ruby!

Rubin:

first_name, last_name = "James Bond" .split
pune „My name is # {last_name}, # {first_name} # {last_name}”

Notă: Deși putem distruge matricile în Ruby la fel de mult ca și în JavaScript, nu există niciun Ruby echivalent cu hașe direct pentru distrugere.

Spread operator

JavaScript modern a introdus de asemenea operatorul de propagare, care permite extinderea expresiilor iterabile acolo unde sunt așteptate zero sau mai multe argumente sau elemente.

JavaScript:

suma funcției (x, y, z) {
  returnare x + y + z;
};
numere const = = 1, 2, 3];
console.log (sumă (... numere);
[a, b, ... rest] = [10, 20, 30, 40, 50];
console.log (a);
console.log (b);
console.log (restul); // odihna este un Array!

În Ruby, avem operatorul pentru splat.

Rubin:

sumă def (x, y, z)
  x + y + z
Sfârșit
numere = [1, 2, 3]
pune suma (* numere)
a, * rest, b = [10, 20, 30, 40, 50]
pune un
pune b
pune odihna # rest este un Array!

Notă: Probabil ați observat că în Ruby * restul este între celelalte variabile. Acesta este operatorul de splat poate fi plasat oriunde printre variabile. În JavaScript, operatorul de răspândire trebuie să fie ultim.

De asemenea, Ruby are operatorul dublu splat ** pentru a face același lucru pe hașe. Specificația JavaScript ES2018 introduce și operatorul de răspândire pe obiecte.

Cuvânt final

După cum v-ați dat seama, ambele limbi nu sunt atât de diferite până la urmă și, cu ES6, JavaScript a devenit tot mai plăcut de scris. Sigur, JavaScript este limba browserului, iar bucla de eveniment oferă un comportament asincron. Pe de altă parte, Ruby are instrumente foarte puternice pentru a face metaprogramarea și este iubit pentru sintaxa idiomatică. La sfârșitul sfârșitului, cred că este benefic să înveți și să știi atât cât de des cunoașterea unui limbaj de programare îți va oferi idei despre cum poți codifica sau rezolva o anumită problemă într-o altă.