Datatypes, Variables & Operators

What are 'data types'

  • 'Data' is the information we hold within our programs
  • 'Types' refer to the kind [or category] of data. e.g. text, number, etc.
  • We split data up into types because:
    • Each type is recorded in memory in a different manner
      • it will require different amounts of memory
      • it will be encoded differently
    • This helps with efficiency. Numbers, for example, will be stored in such a way that mechanically they can be manipulated mathematically in a rapid fashion
    • So what types do we use?

Which types are there?

  • string - for holding text
  • number - for holding numbers
  • boolean - for holding a true or false value
  • null - a placeholder for representing a value which is not currently valid but we expect to be populated later
    • null itself is a system created object (type it to create it)
    • typeof null is therefore "object"
  • undefined - EVERYTHING starts off as undefined.
    • If you declare a variable and give it no value then it is 'undefined'
    • undefined is both a type and an system created object
  • symbol - to represent a unique entity in a system (we visit briefly in es6 sessions)
  • The types on the previous slide are know as primitives
  • They are built-in object types used by the system.
  • JavaScript is 'loosely typed'; which means that you can change the type of a literal once it has been created. (both with casting and type coercion)
  • Whilst being loosely typed can be an advantage, it can also cause problems.
  • There are things called 'Object Wrappers' which were created for these types in early JavaScript. They look like this:
    • var str = new String('Hello');
    • avoid!!! They make things confusing: 
    • var nope = new Boolean(false);
    • If we test nope for truthyness it comes out as true because the object exists. Don't use them.

How do I find out what type something is?

typeof

'typeof someThing' might give you 'string', or 'number' gets you the basic type
 

In JavaScript Everything is an object

But what is an object:

In the C layer below data is often held in [hash] TABLES. The whole DOM API (the way we interact with a web page) is run off a table which is re-analysed every time something changes. OBJECTS are a fast way to access those tables.

We'll deal with creating our own objects later on, but for now just understand that they can hold values and methods (functions) and in the primitives you can use these to manipulate and format the data.

Theory: Objects & Classes

  • Objects of a type have a corresponding constructor function that makes them.
  • This keeps consistency and predictability
  • Constructors in JavaScript [by convention] have capitalised first letters, like String, Number, etc.
  • They are analogous to 'classes' in other languages, and they are what is below the class keyword in javascript.
  • A class is a 'type of thing'
  • An object is an instance of that type of thing
    • benji is an instance of labrador
    • spot is also an instance of labrador
    • var name = 'James'; name is an instance of String

Strings

Properties:

  • length - shows how many characters are in the string

Methods (selected examples):

  • .toUpperCase()
  • .toLowerCase()
  • .slice() - create a new string from a portion of this one
  • .concat() - but use + (or es6 string interpolation)
  • .replace(a, b) - allows you to replace a with b throughout the string.
  • Regular Expressions methods allow you to search a string for occurrences of a pattern. .search(), .replace() and .match() are examples.
  • Literals may be created with single or double quotes
    • If I don't put quotes around it it will look for an entity (variable or function) with that name
// Can be enclosed in double or single quotes.
var greeting = "hello";
var valediction = 'goodbye';

// BEWARE: var do = 'don't'; <- will not work because it thinks the
// string is 'don', then it finds the t and the next ' and doesn't understand

// Ways to fix:
var do = "don't";
//or
var do = 'don\'t'; //Here, the backslash 'escapes' the second single quote (see link below)


// You can declare a 'String Literal' (a string made 'on the fly'), like:
'test'

// so that you can 'concatenate' (join) strings (using the + operator) like

console.log('Hi, my name is ' + rapper); //if the value of rapper is a string 
// it will concatenate instantly before console.log is called; else it will be coerced 
// into a string and then concatenated: 'Hi my name is undefined'

About number string concatenation

2 + 2    //4

"2" + "2"    // "22"

2 + 4 +"6"    // "66"

3 + 6 +"9" + 4    // "994"

As soon as a string gets involved it becomes (or coerces the number into) a string.

(the reverse type coercion happens if you do any maths/logic operation (other than +, obvs) )

"664" * 1 + 3    // 667

Numbers

Unlike other programming language, JavaScript only has one number type.

Java: byte, short, int, long, float, double

JavaScript: number (which, just FYI, is a double precision floating point number the same as the Java double above)

 

This is good as it takes a lot of worry away from you: You just declare the number and JavaScript will take care of the rest.

 

You can specify a number anywhere between:

(Number.MAX_VALUE) 1.7976931348623157e+308 AND (Number.MIN_VALUE) 5e-324

Numbers

Anything greater than Number.MAX_VALUE is represented by the keyword Infinity (Same for Number.MIN_VALUE & -Infinity)

 

If maths is done and you get something that is not a computable result the system object NaN is produced. This is not your grandmother, this is Not a Number

 

You can find out whether this has happened by using the inbuilt method isNaN() on the number, which will return true if the value is Not a Number (i.e. an errored maths operation result)

 

Numbers can be exponentiated like so: 10e4, 10e-5

Raising numbers to the power of n is done using Math.pow(number, power) or 5**4

Numbers

Properties:

(You don't need any. To measure length, cast to string then measure.)

Methods:

  • .toFixed(n) - changes format to n decimal places
  • .toString(<radix>) - casts 2 into "2", so 2 the number becomes "2" the character (letter) (radix = counting base)

Side note: Most objects, built in or otherwise have a toString method. This is what is returned when you console.log something - it activates its toString method. What you get back depends on how well that method has been written by the object's author. See arguments keyword in functions, for example

Numbers

Two public built-in objects that help you with numbers:

Number

contains: .isNaN(<value>), .parseInt(<value>, <radix>), .parseFloat(<value>)

use like: Number.parseInt(5.62, 10);   // returns 5

 

Math

Contains many helper methods, including:

sin, cos, tan, pow, round, ceil, floor, random

use like: Math.pow(2, 3);   // returns 8

 

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math

Booleans

  • holds a value which is either true or false
  • use descriptive variable names: isDeveloper, hasTicket, ownsPassport, etc.
  • declare them literally: var isDeveloper = false;
  • avoid the Object wrapper constructor.
  • Boolean(someVar); is not a great idea because you don't know what someVar is! What if you call a server to get someVar and instead of getting the result you expect you get an error object? That will be cast to true because the object exists! #notGreat
  • apparently new Boolean(someVar); is worse. meh.

Writing JavaScript

JavaScript is CASE SENSITIVE

Comments

Comments are NOT processed by the interpreter. They are for humans only!!

// This is a line comment

/*
    This is a
    multi-line comment
*/

/*****************************************
*
* So is this; the stars make no difference
* 
*******************************************/

Line Terminators

Whenever you DO something in javascript you need to add a `;` (semi-colon) character as a line terminator.

 

Javascript will 'intelligently' add its own if you don't - you don't want to give it that option!!! (#contentious)

function add(a, b){
    return a + b; //*
}

add(2,4); //*

var test = 4; //*

// Everywhere with a * requires
// a line terminator because
// you did something.

// NOTE that you don't need them
// after you declared a function.

function respond(){
 return true;
}

// ISSUES
function thing(n) {
 return //;
        {
          score: n
        };
}

// JavaScript will insert a semicolon 
// after the return keyword

Variables

Literals vs Variables

  • If I just type 'hello', that is a string literal.
    • The interpreter makes a 'string object' with the value of hello and uses it on the spot.
    • You can create literals of any type.
    • I created it just there and then for use at that point in the code. I have no reference to it and can't use it again later.
    • IT WILL BE GARBAGE COLLECTED! (see next slide)
    • If I want to use it again later I must store it as a variable
  • N.B. If I just type hello (without speech marks) then the interpreter looks for a variable or function called hello.

Garbage Collection

  • In JavaScript memory management is taken care of for you
  • It is handled using a system called Garbage Collection
  • IF you create something and once it is used there is no further reference to it then JavaScript's memory management will wipe it - it will be Garbage Collected
  • References are determined by JavaScript's algorithms BUT an example is that a literal is used there and then and is collected BUT it you assign it to a variable it will remain until the end of it's parent functions lifespan if that variable is referenced in the code.

Variables

Variables are used to store data. They are when we save something we want to use later.

 

The var keyword means 'reserve me some memory'

(let is like var, but block scoped)

The const keyword means 'reserve me some memory and don't allow changes once set'.

 

Only declare a var once!

/*
* Variables - things that we expect to change
* Use the 'var' keyword (or 'let' in ES6)
*/
var age = 32;
var a = 1, b = 2, c = 3; //  chain creation

/*
* LET (ES6) - same as 'var' but scoped to a block
*/
let name = "James";

/*
* CONSTANTS (ES6) - things that we do not expect
* to change use the 'const' keyword
*/
const PI = 3.14;

// Using the 'var' keyword more than once will
// 'redeclare' the variable, wiping its 
// original value, so to simply update it:

var num = 1; // soon to be pointless
var num = 2; //<-- wiped ^^

let num = 1; 
let num = 2; //<-- Error. Can't redefine let

// USE LIKE THIS
var num;
num = 1;
num = 2;

const PI = 3.14;
const PI = 6; //<- this will error. 
//Cannot redeclare constants

Variable Names

  • You use variables as symbolic names for values in your application. The names of variables, called identifiers, conform to certain rules.

  • A JavaScript identifier must start with a letter, underscore (_), or dollar sign ($); subsequent characters can also be digits (0-9). Because JavaScript is case sensitive, letters include the characters "A" through "Z" (uppercase) and the characters "a" through "z" (lowercase).

  • Constants, by convention, are named in CAPITALS
  • REMEMBER: It's case sensitive, so be EXACT!

The Custom Objects Family

The objects that you can make form a family:

  1. A normal object - a dictionary store
  2. An array is an object with a pointer
  3. A function is an object with an execution context

 

side-note: object family quirk

Objects

Quick intro

  • Formed using {} (or Object() constructor - don't!)
  • They store pairs of values (properties/members)
  • They value pairs are associated data
  • The name of the pair is referred to as the key
  • The value of that pair is referred to as the value
  • So key/pair values
  • After each key goes a colon
  • After all but the last pair, put a comma
{
    name: 'James',
    age: 39
}

var player = {
    name: 'Ryan Giggs',
    age: Math.MAX
};

$element.carousel({
    noOfSlides: 4
});

Getting from an object

  • Can use dot syntax or square bracket syntax
var player = {
    name: 'Ryan Giggs',
    age: Math.MAX
};

var name = player.name;
var age = player['age'];

Setting data in an object

  • Can use dot syntax or square bracket syntax
var player = {
    name: 'Ryan Giggs',
    age: Math.MAX
};

player.name = 'fred bloggs'; 
// player is now: { name: 'fred bloggs', age: Math.MAX }

player['age'] = 42; 
// player is now: { name: 'fred bloggs', age: 42 }

Use square brackets syntax when:

  • You have a hyphenated property: car['body-kit']
  • You don't know the key at the time: paints[color]
  • Objects are great, but have no guaranteed order about them
    • keys are not guaranteed to be alphabetised
    • no memory of what was inserted and when

The Array

What is an array?

Conceptually

A construct for:

  • organising things into groups/lists
  • representing sequential order

Actually

  • An object
  • with numbers for keys
  • and a pointer (see 3 slides time)

How to declare an array

var friends = ['Moe', 'Larry', 'Curly']; // Prefer this way
// OR
var friends = new Array('Moe', 'Larry', 'Curly');

Arrays are symbolised and declared using [ ]

Array Length Property

var friends = ['Moe', 'Larry', 'Curly'];

console.log(friends.length); // outputs 3 as there are 3 members in the array
  • The things in an array are called 'items'
  • An item can be any JavaScript entity. Any primitive or array, function, object, set, etc. etc.
  • Arrays are NOT fixed in length. There is no way to naturally say 'this array will only have 4 items'. (Object.freeze can)
  • You can change the length of an array like so:
friends.length = 5;

Now the array will contain two 'undefined's at the end of the array

  • Shortening an array will mutate it and cause it to lose items

Array Indexes

  • Arrays are objects with a pointer
  • It is that pointer that allows you to access items of the array
  • THE POINTER IS ZERO-BASED which means that the first item of the array is at index 0
  • Accessing an item looks like this:
var myArray = ['str', 2, null, [1,2,4], function(){}];

//to access a member we do it by it's index in this notation:

myArray[0] // returns 'str'
myArray[1] // returns 2

// Nested arrays
myArray[3][1] // returns 2

// Accessing beyond the length
myArray[96] // undefined
myArray[-2] // undefined
  • You can count from the other end, like so:
myArray[myArray.length-1] // function(){}
myArray[myArray.length-2] // [1,2,4]

Adding/mutating an Array

  • Using the same index system we can overwrite items in an array
var myArray = ['str', 2, null, [1,2,4], function(){}];

myArray[2] = true;

console.log(myArray); // ['str', 2, true, [1,2,4], function(){}];
  • We can also add new items after the array is created using the .push(val1[, val2, val3, etc.]) method
var myArray2 = [1, 2, 3];
myArray2.push(4);

console.log(myArray2); // [1, 2, 3, 4]

Adding items at a specific index

  • We can add/remove items from an array at a specific index using the .splice(start, deleteCount, [insertItem1, item2]) method
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

myFish.splice(2, 0, 'drum'); 
// myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"]

myFish.splice(2, 1); 
// myFish is ["angel", "clown", "mandarin", "sturgeon"]

Getting items sequentially from an Array

  • We can retrieve items sequentially from either end of the array using .pop(item[, item2, etc]), .shift() and .unshift(item1[, item2, etc.])
var myArray5 = ['a', 2, 3, 19];

// return last element
myArray5.pop(); // 19

// remove first element of array and return it
myArray5.shift(); // 'a'

// add a new element to the front of the array and return array length
myArray5.unshift(2); // 5 (the new length) [2, 'a', 2, 3, 19] 

Functions

Very Basic Intro

Operators

Allowing entities to interact

Assignment Operators

Allow you to set values

Name	                Shorthand operator	Meaning

Assignment	        x = y	                x = y

Addition assignment	x += y	                x = x + y
Subtraction assignment	x -= y	                x = x - y
Multiplication assign.	x *= y	                x = x * y
Division assignment	x /= y	                x = x / y

Remainder assignment	x %= y	                x = x % y
Exponentiation assign.	x **= y	                x = x ** y


Whatever happens on the right side of the assignment equation is put into the memory space of the 
variable on the left.

So x = y+7, whatever y+7 turns out to be, it replaces whatever value x used to be.

Comparison Operators

Allow you to compare values

// These return a boolean of true or false IF the things being compared are equal.

 2 == 2         // equality comparison (don't use). This results in true.
 '2' == 2         // but so is this

4 === 4   // strict equality comparison. Does value AND type. ALWAYS USE!!

// What if we want to ask if something is NOT EQUAL?

2 != 5          // Not equal - again don't use
3 !== 'fish'    // Strict Not equal - do use.


// Greater Than
age > 18

// Greater than or equal to
age >= 16

// Less Than
yearsDriving < 3

// Greater than or equal to
age <= 2

Javascript Equality

#dodgy

Javascript Equality

#dodgy

Arithmetic Operators

Allow you to do maths

Operator	Description	                                Example
Remainder (%)	Binary operator. (needs 2 numbers to work)
                Returns the integer remainder of dividing 
                the two operands.	                        12 % 5 returns 2.

Increment (++)	Unary operator. Adds one to its operand. If 
                used as a prefix operator (++x), returns the 
                value of its operand after adding one; if used
                as a postfix operator (x++), returns the value 
                of its operand before adding one.	        
                                                                If x is 3, then ++x 
                                                                sets x to 4 and returns
                                                                4, whereas x++ returns 
                                                                3 and, only then, 
                                                                sets x to 4.

Decrement (--)	Opposite of ++

Unary negation (-)	Unary operator. Returns the negation of its operand.	
                            If x is 3, then -x returns -3.

Unary plus (+)	        Unary operator. Attempts to convert the operand to a number, 
                        if it is not already.	
                           +"3" returns 3.

Prefer +=1 to ++. (Same for --)

Logical Operators

Allow you to compare values

Operator	        Usage	        Description

Logical AND (&&)	expr1 && expr2	Returns expr1 if it can be converted
                                        to false; otherwise, returns expr2. Thus, 
                                        when used with Boolean values, && returns
                                        true if both operands are true; 
                                        otherwise, returns false.

Logical OR (||)    	expr1 || expr2	Returns expr1 if it can be converted to true;
                                        otherwise, returns expr2. Thus, when used with
                                        Boolean values, || returns true if either 
                                        operand is true; if both are false, returns false.

Logical NOT (!)	        !expr	        Returns false if its single operand can be converted 
                                        to true; otherwise, returns true.

More Array Methods

Reversing Array sequence

  • We can reverse the order of an array using the .reverse() method
var a = ['one', 'two', 'three'];
a.reverse(); 

console.log(a); // ['three', 'two', 'one']

Concatenating two arrays

  • Concatenation is a technical term meaning to join two entities (strings, arrays, etc.) together. The method in arrays is called .concat(entity1[, entity2]) for short. Entities can be values or arrays, and are comma separated.
var arr1 = ['a', 'b', 'c'];
var arr2 = ['d', 'e', 'f'];

var arr3 = arr1.concat(arr2);

// results in a new array [ "a", "b", "c", "d", "e", "f" ]

.join()

  • .join(separator) outputs the items of an array, separated by a 'separator' [default separator is a comma]
var a = ['Wind', 'Rain', 'Fire'];
a.join();    // 'Wind,Rain,Fire'
a.join('-'); // 'Wind-Rain-Fire'

Iterating over an Array

  • Regularly you will need to go over each item in an array in turn and do something with/based on its value
  • This is called iteration and there are two ways to do it:
    • for loop (which we'll cover in future lessons)
    • .forEach(function) method (better and faster)
      • The function is run on each item of the array, with the item passed in as an argument (here as 'element')
var a = ['a', 'b', 'c'];

a.forEach(function(element) {
    console.log(element);
});

// a
// b
// c

.every()

  • The .every(function) method runs a function against each item of the array
    • The function tests the item [in some way] and returns true or false
    • If all items pass then it the every function returns true
var evens = [2,4,6,8,10];

evens.every(function(num){
    return num % 2 === 0;
});

// ^^ returns true

evens.every(function(num){
    return num % 4 === 0;
});

// ^^ returns false

.some()

  • Same as .every() but .some(function) returns true if any item in the array passes the test
var evens = [2,4,6,8,10];

evens.every(function(num){
    return num % 4 === 0;
});

// ^^ returns true

.filter()

  • .filter(function)
  • The function runs a test against each item
  • It is used for finding a subset of an array, i.e. 0 to all
  • The test must be an expression that evaluates to true or false
  • .filter() then creates a new array of items that pass that test
var evens = [2,4,6,8,10];

var bigNumbers = evens.filter(function (num) {
  return num > 5;
});

// bigNumbers [6, 8, 10]

.find()

  • .find(function)
  • The function runs a test against each item until it finds the matching one
  • It is used for finding a single item in an array
  • The test must be an expression that evaluates to true or false
  • .find() returns the FIRST ITEM item that passes the test
var evens = [2,4,6,8,10];

var bigNumbers = evens.find(function (num) {
  return num > 5;
});

// bigNumbers 6

.findIndex()

  • .findIndex(function)
  • The function runs a test against each item until it finds the matching one
  • It is used for finding a single item in an array
  • The test must be an expression that evaluates to true or false
  • .filter() returns the INDEX of the FIRST ITEM that passes the test
var evens = [2,4,6,8,10];

var bigNumbers = evens.filter(function(num) {
  return num > 5;
});

// bigNumbers 2

.sort()

  • .sort(function) allows us to sort an array
  • if no method to sort is passed by the programmer then it uses a sort that sorts by unicode value (can be a problem!)
var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); // ['apples', 'bananas', 'cherries']

var scores = [1, 10, 21, 2]; 
scores.sort(); // [1, 10, 2, 21]
// Note that 10 comes before 2,
// because '10' comes before '2' in Unicode code point order.

A custom sort method is passed the current and next items:

var nums = [3,1,2];
nums.sort(function compareNumbers(current, next) {
  return current - next;
}); 

// [1,2,3]

.map()

  • .map(function) creates a new array using values from the original array
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt); // Math.sqrt is an existing function
// roots is now [1, 2, 3]
// numbers is still [1, 4, 9]

Just a quick point about the second line: You have to pass map() (and other functions we've discussed) a function to run against each item to create the new array. What I've done there is pass the sqrt function from the Math object. As we'll see later, if you give the name of a function and don't execute it with () then it just passes the function.

Resources

Copy of JS: Data Types

By James Sherry

Copy of JS: Data Types

Datatypes, Variables & Operators in JavaScript

  • 886