Ruby to JavaScript
Published in
5 min readAug 25, 2022
--
A short guide for Rubyists starting JS210
Variables
- Local variable declaration:
let schoolName = 'Launch School';
- Constant variable declaration:
const SCHOOL_NAME = 'Launch School';
- An undeclared variable with global scope:
schoolName = 'Launch School';
(don’t do this) camelCase
for local variables (and functions)SCREAMING_SNAKE_CASE
for constants- We can also create variables with the dated
var
statement:var weather = 'Sunny';
var
is function-scoped (weird) whilelet
is block-scoped (normal)
Something to be aware of becauselet
andconst
are recent additions - Local variables have the expected block scope, except they are accessible within functions (JS equivalent of methods):
// Example 1let dog = 'Banjo';
function example() { // curly braces delimit the function body
console.log(dog);
}example(); // Banjo
console.log(dog); // Banjo// Example 2function example() {
let dog = 'Banjo';
console.log(dog);
}example(); // Banjo
console.log(dog); // ReferenceError: dog is not defined
Functions
- From a Ruby perspective, JS functions are methods with lenient arity and what is essentially block scope
- Curly braces
{}
surrounding a function body do not define a block. Function bodies and blocks are distinct. However, they are so similar that function bodies are commonly referred to as blocks. - Implicit return is
undefined
except when using an arrow function with one expression. In that case, JS allows us to omit keywordreturn
. - Explicit return requires keyword
return
- Default parameters work as expected
- Function Declaration:
function hello() { …
(starts withfunction
) - Named Function Expression:
let hello = function hello() { …
(useful for debugging) - Anonymous Function Expression:
let hello = function () { …
(common) - Arrow Function: a shorthand way to write a function expression:
let greeting = (arg1, arg2) => { …
Commonly used in callback functions: a function passed as an argument to another function:
// Example 1arr.forEach((ele, idx) => console.log(ele, idx));// Example 2arr.forEach((ele, idx) => {
console.log(ele, idx);
if (ele === 1) arr2.push(ele);
})
- Pure function: a function without side effects and with a return value determined only by its arguments
- Rest parameter: similar to Ruby’s splat, it takes any number of arguments and makes them available as elements within an array:
function dogNames(…args) { …
- Functions are first-class objects: they can be assigned to a variable or collection element, passed as an argument to a function, or returned by a function
Objects
- We can think of a JS object as a Ruby hash
- Objects have name/value pairs called properties
- Properties are referenced and created by dot notation (preferred) or bracket notation:
let obj = {num: 5, str: 'dog'};
console.log(obj.num); // 5
console.log(obj['num']); // 5obj.wowz = 'powz';
console.log(obj); // { num: 5, str: 'dog', wowz: 'powz' }
obj.wowz = 'zowz';
console.log(obj); // { num: 5, str: 'dog', wowz: 'zowz' }
- A property name must be a string (quotation marks can be omitted, as above). A property value can be a function expression, an array, an object, a string, a number, or any valid expression:
let obj = {
num: 5,
str: 'dog',
arr: [1, 2, 3],
obj: {hello: 'goodbye'},
bool: true,
add(num1, num2) { // compact method syntax
return num1 + num2;
},
'multiple words': 'this works',
};console.log(obj.add(1, 2)); // 3
// add is a 'method' because it is part of an object
// compact method syntax saves us from
// add: function add(num1, num2) {
// return num1 + num2;
// },
Arrays
- Arrays work mostly the same as in Ruby. They are zero-indexed: indexes start at 0 and
arr.length
returns the last index + 1. - Arrays are a type of object: indexes are names and elements are values
arr[-1]
does not reference the last index- We can create different n/v pairs in an array, but not in a literal:
let arr = [1, 2, 3];
arr[3] = 4;
arr[-11] = 'wow!';
arr['hello'] = 'bye';console.log(arr[3]); // 4
console.log(arr['hello']); // bye
console.log(arr[-11]); // wow!
console.log(arr); // [ 1, 2, 3, 4, '-11': 'wow!', hello: 'bye' ]let arr2 = [1, 2, 3, 4, '-11': 'wow!', hello: 'bye'];
// SyntaxError: Unexpected token ':'
// Note the type coercion
- All n/v pairs are properties. Non-negative integer names are by default normal index properties. All other properties do not count toward an array’s length. Neither are they processed by other Array methods:
let arr = [1, 2, 3];
arr[3] = 4; // new element increases length
arr[-11] = 'wow!'; // does not increase length
arr['hello'] = 'bye'; // does not increase lengthconsole.log(arr.length); // 4console.log(arr); // [ 1, 2, 3, 4, '-11': 'wow!', hello: 'bye' ]arr.forEach(ele => console.log(ele));
// 1
// 2
// 3
// 4
- Array properties are referenced by dot notation (preferred) or bracket notation:
console.log(arr.hello); // bye
orconsole.log(arr['hello']); // bye
- View all property names with
console.log(Object.keys(arr));
- A sparse array has gaps. Gaps can be created by increasing the
length
property:
console.log(arr); // [ 1, 2, 3, 4, '-11': 'wow!', hello: 'bye' ]
arr.length = 20;
console.log(arr);
// [ 1, 2, 3, 4, <16 empty items>, '-11': 'wow!', hello: 'bye' ]
Switch Statement
- The JS equivalent of Ruby’s case statement
- Use
break
in each branch. Break prevents execution ‘falling through’ from the truthy branch:
let dog = 'Banjo';// Example 1switch (dog.charAt(1)) {
case 'a':
console.log('a is at 1');
break;
case 'n':
console.log('n is at 1');
break;
default:
console.log('neither');
break;
} // => a is at 1// Example 2switch (dog.charAt(2)) {
case 'a':
console.log('a is at 2');
break;
case 'n':
console.log('n is at 2');
default:
console.log('neither');
break;
}
// n is at 2
// neither
Miscellaneous
- No syntactical sugar for
()
- End statements with
;
exceptfunction
andclass
declarations andif
,for
,while
statements - Strings are immutable
===
instead of==
(==
performs type coercion)console.log(arg)
instead ofputs arg
- Falsy:
0
,false
,‘’
,undefined
,null
,NaN
if
statement syntax:
let type = 'Dog';if (type === 'Dog') {
console.log('Banjo');
} else if (type === 'Cat') {
console.log('Scruffers');
} else {
console.log('Crumps');
}
if (var) console.log(var2);
orvar && console.log(var2);
`hello ${name}`
instead of"hello #{name}"
{}
delimits a block except in a function declaration or when surrounding an object literal.typeof
instead of.class
forEach
instead ofeach
(but you cannot prematurely break iteration)- CoderPad JS uses strict mode by default