Functions and Objects

Similar documents
Variables and Typing

CSCE 120: Learning To Code

Intro. Scheme Basics. scm> 5 5. scm>

Intro to Programming. Unit 7. What is Programming? What is Programming? Intro to Programming

C++ Data Types. 1 Simple C++ Data Types 2. 3 Numeric Types Integers (whole numbers) Decimal Numbers... 5

Variables and Constants

Mobile Computing Professor Pushpendra Singh Indraprastha Institute of Information Technology Delhi Java Basics Lecture 02

CS1046 Lab 4. Timing: This lab should take you 85 to 130 minutes. Objectives: By the end of this lab you should be able to:

Racket Style Guide Fall 2017

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

Lecture 05 I/O statements Printf, Scanf Simple statements, Compound statements

Web Site Design and Development JavaScript

Lab # 2. For today s lab:

(Refer Slide Time: 01:12)

JavaScript. Like PHP, JavaScript is a modern programming language that is derived from the syntax at C.

LOOPS. Repetition using the while statement

CMPT 100 : INTRODUCTION TO

JavaScript. History. Adding JavaScript to a page. CS144: Web Applications

CS/IT 114 Introduction to Java, Part 1 FALL 2016 CLASS 8: SEP. 29TH INSTRUCTOR: JIAYIN WANG

Princess Nourah bint Abdulrahman University. Computer Sciences Department

TOPIC 2 INTRODUCTION TO JAVA AND DR JAVA

6.001 Notes: Section 8.1

JavaScript. History. Adding JavaScript to a page. CS144: Web Applications

COMS 469: Interactive Media II

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

JME Language Reference Manual

R programming I expressions, variables, and data types. Luigi Cerulo University of Sannio

Working with JavaScript

JavaScript Basics. The Big Picture

3 The Building Blocks: Data Types, Literals, and Variables

Expressions and Variables

Coding Workshop. Learning to Program with an Arduino. Lecture Notes. Programming Introduction Values Assignment Arithmetic.

B l o c k B i n d i n g s

Excel Basics Rice Digital Media Commons Guide Written for Microsoft Excel 2010 Windows Edition by Eric Miller

CSC Web Programming. Introduction to JavaScript

CGS 3066: Spring 2015 JavaScript Reference

Overview of the Ruby Language. By Ron Haley

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

Functional Programming in Haskell Prof. Madhavan Mukund and S. P. Suresh Chennai Mathematical Institute

HTML5 and CSS3 More JavaScript Page 1

String Computation Program

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #43. Multidimensional Arrays

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

Web Application Development

Sprite an animation manipulation language Language Reference Manual

Math Modeling in Java: An S-I Compartment Model

Algorithmic Thinking and Structured Programming (in Greenfoot) Teachers: Renske Smetsers-Weeda Sjaak Smetsers Ana Tanase

9. MATHEMATICIANS ARE FOND OF COLLECTIONS

Lesson 1: Writing Your First JavaScript

CS/IT 114 Introduction to Java, Part 1 FALL 2016 CLASS 3: SEP. 13TH INSTRUCTOR: JIAYIN WANG

CONTENTS: Arrays Strings. COMP-202 Unit 5: Loops in Practice

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #29 Arrays in C

OUTLINES. Variable names in MATLAB. Matrices, Vectors and Scalar. Entering a vector Colon operator ( : ) Mathematical operations on vectors.

Assessment - Unit 3 lessons 16-21

Contents. Jairo Pava COMS W4115 June 28, 2013 LEARN: Language Reference Manual

CS/IT 114 Introduction to Java, Part 1 FALL 2016 CLASS 10: OCT. 6TH INSTRUCTOR: JIAYIN WANG

Programming with Python

5. Control Statements

Python for Analytics. Python Fundamentals RSI Chapters 1 and 2

Matrices. Chapter Matrix A Mathematical Definition Matrix Dimensions and Notation

(Refer Slide Time 01:41 min)

6.001 Notes: Section 15.1

Pace University. Fundamental Concepts of CS121 1

IDM 231. Functions, Objects and Methods

Chapter 2. Designing a Program. Input, Processing, and Output Fall 2016, CSUS. Chapter 2.1

JavaScript I Language Basics

Scripting with Praat. Day 3: Make Praat make decisions for you! 1

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Microsoft Office Excel Training

Fortunately, you only need to know 10% of what's in the main page to get 90% of the benefit. This page will show you that 10%.

Client-Side Web Technologies. JavaScript Part I

FUNCTIONS. The Anatomy of a Function Definition. In its most basic form, a function definition looks like this: function square(x) { return x * x; }

ACORN.COM CS 1110 SPRING 2012: ASSIGNMENT A1

S206E Lecture 19, 5/24/2016, Python an overview

How To Think Like A Computer Scientist, chapter 3; chapter 6, sections

PHP and MySQL for Dynamic Web Sites. Intro Ed Crowley

CSCE 120: Learning To Code

Unit E Step-by-Step: Programming with Python

MIT AITI Python Software Development

printf( Please enter another number: ); scanf( %d, &num2);

These are notes for the third lecture; if statements and loops.

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

6.001 Notes: Section 6.1

8. Control statements

First-Order Translation Checklist

Software Testing Prof. Meenakshi D Souza Department of Computer Science and Engineering International Institute of Information Technology, Bangalore

Binghamton University. CS-211 Fall Syntax. What the Compiler needs to understand your program

Week 2: The Clojure Language. Background Basic structure A few of the most useful facilities. A modernized Lisp. An insider's opinion

Definition: A data structure is a way of organizing data in a computer so that it can be used efficiently.

1.2 Real Numbers. Objectives In this section, you will learn to:

Lecture 5. Defining Functions

egrapher Language Reference Manual

Session 3: JavaScript - Structured Programming

CS 231 Data Structures and Algorithms, Fall 2016

Syntax and Variables

Background. Javascript is not related to Java in anyway other than trying to get some free publicity

Monday. A few notes on homework I want ONE spreadsheet with TWO tabs

CSE143 Notes for Monday, 7/06/15

COMP-202 Unit 2: Java Basics. CONTENTS: Using Expressions and Variables Types Strings Methods

Have examined process Creating program Have developed program Written in C Source code

Transcription:

Functions and Objects Christopher M. Harden Contents 1 Arrays 2 1.1 Defining arrays.......................... 2 1.2 Array length............................ 3 1.3 Multi-dimensional arrays..................... 5 2 Functions 6 2.1 Defining and calling functions.................. 6 2.2 Parameters and return values.................. 7 3 Objects 8 3.1 Creating and using objects.................... 9 3.2 The in keyword.......................... 10 4 The function/object relationship 11 4.1 First-class objects......................... 11 4.2 Closures.............................. 13 4.3 Constructors............................ 14 4.4 Methods.............................. 15 4.5 Constant objects......................... 16 5 Try it yourself 17 1

1 Arrays It is often convenient to be able to store multiple pieces of data in a single variable. An example of this would be a list of ingredients. While it would be possible to create multiple variables such as var firstingredient, var secondingredient, var thirdingredient, and so on, this is not easy to work with inside a script. A better way would be to have an ingredients list, and then refer to the first, second, and third ingredient in the list. 1.1 Defining arrays An array is how we store lists in JavaScript. Arrays are declared with square brackets. Inside the square brackets goes your list of items, separated by commas. You can store any type of variable inside an array, and each item in an array can have a different type. However, unlike other types, JavaScript will not automatically turn the previously mentioned types into an array. Thus you will sometimes see empty arrays being assigned to variables, such as var ingredients = [], if the list of ingredients is not known in advance. Once you have an array you use square brackets to retrieve the data inside them. This process is called indexing. Arrays have integer indexes starting from 0. Thus the first element has index 0, the second element has index 1, and so on. For example, to get the second ingredient in a list (stored in an array) you would write ingredients [1]. Note. The fact that humans count from 1 and computers count from 0 is an endless source of bugs and errors. The reason for computers counting from 0 is historical and comes from earlier, lower-level programming languages such as C. For example, in C, memory is accessed via its address, which is an integer representing blocks of memory. An array would simply be a continuous block of memory, and you would be given the address of the first block. Thus to access the first element, you would look up that address. To access the second element, you would add 1 to the address and then loop it up. To access the third element, you would add 2 before looking up, and so on. As you can see, to get element n you would add n 1 to the address, and from this it is easy to see why counting from 0 makes sense. JavaScript is not bound by the same restrictions as C, but counts from 0 anyway as tradition. Simply put, it is a convention you will get used to over time. Once you have indexed the array you have a regular variable just like in previous classes. Just like normal you can assign to it or use it in various calculations. If you happen to index an element that doesn t exist, JavaScript 2

returns undefined since no data was stored there. Listing 1 gives a quick overview of this as a small script. 1 var emptyarray = [ ] ; Listing 1: Using arrays 2 var mixedarray = [ "Peter", 17, "Glasgow" ] ; 3 4 var daysofweek = [ 5 "Sunday", 6 "Monday", 7 "Tuesday", 8 "Wednesday", 9 "Thursday", 10 "Friday", 11 " Saturday" 12 ] ; 13 14 a l e r t ( "Today is " + daysofweek [ 2 ] ) ; // Tuesday 15 16 // Make Peter older 17 mixedarray [ 1 ] = 1 8 ; 18 19 // Demonstrating that you can store whatever you like 20 // inside an array 21 c o n s o l e. l o g ( typeof mixedarray [ 0 ] ) ; // "string" 22 c o n s o l e. l o g ( typeof mixedarray [ 1 ] ) ; // "number" 23 c o n s o l e. l o g ( typeof mixedarray [ 2 ] ) ; // "string" 24 25 // Shows you the entire array. 26 // Format depends on web browser 27 c o n s o l e. l o g ( mixedarray ) ; 1.2 Array length Looping constructs are often seen whenever arrays are used. Arrays are generally used to store related data, and so there is often a need to do some particular action on every element of an array. However, to loop over an array we need to know what indexes there are in the array, and we can only know that if we know its size. In most cases we cannot assume the array s size. Fortunately, JavaScript gives us a way to simply ask the array itself, 3

since it knows how many elements it has inside it. If arr is an array then arr.length will tell us the size of arr. More specifically, it returns the smallest integer n such that arr[m] is undefined for all m n. Listing 2 has a named block called makearray, which creates an array of random size representing a list of people and randomly decides whether that person is male or not. This named block is supposed to represent some code somewhere else in a script. Consequently, the size of the array is lost after the makearray block ends due to scoping. However, in the usearray block, we can still loop over the array since we can directly ask the array for its own size. We use this to count the number of males in the list. 1 var ismale = [ ] ; 2 3 makearray : { Listing 2: Iterating over an array 4 const numberofpeople = Math. f l o o r (100 Math. random ( ) + 1) ; 5 f o r ( l e t i = 0 ; i < numberofpeople ; i++) { 6 ismale [ i ] = (Math. random ( ) < 0. 5 ) ; 7 } 8 } 9 10 usearray : { 11 var numberofmales = 0 ; 12 13 f o r ( l e t i = 0 ; i < ismale. length ; i++) { 14 i f ( ismale [ i ] ) numberofmales++; 15 } 16 17 c o n s o l e. l o g ( "There are " + numberofmales + " males." ) ; 18 } Since JavaScript allows you to store anything inside an array, that includes undefined. This means that you can skip indexes if you so choose. As mentioned before, these undefined indexes have value undefined. However the words size and length are no longer interchangeable. Listing 3 creates two arrays with length 5, but one of the arrays only has 4 items in it. This is why length was defined above in terms of the smallest number with a given property, since the naïve definition based on the number of elements (i.e. size) can be misleading. 4

Note. It goes without saying that because of this you should not skip indexes without a very good reason. 1 var a r r = [ 1, 2, 3, 4, 5 ] ; 2 Listing 3: Size vs Length 3 // Demonstrate that this array has 5 elements 4 c o n s o l e. l o g ( a r r ) ; 5 c o n s o l e. l o g ( a r r. length ) ; 6 7 // Redefining arr. Notice how I skip arr[2] 8 a r r = [ ] ; 9 a r r [ 0 ] = 1 ; 10 a r r [ 1 ] = 2 ; 11 a r r [ 3 ] = 3 ; 12 a r r [ 4 ] = 4 ; 13 14 // Now arr has 4 elements, but it is still of length 5 15 c o n s o l e. l o g ( a r r ) ; 16 c o n s o l e. l o g ( a r r. length ) ; 1.3 Multi-dimensional arrays As mentioned a few times previously, JavaScript arrays can store anything. In particular, an array can store other arrays. This is called a multi-dimensional array, and is often used for storing tabular data. If arr [0] contains an array, then you can immediately index again to get the contents of that array. For example, arr [0][2] will grab the first row of arr, and then get the third column of that row. Listing 4 uses this to create a three-dimensional array. This array represents the seating arrangements at a wedding. There are three tables, each table has two sides, and each side has three chairs. White space is added to the array to line up the opening and closing brackets, to make sure we don t accidentally miss one. 1 var s e a t i n g = [ 2 [ 3 [ Listing 4: A three-dimensional array 4 [ "Peter", "David", "Mark" ], 5 [ "May", "Helen", "Jill" ] 5

6 ] 7 ], 8 [ 9 [ 10 [ "Natasha", "Roxanne", "Lana" ], 11 [ "Scott", "Emmet", "Darren" ] 12 ] 13 ], 14 [ 15 [ 16 [ "Francis", "Christina", "Cedric" ], 17 [ "Nicole", "Albert", "Shelia" ] 18 ] 19 ] 20 ] ; 21 22 // Who is sitting on the third table, in the middle of the right side? 23 c o n s o l e. l o g ( s e a t i n g [ 2 ] [ 1 ] [ 1 ] ) 2 Functions In previous exercises we have seen things such as alert (), console. log(), Math.random() and so on. In the case of Math.random(), it gives us random numbers between 0 and 1, including 0 and excluding 1. While we could in theory look up the mathematical theory of Mersenne Twisters and reimplement that algorithm ourselves in every single script we write, it is not advised. Generating random numbers is a surprisingly difficult task, and mistakes may not be spotted over thousands of runs of our scripts. The far superior option is to have somebody with experience with mathematics write this algorithm for us, and we simply call it as needed. Our first step into such code reuse is the idea of a function. 2.1 Defining and calling functions Functions come in two parts: the definition and the calling. Listing 5 shows a function definition. Line 1 starts with the function keyword, telling the JavaScript interpreter that a function is about to be defined. Next comes the name of the function, which you may define just like every other identifier. 6

Next comes a matching pair of parentheses, which becomes important later. Finally there is a block containing some code. Listing 5: Defining a function 1 function h e l l o ( ) { 2 a l e r t ( "Hello everyone!" ) ; 3 } Whenever you wish to run the function, you call it with hello () ;. You can call it as many times as you wish, and the function will run every time. 2.2 Parameters and return values Listing 5 is a simple function that doesn t do very much. It has no data to work with, so it does the same thing over and over. Data can be passed into a function via its parameters. You may take as many parameters as you want. To take parameters, you add a comma separated list of variable names between the set of parentheses mentioned before. Inside your function you may use these variables just like any other variables you have used before. You may also define your own variables inside a function. Any variables you define inside a function are scoped to that function. Thus you will not accidentally overwrite any variables outside the function. Note. Consider the inside of a function as a clean space. You may do whatever you like inside the function, without affecting the outside world. There are various tricks to break the confines of a function and affect the outside world, but you should avoid them. There is almost never a good reason to do this, and it makes it difficult to know what your function will do if you do. Breaking this promise tends to result in actions at a distance, where (for example) your image gallery happens to break randomly because an analytic script you use that was written by another company in another language in another country just happens to have picked the same variable name. Functions may also return a single value. For example, Math.random() should give you the random number it generated. To do that we have the return keyword, which immediately ends the function. If anything follows return it becomes the return value of the function. If the return keyword is by itself, the function returns nothing. Note. Of course, using arrays (and objects, which are mentioned later) as a return value means that your single return value actually consists of multiple pieces of data. So there is never a need to return multiple values. 7

When you call a function, you may fill in parameters between the parenthesis, and use the function to get a return value. If you do not fill in all the parameters the rest automatically default to undefined. Similarly, if the function does not return a value then you are given undefined. Note. You can define a function to default to a different value. Unfortunately this is not common across all web browsers. If you wish to take optional parameters, you will need to define a default inside your function using code similar to the following: 1 var data = ( param === undefined )? d e f a u l t : param Listing 6 uses the above to calculate the area of 5 circles of random radius. A function is defined that deals with finding the area of a circle, using its own copy of π to 50 decimal places just in case another function is using a different approximation. Listing 6: Defining a function 1 function a r e a O f C i r c l e ( r a d i u s ) { 2 const pi = 3.14159265358979323846264338327950288419716939937510; 3 return pi r a d i u s r a d i u s ; 4 } 5 6 f o r ( l e t i = 0 ; i < 5 ; i++) { 7 let r = Math. f l o o r (100 Math. random ( ) + 1) ; 8 let a = a r e a O f C i r c l e ( r ) ; 9 10 c o n s o l e. l o g ( 11 "Radius: " + b 12 + ", Area: " + a 13 ) ; 14 } 3 Objects Arrays are useful for storing data that has some natural order to it. Objects can be considered to be a more general version of an array, which is appropriate for representing more complicated data. Objects associate a string, called a key, with a value. While all keys are strings the values associated 8

with these keys can be any JavaScript type. In particular this includes arrays and other objects. 3.1 Creating and using objects Objects can be initialized with curly brackets. Inside these brackets are a comma separated list of key-value pairs separated by a colon. Since keys are automatically strings, you do not need to quote them if they do not contain symbols such as spaces. Objects are indexed just like arrays. However, if the key is known in advance and it satisfies the requirements to be a JavaScript identifier, you may use dot notation instead. Dot notation is preferred when available. Just like with arrays non-existent keys will return undefined. If you have no more use for a key, delete obj.key will delete key and its value from obj. Listing 7 represents three people as objects and shuffles their relationships around. 1 var stephen = { 2 name : "Stephen", 3 age : 23 4 } ; 5 var j e s s i c a = { 6 name : "Jessica", 7 age : 21 8 } ; 9 var samantha = { 10 name : "Samantha", 11 age : 28 12 } ; 13 Listing 7: Representing people as objects 14 c o n s o l e. l o g ( stephen [ "name" ] ) ; 15 c o n s o l e. l o g ( stephen. age ) ; 16 17 // Create a two way relationship 18 stephen. l i k e s = j e s s i c a ; 19 j e s s i c a. l i k e s = stephen ; 20 // And a one way relationship 21 samantha. l i k e s = j e s s i c a ; 22 23 // And now we make this love story more complicated 9

24 d e l e t e stephen. l i k e s ; 25 samantha. l i k e s = stephen ; 26 27 c o n s o l e. l o g ( j e s s i c a. name + " likes " + j e s s i c a. l i k e s. name) ; 28 c o n s o l e. l o g ( samantha. name + " likes " + samantha. l i k e s. name) ; 3.2 The in keyword Since keys can be added and removed from an object at will, we need a way to check whether or not a key exists in a given object. The in keyword is used to test for a key s existence. It takes the form key in obj. Since keys are strings you almost always want to quote key in double quotes, unless you actually want to look for the string inside the variable key as the test key. Note. Since undefined keys return undefined when accessed, you might think that testing for undefined will tell you if a key exists or not. However this is not true. There is nothing stopping you from declaring a key with a value of undefined. This key exists, but its value does not. However without using in you cannot tell the difference! The in keyword also serves a second purpose inside a for loop. It can be used to get all the keys of an object. This allows you to check the contents of an object. Listing 8 uses objects inside objects to represent people attending a party, and whether or not they are vegetarian or suffer from a nut allergy. We count the number of vegetarians attending so the chefs can prepare in advance. We also emit a warning if anyone has listed themselves as having a nut allergy, since even accidental contamination can be fatal. 1 var f o o d P r e f s = { Listing 8: Iterating over an object 2 Stacy : { v e g g i e : true, nut : f a l s e }, 3 N i c o l e : { v e g g i e : false, nut : f a l s e }, 4 David : { v e g g i e : false, nut : true }, 5 Daniel : { v e g g i e : true, nut : f a l s e } 6 } ; 7 8 let noofveg = 0 ; 9 let n u t A l l e r g i e s = f a l s e ; 10 10

11 f o r ( l e t i in f o o d P r e f s ) { 12 i f ( f o o d P r e f s [ i ]. v e g g i e ) { 13 noofveg++; 14 } 15 i f ( f o o d P r e f s [ i ]. nut ) { 16 n u t A l l e r g i e s = true ; 17 } 18 } 19 20 i f ( noofveg === 0) { 21 a l e r t ( "No vegetarians are attending this party.") ; 22 } else { 23 a l e r t ( "At least " + noofveg + " vegetarian meals are required." ) ; 24 } 25 26 i f ( n u t A l l e r g i e s ) { 27 a l e r t ( "WARNING: chefs must be informed of potential nut allergy." ) ; 28 } Note. While this sounds like an appealing way to iterate over an array, it should not be used for that purpose. The keys are not returned in any particular order, so this will not in general count from 0, 1, 2, 3, etc. Additionally it is possible for an array to have keys other than its indexes, and the in will pick those up without you expecting them. Finally, since all keys are strings, attempting to add with them will cause string concatenation instead due to type coercion. 4 The function/object relationship 4.1 First-class objects Functions are not just something that can be called in JavaScript, but rather something that can be manipulated just like every other type of variable you have seen so far. In JavaScript, we say that functions are first-class objects. Here the word objects refers to JavaScript objects. Indeed, every function you have defined so far has been converted into a Function object stored inside a variable with the same name as the function s name. The parenthesis are considered an operator that works on Function objects. This piece of 11

technical detail has some interesting applications. One such application is that functions can be passed inside other functions. This is the basis of an entire programming style called functional programming, which works with objects called higher-order functions. Since functions are passed around as objects, it is convenient to be able to create functions immediately when they are required. We can do this by creating an anonymous function. An anonymous function has no name, and is defined with the function keyword followed by an pair of parenthesis defining arguments. To use such a function, you must either assign it to a variable or immediately call it with another pair of parenthesis. Since the function has no name, there is no way to call the function directly. One of the easiest higher-order functions to understand is the map function. It takes an array and a function as a parameter, and returns an array. For every element in the input array it applies the function to that element and assigns the result to the output array. Listing 9 defines map in JavaScript. Line 17 passes the sayhello() function into map. Lines 18-20 do a similar thing to say goodbye to everyone, except it anonymously defines the function right at the point it is used. 1 function map( arr, func ) { 2 var r e s u l t s = [ ] ; 3 Listing 9: Implementing map 4 f o r ( l e t i = 0 ; i < a r r. length ; i++) { 5 r e s u l t s [ i ] = func ( a r r [ i ] ) ; 6 } 7 8 return r e s u l t s ; 9 } 10 11 function sayhello (name) { 12 c o n s o l e. l o g ( "Hello " + name) ; 13 } 14 15 var names = [ "Peter", "David", "Susan" ] ; 16 17 map( names, sayhello ) ; 18 map( names, function (name) { 19 c o n s o l e. l o g ( "Goodbye " + name) ; 20 }) ; 12

Note. In more modern browsers the Array object has some built-in higherorder functions as methods, including the map function just discussed. However, map does not exist in older browsers and other higher-order functions such as foldl and foldr do not exist at all. In actual code you should use if statements to check if you have a map method and use it if available, and only re-implement it if it doesn t exist. This process is called polyfilling, and many JavaScript libraries exist which are devoted just to polyfilling. 4.2 Closures Since functions are objects, and objects can be returned from a function, it follows that functions can also be returned from a function. Functions have access to variables within their scope as discussed in previous classes. However because functions can be passed around in variables they can end up in a completely different scope where their variables no longer exist. Despite this functions can continue to use their variables, as the JavaScript interpreter makes sure that each function has access to everything it should. The process which makes this work is called a closure. Listing 10 implements the sayhello() and saygoodbye() functions referred to in listing 9. This is done via a greetname() function that creates these functions. Since greeting is a parameter to greetname(), and the function returns another function, the function returned should have no access to greeting any more and thus should cease to work. However, via the power of closures these returned functions keep their reference to the greeting that existed when it was created. Listing 10: Creating a closure 1 function greetname ( g r e e t i n g ) { 2 return function ( name) { 3 c o n s o l e. l o g ( g r e e t i n g + " " + name) ; 4 } 5 } 6 7 sayhello = greetname ( "Hello" ) ; 8 saygoodbye = greetname ( "Goodbye" ) ; 9 10 // Demonstrate that these are the required functions 11 sayhello ( "Nicole" ) ; 12 saygoodbye ( "Nicole" ) ; 13 13

14 // All of these produce errors. You have no access to either greeting 15 g r e e t i n g ; 16 sayhello. g r e e t i n g ; 17 saygoodbye. g r e e t i n g ; 4.3 Constructors When we use curly brackets to define an object, what we are technically doing is creating an Object object and assigning some keys and values to it. Since objects tend to represent something, we can name our type of object. Not only is this useful to trace errors the console shows us, but it is also useful to ensure that every object is constructed correctly. When working with objects nested inside objects it is especially easy to accidentally mistype after creating multiple copies of an object, or to accidentally create an inconsistent object. For example, if you are representing people as objects, you don t want to declare them as simultaneously dead and alive. To help with this we can define a function called a constructor. A constructor creates an object on our behalf. Since a constructor is a function, it can take whatever parameters you need to help you create the object. Constructors are typically given names starting with a capital letter, but this is merely convention. Since the constructor doesn t know what object it is creating, the this keyword is introduced to represent the object it is working on. Once a constructor is defined we use the new keyword to call the constructor. Listing 11 creates a constructor to represent the object used in listing 8 to represent food preferences and allergies. We also use the constructor to perform some basic error checking, in this case ensuring that the Preferences object only contains booleans. Listing 11: Using constructors 1 function P r e f e r e n c e s ( veggie, nut ) { 2 this. v e g g i e =!! v e g g i e ; 3 this. nut =!! nut ; 4 } 5 6 var f o o d P r e f s = { 7 Stacy : new P r e f e r e n c e s ( true, f a l s e ), 8 N i c o l e : new P r e f e r e n c e s ( false, f a l s e ), 9 David : new P r e f e r e n c e s ( false, true ), 10 Daniel : new P r e f e r e n c e s ( true, f a l s e ) 14

11 } ; 4.4 Methods Particularly complicated objects generally require their own functions to handle them. Objects can be given keys with function values to store these functions. These functions are called methods. For example, console is an object that represents a developer s console inside a web browser. Logging to it is a function that makes sense only for a console, and as such there is a console. log() method on the console object. Your objects can also have methods associated with them, and assigning these methods is generally left to the constructor. Listing 12 creates an Person object with a name, and two functions which get and set that person s age. 1 function Person ( name) { 2 this. name = name ; 3 4 var age = null ; 5 Listing 12: Adding methods to your objects 6 this. getage = function ( ) { 7 return this. age ; 8 } ; 9 10 this. setage = function ( age ) { 11 i f ( age === null ) { 12 this. age = null ; 13 } else { 14 age = Number( age ) ; 15 this. age = Number. isnan ( age )? null : age ; 16 } 17 } 18 } Line 4 creates a variable inside the Person constructor. This variable would fall out of scope after the function ends, but because JavaScript has closures and because there are two methods, getage() and setage() that access that variable, the variable stays accessible but only by a Person object. Thus all access to the age variable passes through the Person methods. There are two main benefits of this: 15

1. A Person object can assume that it has a valid age, since the only function that sets age is the setage() method, and that method ensures that only valid ages are set. 2. A Person object can be changed later to store a date of birth instead of an age, and as long as you re-implement getage() and setage() correctly no other changes to your script will be needed, since no-one else could possibly touch age directly. When designing your own objects, you should think carefully about what keys and methods should be accessible to the outside world, and only expose a simple interface between you and your object. Similarly, when using objects designed by others, you should stick to the interface you are given and should not attempt to break into the internals of the object. Together, functions and objects work together to split scripts into small, manageable chunks, which are easier to test for bugs and other errors. Well designed functions and objects can even be used on multiple websites without any modification whatsoever. 4.5 Constant objects You can declare constants with the const keyword mentioned in the first class. This keyword ensures that a variable is not reassigned. However objects can have keys added and removed at will, and so declaring them as constant will not do as you would expect. While the object cannot be reassigned for a new object, we can manipulate the old object into looking like the new object, which defeats the purpose of a constant. To stop this tampering of your objects there are two levels of constantness you can define. In strict mode attempting to break this protection will result in an immediate error, while non-strict mode will just silently ignore your attempts. Object.seal() takes an object and stops any addition or deletion of keys. Keys that exist when the object is sealed can still be modified at will. Object.freeze() takes an object and stops all further changes. change of any kind results in either an error or silent ignoring. Any Listing 13 defines a constant object representing a person, which we immediately manipulate into looking like an item on a supermarket shelf. We use Object.seal() to stop any further changes to the keys, and show that we can still change the name of the item since name existed when the seal 16

was applied. Finally we freeze the object before we get tricked into selling a luxury mansion for 5.50. Listing 13: Sealing and freezing objects 1 const mia = { 2 name : "Mia", 3 age : 17 4 } ; 5 6 // This will fail since we cannot reassign 7 mia = { 8 name : "Chicken", 9 pricegbp : 5.50 10 } ; 11 12 // We can just bypass this check by mutating a person into a food item 13 mia. name = "Chicken" ; 14 d e l e t e mia. age ; 15 mia. pricegbp = 5. 5 0 ; 16 17 // This will stop us from changing the keys, but we can still edit the contents 18 Object. s e a l ( mia ) ; 19 mia. priceusd = 8. 3 0 ; // An error 20 mia. name = "Can of baked beans" ; // Fine! 21 22 // And now the object is truly constant. 23 Object. f r e e z e ( mia ) ; 24 mia. name = "Deed to a luxury mansion" ; // An error 5 Try it yourself To check this week s knowledge, try the following tasks below. Each task should take no more than a few minutes, and does not require information from a future class. 1. Consider a web site that sells music online. (a) Design an object that represents a song or music track, and create the appropriate constructor. 17

(b) Design an object that represents an album, and create the appropriate constructor. Give your album object a method that adds a given song to the end of the album. (c) Assuming your song objects have a property which represents a rating, write two functions that return the best and worst songs on any given album. 2. There are two expressions which returns a random integer depending on the values of min and max. These are: 1 Math. round (Math. random ( ) (max min + 1) + min ) 2 Math. f l o o r (Math. random ( ) (max min + 1) + min ) (a) Create two functions for each expression. (b) Generate 1,000,000 random integers between 1 and 10 using each function. For each function count how many times each function generates a particular integer. (c) Determine if either expression ever generates a random number outside of its supposed range. (d) Looking at your two sets of results, determine which expression (if any) fairly generates integers. (e) If you were given the task of randomly choosing images to display in an image gallery, which expression (if any) would you use? 18