Выкрыццё кода: Ruby vs Javascript

Ruby і JavaScript хутка ідуць галава да галавы. Абодва гэтыя мовы сцэнарыяў дынамічна набіраюцца і падтрымліваюць аб'ектна-арыентаванае праграмаванне. Мы разгледзім іх адрозненні і падабенствы ў некаторых іх больш агульных рысах.

Адмова ад адказнасці. Мы глядзім толькі сучасны сінтаксіс JavaScript ES6.

Фота Pramote Polyamate на 500px

Інтэрпаляцыя радкоў

У кампутарным праграмаванні радкавая інтэрпаляцыя - гэта працэс увядзення значэння зменнай або выраза ў літаральны радок.

У Рубі гэта называецца, як вы ўжо здагадаліся, радком інтэрпаляцыі.

Ruby:

first_name = "Марцін"
last_name = "Настроі"
ставіць "Прывітанне, я # {first_name} # {last_name}."

У Javascript тое ж самае можна дасягнуць і з літаральнымі шаблонамі.

JavaScript:

const firstName = 'Марцін';
const lastName = 'Riggs';
console.log (`Прывітанне, я $ {firstName} $ {lastName}.");

Метады і функцыі

Вікіпедыя тлумачыць, што ў кампутарным праграмаванні падпраграма ўяўляе сабой паслядоўнасць інструкцый праграмы, якая выконвае пэўную задачу, упакаваную ў адзінку. Затым гэты прыбор можа быць выкарыстаны ў праграмах, дзе б выконвалася пэўная задача.

У розных мовах праграмавання падпраграму можна назваць працэдурай, функцыяй, працэдурай, спосабам ці падпраграмай.

Каб выкарыстоўваць, гэтыя падпраграмы трэба спачатку вызначыць, а потым выклікаць. У Ruby яны вядомыя як метады, а ў JavaScript - іх называюць функцыямі.

Ruby:

вызначыць поўнае імя (імя, прозвішча)
  "# {first_name.capitalize} # {last_name.capitalize}"
канец
ставіць full_name ("beatrix", "kiddo")

JavaScript:

функцыя fullName (firstName, lastName) {
  вярнуцца `$ {firstName.capitalize ()} $ {lastName.capitalize ()}`;
};
console.log (fullName ("beatrix", "kiddo"));

Калі вы прыводзіце прыклады вышэй, вы, напэўна, заўважылі, што прыклад JavaScript не працуе, але выдае памылку: Uncaught TypeError: firstName.capitalize не з'яўляецца функцыяй!

Гэта таму, што JavaScript не вызначае функцыю выкарыстання вялікай літары. У Ruby ёсць шмат зручных і акуратных ідыяматычных метадаў, такіх як #capitalize, якія сапраўды зручныя. Каб зрабіць прыведзены вышэй прыклад, нам трэба будзе выкарыстаць прататып ланцуга (малпа патч) у аб'екце String JavaScript:

String.prototype.capitalize = function () {
  вярнуць this.charAt (0) .toUpperCase () + this.slice (1);
}

Блокі

У Ruby, блокі ў асноўным неназваныя кавалкі кода, якія могуць быць перададзены і выкліканы метадамі знутры. Многія з убудаваных аб'ектных метадаў у Ruby прымаюць блокі, і гэта зручны спосаб наладзіць тое, як такія метады паводзяць сябе.

Ruby:

таймер def
  start_time = Time.now
  ставіць "Запуск блока ..."
  
  ўраджайнасць
  ставіць "Гатова!"
  end_time = Time.now - start_time
  "Час выканання: # {end_time}"
канец
ставіць таймер {(0..10000000) .sort}

Прывітанне, у JavaScript няма блокаў, таму рэалізацыя вышэй не магчымая і параўнанне глупства! Ці гэта? Функцыі JavaScript могуць прымаць функцыі зваротнага званка як аргументы, і калі мы лічым, што блокі Ruby як падобныя да ананімных метадаў, мы можам дасягнуць аналагічнага выніку.

JavaScript:

таймер функцыі (зваротны званок) {
  const startTime = new Date (). getTime ();
  console.log ("Запуск званка выкліку ...");
  
  ператэлефанаваць();
  console.log ("Гатова!");
  const endTime = new Date (). getTime ();
  return `Час выканання: $ {endTime - startTime}`;
};
таймер (() => Array.from (масіў (10000000) .keys ()). sort ());

Заўвага: у адрозненне ад Ruby, JavaScript не мае ўбудаванага аб'екта Range. Вышэй Array.from (Number) .keys () вяртае масіў ад 0 да нумара.

Фразеалагічныя ітэрацыі

Рубі вядомы тым, што мае вельмі прыгожыя ідыяматычныя ітэратары, якія праглядаюць масівы (і іншыя пералічальныя матэрыялы альбо ітэратыўныя структуры).

Ruby:

імёны = ["Танга", "Наяўныя", "Далтан", "Рыггі"]
names.each do | імя |
  ставіць імя
канец

З ES6 ітэрацыя праз масіў у JavaScript становіцца ветрыкам:

JavaScript:

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

Заўвага: Функцыя Javascript forEach таксама можа атрымаць доступ да індэкса элемента. У Ruby мы выкарыстоўвалі б іншы ітэратар для названага every_with_index.

Класы і спадчыннасць класа

У аб'ектна-арыентаваным праграмаванні класы - гэта шаблоны кода для стварэння аб'ектаў, якія забяспечваюць значэнні стану (уласцівасці альбо атрыбуты аб'екта) і паводзіны рэалізацыі (напрыклад, гетэры і сетэры для чытання і запісу такіх уласцівасцей альбо атрыбутаў).

Ruby:

Аўтамабіль класа
  вызначыць ініцыялізацыю (імя, тып)
    @ імя = імя
    @type = тып
  канец
  імя Def
    @ імя
  канец
  тып def
    @type
  канец
канец
Аўтамабіль класа <Аўтамабіль
  вызначыць ініцыялізацыю (імя)
   супер (імя, "машына")
  канец
канец
diablo = Car.new ("Lamborghini")
ставіць diablo.name
ставіць diablo.type

JavaScript:

Аўтамабіль класа
 
  канструктар (імя, тып) {
    this.name = імя;
    this.type = type;
  }
 
  getName () {
    вярнуць this.name;
  }
 
  getType () {
    вярнуць гэты.тып;
  }
 
}
Аўтамабіль класа падаўжае аўтамабіль {
 
  канструктар (імя) {
    супер (назва, «машына»);
  }
}
const diablo = новы аўтамабіль ('Lamborghini');
console.log (diablo.getName ());
console.log (diablo.getType ());

Заўвага: У прыведзеным вышэй прыкладзе клас Ruby Vehicle звычайна будзе рэалізаваны з дапамогай ачышчальніка атрыбутаў для стварэння метадаў getter для зменных асобнікаў. Я вырашыў не выкарыстоўваць счытвальнік атрыбутаў, каб мець больш падобны выгляд рэалізацыі JavaScript.

Разбурэнне

Сучасны JavaScript прадставіў гэтую сапраўды класную рэч, званую разбурэннем, дзе вы можаце прысвоіць элементам масівы альбо аб'екты пераменным з кароткім сінтаксісам.

JavaScript:

firstName, lastName = 'Джэймс Бонд'.split ();
console.log (`Мяне завуць $ {lastName}, $ {firstName} $ {lastName}`);

Напэўна, у Рубі гэтага зрабіць нельга!

Ruby:

first_name, last_name = "Джэймс Бонд" .split
ставіць "Мяне завуць # {last_name}, # {first_name} # {last_name}"

Заўвага: Хоць мы можам разбурыць масівы ў Ruby так жа, як і ў JavaScript, у Ruby няма эквівалента непасрэдна хэшаў разбурэння.

Аператар Spread

Сучасны JavaScript таксама прадставіў аператар спрэду, які дазваляе пашыраць памятныя выразы там, дзе чакаецца нуль і больш аргументаў ці элементаў.

JavaScript:

сума функцый (x, y, z) {
  вяртанне x + y + z;
};
лік const = [1, 2, 3];
console.log (сума (... нумары);
[a, b, ... адпачынак] = [10, 20, 30, 40, 50];
console.log (a);
console.log (b);
console.log (адпачынак); // астатняе масіў!

У Рубі ў нас ёсць аператар "брызг".

Ruby:

сума def (x, y, z)
  x + y + z
канец
лік = [1, 2, 3]
ставіць суму (* лічбы)
a, * адпачынак, b = [10, 20, 30, 40, 50]
ставіць
ставіць б
кладзе адпачынак # адпачынак - гэта масіў!

Заўвага: Вы напэўна заўважылі, што ў Ruby * адпачынак знаходзіцца паміж іншымі пераменнымі. Вось аператар брызгавікоў можа быць размешчаны ў любым месцы сярод зменных. У JavaScript аператар распаўсюджвання павінен быць апошнім.

У Ruby таксама ёсць аператар з падвойным застаўкай **, каб зрабіць тое ж самае на хэшах. Спецыфікацыя JavaScript ES2018 таксама ўводзіць аператар распаўсюджвання на аб'екты.

Заключнае слова

Як вы ўжо напэўна зразумелі, абедзве мовы ў рэшце рэшт не так ужо і розныя, і з ES6 JavaScript пісаць становіцца ўсё больш прыемна. Вядома, JavaScript з'яўляецца мовай браўзэра, і яго цыкл падзей забяспечвае асінхроннае паводзіны. З іншага боку, у Рубі ёсць вельмі магутныя інструменты для метапраграмавання і яе любімая ідыяматычная сінтаксіс. У рэшце рэшт, я лічу, што выгадна вывучаць і ведаць, як часта веданне адной мовы праграмавання дасць вам ідэі, як правільна кодаваць альбо вырашаць іншую праблему ў іншай.