0% found this document useful (0 votes)
4K views

Eloquent JavaScript

This document provides notes on JavaScript concepts covered in 3 chapters: Chapter 1 introduces JavaScript data types, operators, and expressions. Chapter 2 covers control flow, conditionals, loops, and functions. Chapter 3 discusses defining and invoking functions, scope, and function notation including arrow functions. The notes define key terms like bindings, blocks, statements, side effects, and more. Operators, variables, reserved words, and data types are outlined. Control structures like if/else, while, for loops, break and continue are explained. Functions are defined as reusable blocks of code that associate names with subprograms. Scoping rules and nested scopes are covered.

Uploaded by

amandajbatts
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4K views

Eloquent JavaScript

This document provides notes on JavaScript concepts covered in 3 chapters: Chapter 1 introduces JavaScript data types, operators, and expressions. Chapter 2 covers control flow, conditionals, loops, and functions. Chapter 3 discusses defining and invoking functions, scope, and function notation including arrow functions. The notes define key terms like bindings, blocks, statements, side effects, and more. Operators, variables, reserved words, and data types are outlined. Control structures like if/else, while, for loops, break and continue are explained. Functions are defined as reusable blocks of code that associate names with subprograms. Scoping rules and nested scopes are covered.

Uploaded by

amandajbatts
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Eloquent Javascript notes

INTRO
`half of 100 is ${100 / 2}` // → “half of 100 is 50”
- Template literal = string literal but with `` instead of “ ”
- Some operators are symbols, some are words
- Operators:
-
CH1
- There are 4 types of values: string, #, boolean, undefined
- You can type in their name ( true, null) or value (13, “abc))
- Operators:
- Binary operators: +, -, *, /, %
- String concatenator +
- comparison (==, !=, ===, !==, <, >, <=, >=),
- logic (&&, ||)
- unary operators (- to negate a number, ! to negate logically, and typeof to find a
value’s type)
- ternary operator (?:) to pick one of two values based on a third value
CHAPTER 2:
- Expression = A fragment of code that produces a value
- Expressions make up statements (like sentence fragments make up full sentences)
- 1; // is a statement that is just a single expression then a (;)
- Side effects of statements = effects that ‘leave an impression on the world’ (i.e.
produce a value on the screen
- !false; //this will give us ‘true’, and then be thrown out, leaving no
impression on the world, so it’s useless code b/c nothing observable
happens
- You can define/assign multiple variables in the same line
- let one = 1, two = 2;
- console.log(one + two);
- // → 3
- Words JavaScript understands: (AKA reserved words; you can’t use for variable names)
- break case catch class const continue debugger default delete do else enum
export extends false finally for function if implements import interface in
instanceof let new package private protected public return static super switch this
throw true try typeof var void while with yield
- Environment = collection of bindings and their values that exist at a given time
- Executing a function = invoking/applying/calling
- console.log function() = executes that function
- Writes out response in hidden console if using browser
- You can open this by pressing “F12” or COMMAND-OPTION-1 on Macs
- Or search thru menus for something called “developer tools”
- Console is a binding, and log is a property
- console.log(Math.max(2, 4)); // → 4
CONTROL FLOW
- When program has more than 1 statement, it executes the statements in order (top to
bottom, left to right)
- Functions()
- Number() = converts values to numbers (i.e. converts string to #)
- String() = converts values to string (i.e. converts a number to a string value)
- Boolean() = converts values to boolean
- Number.isNaN() = returns true only if (#) is NaN
- !Number.isNan() = returns true only if (#) is a #
- {} called braces
- They link any amount of statements into one “block”
CONDITIONAL EXECUTION
- Not all programs are straight roads. We can write code with a branching road, then the
program takes one of the multiple options of roads. It makes the decision of which road
to take based on the situation at hand
- Created using “if” statements: the code only executes the “then” statement IF the
conditional statement is true
- “If, else” codes for telling program what to do if the statement is false

WHILE AND DO LOOPS


- A type of control flow to re-run the code multiple times until a condition isn’t met
- While loop: checks if condition is true, then runs program, and runs alteration
- let result = 1;
- let counter = 0;
- while (counter < 10) {
- result = result * 2; //result*=2
- counter = counter + 1;
- }
- console.log(result);
- // → 1024
- Do loop: different than a while loop bc it will always execute the program at least 1time,
then check to see if it should stop after than 1st time
- let yourName;
- do {
- yourName = prompt("Who are you?");
- } while (!yourName);
- console.log(yourName);
- //this program will force you to enter a name, it will keep asking until you enter
something that’s a string
INDENTING CODE
- To create obvious structure for yourself and other coders reading your code, use spaces
or tabs to indent subsequent lines of code in a block
- Most code editing software will automatically include these indents
FOR LOOPS
- Created as a shorthand for the while loops
- for (let number = 0; number <= 12; number = number + 2) {
- console.log(number);
- }
- // → 0
- // → 2
- // … etcetera
- // first statement initializes the loop (usually defines the variable); 2nd statement
checks whether the loop must continue; 3rd statement updates state of the loop
after each iteration
- let result = 1;
- for (let counter = 0; counter < 10; counter = counter
+ 1) {
- result = result * 2;
- }
- console.log(result);
- // → 1024
BREAKING OUT OF A LOOP
- Having the loop condition produce false is not the only way to finish a loop
- “Break” statements jump out of loop
- for (let current = 20; ; current = current + 1) {
- if (current % 7 == 0) {
- console.log(current);
- break;
- }
- }
- // → 21
- // bc there is no check statement in the for loop, the code will keep running an
infinite loop. That’s bad. the computer will usually ask if you want to continue the
infinite loop after a few seconds, OR you have to close the tab you’re working in
to continue.
- “continue” keyword works similarly
UPDATING BINDINGS SUCCINCTLY
- counter = counter + 1; → counter += 1; → counter++
DISPATCHING ON A VALUE WITH A SWITCH
- Switch statement vs a chain of if then statements..which one to use is up to you.
- *remember to include break after each case when necessary
CAPITALIZATION
- fuzzylittleturtle
- fuzzy_little_turtle
- FuzzyLittleTurtle
- fuzzyLittleTurtle
- //different ways to write bindings (variables), but camelCase is default
COMMENTS
- //comment here and the computer won’t read it
- /*also comment here and the computer won’t read it*/

CHAPTER 3
FUNCTIONS
- Defines new vocab
- Structures larger programs
- Reduces repetition
- Associates names w subprograms
- Isolates subprograms
DEFINING A FUNCTION
- Like a regular binding, but the value of the binding is the function
- const square = function(x) {
- return x * x;
- };
-
- console.log(square(12));
- // → 144
- //second function below
- const makeNoise = function() {
- console.log("Pling!");
- };
-
- makeNoise(); // → Pling!
- // this code doesn’t have parameters and its result is “undefined” and is a
byproduct of the function
BINDINGS AND SCOPE
- Bindings defined outside of a function are global in scope
- Bindings defined inside a function are local in scope
- Let and const bindings are local to the block they’re declared in
- I.e. if you declare variable with const inside a loop, code before/after that loop
cannot see it
- Var keyword is global if outside a function
- Var is considered old-style, pre-2015 JavaScript
- Local > global for priority
- const halve = function(n) {
- return n / 2;
- };
-
- let n = 10;
- console.log(halve(100));
- // → 50
- console.log(n);
- // → 10
NESTED SCOPE
- Blocks and functions can nest inside other blocks and functions
- This creates multiple degrees of “locality”
- All scopes can see the global scope
- Local scopes can see the local scope one level up
- I.e. if there’s a loop inside a function, the loop can see the function’s local
bindings
- “Lexical scoping”
FUNCTIONS AS VALUES
- let launchMissiles = function() {
- missileSystem.launch("now");
- };
- if (safeMode) {
- launchMissiles = function() {/* do nothing */};
- }
- //launchMissiles was reassigned to do nothing in the if statement
- //launchMissiles is the name of the function, and can be used as a value in other
functions etc as a stand-in for the value “now”.
DECLARATION NOTATION
- Shortcut to create a function
- function square(x) {
- return x * x;
- }//this is a function declaration
- As opposed to this:
- const square = function(x) {
- return x * x;
- };
- console.log(square(12));
- // → 144
- They both do the same thing, but written differently
- console.log("The future says:", future());
-
- function future() {
- return "You'll never have flying cars";
- }
- You can define a function AFTER you use it bc the code always orders the
function at the top of its scope
ARROW FUNCTIONS
- A type of function notation used instead of “function” keyword
- const power = (base, exponent) => {
- let result = 1;
- for (let count = 0; count < exponent; count++) {
- result *= base;
- }
- return result;
- };
- //arrow is between function parameters and function body
- //arrow means this input (parameters) produces this result (body)
- const square1 = (x) => { return x * x; };
- const square2 = x => x * x;
- //square1 =square2, just written differently
- When arrow function has no parameters, () are empty
- const horn = () => {
- console.log("Toot");
- };
- Pretty much same as function keyword, just less wordy
THE CALL STACK
- function greet(who) {
- console.log("Hello " + who);
- }
- greet("Harry");
- console.log("Bye");
- //returns “Hello Harry
- //Bye”
- The function is called, then it finishes
- The order the function goes in (calls, switches to next console.log command etc) is
called “call stack”
- Every time function is called, the current context is stored on top of the stack
- When a function returns, it is removed from stack
- Storing the stack requires memory on the computer
- If the stack is too big and the comp runs out of memory, it’ll say “out of stack space” or
“too much recursion”
- If you accidentally create an infinite loop, you will run out of stack space or “blow the
stack”
- //below code creates infinite loop
- function chicken() {
- return egg();
- }
- function egg() {
- return chicken();
- }
- console.log(chicken() + " came first.");
- // → ??
OPTIONAL ARGUMENTS
- function minus(a, b) {
- if (b === undefined) return -a;
- else return a - b;
- }
-
- console.log(minus(10));
- // → -10
- console.log(minus(10, 5));
- // → 5
- If the # of given parameters != # of parameters in function, it can still work
- The code will just use the first parameters and ignore the rest, or assign
“undefined” to left out parameters
- function power(base, exponent = 2) {
- let result = 1;
- for (let count = 0; count < exponent; count++) {
- result *= base;
- }
- return result;
- }
-
- console.log(power(4));
- // → 16
- console.log(power(2, 6));
- // → 64
- //writing the parameter as “exponent = 2” makes the exponent parameter
optional, and if not given, then defaulting it to the value 2
CLOSURE
- Local bindings are recreated every time a function is called
- function wrapValue(n) {
- let local = n;
- return () => local;
- }
-
- let wrap1 = wrapValue(1);
- let wrap2 = wrapValue(2);
- console.log(wrap1());
- // → 1
- console.log(wrap2());
- // → 2
- //this code works fine, just like you’d expect
- //using empty parenthesis = to call the function, so “wrap1()” is calling the return function
- It shows that local bindings are made anew for every call; different calls can’t trample
over one another
- closure= being able to reference a specific instance of a local binding in an enclosing
scope
- Function values contain:
- Code body
- Environment in which they were created (not the environ in which they were
called)
- function multiplier(factor) {
- return number => number * factor;
- }
-
- let twice = multiplier(2);
- console.log(twice(5));
- // → 10
- //In the example, multiplier is called and creates an environment in which its factor
parameter is bound to 2. The function value it returns, which is stored in twice,
remembers this environment. So when that is called, it multiplies its argument by 2.
RECURSION
- Recursion = A function that calls itself
- If it calls itself too often, the stack will overflow
- Recursion is slower/more expensive than a simple loop b/c recursion will call the function
multiple times
- It’s a Q of speed vs elegance (machine-friendly vs human-friendly)
- Programmer has to decide what code is easy enough for human to read vs how
much space/time it takes up in the computer
- Rule of thumb= start by writing easy to read code, then improve if necessary
- function findSolution(target) {
- function find(current, history) {
- if (current == target) {
- return history;
- } else if (current > target) {
- return null;
- } else {
- return find(current + 5, `(${history} + 5)`) ||
- find(current * 3, `(${history} * 3)`);
- }
- }
- return find(1, "1");
- }
-
- console.log(findSolution(24));
- // → (((1 * 3) + 5) * 3)
- If we try to find findSolution(13), here’s what the computer does:
- find(1, "1")
- find(6, "(1 + 5)")
- find(11, "((1 + 5) + 5)")
- find(16, "(((1 + 5) + 5) + 5)")
- too big
- find(33, "(((1 + 5) + 5) * 3)")
- too big
- find(18, "((1 + 5) * 3)")
- too big
- find(3, "(1 * 3)")
- find(8, "((1 * 3) + 5)")
- find(13, "(((1 * 3) + 5) + 5)")
- found!
GROWING FUNCTIONS
- There are 2 ways for functions to be introduced
- 1: If you find yourself writing similar code a lot, you make that repeated code into
a function that you can re-call over and over
- 2: you realize you need some functionality that you haven’t written yet, and you
make a new function
- Resist urge to add cleverness to your code: it’s needlessly hard to read
- Resist urge to write general “framework” for every bit of functionality you come across,
bc it’s too much work
- Try to make it as easy for the next coder to understand as possible

FUNCTIONS AND SIDE EFFECTS


- Functions can be called for the side effects and/or return value
- Pure function = value-producing function sin side effects AND doesn’t rely on side effects
from other code (whose values might change)
- To test if it’s working, just call it
- Nonpure functions tend to require more scaffolding to test
- I.e. console.log is a nonpure function

CHAPTER 4
DATA STRUCTURES: OBJECTS AND ARRAYS
- Think of the index as the amount of items to skip, counting from the start of the array.
- Math.max = we access the prop named “max” in the Math object
- All javascript values have properties
- Except “null” and “undefined”
- If you know the name of prop you want is “color”, use value.color
- If you want to extract prop named by value held in binding i, use value[i]
- Prop names are strings
- Array
- An object
- Elements in array are properties (numbers are prop names)
- Property names are strings
- To find how many elements in array, use array.length (or array[“length”])
- array.push() is a method
- Array.length //tells us how many elements in array
-
- String
- Every string has a toUpperCase and toLowerCase prop
- These are functions called “methods” of the value they belong to
- Aka, “toUpperCase is a method of a string
- let doh = "Doh";
- console.log(typeof doh.toUpperCase);
- // → function
- console.log(doh.toUpperCase());
- // → DOH
- In operator tells you whether that object has a prop with that name
- let anObject = {left: 1, right: 2};
- console.log(anObject.left);
- // → 1
- delete anObject.left;
- console.log(anObject.left);
- // → undefined
- console.log("left" in anObject);
- // → false
- console.log("right" in anObject);
- // → true
- Delete method will remove prop, but undefined property will return true
- Object.keys function = finds out what prop names of the object tree
- console.log(Object.keys({x: 0, y: 0, z: 2}));
- // → ["x", "y", "z"]
- Object.assign function copies all props from one object into another
- let objectA = {a: 1, b: 2};
- Object.assign(objectA, {b: 3, c: 4});
- console.log(objectA);
- // → {a: 1, b: 3, c: 4}
- Mutability
- let object1 = {value: 10};
- let object2 = object1;
- let object3 = {value: 10};
-
- console.log(object1 == object2);
- // → true
- console.log(object1 == object3);
- // → false
- If you change object1, it does not change object3
- Correlation is a measure of dependence between statistical variables
- **statistical variable does not equate to a programming variable
- Correlation expressed as number -1 to +1
- -1 = inversely related (if one is true, the other is false)
- 0 = no relation
- +1 = positively correlated (if you know one, you know the other)
- phi coefficient (ϕ) used to compute measure of correlation btw 2 booleans
- This is a formula
- The input of the formula is a frequency table containing # of
different combos of 2 variables that were observed
- Output = number btw (-1) and (+1) that describes correlation
- If the coefficient = 0.06 for example, there is a very small relation
btw the 2 variables
ARRAYOLOGY
- For array loops, old way of writing loop:
- for (let i = 0; i < JOURNAL.length; i++) {
- let entry = JOURNAL[i];
- // Do something with entry
- }
- BETTER WAY OF WRITING LOOP:
- for (let entry of JOURNAL) {
- console.log(`${entry.events.length} events.`);
- }
- Used for strings and arrays
- When a for loop looks like this, with the word ‘of’ after a variable
definition, it will loop over the elements of the value given after ‘of’.
- Indexof = method to search thru array for specific value
- Returns index where specific value was found or (-1) if it was not found
- lastIndexOf = performs indexOf but starts searching from end of array
- Can take optional 2nd argument to tell method where to start searching from
- console.log([1, 2, 3, 2, 1].indexOf(2));
- // → 1
- console.log([1, 2, 3, 2, 1].lastIndexOf(2));
- // → 3
-
- Slice method
- takes start and end indices and returns an array that has only the elements
between them. The start index is inclusive, the end index exclusive.
- console.log([0, 1, 2, 3, 4].slice(2, 4));
- // → [2, 3]
- console.log([0, 1, 2, 3, 4].slice(2));
- // → [2, 3, 4]
-
- When the end index is not given, slice will take all of the elements after the start
index. You can also omit the start index to copy the entire array.
- Concat method
- Glues arrays together to create a new array (similar to + operator for strings)
- If you pass concat an argument that is not an array, that value will be added to
the new array as if it were a one-element array
- function remove(array, index) {
- return array.slice(0, index)
- .concat(array.slice(index + 1));
- }
- console.log(remove(["a", "b", "c", "d", "e"],
2));
- // → ["a", "b", "d", "e"]
- Strings and other properties
- You cannot add new properties to strings
- String, number, and Booleans are not objects. They are immutable.
- Strings have built-in methods:
- console.log("coconuts".slice(4, 7));
- // → nut
- console.log("coconut".indexOf("u"));
- // → 5
-
- console.log("one two three".indexOf("ee"));
- // → 11
-
- Trim method removes whitespace (spaces, newlines, tabs, and similar
characters) from the start and end of a string.
- console.log(" okay \n ".trim());
- // → okay
-
- padStart method: takes the desired length and padding character as
arguments.
- console.log(String(6).padStart(3,
"0"));
- // → 006
- Split method
- let sentence = "Secretarybirds
specialize in stomping";
- let words = sentence.split(" ");
- console.log(words);
- // → ["Secretarybirds", "specialize",
"in", "stomping"]
-
- Join method
- console.log(words.join(". "));
- // → Secretarybirds. specialize. in.
stomping
-
- Repeat method
- console.log("LA".repeat(3));
- // → LALALA
- let string = "abc";
- console.log(string.length);
- // → 3
- console.log(string[1]);
- // → b

- REST PARAMETERS:
- For a function to accept any number of parameters, its useful
- To do this: write “...” before the last parameter
- function max(...numbers) {
- let result = -Infinity;
- for (let number of numbers) {
- if (number > result) result =
number;
- }
- return result;
- }
- console.log(max(4, 1, 9, -2));
- // → 9
-
- You can use the … to call functions also:
- let numbers = [5, 1, 7];
- console.log(max(...numbers));
- // → 7
- //this spreads out the array into the function as separate elements,
instead of 1 element
- You can also do this:
- max(9, ...numbers, 2)
- You can also use … to spread an array into another array
- let words = ["never", "fully"];
- console.log(["will", ...words,
"understand"]);
- // → ["will", "never", "fully",
"understand"]
-
THE MATH OBJECT
- The Math object contains functions
- Math is somewhat useless as a value, unless it’s used as a “namespace” so all
the functions and values don’t have to have global bindings (b/c too many global
bindings pollutes the namespace)
- **the more names that have been used already, the more likely you are to
accidentally overwrite a previously used name
- ***Javascript only warns of overwriting a variable for let and const, NOT
for var or function
- Trig: the Math function has functions for: sin, cos, tan and their inverses: asin,
acos, atan
- Math.pi = 3.14… rounded to terminating digit
- *typically in Javascript, you write the names of constant values in CAPS
- Math.random= function that gets random-ish number between 0-1 (includes 0,
excludes 1)
- Uses hidden, complex algorithm to produce a value that seems random to
humans
- To get a whole#:
- console.log(Math.floor(Math.random() *
10));
- // → 2
- //this can produce any number 0-9
- Math.ceil rounds up the value
- Math.round rounds to nearest whole #
- Math.abs gives absolute number of value (turns neg into pos)
DESTRUCTURING
Making the phi coefficient function more succinct:
- Before:
- function phi(table) {
- return (table[3] * table[0] - table[2] *
table[1]) /
- Math.sqrt((table[2] + table[3]) *
- (table[0] + table[1]) *
- (table[1] + table[3]) *
- (table[0] + table[2]));
- }
-
- After:
- function phi([n00, n01, n10, n11]) {
- return (n11 * n00 - n10 * n01) /
- Math.sqrt((n10 + n11) * (n00 + n01) *
- (n01 + n11) * (n00 + n10));
- }
-
- This works for variables let, var, and const
- You can do the same for objects, using {braces} instead of [square brackets]
- let {name} = {name: "Faraji", age: 23};
- console.log(name);
- // → Faraji
-
- *you cannot destructure a null or undefined value

JSON (JavaScript Object Notation)


- Properties grasp their values, not contain them
- Because properties only grasp their value, rather than contain it, objects and arrays are
stored in the computer’s memory as sequences of bits holding the addresses—the place
in memory—of their contents. So an array with another array inside of it consists of (at
least) one memory region for the inner array, and another for the outer array, containing
(among other things) a binary number that represents the position of the inner array.
- saving/sending the data you made is difficult bc it’s got a tangle
of addresses that must be converted to a description that can be
stored/sent
- You must “serialize” the data: convert into a flat description
- Popular serialization format is JSON, even for
non-JavaScript languages
- Used as data storage/communication across the web
- JSON rules:
- All prop names have to be surrounded by “”
- Only simple data; no function calls, bindings or anything
that involves actual computation
- No comments
- Example:
- {
- "squirrel": false,
- "events": ["work", "touched tree", "pizza",
"running"]
- }
- Use functions JSON.stringify to convert JavaScript value to
JSON string and JSON.parse to convert from JSON back to
JavaScript vlue encoded
-
-
-

You might also like