- Values, Types, and Operators
- inside computer there is only data
- computers have volatile and non-volatile storage
- so much data so we separate into chunks called values
- types: numbers, strings, boolean, objects, functions, undefined
- Javascript uses 64 bit to represent numbers
- Logical operators: && (and), || (or), ! (not)
- true ? 1 : 2 (ternary)
- null and undefined mostly interchangeable in JS
- JS does automatic type conversion, compare exact values with === and !== (recommended)
- Program Structure
- expression: code that produces a values
- statement: ends with ; and cause side-effects
- variables don’t contain values, but point to them
- environment: collection of variables and values that exist in given time
- function: piece of program wrapped in a value invoked by putting parentheses after expression
- for loop is same as while loop, but related statements grouped together
- break: jumps out of enclosed loop
- continue: jumps out and starts next iteration
- switch statement can be used to structure multiple else ifs
- variables typically named in camelCase convention
- Functions
- function definition is a regular variable definition
- variables created inside functions are local to that function (with var)
- in JS, only functions create new scopes
- each local scopes can see all the local scopes that contain it
- function and its name are distinct things
- function declarations ‘function name(x) {}’ are conceptually moved to the top so can be called before definition
- don’t define function in if loop, different browers treat differently
- when function is called computer stores context in call stack
- JS is flexible with number of arguments
- local variables are recreated for every call, multiple instances can exist
- being able to reference a specific instance of local variables in an enclosing function is called a closure
- a way to think about is that a function is frozen with certain variables
- recursion is typically much slower in JS
- rule of thumb: don’t worry about efficiency until you know for sure the program is too slow
- many beginners focus too much on efficiency even for minute/unimportant things
- recursion is good for certain types of problems such as exploring or processing several branches
- naming tip: don’t add cleverness unless absolutely sure you’re going to need it
- functions that return values generally more useful and can be used in multiple ways
- pure functions don’t rely on side effects and returns a value
- Data Structures: Objects and Arrays
- for objects dot notation must have a valid variable name (e.g. no spaces or starting with number) while using brackets tries to evaluate expression
- properties with functions are methods
- objects are arbitrary collections of properties
- arrays are specialized objects with numbers as properties
- can be used to map a property with a value as well
- push/pop for end of array and shift/unshift for beginning of array
- slice can work for arrays and strings
- functions have ‘arguments’ objects
- JS does not remind you if you are overwriting an existing function or object
- in browsers, the global scope is stored in the window variable
- Higher-Order Functions
- large programs introduce more opportunities for bugs
- programs written that describe easily what it is doing is more expressive
- abstractions hide details and give ability to talk about problems at a higher level
- must notice when a concept is begging to be abstracted into a new word
- functions that operate on other functions by modifying or returning are higher-order functions
- allows us to abstract over actions
- function passed in as an argument to another function can only take one parameter
- use ‘apply f.apply(null, arguments)’ by passing in array or array-like arguments and will call function with those arguments
- JSON – JavaScript Object Notation
- all property names must be surrounded by double quotes and only simple expressions allowed (nothing the calculates)
- higher order functions shine when you need to compose functions
- can make writing clear code much easier e.g. console.log(average(ancestry.filter(male).map(age)));
- the cost is inefficiency, building up intermediate arrays can be expensive, but computers insanely fast and if working with relatively manageable data set, is ok
- bind method will create a new function that will call the original function with some of the arguments already fixed
- useful higher-order methods for arrays: forEach, filter, map, reduce
- functions have an apply method that can be used to call an array specifying arguments and bind to create a partially applied version of the function
- The Secret Life of Objects
- objects were used as a way to manage complexity
- hide the difficult part and offer an interface
- ideas worked out in the 1970’s and 1980’s and big revolution in 1990s
- while things can get ideological, focus on practical
- encapsulation or distinguishing between internal complexity and external interface is useful concept
- when method needs to do something with object it was called on will look at this
- call can be used to take methods normally “speak.call({type:’old’}, “oh my”);
- almost all objects have a prototype, a fall back source of properties
- you can create objects with a specific prototype
- adding new in front of a constructor creates a new instance
- prototypes can be used at any time to add new properties and methods to objects based on it
- JS distinguishes between enumerable (properties we create) and nonenumerable (prototype standard) properties
- when using loops, may want to use .hasOwnProperty(name) rather than in
- can create objects with no prototype by using “Object.create(null)”
- polymorphism is when a method can be made to work with objects with various interfaces
- in JS, object literal notation allows you to specify properties that look normal, but have methods associated with them
- inheritance allows us to build slightly different data types with relatively little work
- inheritance is controversial, some people don’t like because ties things together
- Electronic Life
- Bugs and Error Handling
- JS not great at helping find bugs
- “use strict” at top of file or function body may help
- test code/ frameworks can help catch errors as well
- when there is a problem, resist urge to start making random changes
- think, analyze, and come up with a theory, test (console.log can be helpful)
- one way to deal with exceptions is returning a special value (e.g. null), but can result in cluttered code, better for local
- throw new Error(“something: ” + result)
- try { [do something] } catch(error) { [do if error] }
- use finally to clean up errors
- if exception makes it through stack, handled by environment, will show up on developers console
- don’t blanket catch exceptions because doesn’t tell you what exactly caused it
- can catch specific error by creating instance of specific type of error and checking isinstanceof
- Assertions are basic sanity checks that help catch errors where they happen instead of at unrelated parts of the system
- Regular Expressions
- regular expression objects can be constructed or written as literal value
- \+ to use + char
- in brackets means can be any e.g. [0123456789] a number
- can also use dash for range e.g. [a-z]
- \d: digits
- \w: alphanumeric
- \s: Any whitespace char
- \D: char that is not a digit
- \W: a Non-alphanumeric char
- \S: nonwhitespace char
- special char lose meaning in brackets
- match except terms by including ^ in opening bracket
- + matches one or more
- * matches zero or more
- ? makes pattern optional
- {} means pattern occurs precise number of times
- \d{1,2} at least one, at most two
- \d{3} occurs three times
- you can group subexpressions with ()
- test method tells you if there is match
- exec returns null if not found and object (looks like array of strings, but can tell first match)
- when multiple matches, last index kept
- Dates: new Date() returns date object “Wed Dec 04 2013 14:24:57 GMT+0100 (CET)”
- can also create specific dates “console.log(new Date(2009, 11, 9));”
- Months start at zero
- getFullYear, getMonth, getDate, getHours, getMinutes, getSeconds
- /^ $/: caret means must start with and $ means must end with
- \b for word boundary: start or end of the string
- pipe or | allows for OR
- regex expressions backtrack so possible to take very long time if not written correctly
- replace only changes first match
- /[ou]/g – makes replace global
- “Hopper, Grace\nMcCarthy, John\nRitchie, Dennis”
- .replace(/([\w ]+), ([\w ]+)/g, “$2 $1”)
- $digit refers to parethens group
- can also pass a function instead of string
- greed: repetition operators match as much as they can. if you put question mark, they become nongreedy and match as little
- e.g. </p>hi</p> non-greedy will match <p>’s and greedy will match whole sequence with <.+>
- search acts like indexOf, and takes regular expression
- using global regex, returns array instead of object like exec
- generally only want to use with replace and explicit use of lastIndex (where search starts)
- common pattern is scanning through all occurrences of a pattern in a string in way to give access to match object in loop body “while (match = number.exec(input))”
- using match equals works if match succeeds
- INI format
- blank lines and one starting with ; are ignored
- lines wrapped in [ and ] start a new section
- lines containing an alphanumeric identifier followed by an = char add a setting to the current section
- international characters not supported in regex currently
- summary
- /abc/ seq of char
- /[abc]/ any character from a set of characters
- /[^abc]/ any character not in a set of characters
- /[0-9]/ any character in a range of characters
- /x+/ one or more occurrences of the pattern x
- /x+?/ one or more occurrences, nongreedy
- /x*/ zero or more occurences
- /x?/ zero or one occurence
- /x{2,4}/ between two and four occurences
- /(abc)/ a group
- /a|b|c/ any one of several patterns
- /\d/ any digit
- /\w/ any alphanumeric character
- /\s/ any whitespace
- /./ any chacter except new lines
- /\b/ a word boundary
- /^/ start of input
- /$/ end of input
- regex has test and exec methods
- strings have match, search, and replace methods that can take regex
- regex options written after closing slash: i (case insensitive), g (global)
- RegExp constructor creates regex expression from string
- Modules
- literate programming involves leaving detailed comments
- easier to follow, but harder to initially set up and change later
- structuring takes energy, at the beginning of the project, better to just put things where convenient
- in JS, everything visible outside of top-level function is visible everywhere
- objects can be used to create publicly accessible subnamespaces and functions can create isolated private namespaces
- if you have a lot of duplicate shared pieces of code, can waste a lot of time and energy on moving them around and keeping up to date
- Decoupling: isolating pieces of code from each other, keep interface stable, so outside code using doesn’t have to change
- functions can be used to create scope and hold local variables
- wrapping with a function (function() {})(); can prevent variables from polluting global scope. if statement starts with a function, is a function declaration, the parens forces it to be interpreted as an expression
- for bigger modules, you can declare an object, add properties to export. this is global scope in following example
- (function(exports) {})(this.weekDay = {});
- require allows one module to directly ask for interface object of another module, but also requires a readFile and ability to execute string as JS code
- eval: allows you to execute a string of code in the current scope, but breaks some properties such as being isolated from outside world
- better to use Function constructor with a string containing a comma-separated list and string containing function body
- var plusOne = new Function(“n”, “return n + 1”);
- Since function constructor wraps module code, don’t need to wrap namespace function
- Require can help you manage modules easier
- Program like browersify looks for calls to require and resolves all dependencies before
- You can also wrap module in a function so can load in background using define
- learning good interface design involves using a lot of interfaces / fix or wrap things if not working well
- predictability can make easier to use
- use simplest data structures possible and make functions do a single clear thing and if practical make them pure functions
- composability: keeping code in a form that it can be used with other code
- good to provide two interfaces: low-level for complex situations and high-level for routine use
- two main ways for using modules: CommonJS Modules (require) and AMD (define)
- Language
- parser: program that reads a piece of text and produces a data structure that reflects structure of program contained in that text
- in example, expressions have three types: value, name, and apply
- apply expressions represent applications and have operator properties
- in syntax tree, objects can hold expressions, which hold other expressions, etc
- can write a parseExpression function that is recursive in nature
- take string as input and return an object containing data for expression at start of string and part of string left after parsing
- egg is interpreted language, during evaluation acts directly on the representation of program
- compilation ads another step between parsing and running, transforms program into something that can be evaluated more efficiently
- traditionally meant converting to machine code, but doesn’t have to be
- JavaScript and the Browser
- TCP (Transmission Control Protocol) helps transport things in order
- Computers generally have ports which take various protocols
- Listening computer is the server and connecting computer is called the client
- World Wide Web is a set of protocols
- to connect, listen on port 80 using HTTP (Hypertext Transfer Protocol) which allows other computers to request documents over the network
- each document is named by a Uniform Resource Locater (URL) which consists of the protocol (http://), server (eloquentjavascript.net) and path (/12_browser.html)
- HTML consists of text and tags
- tags are written in angle brackets and provide structure
- documents starts with <!doctype html> tells the browser to interpret it as modern HTML
- tag can run javascript code
- use src attribute to fetch a script file
- javascript cannot look at files on your computer or modify anything not web-related
- sandboxing keeps you safe
- among many modern web browsers, there is a lot of uniformity and standards
- The Document Object Model
- browser parses HTML and builds a model of the document’s structure and then uses the model to draw the page on the screen
- This representation is called the Document Object Model
- the global variable document gives us access to these objects
- tree: a branching structure with no cycles and a sincle well-defined root (document.documentElement)
- trees are often used to maintain sorted sets of data because elements can be found or inserted more efficiently in a sorted tree than in a sorted flat array
- each DOM node has nodeType property, which contains a numeric code
- code that interacts heavily with the DOM tends to get long, repetitive, and ugly
- nodes, can link to other nodes through (parent node, previous sibling, next sibling, childnodes, first child, last child)
- don’t want to specify by nth node, because can create empty nodes use tags
- if modifying list of nodes, start from the end, because it is live, if we update first, can result in a loop
- if you want solid collection, create real array with slice
- if you make your own attribute, good to preprend ‘data-‘ so don’t conflict with other attribtues
- inline elements same line, block take up whole width
- block tags are on own line
- css: specificity takes precedence, but if same, then most recent will
- p > a: direct children. p a: all a in p
- querySelectorAll method (on document object and elem nodes) takes selector string an returns array-like object. returned array is not live. without the all part, only returns first.
- “p”, “.animal”, “p .animal”, “p > .animal” – like css
- position: default is static. when set to relative, same place, but left and right can be used to move it from its normal place. absolute: removed from normal flow.
- Handling Events
- browsers allow us to register functions as handlers for specific events
- every dom element has its own eventlistener method
- onclick is similar but can only give to one node
- addEventListener lets you add any number of handlers
- addEventListener / removeEventListener
- event handlers are passed an event object
- mousedown e.which == 1, 2, or 3
- if element inside another element is clicked and both have handlers, more specific one gets handled first
- event handler can call stopPropagation on event object to prevent handlers further up from receiving event
- most also have target property, refering to node where they originated i.e. you could put the event listener on outide element, but get specific clicked element.target
- use event.preventDefault(), if you want to cancel default event behavior (e.g. link click)
- keypress uses keyCode, can find with charCodeAt(index)
- can look at shiftKey, ctrlKey, altKey, and metaKey if looking for multiple held down keys
- event.keyCode == 32 && event.ctrlKey
- keypress gets event for keys that produce char inputs
- charCode property can be interpreted as unicode char
- console.log(String.fromCharCode(event.charCode));
- when nothing is in focus, document.body acts as target node of key events
- click event occurs where mousedown and up happen on same element
- event.pageX and event.pageY gives coordinates
- mousemove: everytime mouse moves, can use to keep track of mouse movement and position
- not all browsers support buttons, some use which instead
- deal with outside or inside node with relatedTarget
- scroll events occur after moving
- focus and blur events do not propagate to parent. the window loses or gains focus when you move from browser tab or window
- when page finishes loading, there is a load event. can be useful if need to do things after other elements are loaded
- script execution timeline. multiple scripts cannot run at same time
- if you want to do something in the background can use web workers
- setTimeout schedules another function to be called later
- use returned value.clearTimeout to cancel scheduled function
- setInterval, clearInterval can be used for repeatedly used functions
- create variable and set it to setTimeout with clearTimeout(variable) set earlier if you want to only execute in intervals
- if we want something spaced at least a cert. amount of time, fire during series of events, not after
- Project: A Platform Game
- Drawing on Canvas
- Some alternatives for graphics: SVG (Scalable Vector Graphics) and canvas
- SVG can be included through the img tag
- SVG can be resized, canvas is converted to pixels
- HTML is simplest to use
- SVG and HTML build up a DOM making it possible to modify elements after they are drawn
- repeatedly changing something small in canvas is expensive
- DOM also allows you to register mouse events / can’t do in canvas
- canvas is good for drawing a huge number of tiny shapes, lower cost per shape
- also certain effects such as rendering a scene on pixel at a time, or post processing an image with javascript use canvas
- HTTP
- Protocol
- GET means you want to get a specified resource
- PUT is replace
- POST is send information
- DELETE is delete
- Method, path, HTTP/1.1 (version of protocol)
- Server responds with 3 digit number and human readable code
- 2– means succeeded
- 4– means error
- 5– means error with the server not request
- response may have any number of headers with key-value pairs
- GET and DELETE don’t send along data
- PUT And POST do
- in GET request, start of query string is indicated by a question mark followed by name, value pairs separated by &
- GET /example/message.html?name=Jean&message=Yes%3F HTTP/1.1
- some characters must be escaped
- if POST is used then the HTTP request will include the data in the body of the request
- By convention, GET used for requests that do not have side effects
- JS makes HTTP requests through XMLHttpRequest interface
- to make simple request, make request object with XMLHttpRequest constructor
- var req = new XMLHttpRequest();
- req.open(“GET”, “example/data.txt”, false); – false makes send will return only after response to our request was received
- req.send(null); – send arg. of request body. null for GET
- console.log(req.responseTest);
- console.log(req.status, req.statusText);
- console.log(req.getResponseHeader(“content-type”));
- can make open asynchronous by passing true as third argument
- req.open(“GET”, “example/data.txt”, true);
- req.addEventListener(“load”, function() { console.log(“Done”), req.status);
- req.send(null)
- XML can be hard to read, easier to deal with JSON
- easy to write helper functions for GET requests
- may want to design responses to failure or error handling
- writing asynchronous code in plain callback style can be hard to do for complicated projects
- promises wrap an asynchronous action in an object
- promises are made with a promise constructor and passed a two functions (one for success, and failure)
- has a then method that you can call with two functions as well
- very useful when chaining functions together
- remote procedure calls: commonly used model for server-browser communication. send function name and arguments to server and request contains returned value
- another approach is using resources and HTTP methods
- instead of a remote procedure addUser
- use PUT request to /users/larry
- makes resources easier to reason about than a jumble of functions
- HTTPS: requires server to prove that is has cryptographic certificate issued by a certificate authority that the browser recognizes and encrypts connection in a way that should prevent eavesdropping and tampering
- Forms and Form Fields
- many field types use input tags
- text
- password
- checkbox
- radio
- file
- whenever value of form field changes, fires a change event
- form fields can get keyboard focus
- document.activeElement corresponds to the focused element
- form elements can also be disabled
- forms can select child elements by position or name
- submitting a form normally means browser navigates to the page indicated by teh form’s action attribute
- <form action=”example/submit.html”>
- before submit, “submit” event is fired, and event can be handled by javascript and prevent default
- can catch errors
- can have program handle input using XMLHttpRequest without reloading page
- can use selectionStart and selectionEnd to capture various parts of a textarea
- change event for text field only fires when field loses focus
- to respond immediately to changes, register a handler for “input” event instead
- label tag used to associate piece of text with an input field
- select fields are similar to radio buttons. when given multiple attribute <select multiple>, pick many
- size attribute will sets how many to show
- options tag of a select attribute can be accessed as an array-like object through field’s options property
- e.g. select.options.length
- file fields allows browser to read a file on the computer
- files property of file field is an array-like object
- data can be stored in the browser in localStorage
- Project: A Paint Program
- Node.js
- traditional way to handle I/O was like readFile, start reading and return only when file fully read i.e. synchronous I/O
- Asynchronous interface allows script to continue running while it does work and calls a callback function when its done
- in node, process variable like console variable, allows you to inspect and manipulate current program
- waiting for I/O to finish is implicit in the synchronous model
- asynchronicity makes expressing straight-line models harder
- trying to add multiple threads of control would add a lot of complexity for JS
- process.argv, allows you to access command=line arguments given to your script
- commonJS (require) takes path. if doesn’t look like rel or abs, assumes to be built-in module or installed in node-modules directory
- fs (file system) is one of most commonly used modules
- if you don’t pass encoding ‘utf8’, node will assume you are interested in binary data and will give you a Buffer object (array-like object containing numbers representing bytes”
- “http” module provide functionality for running HTTP servers and making HTTP requests
- can use to create simple server
- to act as an HTTP client, use request function in http module
- var http = require(“http”);
- var request = http.request({ hostname: “eloquentjavascript.net”, path: “/20_node.html”, method: “GET”, headers: {Accept: “text/html”} }, function(response) { console.log(“Server responded with status code”, response.statusCode);});
- request.end();
- can use streams to write in parts
- reading streams are done using event handlers instead of methods
- objects that emit events in node, have a method called “on” (like event listener)
- readable streams have “data” (when data comes in) and “end” (when over) events
Like this:
Like Loading...