JavaScript is a scripting language supported by all browsers. Browsers don't speak Ruby, so if we want to implement client-side logic that runs in the browser, we need to express ourselves in JavaScript.
Important
Work on this lesson in
teachermode.
Learning goals
- You can explain how JavaScript in the browser differs from Ruby on the server: it runs on the user's machine, has no implicit return, needs parentheses to call a function, and compares with
===. - You can declare variables with
constandlet, and explain why the oldvarkeyword can have confusing semantics. - You can define and call functions in their different forms โ declarations, function expressions, arrow functions โ and explain the difference between passing a function and calling it.
- You can use control flow and iterate over arrays, e.g. with
forโฆofor array methods likemapandfilter. - You can work with the core types: strings, numbers, booleans,
nullandundefined, arrays and objects. - You can define a class with a constructor, instance and static methods, and inheritance.
- You can throw and handle errors.
- You can explain how
thisis determined by the way a function is called, why a detached method loses it, and how to keep it, e.g. withbindor an arrow function. - You can use the browser console to try out JavaScript.
Resources
Read what's new to you, skim what's familiar, skip what you already master. Stop when you can meet the learning goals.
Your agent can also generate an overview, a tutorial or an explanation for anything here, tailored to what you already know. Just ask.
Pick one track
- ๐ MDN: Dynamic scripting with JavaScript Show archive.org snapshot โ lessons with live editors. Do Variables Show archive.org snapshot (read "A note about var"), Arrays Show archive.org snapshot , Conditionals Show archive.org snapshot , Looping code Show archive.org snapshot , Functions Show archive.org snapshot , Function return values Show archive.org snapshot , Object basics Show archive.org snapshot and Debugging and error handling Show archive.org snapshot . Skip Strings, Events, DOM scripting, Network requests and JSON โ later cards
- ๐ javascript.info โ The Modern JavaScript Tutorial Show archive.org snapshot โ reads like a book, with tasks and solutions per chapter. Do Variables Show archive.org snapshot , Data types Show archive.org snapshot , Comparisons Show archive.org snapshot , Loops Show archive.org snapshot , switch Show archive.org snapshot , Function expressions Show archive.org snapshot , Arrow functions Show archive.org snapshot , Array methods Show archive.org snapshot , Class basic syntax Show archive.org snapshot , Class inheritance Show archive.org snapshot , Static properties and methods Show archive.org snapshot and Error handling Show archive.org snapshot
For specific goals
- ๐
The old "var"
Show archive.org snapshot
โ why
varhas confusing semantics: no block scope, redeclaration, hoisting - ๐ javascript.info:
Object methods, "this"
Show archive.org snapshot
,
Function binding
Show archive.org snapshot
and
Arrow functions revisited
Show archive.org snapshot
โ read before the
thisexercise below; they mirror it step by step - ๐ MDN reference:
thisShow archive.org snapshot โ the authoritative, dense version - ๐ MDN reference:
Classes
Show archive.org snapshot
โ constructor, instance and static methods,
super, getters and setters - ๐ฎ Chrome DevTools: Console overview Show archive.org snapshot โ the console as a JavaScript playground
- ๐
You Don't Know JS: this & Object Prototypes, chapter 2
Show archive.org snapshot
โ optional deep dive into the four binding rules of
this
Coming from Ruby
There is no good current "JavaScript for Rubyists" text, so here is the short version. Parentheses are mandatory when you call a function: foo is the function itself, foo() calls it. Nothing is returned implicitly; without return a function returns undefined. Compare with ===, never ==. There are two "nothing" values, null and undefined. Names are camelCase. And your code runs in the browser, so console.log is your puts.
Exercises
First steps
Try the following in a browser tab:
- Press Ctrl+Shift+J to open the developer tools' console.
- Assign some variables.
- Print a variable to the console using
console.log(). - Create an array and iterate over it. Print each element to the console.
- Create an empty object and set/get some properties on it.
- Define a function that prints its first argument to the console.
- Call that function from the loop iterating the array.
Working with lists
- Write your own version of the
Array.mapfunction Show archive.org snapshot . Name itmyMap. It should work exactly likeArray.map, but should be your own code. The function can be a new instance method of all arrays (by patchingArray.prototype) or a stand-alone function that takes an array argument. - Write a JavaScript function
mySelectthat works like Ruby'sEnumerable#selectShow archive.org snapshot , only as a JavaScript equivalent. The function can be a new instance method of all arrays (by patchingArray.prototype) or a stand-alone function that takes an array argument.
Did you learn how this works?
Execute the code snippets below in your browser console (one by one).
Two things to know first: the console runs in "sloppy mode", so this in a detached plain function is the global window object โ that's why the snippets below print what they print. Inside modules (which run in strict mode) it would be undefined instead. And since the snippets redefine student several times: re-declaring a const in the same console needs a page reload first.
First, define this object:
const student = {
name: 'Anna',
sayHello: function() { console.log("Hello, my name is", this.name) }
}
What does the following print?
student.sayHello()
What does the following print? Why?
student.sayHello
What does the following print? Why?
const fn = student.sayHello
fn()
What does the following print? Why?
const fn = student.sayHello.bind(student)
fn()
setTimeout()
Show archive.org snapshot
executes a function after some time.
What does the following print in 1 second? Why?
setTimeout(student.sayHello, 1000)
What does the following print in 1 second? Why?
setTimeout(function() { student.sayHello() }, 1000)
What does the following print in 1 second? Why?
setTimeout(student.sayHello.bind(student), 1000)
Now we use another object:
const student = {
name: 'Anna',
sayHello: function() { console.log("Hello, my name is", this.name) },
sayHelloInOneSecond: function() {
console.log("The value of this is", this)
setTimeout(this.sayHello, 1000)
}
}
What does the following print? Why?
student.sayHelloInOneSecond()
Can we fix it like this? Why not?
student.sayHelloInOneSecond.bind(student)()
Now we use another object:
const student = {
name: 'Anna',
sayHello: function() { console.log("Hello, my name is", this.name) },
sayHelloInOneSecond: function() {
console.log("The value of this is", this)
setTimeout(function() { this.sayHello() }, 1000)
}
}
What does the following print? Why?
student.sayHelloInOneSecond()
Now we use another object:
const student = {
name: 'Anna',
sayHello: function() { console.log("Hello, my name is", this.name) },
sayHelloInOneSecond: function() {
console.log("The value of this is", this)
setTimeout(() => { this.sayHello() }, 1000)
}
}
What does the following print? Why?
student.sayHelloInOneSecond()
Address search
In Ruby basics you built a searchable address book.
Port your code to JavaScript. Put it in your address book repository, next to the Ruby version, so you and your mentor can compare the two.