Ruby to JavaScript

Spencer Wightman
Launch School

--

A short guide for Rubyists learning JavaScript

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) while let is block-scoped (normal)
    Something to be aware of because let and const 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 keyword return.
  • Explicit return requires keyword return
  • Default parameters work as expected
  • Function Declaration: function hello() { …
    (starts with function)
  • 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']); // 5
obj.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 length
console.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 or console.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 ; except function and class declarations and if, for, while statements
  • Strings are immutable
  • === instead of == (== performs type coercion)
  • console.log(arg) instead of puts 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); or var && 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 of each (but you cannot prematurely break iteration)
  • CoderPad JS uses strict mode by default

--

--