Reading notes for Code Fellows!
To find the source of an error, it helps to know how scripts are processed. The order in which statements are executed can be complex; some tasks cannot complete until another statement or function has been run:
function greetUser() {
return 'Hello ' + getName();
}
function getName() {
var name = 'Molly';
return name;
}
var greeting = greetUser();
alert(greeting);
In the case above, the oder of execution is really :
greeting
variable gets its value from the greetUser()
function.greetUser()
creates the message by combining the string 'Hello '
with the result of getName()
.getName()
returns the name to greetUser()
.greetUser()
now knows the name, and combines it with the string. It then returns the message to the statements that called it in step 1.greeting
is stored in memory.greeting
variable is written to an alert
box.The JavaScript interpreter uses the concept of execution contexts. There is one global execution context. Each function creates a new execution context and these coorespond to variable scope.
Every script statement exists in one of three execution contexts:
eval()
.The first two execution contexts correspond with the notion of scope:
var
keyword when creating a variable, it is placed in global scope ( let, const )
1 Function-Level Scope - When a variable is declared within a function, it can only be used within that function. This is because it has function-level scope.The JavaScript interpreter processes one line of code at a time. When a statement needs data from another function, it stacks (or piles) the new function on top of the current task.
Each time a script enter a new execution context, there are two phases of activity:
Prepare
Execute
Understanding these two phases helps to understanding the concept of hoisting which is what lets us:
-Call functions before they have been declared (if they were created using function declarations - not function expressions)
In the interpreter, each execution context has its own variables object. It holds the variables, functions, and parameters available within it. Each execution context can also access its parent’s variables object.
If a JavaScript statement generates an error, then it *throws an exception*. At that point, the interpreter stops and looks for exception-handling code. If it reaches the global context without finding any , it will have to terminate the script and create an Error
object. Error objects can help us find where our mistakes are and browsers have tools to help us read them.
When an Error object is created, it will contain the following properties:
There are seven types of built-in error objects in JavaScript:
OBJECT | DESCRIPTION |
---|---|
Error |
Generic error - the other errors are all based upon this error |
SyntaxError |
Syntax has not been followed |
ReferenceError |
Tried to reference a variable that is not declared/within scope |
TypeError |
An unexpected data type that cannot be coerced |
RangeError |
Numbers not in acceptable range |
URIError |
encodeURI() , decodeURI() and similar methods used incorrectly |
EvalError |
eval() function used incorrectly |
document
objectwrite()
methodtoFixed()
can only be 0-20toPrecision()
can only be 1-21eval()
functionNow that we know what an error is and how the browser treats them, there are two things we can do with the errors.
try
, catch
, throw
, and finally
statements.Debugging is about deduction: eliminating potential causes of an error. Try to narrow down where the problem might be, then look for clues.
Where is the problem?
What exactly is the problem?