Javascript – Variables, Types, Collections

Variables, Types, and Collections

Variables

Keyword
Scope
Mutable Assignment
var
function
yes
let
block
yes
const
block
no

New variables in JavaScript are declared using one of three keywords: let, const, or var.

JavaScript is case sensitive

var is the most common declarative keyword. It does not have the restrictions that the other two keywords have. This is because it was traditionally the only way to declare a variable in JavaScript. A variable declared with the var keyword is available from the function it is declared in.

An example of scope with a variable declared with var:

// myVarVariable *is* visible out here

for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) { 
  // myVarVariable is visible to the whole function 
} 

// myVarVariable *is* visible out here 

let allows you to declare block-level variables. The declared variable is available from the block it is enclosed in.

// myLetVariable is *not* visible out here

for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
  // myLetVariable is only visible in here
}

// myLetVariable is *not* visible out here

Constants

All variables are pointers. Assignment is the act of pointing that variable to something in memory. Mutability is whether or not a variable can be reassigned once it has initially been assigned something. Using var or let creates mutable pointers, whereas const is immutable.

var myBike = "Mountain Bike";
let currentGear = 5;
const numberOfGears = 12;
//reassignment
myBike = "Penny Farthing"; // this works
currentGear = 1; // so does this
numberOfGears = 1; // error

When working with objects (rather than primitives), remember that const only prevents reassigning your variable to a different object. The object itself (its properties, functions, and so on) can still be changed

// call constructor, new object, assign it to bike
const bike = new Bike();
//Change internal state by calling a function
bike.changeGear("front", "Up");
// add a new member to bike that did not exist before
bike.type = "Penny Farthing";
// check for success
console.log(bike.calculateGearRatio()); // 4.0909...
console.log(bike.type); // "Penny Farthing"
// attempt to point bike to new instance of Bike
bike = new Bike(1,2); // error

const allows you to declare variables whose values are never intended to change. The variable is available from the block it is declared in.

const Pi = 3.14; // variable Pi is set 
Pi = 1; // will throw an error because you cannot change a constant variable.

If you declare a variable without assigning any value to it, its type is undefined.

An important difference between JavaScript and other languages like Java is that in JavaScript, blocks do not have scope; only functions have a scope. 

Types

Numbers

Numbers in JavaScript are “double-precision 64-bit format IEEE 754 values”, according to the spec. This has some interesting consequences. 

0.1 + 0.2 == 0.30000000000000004;

The standard arithmetic operators are supported, including addition, subtraction, modulus (or remainder) arithmetic, and so forth. There’s also a built-in object called Math.

Math.sin(3.5);
var circumference = 2 * Math.PI * r;

You can convert a string to an integer using the built-in parseInt() function. This takes the base for the conversion as an optional second argument, which you should always provide

parseInt('123', 10); // 123
parseInt('010', 10); // 10

If you want to convert a binary number to an integer, just change the base:

parseInt('11', 2); // 3

Similarly, you can parse floating point numbers using the built-in parseFloat() function. Unlike its parseInt()parseFloat() always uses base 10.

You can also use the unary + operator to convert values to numbers:

+ '42';   // 42
+ '010';  // 10
+ '0x10'; // 16

A special value called NaN (short for “Not a Number”) is returned if the string is non-numeric:

parseInt('hello', 10); // NaN

NaN is toxic: if you provide it as an operand to any mathematical operation, the result will also be NaN:

NaN + 5; // NaN

You can test for NaN using the built-in isNaN() function:

isNaN(NaN); // true

JavaScript also has the special values Infinity and -Infinity:

 1 / 0; //  Infinity
-1 / 0; // -Infinity

You can test for Infinity-Infinity and NaN values using the built-in isFinite() function:

isFinite(1 / 0); // false
isFinite(-Infinity); // false
isFinite(NaN); // false

The parseInt() and parseFloat() functions parse a string until they reach a character that isn’t valid for the specified number format, then return the number parsed up to that point. However the “+” operator simply converts the string to NaN if there is an invalid character contained within it.

Strings

Strings in JavaScript are sequences of Unicode characters (UTF-16). To find the length of a String (in code units), access its length property:

'hello'.length; // 5

You can use strings like objects. They have methods as well that allow you to manipulate the string and access information about the string

'hello'.charAt(0); // "h"
'hello, world'.replace('world', 'mars'); // "hello, mars"
'hello'.toUpperCase(); // "HELLO"

Dates

JavaScript comes with the built in Date object and related methods

The Date object is a built-in object in JavaScript that stores the date and time. It provides a number of built-in methods for formatting and managing that data.

By default, a new Date instance without arguments provided creates an object corresponding to the current date and time. This will be created according to the current computer’s system settings. JavaScript, however, understands the date based on a timestamp called epoch time and we can get it with getTime()

// Set variable to current date and time
const now = new Date();
// View the output
console.log("" + now); // "Mon Mar 02 2020 09:57:22 GMT+0100 (hora estándar de Europa central)"

console.log(now.getTime()); //1583139516795

Different ways to create Dates

Date CreationOutput
new Date()Current date and time
new Date(timestamp)Creates date based on milliseconds since Epoch time
new Date(date string)Creates date based on date string
new Date(year, month, day, hours, minutes, seconds, milliseconds)Creates date based on specified date and time

We can modify Date properties after the creation with set methods

Date/TimeMethodRangeExample
YearsetFullYear()YYYY1970
MonthsetMonth()0-110 = January
Day (of the month)setDate()1-311 = 1st of the month
Day (of the week)setDay()0-60 = Sunday
HoursetHours()0-230 = midnight
MinutesetMinutes()0-59
SecondsetSeconds()0-59
MillisecondsetMilliseconds()0-999
Timestamp setTime() Milliseconds since Epoch time

And we have several methods to get the Date information

Date/TimeMethodRangeExample
YeargetFullYear()YYYY1970
MonthgetMonth()0-110 = January
Day (of the month)getDate()1-311 = 1st of the month
Day (of the week)getDay()0-60 = Sunday
HourgetHours()0-230 = midnight
MinutegetMinutes()0-59
SecondgetSeconds()0-59
MillisecondgetMilliseconds()0-999
Timestamp getTime() Milliseconds since Epoch time

However, these get methods retrieve the date components based on the user’s local timezone settings. For increased control we can use the getUTC methods that calculate the time based on the UTC standard

Date/TimeMethodRangeExample
YeargetUTCFullYear()YYYY1970
MonthgetUTCMonth()0-110 = January
Day (of the month)getUTCDate()1-311 = 1st of the month
Day (of the week)getUTCDay()0-60 = Sunday
HourgetUTCHours()0-230 = midnight
MinutegetUTCMinutes()0-59
SecondgetUTCSeconds()0-59
Millisecond getUTCMilliseconds() 0-999

Other types

JavaScript distinguishes between null, which is a value that indicates a deliberate non-value (and is only accessible through the null keyword), and undefined, which is a value of type undefined that indicates an uninitialized variable — that is, a value hasn’t even been assigned yet.

JavaScript has a boolean type, with possible values true and false (both of which are keywords.) 

Truthy and Falsy

When an expression expects a Boolean value, the following values are always treated as false. 

  • false (of course)
  • 0 (the number zero)
  • "" or '' (an empty string)
  • null
  • undefined
  • NaN (the result of failed mathematical operations)

false is false (of course!). The rest of these values are coerced to false. As a group they are referred to as falsy

There’s no question that true is just that—true. But any other value of any type is coerced to true. We call these values truthy

This is widely accepted

const myRecord = response.getReturnValue();
if (myRecord) {
  //now process the record
}

Boolean operations such as && (logical and), || (logical or), and ! (logical not) are supported;

Coercion

When most JavaScript operators encounter an invalid type, they attempt to convert the value to a valid type. This process of implicitly converting a type is called implicit type coercion.

let num1 = 9 * "3";
console.log(num1); // 27 (a number)
let num2 = 9 + "3";
console.log(num2); // "93" (a string)

Don’t Use Implicit Type Coercion

false == ""; // true
false == "0"; // true
"" == "0"; // false
[0] == 0; // true

For Boolean comparison the best practice is to use === and !==. With these operators, primitive types are only equivalent when both type and value match, and object comparisons are only true when their respective pointers are pointing to the same memory address. Trying the same comparisons as above: 

false === ""; // false
false === "0"; // false
"" === "0"; // false
[0] === 0; // false

Arrays

Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array’s length can change at any time, and data can be stored at non-contiguous locations in the array, JavaScript arrays are not guaranteed to be dense;

Arrays cannot use strings as element indexes (as in an associative array) but must use integers. 

Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array’s object property collection.

Create Array

let fruits = ['Apple', 'Banana']
console.log(fruits.length); // 2

Access (index into) an Array item

let first = fruits[0]; // Apple
let last = fruits[fruits.length - 1]; // Banana

Iterate

fruits.forEach(function(item, index, array) {
  console.log(item, index);
})
// Apple 0
// Banana 1

Add to the end of an Array

let newLength = fruits.push('Orange');
// ["Apple", "Banana", "Orange"]

Remove from the end of an Array

let last = fruits.pop(); // remove Orange (from the end)
// ["Apple", "Banana"]

Remove from the front of an Array

let first = fruits.shift(); // remove Apple from the front
// ["Banana"]

Add to the front of an Array

let newLength = fruits.unshift('Strawberry'); // add to the front
// ["Strawberry", "Banana"]

Find the index of an item in the Array

fruits.push('Mango'); // ["Strawberry", "Banana", "Mango"]
let pos = fruits.indexOf('Banana'); // 1

Remove an item by index position

let removedItem = fruits.splice(pos, 1); // this is how to remove an item
// ["Strawberry", "Mango"]

Copy an Array

let vegetables = ['Cabbage', 'Turnip', 'Radish', 'Carrot'];
console.log(vegetables); // ["Cabbage", "Turnip", "Radish", "Carrot"]
let shallowCopy = vegetables.slice();
console.log(shallowCopy); // ["Cabbage", "Turnip", "Radish", "Carrot"]

Accessing array elements

JavaScript arrays are zero-indexed: the first element of an array is at index 0, and the last element is at the index equal to the value of the array’s length property minus 1.

There is nothing special about JavaScript arrays and the properties that cause this. JavaScript properties that begin with a digit cannot be referenced with dot notation, and must be accessed using bracket notation.

let years = [1950, 1960, 1970, 1980, 1990, 2000, 2010];
console.log(years.0);  // a syntax error
console.log(years[0]);  // works properly
renderer.3d.setTexture(model, 'character.png');  // a syntax error
renderer['3d'].setTexture(model, 'character.png');  // works properly

When setting a property on a JavaScript array when the property is a valid array index and that index is outside the current bounds of the array, the engine will update the array’s length property accordingly:

fruits[5] = 'mango'
console.log(fruits[5])            // 'mango'
console.log(Object.keys(fruits))  // ['0', '1', '2', '5']
console.log(fruits.length)        // 6

JSON

JSON is a text-based data format following JavaScript object syntax. Even though it closely resembles JavaScript object literal syntax, it can be used independently from JavaScript.

JSON exists as a string — useful when you want to transmit data across a network. It needs to be converted to a native JavaScript object when you want to access the data. This is not a big issue —  JavaScript provides a global JSON object that has methods available for converting between the two.

Accesing data

let myJSON = { "name": "Chris", "age": "38" };
console.log(myJSON['age']); // 38
console.log(myJSON['name']); // Chris

If we have to deal with a complex JSON object we can traverse the properties like this

staffJSON['members'][1]['roles'][2];

Convert String to JSON

request.open('GET', requestURL);
request.responseType = 'text'; // now we're getting a string!
request.send();

request.onload = function() {
  const superHeroesText = request.response; // get the string from the response
  const superHeroes = JSON.parse(superHeroesText); // convert it to an object
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}

Convert JSON to String

let myJSON = { "name": "Chris", "age": "38" };
console.log(typeof myJSON); // object
let myString = JSON.stringify(myJSON);
console.log(typeof myString); // string