What’s going on inside a computer
- CPU can do very simple things with a small amount of data that has been pulled into the CPU.
- CPU pulls that data from memory and when it’s done often puts new values back into memory.
- In high-level languages like Javascript we don’t have to keep track of where values live in memory and we definitely don’t have to keep track of moving data in and out of the CPU; the lanuage takes care of all of that for us.
Variables
- Variables in programming are different than variables in math in that they can change value.
x = x + 1
is sensible in programming but nonesense in math.
- Each variable has associated memory that is used to hold its value.
- x = x + 1 turns into, figure out where
x
lives in memory; load the value from memory into the CPU; execute the CPUs addition function to change the value in the CPU by 1; then store the value from the CPU back to the original location in memory.
- Declaring a variable is how we say, this is a name that we are going to use. Each variable is declared once.
- There are two parts of creating a variable: declaring the variable and initializing it.
- Initializing a variable is how we assign a variable its initial value. This can happen at the point we declare the variable or later.
- The memory associated with a variable of a primitive type holds the actual representation of the primitive value while the memory associated with a variable of a reference type holds a reference to the actual data which exists somewhere else in the computer’s memory.
Declaring variables
- We declare variables with
const
or let
. const
variables must be assigned a value when they are declared and cannot be reassigned; let
variables can start out undefined and can be assigned new values whenever we want. Prefer const
variables unless there’s a good reason to use let
.
- Javascript does not enforce it but in general you should have a notion of what type of value you are going to store in a variable (especially a
let
variable). I.e. don’t assign a number to a variable at one point and then later assign a string to the same variable. You’ll just confuse yourself. You should always be able to answer the question (one I might ask you): “What is the type of this variable?” meaning what type of value is stored in the variable.
- The name of a variable allows us to refer to it in assignment expression and as a value.
- There are two kinds of variables in Javascript: local variables and object and array properties.
- Local variables are declared in the body of functions. These variables may only be used within the construct where they are declared.
- Parameters declared in a function are also local variables.
Arrays
- Arrays are a reference type that collect multiple values into a single value. Typically all the values should be of the same type.
- The places where values can be stored in an array are called the \i{components} of the array. You can think of the components of an array as a bunch of anonymous variables. That is, they are places in memory that can hold a value just like named variables but they don’t have their own names. Instead each component is referred to with an array access expression like
xs[0]
or xs[10]
.
- The elements of an array are accessed using square brackets ([]) and an index, e.g.
xs[0]
accesses the 0th element of the array xs
.
- The values in an array can be any kind of value.
- Arrays have a read-only property
length
which gives the number of components in the array.
- The valid indices for an array are 0 through length - 1, inclusive.
- Accessing an array with an invalid index (less than 0 or greater than length - 1) will evaluate to
undefined
. Assigning
- Literal arrays can be written as a comma-delimited list of expressions in
[]
s, e.g. [10, 23, 57]
.
- An array access expression is like a variable in that it can be used to obtain a value or as a place that can be assigned a value with = or any applicable compound assignment operator (e.g.
+=
or ++
on on an array of numbers).
Variables holding reference types
- Because the value of a reference type is the reference, not the actual memory representing the referenced value, multiple variables can hold references to the same object, i.e. the value stored in each variable is the same reference which points to the one place in memory where the actual data that makes up the reference type lives.
- When multiple variables hold the same reference, changes made to the referenced object via one variable will be be visible via the other variable.
Assignment operators
- The thing that we can do with variables is \i{assign} them values. Unless a variable is declared with
const
it can be assigned a new value at any time. Assigning a new value to a variable has no effect on the value that was previously assigned to that variable; it just means the variable is now a name for the new value instead of the old value.
- The assignment operator
=
allows a program to initialize or change the value stored in a variable or an array element. The value of the expression on the right of the =
is stored in the variable or array element referenced on the left. The value of of an assignment expression is the value that was assigned.
- The only assignable places in Javascript are local variables, array elements, and object properties, e.g.
x
, nums[0]
, and obj.someField
. We’ll talk about arrays and member variables later.
- Assignments in Javascript are technically also expressions that produce a value, namely the value that was assigned, but normally we care more about their side effect, namely changing the value the variable or array element being assigned to. (In general using the value of an assignment expression is a bad idea.)
- Compound assignment operators (
+=
, −=
, *=
, /=
, %=
) can be used to assign a new value to a variable or array element computed from the old value. For instance x += 2
is equivalent to x = x + 2
. The value of a compound assignment expression is the new value of the variable or array element.
- The increment operator (
++
) and decrement operator (−−
) are used to add 1 or subtract 1 from the value of a variable or an array element. For instance x++
is equivalent to x += 1
or x = x + 1
. The value of a ++
or --
is the value of the variable or array element \i{before} it was incremented or decremented.
- Note that
=
(one equals sign) is the assignment operator and ===
(three equals signs) is the equality comparison operator. If you mix them up, you’ll get either compiler errors or incorrect and confusing behavior from your program. Remember: = !== ===
.
2d arrays
- 2d arrays are stored as arrays of arrays. Therefore, the way 2d arrays are created and indexed is similar to 1d array objects.
- It is equally correct to think of a 2d array as a 1d array whose components happen to be arrays.
- Sometimes we refer to the non-array values stored in a 2d array as the \i{elements} of the array. So in a 2d array of numbers the components of the array are 1d arrays of numbers but the elements are ints.
- The square brackets
[row][col]
are used to access and modify an element in a 2d array.
- 2d arrays can be initialized with specific values by writing a nested initialization expression like
[[1, 2, 3], [4, 5, 6]]
- Since 2d arrays are stored as arrays of arrays, the outer loop iterates over the array whose elements are 1d arrays and the inner loop iterates over the elements of the 1d array.
- Typically when we think of a 2d array as a grid, it is arranged with the outer array holding 1d array representing the rows of the grid. Thus to access the element at row
r
and column c
, we use arr[r][c]
. This form is called “row-major order”.
- It is, however, possible to think of a 2d array as representing an array of columns in which case to get the element at row
r
and column c
you would write arr[c][r]
. This is called “column-major order”.
- All algorithms that work with 1d arrays will work with 2d arrays, as long as they apply to arrays whose elements are arrays.