JavaScript Basics
This post is meant for some those interested in an extremely brief JavaScript reference. I will not be going into programming, just introducing the syntax to someone who presumably is already very experienced with coding.
What is JavaScript?
JavaScript is technically ECMAScript. It is a scripting language originally developed in 1995. Over time it became supported by all major internet browsers and today is the only programming language run natively by internet browsers.
As the popularity of JavaScript has grown, the use cases for it has grown as well and today you can build full-stack applications for desktop, server, web, and mobile. It is quickly becoming the most popular cross-platform application development language today. Everybody from GitHub, to Microsoft, to Amazon, and Facebook all write desktop applications with it.
That being the case, it is very important that programmers have a basic grasp of the language. That is why I am writing this blog post.
Variables
JavaScript has three different ways to declare variables. The traditional way of declaring variables is with the var
keyword. (reference)
var myStr = 'something';
Today we have a better form of var
with let
. The major difference between the two is that let
is block scoped. This means that it will always be scoped to the block it is in, whether inside a function, a for
loop, or any other type of block. (reference)
let myStr = 'something';
The safest and most preferable way to declare variables is with the const
keyword. It is block-scoped, like let
, but it can never be reassigned. (reference)
const myStr = 'something';
It is important to remember that even though you use the keyword const
you are not making a constant. While the variable itself can't be reassigned, if the value is any type of object, you can change properties and methods within it. Only primitives are completely safe. For example:
const myStr = 'something';
// changing the value throws an error
myStr = 'something else'; // throws error!
const myObj = {name: 'Ryan', age: 31};
// changing a property does not throw an error
myObj.age = 32;
// reassigning the variable to a new object throws an error
myObj = {}; // throws error!
Blocks
Anything within curly braces is a block. This can include for
loops, while
loops, if
blocks, and block statements.
Loops
You can make traditional for
loops. (reference)
const names = ['Ryan', 'Rand', 'David'];
for(let i = 0; i < names.length; i++) {
console.log(names[i]);
}
for...of loops can loop over any iterable object. (reference)
// looping over items in an array
const names = ['Ryan', 'Rand', 'David'];
for(const name of names) {
console.log(name);
}
// looping over characters in a string
const str = 'Ryan';
for(const character of str) {
console.log(character);
}
You can also make while
loops, but these are generally frowned upon in JavaScript. You should avoid these unless absolutely necessary. (reference)
let numStr = '12';
while(numStr.length < 4) {
numStr = '0' + numStr;
}
console.log(numStr); // logs '0012'
Functions
Traditionally, you can declare functions in two ways. First, you can use a function declaration. (reference)
// function declaration
function printName(name) {
console.log(name);
}
printName('Ryan'); // logs 'Ryan'
The more common way to declare functions is with function expressions. (reference)
// function expression
const printName = function(name) {
console.log(name);
};
printName('Ryan'); // logs 'Ryan'
Today, you also have arrow functions. These are more concise than traditional declarations and are preferable in most cases because they are stateless, meaning that they have no this
of their own. They always bind to the current this
when declared. (reference)
// function with one parameter
const printName = name => {
console.log(name);
};
printName('Ryan'); // logs 'Ryan'
// function with two parameters
const printNameAge = (name, age) => {
console.log(name + ' is ' + age);
};
printNameAge('Ryan', 31); // logs 'Ryan is 31'
Values are returned from functions with the return
keyword.
const hasLetterA = str => {
if(str.includes('a')) {
return true;
} else {
return false;
}
}
hasLetterA('Fred'); // returns false
When using arrow functions, if you only have one expression you can add it immediately following the arrow and it will be implicitly returned.
const addNum = num => num + 1;
addNum(4); // returns 5
You can also specify default values for function parameters.
const printNameAge = (name = 'nobody', age = 0) => {
console.log(name + ' is ', age);
};
printNameAge('Ryan'); // logs 'Ryan is 0'
printNameAge(null, 100) // logs 'nobody is 100'
printNameAge(); // logs 'nobody is 0'
Objects
Objects are the most basic key/value structures in JavaScript. In an object, all keys are strings, but the values can be anything. Objects are unordered and cannot be looped over directly. Values are referred to as properties and functions in the object are referred to as methods. The most common way to make an object is with an object literal. (reference)
const myObj = {
name: 'Ryan', // string property
age: 31, // number property
printNameAge() { // method
console.log(this.name + ' is ' + this.age);
}
}
Properties on an object can be retrieved using dot notation or bracket notation. (reference)
const myObj = {
name: 'Ryan', // string property
age: 31, // number property
printNameAge() { // method
console.log(this.name + ' is ' + this.age);
}
}
console.log(myObj.name); // logs 'Ryan'
console.log(myObj['age']); // logs 31
myObj.printNameAge(); // calls printNameAge method
Map
Maps are special objects for storing key/value pairs. Unlike plain objects, they are ordered and can be iterated over. (reference)
const peopleMap = new Map();
// set items
peopleMap.set('Ryan', {
name: 'Ryan',
age: 31
});
peopleMap.set('Rand', {
name: 'Rand',
age: 60
});
// check for items
peopleMap.has('David'); // false
peopleMap.has('Ryan'); // true
// get items
peopleMap.get('Rand');
// delete items
peopleMap.delete('Ryan');
// check size (length) of Map
peopleMap.size; // 1
// loop over items
for(const [key, val] of peopleMap) {
console.log(val);
}
Array
Arrays are list-like objects which are ordered and accessible by a zero-based index. As with objects, JavaScript arrays are most often created as an array literal. (reference)
const names = ['Ryan', 'Rand', 'David'];
console.log(names[1]); // logs 'Rand'
Arrays are iterable, so they can be used in a for...of loop.
const names = ['Ryan', 'Rand', 'David'];
for(const name of names) {
console.log(name);
}
Arrays also have many useful methods. Some of the methods return new arrays and others are mutative. In general, you should avoid mutative methods. Because JavaScript is a loosely-typed language, it is always best to avoid mutation so that your code is as explicit as possible.
const names = ['Ryan', 'Rand', 'David'];
// adding to an array
const newNames = names.concat(['Don']);
// checking if a value is in an array
const hasDavid = names.includes('David'); // true
// finding the index of a value
const randIndex = names.indexOf('Rand'); // 1
// taking a slice of an array
const someNames = names
.slice(0, 2); // returns ['Ryan', 'Rand']
// joining items into a string
const nameStr = names.join(', '); returns 'Ryan, Rand, David'
Many array methods expect a function expression as a parameter.
const numbers = [1, 2, 5, 3, 8, 9, 4];
// finding the index of a value
const indexOfEight = numbers
.findIndex(num => num === 8); // 4
// check if any item in an array meets a condition
const hasTen = numbers
.some(num => num === 10); // false
// check if every item meets a condition
const allAreLessThanTen = numbers
.every(num => num < 10); // true
// find item in an array (returns item if found, otherwise returns null)
const num5 = numbers
.find(num => num === 5); // returns 5
// filtering out items
const numbersAboveFour = numbers
.filter(num => num > 4); // returns [5, 8, 9];
// mapping over and modifying every item in an array
const numsPlusOne = numbers
.map(num => num + 1); returns [2, 3, 6, 4, 9, 10, 5];
// reducing all items down to a single value
const total = numbers
.reduce((sum, num) => {
return sum + num;
}, 0);
// sorting items in an array
const orderedNumbers = [5, 3, 7, 1, 9]
.sort((a, b) => {
if(a > b) {
return 1;
} else if (a < b) {
return -1;
} else { // a === b
return 0;
}
});
console.log(orderedNumbers); // logs [1, 3, 5, 7, 9]
// looping over all items
numbers.forEach(num => console.log(num));
Any value-returning methods can be chained together as well.
const numbersLessThanFive = numbers
.filter(num => num < 5) // only keep numbers less than 5
.sort((a, b) => a === b ? 0 : a > b ? 1 : -1) // sort
.join(', ') // join them into a string
console.log(numbersLessThanFive); // logs '1, 3'
Set
A set is an ordered list in JavaScript for storing unique values. Like Arrays, Sets are iterable and you can loop over them with for...of loops. (reference)
const nameSet = new Set();
// add items
nameSet.add('Ryan');
nameSet.add('Rand');
nameSet.add('David');
// check for items
nameSet.has('Paul'); // false
nameSet.has('Rand'); // true
// delete item
nameSet.delete('Ryan');
// check size (length) of Set
nameSet.size; // 2
// loop over items
for(name of nameSet) {
console.log(name);
}
Strings
Strings are exactly what you would assume they are. You can use quotes or double quotes to make regular strings. (reference)
const myStr = 'something';
const myOtherStr = "something else";
Strings can be concatenated using +
.
const firstName = 'Ryan';
const lastName = 'Burgett';
const fullName = 'Ryan' + ' ' + 'Burgett';
You can also use backticks to make special strings called template strings. These can be used to make multi-line strings. They can also be used for string interpolation which is often preferable to concatenation. (reference)
const myMultiLineString = `
line one
line two
line three
`;
const firstName = 'Ryan';
const lastName = 'Burgett';
// using ${} to insert variable values into the string
const fullName = `${firstName} ${lastName}`;
Strings have many useful methods, including the following.
const myStr = 'Here is a first sentence. I also have a second sentence. And here is a third!';
// check for item in string
const hasA = myStr.includes('a'); // true
// get part of a string using a beginning and ending index
const shortStr = myStr.substring(5, 7); // 'is'
// find index of character
const idxOfA = myStr.indexOf('a'); // 8
// find any matches using a regular expression pattern
const matches = myStr.match(/\w/); // returns ['H']
// get char code (UTF-16) at a particular index
const str = 'abc';
const charCode = str.charCodeAt(0); // 97
// convert all characters to upper case
const upperStr = myStr.toUpperCase();
// convert all characters to lower case
const lowerStr = myStr.toLowerCase();
// trim string
const dirtyStr = ' something ';
const cleanStr = dirtyStr.trim(); 'something'
// replace item in a string
const name = 'Ryan';
const newStr = name.replace('a', 'u'); // 'Ryun'
// replace all occurrences of an item in a string using a regular expression
const name = 'Ryan Scott Burgett';
const newName = name.replace(/t/g, ''); // 'Ryan Sco Burge'
// split string into an array
const splitStr = myStr.split('.'); // ['Here is a first sentence', ' I also have a second sentence', ' And here is a third!']
You can also check the length of a string,
const name = 'Hannah';
name.length; // 6
You can use bracket notation to grab a character at a particular index.
const name = 'David';
const charAtIdxTwo = name[2]; // 'v'
You can convert a string with a numeric value to a number.
const numStr = '24';
const num = parseInt(numStr); // 24
Numbers
Numbers are any type of numerical object in JavaScript. All number values in JavaScript are 64-bit floats. There are precision problems as result of this, so it is often preferable to convert decimal numbers to integer values before doing arithmetic operations. There are a few ways to make numbers. (reference)
// create a number
const num = 2; // 2
// create a number from a string
const numStr = '16.5';
const intFromString = Number.parseInt(numStr); // 16
const floatFromString = Number.parseFloat(numStr); // 16.5
JavaScript numbers allow you to do all common number operations. (reference)
const sum = 3 + 2; // 5
const diff = 3 - 2; // 1
const multRes = 3 * 2; // 6
const divRes = 6 / 3; // 2
const remainder = 7 % 3 // 1
If you want to fix a number to a certain number of digits places after the decimal point, you can use the toFixed()
method.
const myLongerNum = 3.1415;
const myShorterNum = myLongNum.toFixed(2); // 3.14
Convert a number to a string with the toString()
method.
const myNum = 123;
const myNumStr = myNum.toString(); '123'
Classes
As with any object-oriented language, you have classes in JavaScript. These are a relatively new addition to the language, but they can be used today with the help of transpilers which convert them to syntax which is understood by all browsers. (reference)
class Person {
constructor(name) {
this._name = name;
}
getName() {
return this._name;
}
setName(newName) {
this._name = newName;
}
printName() {
console.log(this._name);
}
}
const person = new Person('Ryan');
Regular Expressions
JavaScript provides a robust API for building regular expressions. It generally follows the Perl conventions. (reference)
// building a regular expression literal
const myPatt = /.+@.+\..+/;
// constructing a regular expression from a string
const myPatt2 = new RegExp('.+@.+\\..+');
Regular Expressions have a few methods available.
// test a string to by the pattern
const myEmailPatt = /.+@.+\..+/;
const emailAddress = 'ryan@burgettweb.net';
myPatt.test(emailAddress); // true
// search for a match in a string
const spacePatt = /\s/;
const myStr = 'Here is a string to search.';
spacePatt.exec(myStr); // returns [' ']
Flags can be added to patterns. The most common are the global and case-insensitive flags.
// pattern to match all lower case a's
// the g flag makes it find all matches
const findAPatt = /a/g;
// pattern to match all upper and lower case a's
// the g means find all and the i means case-insensitive
const findAllAPatt = /a/gi;
Condition Statements
You can use if...else if...else
in JavaScript as well as switch
statements.
const name = 'Tommy';
// using if statements
if(name.length < 5) {
console.log('That is a short name!');
} else if(name.length > 7) {
console.log('That is a long name!');
} else {
console.log('That is a medium-sized name');
}
// using a switch statement
switch(name) {
case 'Susan':
console.log('That is likely a girl's name');
break;
case 'Tommy':
console.log('That is likely a boy's name');
break;
default:
console.log('I don't know about this name');
}
One of the easiest and most concise ways of making condition expressions is with the ternary operator. (reference)
const number = 5;
// using parenthesis
const isEven = (number % 2 === 0) ? true : false;
// without parenthesis
const isOdd = number % 2 > 0 ? true : false;
One common use case for the ternary operator is in sorting functions.
const numbers = [5, 3, 4, 1, 2]
.sort((a, b) => a === b ? 0 : a > b ? 1 : -1);
Comparison Operators
JavaScript has operators for both strict comparison and type-converting comparison. You need to be careful and always use strict comparison operators. If you allow it to automatically convert types when comparing values, you risk many bugs in your code. (reference)
const num1 = 2;
const num2 = 2;
const numStr = '2';
// strict equality
num1 === num2; // true
num1 === numStr; // false
// strict inequality
num1 !== num2; // false
num1 !== numStr; // true
// comparison
2 < 5; // true
2 <= 5; // true
2 > 5; // false
2 >= 5; // false
Conclusion
There you go. JavaScript is a powerful and versatile language for developing applications. It has its problems, nearly all of which are related to it being loosely-typed. But, if you follow best practices, if you use as little mutation as possible, you will be able to write code with as few bugs possible.
The best place in the world to find JavaScript documentation is the Mozilla Developer Network. If you are looking something up, always choose the MDN docs if you can.