Javascript Tutorial

Loading
Try an online Javascript class for free!

Advanced Techniques

You can go very far in JavaScript using only the language basics that we have seen up to now but, to really unleash JavaScript's power, we need to get more familiar with a few programming techniques.

These techniques will help your code become more expressive and more reusable at the same time. They are programming patterns that leverage some language features that may not be present in other programming languages.

If you don't have experience with any other dynamically typed or functional language, the patterns you will see here may look very strange at first. But fear not, we will provide plenty of explanations and examples to allow you to practice as you learn.

Lesson Goals

  • To use the default operator.
  • To pass a flexible number of arguments to a function.
  • To pass a function as an argument to another function.
  • To create anonymous and inner functions.
  • To observe and capture events.
  • To catch and handle errors.

Lesson Activities

  1. Optional Function Arguments
  2. Truthy and Falsy
  3. Default Operator
  4. Functions Passed as Arguments
  5. Anonymous Functions
  6. Nested Functions
  7. Variable Scope
  8. Observing and Capturing Events
  9. The eval() Function
  10. Error Handling
  11. The delete Operator

Optional Function Arguments

When we declare a function in JavaScript, we normally include a list of the arguments the function expects.

Code Sample:

AdvancedTechniques/Demos/sumAll-1.html
---- C O D E   O M I T T E D ----
	function sumValues(val1, val2, val3) {
		return val1 + val2 + val3;
	}
---- C O D E   O M I T T E D ----

But this does not guarantee that our function will always be called with three arguments. It's perfectly valid for someone to call our function passing fewer or more than three arguments.

var result1 = sumValues(3, 5, 6, 2, 7);
var result2 = sumValues(12, 20);

Both calls will return surprising results (surprising from the caller's perspective).

In the first case, since we are not expecting more than three arguments, the extra values, 2 and 7, will simply be ignored. It's bad because the returned value is probably not what the calling code expected.

It's even worse when we look at the second example. We are passing only two arguments. What happens to val3? It will have the value of undefined. This will cause the resulting sum to be NaN, which is clearly undesirable.

Let's fix our function to deal with these types of situations.

Code Sample:

AdvancedTechniques/Demos/sumAll-2.html
---- C O D E   O M I T T E D ----

	function sumValues(val1, val2, val3) {
		if (val1 === undefined) {
			val1 = 0;
		}

		if (val2 === undefined) {
			val2 = 0;
		}

		if (val3 === undefined) {
			val3 = 0;
		}

		return val1 + val2 + val3;
	}

	var result1 = sumValues(3, 5, 6, 2, 7);
	var result2 = sumValues(12, 20);

	alert(result1);
	alert(result2);
---- C O D E   O M I T T E D ----

If we run our example again, we will see that we no longer get NaN for the second function call. Instead we get 32, which is probably what the calling code expected.

We now have a pretty robust function that adds three numbers but it still doesn't feel all that useful. Sooner or later we will need to add four or five numbers and we don't want to be updating our function to accept additional parameters. That would be a less than desirable maintenance task. Fortunately, JavaScript can help us with that too.

Every function, when called, has a variable called arguments, which is an array of all the arguments passed to the function. Back to our example, the first time we call sumValues, the arguments array will contain [3, 5, 6, 2, 7] and in the second call [12, 20].

What this means is that we can ignore the passed parameters altogether an deal only with the arguments array. Let's update our function once again.

Code Sample:

AdvancedTechniques/Demos/sumAll-3.html
---- C O D E   O M I T T E D ----

	function sumValues() {
		var sum = 0;
		for (var i = 0; i < arguments.length; i++) {
			sum += arguments[i];
		}
		return sum;
	}

	var result1 = sumValues(3, 5, 6, 2, 7);
	var result2 = sumValues(12, 20);

	alert(result1);
	alert(result2);
---- C O D E   O M I T T E D ----

Note how we got rid of the parameter list and now we get the values directly from the arguments array. When we run our example now we see that the returned values are correct and precisely what was expected by the caller. We now have a function that accepts as many parameters as are thrown at it and will always return the sum of all those arguments.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Truthy and Falsy

JavaScript, as we already know, has a boolean data type, which has only two possible values: true or false. Boolean expressions (e.g., a == b) also evaluate to a boolean value. But that's not the entire story.

When used in a boolean context (e.g, an if condition) non-boolean expressions are implicitly converted to booleans. This process is called Type Coercion. For example, in the expression if (1) { alert('Hi!') }, 1 is interpreted as true, so the alert will pop up. The value 1 is said to be truthy. The value 0, on the other hand, is said to be falsy.

When used in a context that expects a boolean value, any JavaScript expression can be used. See below:

Code Sample:

AdvancedTechniques/Demos/truthy-falsy.html
---- C O D E   O M I T T E D ----

var truthies = [
	"false",
	"0",
	-1,
	"null",
	"undefined",
	"NaN",
	5/0,
	Infinity
];

var foo;
var falsies = [
	null,
	undefined,
	foo,
	0,
	NaN,
	""
];
---- C O D E   O M I T T E D ----

	for (var t=0; t<truthies.length; t++) {
		document.write("<li>" + truthies[t] + " : " + Boolean(truthies[t]) + "</li>");
	}
---- C O D E   O M I T T E D ----

	for (var f=0; f<falsies.length; f++) {
		document.write("<li>" + falsies[f] + " : " + Boolean(falsies[f]) + "</li>");
	}
---- C O D E   O M I T T E D ----

Open the above page in a browser and you'll see how the different values get evaluated when implicitly converted to booleans. The table below shows how different values are converted:

Truthy-Falsy Values
Value Truthy-Falsy Explanation
0 falsy 0 is falsy.
"0" truthy Non-zero-length strings are truthy.
-1 truthy All numbers but 0 are truthy.
null falsy null is falsy.
"null" truthy Non-zero-length strings are truthy.
undefined falsy undefined is falsy.
"undefined" truthy Non-zero-length strings are truthy.
NaN falsy NaN is falsy.
"NaN" truthy Non-zero-length strings are truthy.
Infinity truthy Infinity is a reserved word and is a non-zero number.
5/0 truthy 5/0 evaluates to Infinity.
"" (empty string) falsy Zero-length strings are falsy.
"false" truthy Non-zero-length strings are truthy.

Type coercion is the reason we have the === (triple-equal or strictly equal) comparison operator in JavaScript. The regular equality operator == applies type coercion and sometimes your comparisons will not result as expected. Look at the following sample code:

Code Sample:

AdvancedTechniques/Demos/type-coercion.html
---- C O D E   O M I T T E D ----

var num = 0;
if (num == "") {
	alert('Hey, I did not expect to see this.');
}
if (num === "") {
	alert('This will not be displayed.');
}
---- C O D E   O M I T T E D ----

In the first if conditional, we compare two falsy values, and the type coercion will resolve both of them to false, causing the result of the comparison to be true, which is probably not the original intent of the code.

To detect the type difference (string vs. number) we would need to use the triple equal operator, as shown in the second if statement.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Default Operator

The boolean operators && and || also use truthy and falsy to resolve each of the operands to a boolean value.

From your previous experiences with other programming languages you may be led to believe that the result of a boolean operation is always true and false. This is not the case in JavaScript.

In JavaScript, the result of a boolean operation is the value of the operand that determined the result of the operation. Let's clarify that with an example:

Code Sample:

AdvancedTechniques/Demos/default-operator.html
---- C O D E   O M I T T E D ----

var a = 0, b = NaN, c = 1, d = "hi";
var result = ( a || b || c || d );
alert("Result: " + result);

result = ( d && c && b && a );
alert("Result: " + result);
---- C O D E   O M I T T E D ----

The first boolean expression ( a || b || c || d ) is evaluated from left to right until a conclusion is made. The || is the boolean OR operator, which only needs one of the operands to be true (truthy) for the operation result to be true:

  1. a is 0, which is falsy. The evaluation continues with the remaining operands because falsy doesn't determine anything yet. We need one truthy value for the whole statement to be true.
  2. b is NaN, also falsy. We have the same situation and we need to continue evaluating.
  3. c is 1,which is truthy. We no longer need to continue evaluating the remaining operands because we already know the expression will result true.

But here's the catch. Instead of resulting strictly true, it will result in the truthy value that ended the evaluation, the value of c in this case. The message displayed will be "Result: 1".

As you might already expect, the && (boolean AND operator) works in a similar fashion, but with opposite conditions. The AND operator returns the value of the last operand evaluated, which is either the first falsy operand or, in the case that all operands are truthy, the last operand in the expression. If for the expression ( d && c && b && a ) we follow the same sequence we did for the OR operator we will see that, d and c are both truthy so we need to keep going, then we get to b, which is falsy and causes the evaluation to stop and return b. The message displayed then is "Result: NaN".

You may be reading all this and thinking how can this be of any use. It turns out that this behavior of returning the first conclusive value can be very handy when ensuring that a variable is initialized.

Let's take a look at the function below.

function checkLength(text, min, max){
	min = min || 1;
	max = max || 10000;

	if (text.length < min || text.length > max) {
		return false;
	}
	return true;
}

The first two lines in this function make sure that min and max always have a valid value. This allows the function to be called like checkValue("abc"). In this case the min and max parameters will both start with the undefined value.

When we reach the line min = min || 1; we are simply assigning 1 to min, ensuring it overrides the undefined. Similarly we assign 1000 to max.

If we had passed actual values for these parameters as in checkLength("abc", 2, 10) these values would be kept because they are truthy.

With this usage of the || we are effectively providing default values for these two parameters. That's why this operator, in this context, is also called the Default Operator.

The default operator replaces more verbose code like:

if (min === undefined) {
	min = 1;
}

...becomes simply...

min = min || 1;

Here is another example of shortening your code using the default operator:

var contactInfo;
if (email) {
	contactInfo = email;
} else if (phone) {
	contactInfo = phone;
} else if (streetAddress) {
	contactInfo = streetAddress;
}

...is greatly shortened to...

var contactInfo = email || phone || streetAddress;

Default Operator Gotcha!

Be careful using the default operator with variables that can accept falsy values. The following example illustrates the danger:

Code Sample:

AdvancedTechniques/Demos/default-operator-gotcha.html
---- C O D E   O M I T T E D ----

function calculatePrice(basePrice, tax) {
	basePrice = basePrice || 0;
	tax = tax || .1; //default tax is 10%
	var price = (basePrice * (1 + tax)).toFixed(2);
	alert("The price including tax is " + price); 
}

calculatePrice(100, 0); //no tax
---- C O D E   O M I T T E D ----

The calculatePrice() function uses the default operator to set a default tax of .1. The problem comes when we pass 0 as the value for tax. Our intent is to indicate that there is no tax; however, because 0 is falsy, tax = tax || .1 evaluates to .1.

We can fix this by changing tax = tax || .1 to tax = (tax === 0) ? 0 : tax || .1;.

Like this Javascript tutorial? Try our self-paced online Javascript courses, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Functions Passed as Arguments

In JavaScript, functions are first-class objects. Functions aren't just an immutable block of code that can only be invoked. Rather, each function we declare becomes an object, with its own properties and methods, that can be passed around like any other object.

Let's see how we can use functions as parameters to other functions. Consider the following example:

Code Sample:

AdvancedTechniques/Demos/function-arguments.html
---- C O D E   O M I T T E D ----

	var values = [5, 2, 11, -7, 1];
		
	function add(a, b) {
		return a+b;
	}
				
	function multiply(a, b) {
		return a*b;
	}
		
	function combineAll(nums, initialValue, operation) {
		var runningResult = initialValue;
		for (var i=0; i < nums.length; i++) {
			runningResult = operation(runningResult, nums[i]); 
		}
		return runningResult;
	}
	
	var sum = combineAll(values, 0, add);
	var product = combineAll(values, 1, multiply);
	
	alert("Sum: " + sum);
	alert("Product: " + product);
---- C O D E   O M I T T E D ----

You may be wondering what the following function call means: var sum = combineAll(values, 0, add);. In this statement we are passing the function add as the third parameter of combineAll. We are not invokingadd yet, just passing a reference to it. Note that the open and close parenthesis aren't used after sum. That should serve as a tipoff that this is not a function invocation.

The line that ultimately invokes add is:

runningResult = operation(initialValue, nums[i]);

...which received a reference to add in the operation parameter. When operation is invoked, in reality, it is add that is getting called, returning the sum of the two values passed in.

This is a very important technique and the combineAll function is often called reduce. Take your time to review the code and run the example until you feel comfortable with it. We will be using this capability extensively in the remaining lessons.

Like this Javascript tutorial? Try our self-paced online Javascript courses, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Anonymous Functions

Going back to our previous example, the functions add and multiply are only referred to once, in each call to combineAll. Furthermore, if we stick to that pattern, we will need to create a new function for each new combination behavior we desire (e.g., concatenation) just so we can pass it to combineAll. That seems like too much overhead for such a simple thing.

Thankfully, we don't actually need to declare each of these functions. We don't even need to come up with names for them. JavaScript allow us to create functions on the spot, any time we need a function that will only be used in that location.

The syntax is rather compact:

function (arg1, arg2) {
	//function statements here
	}

Because functions created this way don't have names, they are aptly called anonymous functions.

Let's revisit our previous example and use anonymous functions to replace the single-use functions we declared:

Code Sample:

AdvancedTechniques/Demos/anon-func-arguments.html
---- C O D E   O M I T T E D ----

	var values = [5, 2, 11, -7, 1];
		
	function combineAll(nums, initialValue, operation) {
		var runningResult = initialValue;
		for (var i=0; i < nums.length; i++) {
			runningResult = operation(runningResult, nums[i]); 
		}
		return runningResult;
	}
		
	var sum = combineAll(values, 0, function (a, b) {
			return a+b;
		});
		
	var product = combineAll(values, 1, function (a, b) {
			return a*b;
		});
		
	var list = combineAll(values, 1, function (a, b) {
			return a + ", " + b;
		});
			
	alert("Sum: " + sum);
	alert("Product: " + product);
	alert("Number List: " + list);
---- C O D E   O M I T T E D ----

The highlighted code represent the three anonymous functions. The first two replace where we previously had add and multiply functions defined. The third anonymous functions is used to concatenate the integers into a comma separated list.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Nested Functions

Since functions in JavaScript are just one more type of object, we can create a function inside another function. These are called nested functions or inner functions.

The example below shows how to create and use a function inside another one:

Code Sample:

AdvancedTechniques/Demos/inner-functions.html
---- C O D E   O M I T T E D ----

	var values = [5, 2, 11, -7, 1];
		
	function combineAll(nums, initialValue, operator) {
		var runningResult = initialValue;
		for (var i=0; i < nums.length; i++) {
			runningResult = calculate(nums[i]); 
		}
		return runningResult;
		
		function calculate(num) {
			switch (operator.toLowerCase()) {
				case "+" :
					return runningResult + num;
				case "x" :
					return runningResult * num;
				case "*" :
					return runningResult * num;
				case "a" :
					return runningResult + ", " + num;
			}
		}
	}
		
	var sum = combineAll(values, 0, "+");
	var product = combineAll(values, 1, "x");
	var list = combineAll(values, 1, "a");
			
	alert("Sum: " + sum);
	alert("Product: " + product);
	alert("Number List: " + list);
---- C O D E   O M I T T E D ----

We will see more important uses of inner functions when we look at private members. For the time being, just notice how calculate() has access to operator and runningResult, which are scoped to the combineAll() function.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Variable Scope

Variables in JavaScript are declared with the var keyword and are either globally or locally scoped.

A variable is globally scoped if:

  1. It is declared outside of a function.
  2. It is used without being declared using the var keyword.

A variable is locally scoped if it is declared within a function using the var keyword.

Global variables are accessible from anywhere within of your JavaScript code.

Code Sample:

AdvancedTechniques/Demos/variable-scope.html
---- C O D E   O M I T T E D ----

	var maxNum; //global
	function prepare() {
		var maxNum = 5; //local to function
		//let's forget the "var" in the "for" declaration
		for (i=0; i <= maxNum; ++i) { //no var, so i will be global
			//do something
		}
	}
	
	prepare();
	alert(maxNum); //undefined
	alert(i); //5 (because it is globally scoped)
---- C O D E   O M I T T E D ----

Notice that maxNum is declared globally but not assigned a value. It is also declared within the prepare() function and assigned the value of 5. When we read the maxNum value after calling prepare(), we see that the value is undefined. That's because it's reading the global variable. We can't access the function variable from outside of the function.

We can access the i variable though. That's because we assigned a value to it within the function without declaring it using var.

JavaScript does not have block scope, so variables are never local to an if statment or a for loop.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Observing and Capturing Events

You are probably accustomed to using the HTML event handlers ("on" attributes) to capture events as in the demo below:

Code Sample:

AdvancedTechniques/Demos/onclick.html
---- C O D E   O M I T T E D ----

<ul>
	<li onclick="document.bgColor='red';">Red</li>
	<li onclick="document.bgColor='orange';">Orange</li>
	<li onclick="document.bgColor='green';">Green</li>
	<li onclick="document.bgColor='blue';">Blue</li>
</ul>
---- C O D E   O M I T T E D ----

It's better, however, to keep your JavaScript completely separate from your HTML. In a later lesson we'll learn more about unobtrusively attaching events to elements in the DOM to avoid using HTML event handlers.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

The eval() Function

The reason we are mentioning eval() in this lesson is to acknowledge its existence and to urge you not to use it. We will explain why, but first let's explain what it does.

eval compiles and executes a string containing JavaScript code. It can be a simple expression like "1 + 2" or a long and complex script, with functions and all.

Here's one example that is not too different from what we can find in live sites on the web.

Code Sample:

AdvancedTechniques/Demos/eval.html
---- C O D E   O M I T T E D ----

	function getProperty(objectName, propertyName) {
		var expression = objectName + "." + propertyName;
		var propertyValue = eval(expression);
		return propertyValue;
	}
	
	var prop = "title"; //assume this was given by the user
	alert(getProperty("document", prop)); 
---- C O D E   O M I T T E D ----

This function creates a JavaScript expression by concatenating an object name, with a dot and a property name. Then it uses eval() to evaluate that expression.

As we can see eval() is a powerful function, but it is also potentially dangerous and incredibly inefficient. It's dangerous because it's typically used to evaluate user entered input, which not always is a safe thing to do. It's inefficient because each call to eval() starts a JavaScript compiler.

The use of eval() normally reveals lack of knowledge from the developer that wrote the script. In the example above, we could have used the [ ] accessor for properties. The same effect would be obtained with alert(window[prop]); without having to fire up a compiler just to retrieve the property value.

Remember this: eval is evil. Avoid it as much as you can. If you think you need it, maybe it's because you did not learn yet about an alternative way in JavaScript.

Like this Javascript tutorial? Try our self-paced online Javascript courses, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Error Handling

No matter how careful you are, it always seems that errors find their way into your code. Sometimes they are runtime errors caused by unpredicted scenarios. Sometimes the errors are just incorrect behavior of your code, popularly known as bugs.

Fortunately, we have tools to deal with either type of problem. In this lesson we will talk about detecting and handling errors, debugging and fixing bugs in our applications.

Runtime Errors

Web browsers are such a hostile environment that it is almost guaranteed that we will constantly deal with runtime errors. Users provide invalid input in ways you didn't think of. New browser versions change their behavior. Ajax calls can fail for any number of reasons.

Many times we cannot prevent runtime errors from happening, but at least we can deal with them in a manner that makes the user experience less traumatic.

Unhandled Errors

Look at this seemingly trivial code sample:

Code Sample:

AdvancedTechniques/Demos/simple-bug.html
---- C O D E   O M I T T E D ----

function getInput() {
	var name = prompt('Type your name');
	alert('Your name has ' + name.length + ' letters.');
}
getInput();
---- C O D E   O M I T T E D ----

It may not be obvious, but this code has a bug waiting to break free. If the user clicks Cancel or presses Esc the prompt() function will return null, which will cause the next line to fail with a null reference error.

If you as a programmer don't take any step to deal with this error, it will simply be delivered directly to the end user, in the form of a utterly useless browser error message like the one below: Error dialog

Depending on the user's browser or settings, the error message may be suppressed and only an inconspicuous icon shows up in the status bar: Error icon This can be worse than the error message, leaving users thinking the application is unresponsive.

Globally Handled Errors

The window object has an event called onerror that is invoked whenever there's an unhandled error on the page.

Code Sample:

AdvancedTechniques/Demos/simple-bug-onerror.html
---- C O D E   O M I T T E D ----

window.onerror = function (message, url, lineNo) {
	alert(
		'Error: ' + message + 
		'\n Url: ' + url + 
		'\n Line Number: ' + lineNo);
	return true;			
}

function getInput() {
	var name = prompt('Type your name');
	alert('Your name has ' + name.length + ' letters.');
}
getInput();
---- C O D E   O M I T T E D ----

As you can see, the event will pass three arguments to the invoked function. The first one is the actual error message. The second one is the URL of the file containing the error (useful if the error is in an external .js file.) The last argument is the line number in that file where the error happened.

Returning true tells the browser that you have taken care of the problem. If you return false instead, the browser will proceed to treat the error as unhandled, showing the error message and the status bar icon.

Here's the message box that we will be showing to the user: Error message

Structured Error Handling

The best way to deal with errors is to detect them as close as possible to where they occur. This will increase the chance that we know what to do with the error. To that effect JavaScript implements structured error handling, via the try...catch...finally block, which is also present in many other languages:

try {
	//try statements
} catch (error) {
	//catch statements
} finally {
	//finally statements
}

The idea is simple. If anything goes wrong in the statements that are inside the try block, then the statements in the catch block will be executed and the error will be passed into the error variable. The finally block is optional and, if present, is always executed last, whether or not an error is caught.

Let's fix our example to catch that error:

Code Sample:

AdvancedTechniques/Demos/simple-bug-try-catch.html
---- C O D E   O M I T T E D ----

window.onerror = function (message, url, lineNo) {
	alert(
		'Error: ' + message + 
		'\n Url: ' + url + 
		'\n Line Number: ' + lineNo);
	return true;			
}

function getInput() {
	try {
		var name = window.prompt('Type your name');
		alert('Your name has ' + name.length + ' letters.');			
	} catch (error) {
		alert('The error was: ' + error.name + 
		'\n The error message was: ' + error.message);
	} finally {
		//do cleanup
	}
}
getInput();
---- C O D E   O M I T T E D ----

The error object has two important properties: name and message. The message property contains the same error message that we have seen before. The name property contains the kind of error that happened and we can use that to decide if we know what to do with that error.

With that in place, if we reload the page and cancel out of the prompt, we will get the following alert: Error message

It's good programming practice to only handle the error on the spot if you are certain of what it is and if you actually have a way to take care of it (other than just suppressing it altogether.) To better target our error handling code, we will change it to only handle errors named "TypeError", which is the error name that we have identified for this bug.

Code Sample:

AdvancedTechniques/Demos/simple-bug-try-catch-specific.html
---- C O D E   O M I T T E D ----

window.onerror = function (message, url, lineNo) {
	alert(
		'Error: ' + message + 
		'\n Url: ' + url + 
		'\n Line Number: ' + lineNo);
	return true;			
}

function getInput() {
	try {
		var name = window.prompt('Type your name');
		alert('Your name has ' + name.length + ' letters.');			
	} catch (error) {
		if (error.name == 'TypeError') {
			alert('Please try again.');
			getInput();
		} else	{
			throw error;
		}
	} finally {
		//do cleanup
	}
}
getInput();
---- C O D E   O M I T T E D ----

Now if a different error happens, which is admittedly unlikely in this simple example, that error will not be handled. The throw statement will forward the error as if we never had this try...catch...finally block. It is said that the error will bubble up.

Throwing Custom Errors

We can use the throw statement to throw our own types of errors. The only recommendation is that our error object also has a name and message properties to be consistent with the built-in error handling.

throw {
	name: 'InvalidColorError', 
	message: 'The given color is not a valid color value.'
};

Like this Javascript tutorial? Try our self-paced online Javascript courses, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

The delete Operator

The delete operator is used to delete properties of objects and elements of arrays. Deleting is different from setting the value to null. The former removes the property or element (i.e, makes it undefined) while the latter keeps the property or element, but sets its value to null. The following example illustrates this.

Code Sample:

AdvancedTechniques/Demos/delete.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
	var colors = [];
	colors["red"] = "#f00";
	colors["green"] = "#060";
	colors["blue"] = "#00f";
	colors["yellow"] = "#ff0";
	colors["orange"] = "#0ff";
	
	function deleteItem() {
		delete colors["blue"];
		showArray();
		revealArray();
	}
	
	function setToNull() {
		colors["blue"] = null;
		showArray();
		revealArray();
	}
	
	function showArray() {
		var output = document.getElementById("colors");
		var strOutput = "<ol>";
		for (var i in colors) {
			strOutput += "<li style='color:" + colors[i] + ";'>" + i + "</li>";
		}
		strOutput += "</ol>";
		output.innerHTML=strOutput;
	}
	
	function revealArray() {
		var colorsCode = document.getElementById("colors-code");
		var strOutput = "&lt;ol&gt;";
		for (var i in colors) {
			strOutput+="\n\t&lt;li style='color:" + colors[i] + ";'&gt;" + i + "&lt;/li&gt;";
		}
		strOutput += "\n&lt;/ol&gt;";	
		colorsCode.innerHTML=strOutput;
	}
</script>
<title>Delete vs. Setting to NULL</title>
</head>
<body onload="showArray();revealArray();">
<button id="set-to-null" onclick="setToNull();">Set Blue to Null</button>
<button id="del" onclick="deleteItem();">Delete Blue</button>
<output id="colors"></output>
<pre id="colors-code"></pre>
</body>
</html>

Don't worry about the showArray() and revealArray() functions yet. Just note that when you click the Set Blue to Null button, the array element stays, but becomes an invalid color: null. When you click the Delete Blue button, the array element is removed.

Like this Javascript tutorial? Try our self-paced online Javascript course, which includes videos and exercises in addition to the content in this Javascript tutorial. Not sure if you want to pay for that? Register for a free demo of the course.

Continue to the next lesson on Regular Expressions »

Try an online Javascript class for free!

Table of Contents

Quick JavaScript Recap

  1. Primitive data types
  2. Native Types
  3. Functions
  4. The DOM
  5. The XMLHttpRequest object
  6. JSON

Advanced Techniques

  1. Optional Function Arguments
  2. Truthy and Falsy
  3. Default Operator
  4. Functions Passed as Arguments
  5. Anonymous Functions
  6. Nested Functions
  7. Variable Scope
  8. Observing and Capturing Events
  9. The eval() Function
  10. Error Handling
  11. The delete Operator

Regular Expressions

  1. Getting Started
  2. Regular Expression Syntax
  3. Backreferences
  4. Form Validation with Regular Expressions
  5. Cleaning Up Form Entries

The HTML Document Object Model

  1. innerHTML
  2. Accessing Element Nodes
  3. Attaching Events
  4. Event Propagation: Capturing and Bubbling
  5. Detaching Events
  6. Accessing Attribute Nodes
  7. Accessing Nodes by Type, Name or Value
  8. Removing Nodes from the DOM
  9. Creating New Nodes
  10. Identifying the Target of an Event

Dynamic Forms

  1. Jump Menus
  2. Adding Options to a Select Menu
  3. Cascading Select Menus
  4. Creating a JavaScript Timer
  5. A Sample Quiz Tool

Dynamic HTML

  1. Introduction
  2. Accessing and Modifying Styles
  3. Hiding and Showing Elements
  4. Manipulating Tables
  5. Dynamically Changing Dimensions
  6. Positioning Elements Dynamically
  7. Changing the Z-Index
  8. A Note on JavaScript Frameworks
  9. JavaScript style Properties

Webucator Tutorials

Webucator Courses

Webucator Training

Self-Paced Training

This page was last updated on 2013-01-03

All pages and graphics in this Javascript Tutorial is copyright 2013 and are the property of Webucator, Inc. unless otherwise specified. The purpose of this website is to help you learn Javascript on your own and use of the website implies your agreement to our Terms of Service.