Ukázka kódu: Ruby vs Javascript

Ruby a JavaScript se chystají jít hlava po hlavě. Oba tyto skriptovací jazyky jsou dynamicky psané a podporují objektově orientované programování. Prozkoumáme jejich rozdíly nebo podobnosti v některých z jejich běžnějších rysů.

Zřeknutí se odpovědnosti: Zde se zabýváme pouze moderní syntaxí jazyka JavaScript ES6.

Foto Pramote Polyamate na 500px

Řetězcová interpolace

V počítačovém programování je řetězcová interpolace procesem injektování hodnoty proměnné nebo výrazu do literálu řetězce.

V Ruby se tomu říká, uhodli jste to, řetězcová interpolace.

Rubín:

first_name = "Martin"
last_name = "Riggs"
uvádí "Ahoj, jsem # {first_name} # {last_name}."

V Javascriptu lze toho samého dosáhnout s literály šablony.

JavaScript:

const firstName = 'Martin';
const lastName = 'Riggs';
console.log (`Ahoj, jsem $ {firstName} $ {lastName} .`);

Metody a funkce

Wikipedia vysvětluje, že v počítačovém programování je podprogram posloupnost programových instrukcí, které vykonávají konkrétní úlohu, zabalené jako jednotka. Tuto jednotku lze poté použít v programech, kdekoli by měl být tento konkrétní úkol proveden.

V různých programovacích jazycích může být podprogram nazýván procedurou, funkcí, rutinou, metodou nebo podprogramem.

Aby byly tyto podprogramy použity, musí být nejprve definovány a poté vyvolány. V Ruby jsou známy jako metody a v JavaScriptu se nazývají funkce.

Rubín:

def full_name (křestní jméno, příjmení)
  "# {first_name.capitalize} # {last_name.capitalize}"
konec
vloží full_name ("beatrix", "kiddo")

JavaScript:

function fullName (jméno, příjmení) {
  return `$ {firstName.capitalize ()} $ {lastName.capitalize ()}`;
};
console.log (fullName ("beatrix", "kiddo"));

Pokud používáte výše uvedené příklady, pravděpodobně jste si všimli, že příklad JavaScriptu nefunguje, ale vyvolá chybu: Uncaught TypeError: firstName.capitalize není funkce!

Důvodem je, že JavaScript nedefinuje nativně funkci velkých písmen. Ruby má mnoho praktických a elegantních idiomatických metod, jako je #capitalize, které jsou opravdu pohodlné. Aby výše uvedený příklad fungoval, je třeba použít prototyp prototypu (opičí patch) na objektu JavaScript String:

String.prototype.capitalize = function () {
  vrátit this.charAt (0) .UUpperCase () + this.slice (1);
}

Bloky

V Ruby jsou bloky v podstatě nejmenované kousky kódu, které lze předat a vyvolat zevnitř metod. Mnoho vestavěných metod objektu v Ruby přijímá bloky a to je pohodlný způsob, jak vyladit způsob, jakým se tyto metody chovají.

Rubín:

def časovač
  start_time = Time.now
  vloží "Běžecký blok ..."
  
  výtěžek
  staví „Dokončeno!“
  end_time = Time.now - start_time
  "Čas provedení: # {end_time}"
konec
staví časovač {(0..10000000) .sort}

Hej, JavaScript nemá bloky, takže výše uvedená implementace není možná a srovnání je hloupé! Nebo je to? Funkce JavaScriptu mohou akceptovat funkce zpětného volání jako argumenty a pokud si myslíme, že bloky Ruby jsou velmi podobné anonymním metodám, můžeme dosáhnout podobného výsledku.

JavaScript:

funkční časovač (zpětné volání) {
  const startTime = new Date (). getTime ();
  console.log ("Spuštění zpětného volání ...");
  
  zpětné volání ();
  console.log ("Dokončeno!");
  const endTime = new Date (). getTime ();
  návrat `Doba provedení: $ {endTime - startTime}`;
};
časovač (() => Array.from (Array (10000000) .keys ()). sort ());

Poznámka: Na rozdíl od Ruby, JavaScript nemá vestavěný objekt Range. Pole Array.from (Number) .keys () vrací Array od 0 do Number.

Idiomatické iterace

Ruby je známo, že má velmi pěkné idiomatické iterátory, které procházejí skrz pole (a další enumerables nebo iterační struktury).

Rubín:

names = ["Tango", "Cash", "Dalton", "Riggs"]
names.each do | name |
  říká jméno
konec

S ES6 se iterace skrz pole v JavaScriptu stává hračkou:

JavaScript:

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

Poznámka: Funkce Javascript forEach může také přistupovat k indexu prvku. V Ruby bychom použili jiný iterátor, který se jmenuje every_with_index.

Třídy a dědičnost tříd

V objektově orientovaném programování jsou třídy šablon kódů pro vytváření objektů, poskytujících hodnoty pro stav (vlastnosti nebo atributy objektu) a implementační chování (jako jsou getery a setters pro čtení a zápis takových vlastností nebo atributů).

Rubín:

třída vozidla
  def inicializovat (jméno, typ)
    @ jméno = jméno
    @type = type
  konec
  def jméno
    @název
  konec
  typ def
    @typ
  konec
konec
třída Auto 
diablo = Car.new ("Lamborghini")
dá diablo.name
dá diablo.type

JavaScript:

třída Vozidlo {
 
  konstruktor (jméno, typ) {
    this.name = name;
    this.type = type;
  }
 
  getName () {
    návrat this.name;
  }
 
  getType () {
    vrátit this.type;
  }
 
}
třída Car rozšiřuje vozidlo {
 
  konstruktor (jméno) {
    super (jméno, 'auto');
  }
}
const diablo = nové auto ('Lamborghini');
console.log (diablo.getName ());
console.log (diablo.getType ());

Poznámka: Ve výše uvedeném příkladu by třída Ruby Vehicle byla obvykle implementována pomocí čtečky atributů pro vytvoření getterových metod pro proměnné instance. Rozhodl jsem se nepoužívat čtečku atributů, aby se podobal implementaci JavaScriptu.

Ničení

Moderní JavaScript představil tuto opravdu skvělou věc zvanou destruktivní, kde můžete přiřadit prvky uvnitř polí nebo objektů k proměnným se stručnou syntaxí.

JavaScript:

firstName, lastName = 'James Bond'.split ();
console.log (`Jmenuji se $ {lastName}, $ {firstName} $ {lastName}`);

V Ruby to určitě nemůžete udělat!

Rubín:

first_name, last_name = "James Bond" .split
vloží "Jmenuji se # {last_name}, # {first_name} # {last_name}"

Poznámka: I když můžeme v Ruby ničit pole stejně jako v JavaScriptu, neexistuje žádný ekvivalent Ruby přímo k hasiči s přímým ničením.

Spread Operator

Moderní JavaScript také zavedl operátor rozšíření, který umožňuje rozšíření iterovatelných výrazů tam, kde se očekává nula nebo více argumentů nebo prvků.

JavaScript:

součet funkcí (x, y, z) {
  návrat x + y + z;
};
const čísla = [1, 2, 3];
console.log (suma (... čísla);
[a, b, ... zbytek] = [10, 20, 30, 40, 50];
console.log (a);
console.log (b);
console.log (rest); // zbytek je pole!

V Ruby máme na to operátora ikon.

Rubín:

def sum (x, y, z)
  x + y + z
konec
čísla = [1, 2, 3]
součet (* čísla)
a, * zbytek, b = [10, 20, 30, 40, 50]
klade
staví b
staví zbytek # zbytek je pole!

Poznámka: Pravděpodobně jste si všimli, že v Ruby * je zbytek mezi ostatními proměnnými. To je operátor ikon, který lze umístit kdekoli mezi proměnné. V JavaScriptu musí operátor rozprostřít poslední.

Ruby má také operátora dvojitého splatu **, který udělá totéž na hashe. Specifikace JavaScriptu ES2018 také zavádí operátor rozmetání na objekty.

Poslední slovo

Jak jste si pravděpodobně uvědomili, oba jazyky se přece jen neliší a s ES6 se psaní stává stále příjemnějším. Jistě, JavaScript je jazyk prohlížeče a jeho smyčka událostí poskytuje asynchronní chování. Na druhou stranu, Ruby má velmi silné nástroje k provádění metaprogramování a je milován svou idiomatickou syntaxí. Na konci konce se domnívám, že je užitečné se učit a znát, protože často vám znalost jednoho programovacího jazyka poskytne nápady, jak kódovat nebo řešit určitý problém v jiném.