Javascript: types, values and variables

·

10 min read

javascript types can be divided into primitive and object types. primitive types include numbers, strings, boolean, symbols, null and undefined. Anything which is not the above is the object type.

Numbers

javascript represents numbers using a 64-bit floating point format defined by IEEE 754. when a number appears directly in a javascript program then it is called numeric literal. javascript supports numeric literals in several formats like base 10, hexadecimal, octal decimal, binary, and decimals. Hexadecimal numbers are represented using the prefix 0x. Since ES6 we can also represent numbers of base 2 and base 8 using prefixes 0b and 0o respectively.

let n = 1000
let x = 0xfff //  => 4095: (15*16*16 + 15*16 + 15)
let y = 0b10101 // => 21: (1*16 + 0*8 + 1*4 + 0*2 + 1*1)
let z = 0o377    // => 255: (3*64 + 7*8 + 7*1)

Arithmetic

Basic arithmetic operators include addition, subtraction " + ", division " / ", multiplication " * ", and modulo " % ". ES6 added " ** " for exponentiation. Arithmetic in javascript does not raise any errors in case of overflow, underflow, or division by zero. when the result is larger than the largest representable number (overflow) it returns a special value called infinity. Similarly, if the absolute value of the negative value becomes larger than the absolute value of the largest representable negative number then the result is negative infinity.

underflow occurs when the result of an operation is lesser than the smallest representable number which is closer to zero. In this case, it returns zero. If underflow occurs from a negative number it returns negative zero.

Division by zero is not a javascript error. It simply returns infinity or negative infinity. However, zero divided by zero leads to a special value called NAN(not a number).

Number.MAX_VALUE * 2 // => infinity: overflow
Number.MIN_VALUE / 10  // => zero: underflow

In addition to these basic properties, javascript supports more complex mathematical operations through a set of functions defined in the Math object.

Math.pow(2,53) // => 9007199254740992: 2 to the power 53
Math.round(.6) // => 1.0: round to the nearest integer
Math.ceil(.6) // => 1.0: round up to an integer
Math.floor(.6) // => 0.0: round down to an integer
Math.abs(-5) // => 5: absolute value

Rounding errors:

There are infinitely many numbers but the 64 Bit floating point format defined by IEEE 754 can only represent a finite of them. This means a representation of numbers will often be an approximation of the actual number. It is a binary format that can only represent exact fractions that are the power of 2 like 1/2, 1/4, 1/8, 1/1024. This is why many decimal numbers cannot be represented exactly and it will be an approximation. consider the below example.

let x = 0.3 - 0.2
let y = 0.2 - 0.1 
x === 0.1 // => false
y === 0.1 // => true

In the above example because of the rounding method the difference between the approximation of 0.3, 0.2 is not exactly equal to the difference between the approximation of 0.2, 0.1. This is not just in javascript but in every programming language that uses the 64-bit floating point format defined by IEEE 754.

Text

javascript type for representing text is known as a string. String is a primitive type and immutable. Strings are represented as ordered sequences of 16-bit values. The length of a string is no of 16-bit values present in the string.

when a string appears directly in a javascript program then it is known as string literal. To include strings they should be enclosed by matching pairs of single or double quotes or backticks. Double quote characters and backticks can be contained in the strings delimited by single quotes and vice versa. Following are the examples.

""             // empty string
'hello world'  // single quotes
`username`     // back ticks
'pi = "3.14" ' // double quotes delimited by single quotes

Escape sequences

The backslash has a special purpose in javascript. It is used to represent a character that is otherwise not representable. For example, \n is used as an escape sequence to represent a newline character. To use the character single quote inside the string delimited by single quotes we need to use \'. Some of the examples are given below.

Screenshot from 2022-02-15 00-09-11.png

working with strings

one of the built-in features of javascript is the ability to concatenate strings. If you use the " + " operator on 2 numbers it adds them, if you use it for strings it joins them by appending the second operand to the first. Strings can be compared using the comparison operators like ===, !==, >=. Strings are compared using 16-bit values. Two strings are equal if and only if they consist of the same sequence of 16-bit values. Javascript provides a rich API for working with strings like the following example.

let msg = "Hello, " + "world"; // Produces the string "Hello, world"

let s = "Hello, world"; // Start with some text. Obtaining portions of a string

s.substring(1,4) // => "ell": the 2nd, 3rd, and 4th characters.
s.slice(1,4) // => "ell": same thing
s.slice(-3) // => "rld": last 3 characters
s.split(", ") // => ["Hello", "world"]: split at delimiter string Searching a string
s.indexOf("l") // => 2: position of first letter l
s.indexOf("l", 3) // => 3: position of first "l" at or after 3
s.indexOf("zz") // => -1: s does not include the substring "zz"
s.lastIndexOf("l") // => 10: position of last letter l Boolean searching functions in ES6 and later
s.startsWith("Hell") // => true: the string starts with these
s.endsWith("!") // => false: s does not end with that
s.includes("or") // => true: s includes substring "or"

Template literals

Since ES6 strings can be delimited by using backticks. There is also one powerful feature of using backticks. You can embed any javascript expressions inside the backticks. It has a special syntax to include javascript expressions which is ${arbitary javascript expression}. Anything in between curly braces is evaluated, converted to literal strings and inserted into the template replacing dollar sign and curly braces. Everything outside the curly braces is normal string literals which are combined with the evaluated javascript expression to produce the final string.

let name = "joe"
let greeting = `hello ${namee}`
console.log(greeting) // => hello joe

Boolean

A boolean represents two values true or false, on or off, yes or no. The keywords true and false evaluate these values. Booleans are mostly the result of comparisons in programs. Any javascript value can be converted into a boolean. There are values to which they evaluate to false and are called falsy values.

  1. null

  2. undefined

  3. 0

  4. empty string

  5. NAN

  6. 0

Apart from the above values all evaluate to true such as object, array and are called truthy values.

There are three boolean operators which are logical AND, logical OR, and logical NOT.

  1. AND (&&):
    It evaluates to true value if both the operands are true otherwise false. If the first operand is false it just returns the first operand without evaluating the second operand. If the first operand is true it returns the second operand.

  2. OR (||):
    It evaluates to falsy value if both the operands are false otherwise true. If the first operand is true it returns the first operand without evaluating the second operand. If the first operand is false it returns the second operand.

  3. NOT (!):
    It evaluates to true if the operand is false and false if the operand evaluates to true.

Null and undefined

Null is a keyword that is used to indicate the absence of value. Using a type of operator on null returns the string "object" which means it can be thought of as a special object that indicates no object and it does not have any methods. But we can also use it to indicate no value for numbers, or strings.

Undefined is a special value but not a keyword which also indicates the absence of value. It is the value of the variables that are not initialized, it is the value returned when you query an object property that does not exist, and it is the value returned when a function does not have an explicit return value. If you apply the type of operator it returns the string "undefined" which indicates that it can be thought of sole member of its own type.

typeof(null) // => "object"

typeof(undefined) // => "undefined"
let x
x // => undefined
let y = {a: 1}
y[b] // => undefined

Immutable primitives and mutable object references

The fundamental difference between primitives(strings, numbers, null, undefined, boolean, symbols) and objects is primitives are immutable and objects are mutable. For example, if you take a string and tried to change any character using the square brackets it throws an error. It is obvious for numbers, boolean etc . because it doesn't make sense to mutate a number. But you can change the properties of an object.

primitives are compared by values but the objects are compared by reference. Two objects are not equal even if they have the same properties and values. Two objects are equal if and only if they point to the same underlying object.

let a = {}  // empty object
let b = a   // b points to a
a===b       // true
a.x = 1       // can be mutated
b[x]        // is seen on b as well

let c = {}  // new empty object
c.x = 1       // add same property as a has
c===a       //  false

Type conversions

javascript is very flexible in type conversion. It will try to convert to the type it needs. Whatever the value you give if it wants a number it will try to convert it to a number type. If javascript wants a string it will convert to it whatever the value you give.

5 + "hi"    // => "5hi": converts number to string
"9" * "8"  // => 72: both convert to number
"x" - 2     // => NAN: string x cant covert to number

look at some of the following examples

Screenshot from 2022-02-15 14-59-34.png

Screenshot from 2022-02-15 15-00-47.png

variable declaration

one of the most fundamental techniques of a programming language is the use of names or identifiers to represent values. Binding a name to a value gives us a way to refer to it in our program. Before ES6 variables were declared using keyword var. There was no way to declare constants before ES6. In ES6 two keywords were introduced for declaring variables and constants. They are let and const.

The difference between a variable and a constant is that you can change the value of a variable but not a constant. Also, you must initialize a value when declaring constants whereas variables can be initialized later. Let is for declaring variables and const is for declaring constants.

let x
x=5
const y = 10 // must be initialized

hoisting

one difference between var, let and const is that the variables declared by var are hoisted to the top of the scope which means accessing the variable before it is declared will return undefined but it throws an error if they are declared using let and const.

console.log(x) // => undefined
console.log(y) // => will give error
console.log(z) // => will give error

var x = 5
let y = 6
const z = 7

scope

scope refers to the region of the code where the variable or constant is defined. variables and constants declared using let, const are block scoped. if statements, functions, and while loops are all block scoped. It simply means the curly braces are the starting and ending points.

function abc(){
    let x = 5
}
let x = 6
console.log(x) // => 6

Source:

  1. JavaScript: The Definitive Guide, 7th Edition by David Flanagan