Complete Intro Programming
Basic Syntax

The Basic Syntax Overview

This chapter covers

  • Statement and expressions -

Statements and Expressions

We have seen an expression in a previous article; it was:

5 + 2

An expression is a section in code that produces a value. You can think of this as the relation between:

  • One Oxygen atom mixed with two Hydrogen atoms (expression)

  • One Water molecule (value)

// The expression
1 Oxygen atom + 2 Hydrogen atoms

// The value
1 Water molecule

We can use expressions (values) in many places. You will usually see them on the right-hand side (RHS) of the assignment operator =:

someVar = someExpression;

Warning: I’ll use the abbreviations RHS and LHS (left-hand side) from now on.

There is another syntax category in JavaScript that we call statements. Statements are not expressions because they do not produce values. They just do things. Here is an example statement:

let sum;

This statement just creates the variable sum in memory. It does not evaluate to anything beyond that. In fact, we cannot use a statement on the RHS of an assignment operator. For example, we cannot do this:

someVar = let sum; // Error!

The details about what can go on the LHS and RHS of an assignment operator might be boring, but it is an essential thing to understand. For now, remember that anything that you can use on the RHS of an assignment operator is an expression (or value, eventually) and anything you cannot use there is a statement.

Values and Keywords

Every value has a type. For example, a value can be a number, character, or string of characters forming words and sentences:

// Example of values

42      // Number value
'A'     // One Character
'Hello' // String

Note how the character and string above are surrounded by single quotes. You can also use double quotes if you prefer. Those quotes are not optional for strings in programming because without them the computer is going to think what you wrote is a keyword or a variable.

A keyword is a word with a special meaning. For example, we have seen the keyword let. It means define a variable. What if I want to write the sentence “let me understand this” somewhere in code? Without using quotes, you will get an error:

let me understand this // will give an error
picturelearn1

This is because the computer is trying to define a variable me and the rest of that line is invalid syntax (after “let me”, the computer expects a semicolon, a comma, or an = operator. We gave it an unexpected identifier)

However, if we surround the sentence with single or double quotes, the word let becomes part of that string (and not the usual keyword)

"let me understand this" // valid syntax
picturelearn2

Some of the popular keywords in JavaScript include: let, const, if, else, switch, try, catch, return, true, false, class, function, for, and this. You can see the full list here.

You cannot use keywords as names for variables. The following will throw an error:

let function = 5 + 2; // Error
picturelearn3

When the computer sees the word function it wants to define a function, so the use of the token function after the token let was unexpected.

But even if we are not using keywords in our sentences, the computer will try to lookup any unquoted word as either a keyword or a variable and it will complain if it cannot find it.

what // Error
picturelearn4

We started a line with an unquoted what which is not a keyword, so the computer looks it up as a variable and complains that what is not defined.

Boolean Values

One of the most common types of values in programming is the Boolean type. It is the type that determines if an expression is true or false. This type is used in conditional statements (which are explained later in this article).

The Boolean type has two explicit values: true and false. It also has many other implicit values. Every other type in JavaScript can be converted to a Boolean. JavaScript does a lot of auto-conversion between types.

For now, just know that ALL values in JavaScript are also considered true except this short list: undefined, null, 0, "", NaN, and false itself.

In fact, JavaScript has a Boolean function that can explicitly convert values to their Boolean equivalent. You can use it to see how the five special values above are all converted as false while everything else is true:

Boolean("")        // false
Boolean(0)         // false
Boolean(undefined) // false
Boolean(null)      // false
Boolean(NaN)       // false
Boolean(1)         // true
Boolean("Hello")   // true
Boolean(Math.PI)   // true
Boolean(Boolean)   // true

The special NaN value means Not-A-Number. No Joke. For example, in Mathematics, there is no number that can represent the square root of -1. That is why in JavaScript Math.sqrt(-1) will equal NaN.

picturelearn5

You can also get a NaN in many other situations. For example, try to divide a string by a number.

The null and undefined Values

The keywords null and undefined are two special keywords in JavaScript that you need to understand right now. They represent a similar concept: the absence of value.

The following quote is going to be confusing:

null and undefined are both values that represent the absence of values

Weird. I know.

Let me tell you the story of a variable x.

A variable x starts by being undeclared (note how I did not use the term undefined yet). When we use the let keyword, we declare a variable.

let x;

Now x is declared, but it is now undefined. The value inside x is still undefined, but x itself, as a reference to a space in memory, is declared. That space in memory does not have a value.

When we put a value in x, we define x.

x = 42;

With that, x is now defined. It has the defined value of 42.

We can revert x to not be defined, if we need to, using the undefined value:

x = undefined;

Or using the null value:

x = null;

Most other programming languages have only one type to represent the absence of a value. However, for many reasons, mostly historical ones, JavaScript has two types. Sometimes, that is actually helpful. We can use undefined to represent the unexpected and system-level absence of a value and use null to represent the normal and program-level absence of a value. For example, consider this object:

let obj = {
  a: 1,
  b: null,
};

We have three types of properties:

  • The obj.a property is defined and holds the value 1

  • The obj.b property is defined but has no value (it is intentional)

  • The obj.c property is undefined (it is not an expected property)

picturelearn6

So, basically, if you want to check whether a certain object property is defined but empty or not defined at all, null and undefined can be used for that purpose.

Arrays

We have seen a few objects so far. An object is a special value type that holds a collection of other value types and each value gets a unique identifier (object property).

There is one other special value type that can hold a collection of other value types. It is called the Array type.

Just like objects, arrays hold a collection of other values but the identifiers that arrays use for those values are just their positional order, which starts with 0 for the first element.

Counting from 0 is weird, but you need to get used to it. The Xth element has an index value of X -1.

We create arrays and access their elements using the square brackets []. Here is an example array that holds four different numeric values:

let primesUnder10 = [2, 3, 5, 7];

The identifier for the first prime number is its position in the array: 0, and so on:

// Position  // Value
0            2
1            3
2            5
3            7

We can access individual values using their positions:

primesUnder10[0]  // 2
primesUnder10[2]  // 5

The array[position] syntax is an example of an expression that produces a value. Anywhere we can use a value, we can use that syntax as well. For example, I can sum the first three prime numbers using this expression:

primesUnder10[0] + primesUnder10[1] + primesUnder10[2]
// 10

Arrays can hold other value types as well:

let hello = ['h', 'e', 'l', 'l', 'o'];

And they can hold different value types, including objects, arrays, and even functions:

let mix = [1, true, undefined, {}, [], function x() {}];

The last value in the mix array above is a dummy function (one that does nothing). I can call that function directly from its position in the array: mix[5](). We were able to use a function as an element in this mix array because functions are also values.

There are a few other special types in JavaScript that can be used to represent a collection, including Map and Set. Let’s talk about those.

Maps and Sets

A map object in JavaScript is another way to represent a list of key-value pairs. It is very similar to the plain-old JavaScript object, but it offers a bit more features on a collection. These include reading the size of the collection and iterating over its items. Maps are usually a safer bet when you need to manage a collection of records.

Here is how you can create a new map object:

const days = new Map();

To set a new property (key) on this days map, we can use the .set method:

days.set(0, 'Sunday');
days.set(1, 'Monday');
// ...
days.set(6, 'Saturday');

To read a value using its key, we can use the .get method:

console.log('Today is ' + days .get (new Date().getDay()));

You can also do things like checking if a key exist in a map:

days.has(7) // false

A set object in JavaScript is another way to represent a list of values. Just like arrays. However, unlike an array, a set object can only store unique values. You cannot store duplicate values with sets and that makes them very useful in certain cases. For example to manage the list of days in a week.

const days = new Set();

set.add('Sunday');
set.add('Monday');
// ...
set.add('Saturday');

To access these unique days, you will have to loop over the list. We cover loops in upcoming articles.

Classes

A class is simply a blueprint or a template that we can use to generate different objects that share some shape and/or behavior. If you want to build something complicated, you always start with blueprints. This is what classes are for in programming.

We use classes to create objects. All objects created from the same class can share some attributes. Most importantly, they share behavior.

All objects we have seen before were created from built-in classes. Classes in JavaScript begin with a capital-letter. JavaScript has classes like Number, String, Object, and Array. You all also learned about two other classes in the previous section: Map and Set.

To create an object from the Map class, we used the new keyword:

const days = new Map();

Beside the name, a class can be used to defined object-level state and behavior to be shared among all objects. In JavaScript, we can maniple an object’s state within its class using the “this” keyword and we define shared behavior with class functions. Functions that belong to a class are usually referred to as methods.

The class always comes first. We have been working with objects so far because we have been working with built-in classes. However, JavaScript offers a way for you to create a custom class. Let’s create a class to represent a bank account:

class Account {

  constructor(id) {
    this.id = id;
    this.balance = 0;
    this.createAt = new Date();
  }

  deposit = (amount) => {
    this.balance = this.blanace + amount;
  };

  withdraw = (amount) => {
    this.balance = this.balance – amount;
  };

  printBalance = () => // Just for testing...
    console.log('Balance is: ' + this.balance);

}

We can then start managing individual bank accounts using objects:

const accountA = new Account('A');
const accountB = new Account('B');

accountA.deposit(42);
accountB.deposit(420);

accountA.withdraw(10);
accountB.withdraw(10);

accountA.printBalance(); // Balance is: 32
accountB.printBalance(); // Balance is: 410

The process of creating objects from a class has its own fancy name: instantiation. This is why class objects are often referred to as instances.

We can also base a new class on an existing class. We call that concept in programming inheritance. A child class can inherit from a parent class! In JavaScript, we can do that using the extends keyword:

class CheckingAccount extends Account {
  constructor(id) {
    super(id);
    this.type = 'checking';
  }

  // ... Methods specific to checking accounts
}

The above code means that a checking account object will automatically have the state and behavior of a basic account object (like id, balance, createdAt, deposit, and withdraw) but it will also have the other state and data defined in the CheckingAccount class.

It is probably okay for you to use one-level of class inheritance in your applications, but try to avoid using multiple levels as that tends to make the code less clear.

Operators

Operators are special characters (or words in some cases) that we can use between two operands (which are basically values) to perform an operation. The 2-values operators are actually categorized as binary operators. In the next two sections, you will see an example of a unary operator (!), which works on a single operand, and a ternary operator (? :), which works on three operands.

You have seen examples of binary operators like the assignment (=), addition (+), multiplication (*), division (/), and subtraction (-) operators, but there are more. For example, two other popular binary operators are the logical operators && and ||.

The && operator sits between two values (or expressions) and performs the AND logic gate. The || operator performs the OR logic gate. Each of them has four possible outcomes:

true  &&  true   // true
true  &&  false  // false
false &&  true   // false
false &&  false  // false
false ||  false  // false
true  ||  true   // true
true  ||  false  // true
false ||  true   // true

You actually need to memorize this table. If you remember the bolded unique case in each section you will remember the rest.

You can imagine how each true/false value above can also be an actual value because the && and || operators will do type conversion:

0 && anything
// Equivalent to false because Boolean(0) is false
42 || anything
// Equivalent to true because Boolean(42) is true

Of course, the result of any operation is also a value, which means we can combine operator calls together to do more complex operations. Try to figure out the result of these combined operations:

2 * 10 + 22
true && true || false
(3 * Math.PI + Math.PI) / Math.PI

Other commonly used binary operators are the greater than (>), less than (<),and the equality operators described next.

Strict and Loose Equality Operators

JavaScript has many operators that we can use to compare values. They all produce either true or false based on their operands' equality.

There is the loose equality operator, ==, which should generally be avoided (because, well, someone named it loose!):

3 == 3     // true
3 == '3'   // Also true
3 == 4     // false

As you can see, the loose equality operator also does the implicit type conversion thing and does not care about the different operand value types.

On the other hand, the strict equality operator (===) compares two values for equality without any implicit type conversations:

3 === 3        // Sure
3 === '3'      // No
3 === (1 + 2)  // true

Of course, there are also loose and strict inequality operators (!= and !==).

By the way, the character ! (on its own) is used as a prefix logical operator that means NOT. It is an example of a unary operator that operates on a single value.

!true  // false
!0     // true

The Famous if-statement

One statement that is very popular in programming languages is the if-statement. You have probably heard of it or seen a few examples.

Here is the official syntax of an if-statement in JavaScript:

if (expression) {
  statementA1;
  statementA2;
  // ...
} else {
  statementB1;
  statementB2;
  // ...
}

The else part is optional, but it will help you understand the if part.

We know what an expression is and we know what a statement is. However, a more accurate syntax description for an if-statement would describe the expression as a condition: something that is either true or false.

Remember that everything in JavaScript is either true or false. The if-statement’s expression value is no exception.

The if-statement above will first convert the expression in parenthesis to a Boolean value. If that Boolean value is true, it will execute statementA1, statementA2, …etc and it will not execute statementB1, statementB2, …etc. If the Boolean value is false, it will do the exact opposite.

The if-statement is popular because it enables conditional logic. It enables us to execute certain code only when a certain condition applies. For example, let’s assume that we want a function that doubles the value of its single argument only when that argument is an odd number. The function should not double the value for even numbers. This function can be easily written with an if-statement:

function doubleOddOnly(number) {
  if (number % 2 === 1) {
    return 2 * number;
  }

  return number;
}

// Try it with
doubleOddOnly(3);
doubleOddOnly(10);
picturelearn7

We were able to check the oddity of a number using the modulus math operator (%), which gives the remainder of a division operation:

5 % 2  // 1
6 % 2  // 0
11 % 3 // 2

If the remainder when dividing the number by 2 is 1 (a Boolean expression that uses the strict equality operator), the doubleOddOnly function will return the number argument multiplied by 2. Otherwise, it will return the number argument as is.

Note that we did not need to use an else section for that if statement because we used return statements. A return statement is the last statement executed in a function. When the function executes a return statement it will not execute the rest of the code after that. That is why the second return statement is equivalent to having an else section for the if statement.

I included a section about the if-statement here because it is an example of a statement! An if-statement does not evaluate to anything. It only does its conditional picking of other statements. For example, we cannot use an if-statement on the RHS of the assignment operator:

let result = if (3 == '3') { 42 } else { 0 };
// Syntax Error

While writing the whole if-statement on one line is okay (spaces and new lines, in general, are ignored by the computer), the fact that we used that line on the RHS of the assignment will give an unexpected token error.

Other languages (like Ruby for example) treat the if-statement as an expression as well, but In JavaScript an if-statement is just a statement.

There is another syntax that we can use to do the conditional if-logic within an expression. It is called the ternary operator (because it operates on three operands). To do so, we need to use two different characters (? and :):

condition ? if-true-value : if-false-value

Since this is an expression, it will produce the if-true-value if the condition part is true, and the if-false-value if the condition part is false.

The problematic one-line if-statement example above can be easily and correctly written using the ternary operator:

let result = (3 == '3') ? 42 : 0; // No problem

What is the value of result above, by the way?

Practice Challenge

1 -  Write a function that will determine if a number is odd or even.

Examples of expected output:

oddOrEven(17)    // should return 'odd'
oddOrEven(100)   // should return 'even'
oddOrEven(5 + 4) // should return 'odd'

2 -  Determine the output of the following code:

function mystery(arg1, arg2) {
  if (arg1 && arg2) {
    return 'Hello';
  }
  return (arg2 % 3 === 1) ? 'World' : ', ';
}

mystery(null,10) + mystery(true,0) + mystery(10,'null');

Do not copy/paste the code to evaluate it and do not guess. Parse the code line-by-line and follow what it does.