~~SLIDESHOW~~ ====== Programming in JavaScript ====== **Contact Hour 8**: To be discussed on Wednesday 13th February, 2013. **Lecturer**: [[C.P.Jobling@Swansea.ac.uk|Dr Chris P. Jobling]]. Continuing our introduction to //JavaScript// with a look at control statements, objects, arrays and functions. ---- These slides and notes are based on Chapter 4 of Robert W. Sebasta, //Programming the World-Wide Web//, 3rd Edition, Addison Wesley, 2006. with additional examples and explanation from Chris Bates, //Web Programming: Building Internet Applications//, 3rd Edition, John Wiley, 2006. ===== Programming in JavaScript ===== We continue our quick tour of the basics of JavaScript. **Contents of this Lecture** * [[eg-259:lecture6#learning_outcomes_control_statements|Control Statements]] * [[eg-259:lecture6#learning_outcomes_objects|Objects]] * [[eg-259:lecture6#learning_outcomes_arrays|Arrays]] * [[eg-259:lecture6#learning_outcomes_functions|Functions]] * [[eg-259:lecture6#constructors|Constructors]] ===== Learning Outcomes — Control Statements ===== //At the end of this lecture you should be able to answer these questions//: - What is a control construct? - What are the three possible forms of control expressions in JavaScript? - What is the difference between ''=='' and ''===''? - What is the difference between a ''while'' statement and a ''do''-''while'' statement? ===== About the examples ===== I have decided to use [[http://jsfiddle.net|jsFiddle]] to host the examples for this session as this provides a nice way to demonstrate the code and for you to play with the code afterwards. If you want to run the examples yourself you can make use of the template HTML and CSS that has been provided in the [[http://localhost:4567/eg-259/examples/lecture6|examples folder]]. Use the script-tag in the provided HTML template to load the external JavaScript file for the example you wish to see run. ===== Control Statements ===== * Similar to C, Java, and C++ * Compound statements are delimited by braces, but compound statements are **//not//** blocks ===== Control Expressions ===== * Evaluate to ''true'' or ''false'' * Three kinds: * Primitive values * Relational expressions * Compound expressions ===== Primitive values ===== Primitive values can be interpreted as booleans (//truthy// values) * If it is a string, it is ''true'' unless it is empty or ''"0"'' * If it is a number, it is ''true'' unless it is zero * If it is ''null'' or ''undefined'' it is always ''false'' ===== Relational Expressions ===== * The usual six operators: ''=='', ''!='', ''<'', ''>'', ''%%<=%%'', ''%%>=%%'' * Operands are coerced if necessary * If one is a string and one is a number, it attempts to convert the string to a number * If one is Boolean and the other is not, the Boolean operand is coerced to a number (1 or 0) * The unusual two: ''==='' and ''!=='' * Same as ''=='' and ''!='', except that no coercions are done (operands must be identical) * Comparisons of references to objects are not useful (addresses are compared, not values) ---- Generally, for safety, you want to avoid coercion as it adds an element of uncertainty, use ''==='' and ''!=='' rather than ''=='' and ''!=''. ===== Compound Expressions ===== * The usual operators: ''&&'', ''||'', and ''!'' * The //Boolean// object has a method, ''toString'', to allow results of a control expression to be printed (''"true"'' or ''"false"'') ===== Selection Statements — if-then-else ===== * The usual ''if-then-else'' (clauses can be either single statements or compound statements) * See [[http://jsfiddle.net/cpjobling/8x8Ad/3/|jsFiddle]] ---- var a = 2, b = 4, element = $('#result'), message; if (a > b) { message = a + " is greater than " + b; console.log(message); element.append("

" + message + "

"); } else { message = a + " is not greater than " + b; console.log(message); element.append("

" + message + "

"); a = b; } message = "Now a === b is " + (a === b); console.log(message); element.append("

" + message + "

");
===== Selection Statements — Switch ===== * Similar to C and Java switch (expression) { case value_1: // value_1 statements case value_2: // value_2 statements . . . default: // default statements] } * The statements can be either statement sequences or compound statements * The control expression can be a number, a string, or a //Boolean// * Different cases can have values of different types * Fall-through like C and Java ... generally have to use ''break'' at the end of each condition ===== Example ===== Using a script to set the border properties of a table (See [[http://jsfiddle.net/cpjobling/AqtTV/6/|borders2.html]]). ---- 1. Initial dialogue {{eg-259:dialogue1.png|Initial dialogue}} 2. Result {{eg-259:l6-result1.png|Result of example 1}} 3. Code var bordersize, table, element; element = $('#result'); bordersize = prompt("Select a table border size \n" + "0 (no border) \n" + "1 (1 pixel border) \n" + "4 (4 pixel border) \n" + "8 (8 pixel border) \n"); table = ""; switch (bordersize) { case "0": table += ""; break; case "1": table += "
"; break; case "4": table += "
"; break; case "8": table += "
"; break; default: console.error("Error - invalid choice: " + bordersize + "\n"); table += "
"; } table += ""; table += "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
2003 NFL Divisional Winners
" + " American Conference National Conference
East New England Patriots Philadelphia Eagles
North Baltimore Ravens Green Bay Packers
West Kansas City Chiefs St. Louis Rams
South Indianapolis Colts Carolina Panthers
"; console.log(table); element.append(table);
===== Loop Statements ===== * ''while (control_expression) statement or compound'' * ''for (init; control; increment) statement or compound'' * init can have declarations, but the scope of such variables is the whole script * ''do-while'' do statement or compound while (control_expression) * Example: [[http://jsfiddle.net/cpjobling/8x8Ad/5/|date.html]]. ---- // date.js // Illustrates the use of the Date object by // displaying the parts of a current date and // using two Date objects to time a calculation var element = $('#result'); // Get the current date var today = new Date(); // Fetch the various parts of the date var dateString = today.toLocaleString(), day = today.getDay(), month = today.getMonth(), year = today.getFullYear(), timeMilliseconds = today.getTime(), hour = today.getHours(), minute = today.getMinutes(), second = today.getSeconds(), millisecond = today.getMilliseconds(); // Display the parts of the date element.append("

Date: " + dateString + "
" + "Day: " + day + "
" + "Month: " + month + "
" + "Year: " + year + "
" + "Time in milliseconds: " + timeMilliseconds + "
" + "Hour: " + hour + "
" + "Minute: " + minute + "
" + "Second: " + second + "
" + "Millisecond: " + millisecond + "

"); // Time a loop var dum1 = 1.00149265, product = 1; var start = new Date(); for (var count = 0; count < 10000; count++) { product = product + 1.000002 * dum1 / 1.00001; } var end = new Date(); var diff = end.getTime() - start.getTime(); element.append("

The loop took " + diff + " milliseconds

");
===== Learning Outcomes — Objects ===== //At the end of this lecture you should be able to answer these questions//: * What is the difference between a constructor in Java and one in JavaScript? * What properties does an object created with a ''new'' operator and the Object constructor have? * Describe the two ways the properties of an object can be referenced. * How is a new property of an object created? Lets [[http://jsfiddle.net/cpjobling/THrt4/4/|play with some objects]]. ===== Object Creation ===== * Objects can be created with ''new'' * The most basic object is one that uses the ''Object'' constructor, as in var myObject = new Object(); * The new object has no properties -- it is a blank object ===== Object Properties ===== * Properties can be added to an object, at any time var myAirplane = new Object(); myAirplane.make = "Cessna"; myAirplane.model = "Centurian"; ===== Object Modification ===== * Objects can be nested, so a property could be itself another object, created with ''new'' * Properties can be accessed by //dot// notation or in //array// notation, as in var property1 = myAirplane.make; var property2 = myAirplane["model"]; * Properties can be updated myAirplane.make = "Boeing"; myAirplane["model"] = "767"; * Properties can be deleted delete myAirplane.model; ===== Object Literals ===== * Objects can also be created using the //object notation//: var myAirplane = { make: "Cessna", model: "Centurion" }; ---- Please take careful note of the puctuation! ===== Another Loop Statement ===== * ''for (identifier in object) statement or compound'' * Example: for (var property in myAirplane) { console.log(property + ": " + myAirplane[property]); } ===== Learning Outcomes — Arrays ===== //At the end of this lecture you should be able to answer these questions//: * Describe the semantics of the ''for-in'' statement. * Describe the two ways an //Array// object can he created. * What relationship is there between the value of the ''length'' property of an Array object and the actual number of existing elements in the object? * Describe the semantics of the ''join'' method of ''Array''. * Describe the semantics of the ''slice'' method when it is given just one parameter. * What is the form of a nested array literal? Fiddle with [[http://jsfiddle.net/cpjobling/bJUZ2/4/|arrays]] ===== Arrays ===== * Objects with some special functionality * Array elements can be primitive values or references to other objects * Length is dynamic -- the ''length'' property stores the length * Array objects can be created in two ways, with ''new'', or by assigning an //array literal// var myList = new Array(24, "bread", true); var myList2 = [24, "bread", true]; var myList3 = new Array(24); ===== Array Length ===== * The length of an array is the highest subscript to which an element has been assigned, plus 1 myList[122] = "bitsy"; // length is 123 * Because the ''length'' property is //writeable//, you can set it to make the array any length you like, as in myList.length = 150; * Example [[http://jsfiddle.net/cpjobling/mKaqy/2/|insert_names.html]] ---- /* insert_names.html The script in this document has an array of names, name_list, whose values are in alphabetic order. New names are input through prompt. Each new name is inserted into the name array, after which the new list is displayed. */ // The original list of names var name_list = ["Al", "Betty", "Kasper", "Michael", "Roberto", "Zimbo"]; // working variables var new_name, index, last, result, element = $('#result'); // Loop to get a new name and insert it while (new_name = prompt("Please type a new name", "")) { // Loop to find the place for the new name last = name_list.length - 1; while (last >= 0 && name_list[last] > new_name) { name_list[last + 1] = name_list[last]; last--; } // Insert the new name into its spot in the array name_list[last + 1] = new_name; // Display the new array result = "

The new name list is:
"; element.append(); for (index = 0; index < name_list.length; index++) { result += name_list[index] + "
"; } result += "

"; element.append(result); } //** end of the outer while loop
===== Array methods ===== * ''join'' -- e.g., ''var listStr = list.join(", ");'' * ''reverse'' * ''sort'' -- e.g., ''names.sort();'' * Coerces elements to strings and puts them in alphabetical order * ''concat'' -- e.g., ''newList = list.concat(47, 26);'' ===== Array Methods (Continued) ===== * ''slice'' listPart = list.slice(2, 5); listPart2 = list.slice(2); * ''toString'' * Coerce elements to strings, if necessary, and concatenate them together, separated by commas (exactly like join(", ")) * ''push'', ''pop'', ''unshift'', and ''shift'' * Example: [[http://jsfiddle.net/cpjobling/XT4vg/1/|nested_arrays.html]] ---- // nested_arrays.html An example to illustrate an // array of arrays var element = $('#result'), result_text; // Create an array object with three arrays as its // elements var nested_array = [ [2, 4, 6], [1, 3, 5], [10, 20, 30] ]; // Display the elements of nested_list result_text = "

"; for (var row = 0; row <= 2; row++) { result_text += "Row " + row + ": "; for (var col = 0; col <= 2; col++) { result_text += nested_array[row][col] + " "; } result_text += "
"; } element.append(result_text + "

");
===== Learning Outcomes — Functions ===== //At the end of this lecture you should be able to answer these questions//: * What value is returned by a function that contains no ''return'' statement? * Define the scope of a variable in a JavaScript script embedded in an XHTML document when the variable is not declared in a function. * Is it possible to reference global variables in a JavaScript function? * What parameter-passing method does JavaScript use? * Does JavaScript check the types of actual parameters against the types of their corresponding formal parameters? * How can a function access actual parameter values for those actual parameters that do not correspond to any formal parameter? ===== Functions ===== * Declaration: function function_name([formal_parameters]) { -- body - } * Return value is the parameter of ''return'' statement * If there is no ''return'' statement, or if the end of the function is reached, ''undefined'' is returned * If ''return'' has no parameter, ''undefined'' is returned ===== Functions are Objects ===== * variables that reference functions can be treated as other object references * If ''fun'' is the name of a function, ref_fun = fun; // . . . ref_fun(); /* A call to fun */ ===== Defining Functions ===== * We place all function definitions in the head of the the HTML document * All variables that are either //implicitly// declared or //explicitly// declared outside functions are global * Variables explicitly declared in a function are local ===== Function Parameters ===== * Parameters are //passed by value//, but when a reference variable is passed, the **semantics** are //pass-by-reference// * There is no type checking of parameters, nor is the number of parameters checked (excess actual parameters are ignored, excess formal parameters are set to ''undefined'') * All parameters are sent through a property array, ''arguments'', which has the ''length'' property * Example: [[http://jsfiddle.net/cpjobling/m8JAL/6/|parameters.html]] ---- // parameters.html The params function and a test // driver for it. This example illustrates // function parameters var element = $('#result'); // Function describe_params // Parameters: two named parameters and one unnamed // parameter, all numbers // Returns: nothing function describe_params(a, b) { var text = "Function describe_params was passed " + arguments.length + " parameter(s)
" + "Parameter values are:
"; for (var arg = 0; arg < arguments.length; arg++) { text += arguments[arg] + "
"; } text += "In addition named-parameter a was " + a + " and b was " + b; return text; } // A text driver for params element.append("

" + describe_params("Mozart") + "

"); element.append("

" + describe_params("Mozart", "Beethoven") + "

"); element.append("

" + describe_params("Mozart", "Beethoven", "Tchaikowsky") + "

");
===== Passing a Function: Sorting ===== * To sort something other than strings into alphabetical order, write a function that performs the comparison and send it to the ''sort'' method * The comparison function must return a //negative number//, //zero//, or a //positive number// to indicate whether the order is //ok//, //equal//, or //not// function num_order(a, b) {return a - b;} * Now, we can sort an array named ''num_list'' with: num_list.sort(num_order); ===== Function: alternative declaration ===== Function as variable: * Declaration: var function_name = function ([formal_parameters]) { -- body - }; * Right-hand side of declaration is what's known as an //anonymous function//. * It is given a name by assigning it to a variable -- in this case ''function_name''. * This makes explicit the fact that a function is just another primitive in JavaScript. * You'll see this form used a lot in the [[http://www.codecademy.com/tracks/javascript|Codecademy JavaScript course]] and in the definition of event handlers and call-backs to come later. ===== Another Example ===== * [[http://jsfiddle.net/cpjobling/vwYGr/3/|medians.html]] ---- * output: {{eg-259:example1.png|Result of example}} * code // medians.js // A function and a function tester // Illustrates array operations var element = $('#result'); /* Function median Parameter: An array of numbers Return value: The median of the array */ var median = function (list) { list.sort(function (a, b) { return a - b; }); var list_len = list.length; // Use the modulus operator to determine whether // the array's length is odd or even // Use Math.floor to truncate numbers // Use Math.round to round numbers if ((list_len % 2) == 1) { return list[Math.floor(list_len / 2)]; } else { return Math.round((list[list_len / 2 - 1] + list[list_len / 2]) / 2); } }; // end of function median -- note semicolon var my_list_1 = [8, 3, 9, 1, 4, 7], my_list_2 = [10, -2, 0, 5, 3, 1, 7], med; med = median(my_list_1); element.append("

Median of [" + my_list_1 + "] is: " + med + "

"); med = median(my_list_2); element.append("

Median of [" + my_list_2 + "] is: " + med + "

");
===== Constructors ===== * Used to initialize objects, but actually create the properties function Plane(newMake, newModel, newYear){ this.make = newMake; this.model = newModel; this.year = newYear; } myPlane = new Plane("Cessna", "Centurian", "1970"); [[http://jsfiddle.net/cpjobling/s8kFw/6/|Fiddle with constructors]]. ---- Note by convention, constructors use upper case names to distinguish them from ordinary functions. Think //proper noun//. ===== Method Properties ===== * Can also have method properties. Add the following to the constructor: display: function() { console.log("Make: " + this.make); console.log("Model: " + this.model); console.log("Year: " + this.year); } * Use like this: myPlane.display(); ===== Summary of This Lecture ===== Programming in JavaScript * [[eg-259:lecture6#learning_outcomes_control_statements|Control Statements]] * [[eg-259:lecture6#learning_outcomes_objects|Objects]] * [[eg-259:lecture6#learning_outcomes_arrays|Arrays]] * [[eg-259:lecture6#learning_outcomes_functions|Functions]] * [[eg-259:lecture6#constructors|Constructors]] ===== Learning Outcomes — Control Statements ===== //At the end of this lecture you should be able to answer these questions//: - What is a control construct? - What are the three possible forms of control expressions in JavaScript? - What is the difference between ''=='' and ''===''? - What is the difference between a ''while'' statement and a ''do''-''while'' statement? ===== Learning Outcomes — Objects ===== //At the end of this lecture you should be able to answer these questions//: * What is the difference between a constructor in Java and one in JavaScript? * What properties does an object created with a ''new'' operator and the Object constructor have? * Describe the two ways the properties of an object can be referenced. * How is a new property of an object created? ===== Learning Outcomes — Arrays ===== //At the end of this lecture you should be able to answer these questions//: * Describe the semantics of the ''for-in'' statement. * Describe the two ways an //Array// object can he created. * What relationship is there between the value of the ''length'' property of an Array object and the actual number of existing elements in the object? * Describe the semantics of the ''join'' method of ''Array''. * Describe the semantics of the ''slice'' method when it is given just one parameter. * What is the form of a nested array literal? ===== Learning Outcomes — Functions ===== //At the end of this lecture you should be able to answer these questions//: * What value is returned by a function that contains no ''return'' statement? * Define the scope of a variable in a JavaScript script embedded in an XHTML document when the variable is not declared in a function. * Is it possible to reference global variables in a JavaScript function? * What parameter-passing method does JavaScript use? * Does JavaScript check the types of actual parameters against the types of their corresponding formal parameters? * How can a function access actual parameter values for those actual parameters that do not correspond to any formal parameter? There are a few more [[eg-259:review:javascript02|review questions]] available. You might need to refer to a good JavaScript reference to answer them all. ===== Exercises ===== Use jsFiddle or some other method to write, test and debug (if necessary) HTML files that include JavaScript scripts for the following problems. When required to write functions, you must include a script to test the function with at least two different data sets. - //Output//: A table of numbers from 5 to 15 and their squares and cubes, using alert. - //Output//: The first 20 Fibonacci numbers, which are defined as in the following sequence 1, 1, 2, 3, … where each number in the sequence is the sum of the two previous numbers. Use ''console.log'' to produce the output. - Modify the script of Exercise 2 to input a number, //n//, using ''prompt'', which is the number of the Fibonacci number required as output. - //Function//: ''no_zeros''; //Parameter//: An array of numbers; //Result//: The array must be modified to remove all zero values. //Returns//: ''true'' if the given array included zeros; ''false'' otherwise. ===== More Homework Exercises ===== More basic javascript exercises, taken from Chapter 4 of Robert W. Sebasta, //Programming the World-Wide Web//, 3rd Edition, Addison Wesley, 2006., are [[eg-259:homework:8|available]]. ===== What's Next? ===== Text processing with //regular expressions// * [[eg-259:lecture7#text_manipulation_in_javascript|Pattern Matching with Regular Expressions]] * [[eg-259:lecture7#another_example|Another Example]] * [[eg-259:lecture7#debugging_javascript|Debugging JavaScript]] [[eg-259:lecture5|Previous Lecture]] | [[eg-259:home]] | [[eg-259:lecture7|Next Lecture]]