speeding planet | copyright © 2015 ► javascript the language

Post on 17-Jan-2016

218 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Speeding Planet | Copyright © 2015

► JavaScript the Language

Speeding Planet | Copyright © 2015

► Set-up

3

Set-up Checklist

► IDE of some sort (code highlighting, etc.)

► Chrome 32.x (or greater)

► Firefox 27.x (or greater)

► Internet Explorer 9 (or greater)

► Class files, as provided by your instructor

4

Set-up directions

► If you have not already, download the zip file for the class and unzip it to your hard drive● Please choose somewhere easy to get to● Try not to have spaces in the path to the directory

where you unzip the files

► Open a command prompt in the directory for the class files● You can hold down the shift key and right-click on

the directory, which will give you an option to "Open command window here"

► At the command prompt, enter bin\set-path, which will set the path for this window only

5

Running the server

► Now that the path has been set correctly, we can run the server

► Run the command start-server, which kicks off a web server

► Open a web browser and navigate to http://localhost:8000/Installed.html

► You should see a message indicating that the web server is up and running

6

Other Administrative Details

► Can everyone see my applications?

► Asking questions: please feel free to speak up!

► Other questions/concerns before beginning?

Speeding Planet | Copyright © 2015

► Introduction

8

Chapter preview

► JavaScript as a language● ECMAScript and JavaScript

► Different JavaScript engines

► Client-side, not server-side

► Using the console

► Different ways of loading and running JavaScript● In-line JavaScript: why it's bad● Block JavaScript: use occasionally● Included JavaScript files: the logical choice

9

JavaScript as a language

► Over the last few years, JavaScript has become one of, if not the, most popular programming language

► JavaScript started as a scripting language for the Netscape Navigator web browser● It was not intended to run outside the context of the

browser● It updated frequently to keep up with the rapid pace

of browser development at the time

► Now JavaScript is used on a variety of platforms● Standalone: Node JS, Rhino● Java: Nashorn● Browsers, mobile devices, plenty of other platforms

10

JavaScript and ECMAScript

► While JavaScript was always tied to the browser, it has now evolved into a language in its own right

► The language is shepherded by Ecma, a standards body, with participation from Google, Apple, Microsoft, Mozilla and others

► The current standard is ECMAScript 2015, previously known as ECMAScript 6 or ECMAScript.Next● ECMAScript is sometimes abbreviated ES, so you will

see ES6 or ES2015● ECMAScript 7 is in active development, and will be

assigned a year as soon as the spec is finalized● No one writes "ECMAScript" but instead writes in

JavaScript that conforms (to various degrees) to an ECMAScript standard

11

Client-side, not server-side

► Despite the flourishing of JavaScript platforms, we will be using a browser as our JavaScript engine● Specifically, we will focus on using Chrome, though

we will work with code that works on Internet Explorer and Firefox as well

► But we are interested in JavaScript the language so we will not be looking at browser-specific features (DOM, event handling, etc.)

► We will focus on using the browser as an engine, viewing JavaScript output via the browser console

12

Looking at JavaScript

► In the three major browsers, you will access the developer tools to see the developer console● On Windows machines, the developer tools are

usually accessible through Control-Shift-I, or sometimes F12

● On Macs, Command-Alt-I or Command-Alt-J works, depending on your browser

● Or you can find it through various menus

► The console is a JavaScript Read-Eval-Print Loop (REPL)● It will evaluate statements● It will remember variables and maintain state

13

Demo/Exercise: Using the console

► Your instructor will walk you through the following

► Opening the developer tools

► Getting to the console tab

► Evaluating statements in the console

► Using the console's autocomplete and history functions

14

Including JavaScript in an HTML page

► As originally envisioned, JavaScript had flexible use cases● Value of an event handling attribute for a tag● Used with the javascript: URI● <script> block(s) in the <head> section● <script> block(s) in the <body>● Included as separate files (again, via the <script>

tag)

► At this point, there are probably too many options for locating your JavaScript

15

Best practices for using JavaScript

► Programmers are familiar with the goal of separating presentation from logic

► Not to mention that we want to be able to unit test our code

► And make it easier to manage our source code

► Logically, we should separate our JavaScript in separate files from our HTML

► But, as developers, you will need to know that there are other places you might see JavaScript

16

In-line JavaScript

► There are two ways to include in-line JavaScript within an HTML page

► Anchor tags can have a javascript: protocol instead of an http:// or https:// protocol

► Many elements have in-line event handlers as attributes, like so:

► Using in-line code leads to spaghetti code which is difficult to manage, test, and debug

► Unless you have an absolutely compelling reason for using in-line JavaScript, avoid it

<div onclick="doSomething()"></div>

17

Block JavaScript

► You may include a block of JavaScript within a set of <script> tags

► This is useful in several cases:● Small blocks of JavaScript which would be expensive

(time-wise) to load from a separate file● Small blocks of JavaScript which load critical

resources early

► This is not the ideal, though

► Your code is still mixed with HTML, and can be difficult to separately test or manage

► Use with caution

18

External JavaScript

► The recommended default way to include JavaScript in a page is as a separate file loaded through a <script> tag

► The script element must have an opening and closing tag, or the browser will ignore it (true for most browsers)

► You do not need a type attribute

► The async attribute ensures that HTML processing will not be blocked while your script loads

► The defer attribute should make script execution wait until the page loads (depending on browser implementation)

<script src="some-file.js" async defer></script>

19

External JavaScript

► Keeping your JavaScript in a separate file allows for easier management, testing, and reusability

► It is the recommended default for using JavaScript within a browser

► If you are unsure, fall back to using external JavaScript files, and then work with the browser's profiling tools to see if a different approach would work better

20

An HTML container

► To run JavaScript within the browser, we will use a simple HTML container

► For most demos and exercises, you will browse to the JavaScript file directly (e.g., scope.js)

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>Our JavaScript Container</title></head><body>

<script src="some-file.js" async defer></script></body></html>

21

Behind the scenes

► The class uses Node.js, running Express as a web server, serving Jade templates which wrap a request for a JavaScript (*.js) file with an HTML container

► If you are curious, take a peek in the app directory at server.js

► Node.js: http://nodejs.org

► Express: http://expressjs.com

► Jade templates: http://jade-lang.com

22

Conclusion

Speeding Planet | Copyright © 2015

► Scope

24

Chapter preview

► JavaScript and scope

► No block-level scope

► Using Immediately Invoked Function Expressions (IIFEs)

► Localizing references in IIFEs

► Defining variables and hoisting

► Defining functions and hoisting

25

Scope in JavaScript

► JavaScript only has two scopes: global and functional

► Obviously, anything defined outside of a function is global

► Anything defined inside of a function and declared with the var keyword is local to that function

► Functions can nest within one another, creating inner scopes

► As a best practice, declare all your variables with var, which prevents unintended consequences, even with intended globals

► While global variables should be avoided, we will use them briefly until we come up with a solution at the end of this chapter

26

Global variables

► Variables declared outside of a function belong to the global scope

► In the browser, this global scope can be accessed directly, or through the keyword window● That is, any global variable x can be accessed as x or

window.x

► Variables used without declaration are automatically global● Sometimes called unintended globals

► Try to avoid this!

► See "use strict" later on for some help here

27

Block scope

► JavaScript does not have block scope

► Just because you declare a variable within an if, while, for, or the like does not mean that the variable is localized to that block

► That said, when declaring counter variables, for a while or for block, you should still initialize your variable with var

► Again, this prevents unintended globals (and consequences!)

► In ECMAScript 2015, the let keyword is introduced, which allows block scoping, but is not, as yet, widely implemented

for ( var x = 0; x < 10; x++ )

28

Demo: Scopes

► We will look at various scopes and scoping situations

► Chapter: Scope

► Demos/basic-scope.js

29

Avoiding globals

► We would like to avoid using global variables, whether as variables proper, or as function names

► This presents a catch-22 problem:● We need a local scope, thus a function● But we would need to run that function● How can you run a function without a name?● But naming the function means that name is thus

global● Go around again

► The solution is the immediately invoked function expression, or IIFE

30

Immediately invoked function expressions

► Thanks to an awkward bit of JavaScript syntax, it is possible to declare a function that is immediately invoked

► This function does not need to have a name and thus avoids being a globally named member

► Any variables declared inside the function will be local to that function, providing a local context for us to use

► Problem solved!

31

IIFE syntax

► Writing an IIFE is relatively simple:

► The critical components: ● Declare an anonymous function● Wrap it in parentheses (turning it into a function

expression)● Add a set of parentheses at the end of the function

expression to invoke it immediately (thus the name)

(function () { var foo = 'bar';})();

32

Localizing references

► You will likely use a variety of JavaScript libraries

► Most of these libraries export globals ($, _, angular, Backbone, Ext, etc.)

► You want to pass these globals into your IIFE, which has two benefits

► First, it is clearer what your IIFE depends on

► Secondly, JavaScript looks up references from the current scope all the way up the stack to the window object● If you keep library references global, they will be

found later, a minor performance hit

33

Demo: Using IIFEs

► Chapter: Scope

► Demos/using-iifes.js

34

Variables and hoisting

► Due to a quirk in JavaScript's design, variable declarations with var are hoisted to the nearest function declaration

► Despite possibly declaring a variable 20 lines deep into your function, the variable springs into existence as soon as the function is run

► However, the variable is not defined (assigned a value) until you do so within your code● Put another way, declarations are hoisted,

assignments are not

35

Functions and hoisting

► JavaScript is also a bit peculiar about function definitions

► You may have seen a function defined this way, known as a function declaration

► And you have seen a variant on this, known as a function expression

function foo() { // function body here}

var foo = function () { // function body here};

36

Hoist on your own petard

► Function declarations are hoisted to the top of the enclosing context, ahead of everything, including variable declarations

► Function expressions are assigned in-line, and receive no special hoisting

► Best practice, pick one style and go with it, not only for consistency, but to prevent difficult to debug problems down the road

37

Demo: Hoisting

► A look at some of the perils of hoisting

► Chapter: Scope

► Demos/hoisting.js

38

Conclusion

Speeding Planet | Copyright © 2015

► Useful JavaScript language features

40

Chapter preview

► Strict mode

► True and false in JavaScript

► Basic data types

► Pass by value or reference

► Converting to and from JSON

41

Strict mode

► JavaScript has some attributes that are sub-optimal● Variables springing into being as globals, for

instance

► Strict mode can help with this during development

► Add "use strict" to any context (function) to force strict mode for that context

42

Strict mode rules

► Strict mode rules:● Mistakes are made into errors (that is, they are

higher priority)● Cannot accidentally create global variables, all

variables must be declared with var● Assignments which would normally silently fail now

fail loudly• Try assigning to NaN, not a number, a reserved value

● Trying to delete undeletable properties now throws an error

● Duplicate property names are an error● Duplicate function argument names are an error● Octal values (with leading zeroes) are illegal

43

More strictly

► Strict mode also introduces some optimizations which are less of a concern to us, but are worth noting regardless

► The with construct is illegal

► Calling eval cannot introduce new variables into the current scope

► You cannot call delete on plain names (globals, referenced globally)

► In functions, arguments.callee is illegal

► Other details can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

44

Using strict mode

► Strict mode can be enabled globally, or on a per-function basis

► It is recommended to enable strict mode on a per-function basis

► Some libraries depend on code which will fail strict mode (for better or worse)

► Using strict mode globally would prevent the use of said libraries

45

Exercise: Strict mode

► We will turn on strict mode in a file, and then fix the identified problems

► Chapter: LanguageFeatures

► Exercises/strict-mode.js

46

True and false

► JavaScript has the basic concept of a Boolean type, which can be set to true or false

► But any value can be converted to a Boolean in JavaScript● var bVal = Boolean(whatever)● if (someVal) ...

► Values that are Boolean true, but not, you know true are called truthy, and variables that are Boolean false are called falsy

47

Falsy-ness

► There are only six falsy values in JavaScript; all other values are truthy

► They are:● false● 0● '' or "" (the empty string)● undefined● null● NaN

48

Equality

► JavaScript has a complex sense of equality

► Initially, the language allowed for type coercion with comparisons done via == (double equals)

► This could be good, as 0 is equal to "0"

► But it could be awkward, as 0 is equal to the empty string is equal to false, which can make form validation tricky

► Later versions of JavaScript implemented a triple equals comparison (=== and !==)

► This did not permit type coercion and quickly returned false if the two operands were of different types

49

JavaScript equality

Table of various JavaScript values and whether they are equal to other values(Credit: http://algorithmicassertions.com/visualization/2014/03/27/Better-JS-Equality-

Table.html)

50

Basic types

► JavaScript has several primitive data types, which can be detected with the typeof operator

typeof <expression> returns

typeof 'some string' 'string'

typeof 6 'number'

typeof true 'boolean'

typeof function() { ... } 'function'

typeof undefined 'undefined'

typeof null 'object'

typeof /s/ 'object'

typeof <anything else> 'object'

51

By value or by reference?

► Despite certain types being called "primitive" there are distinctions between how they are passed around in functions or as variables

► Strings, numbers, and Booleans are passed by value● That is, they are copied, when passed to a variable

or to a function

► Objects, functions, and arrays (and anything else that is an object as far as typeof is concerned) is passed by reference

► Keep this in mind when working with values that are objects or arrays

52

JSON

► Modern JavaScript makes it easy to convert data to and from JSON

► To convert a JavaScript object to a JSON string, call JSON.stringify on the object in question

► To convert it back to a JavaScript object, pass the JSON string to JSON.parse

► Note that this could be a cheap way to clone an object, since JavaScript has no native clone or copy for objects

53

Conclusion

Speeding Planet | Copyright © 2015

► Functions

55

Chapter preview

► Multi-argument functions

► The arguments object

► Variable number of arguments

► Overloading functions

► Functions as first-class citizens

Multi-argument functions

► JavaScript functions don't need to specify the number of arguments they take

► Every function has the special arguments object available

► This object acts similar to an array, allowing you to iterate over it to access data passed into a function

56

The arguments object

► Has a length property to determine the number of arguments

► Provides array-index access, e.g., arguments[2] provides the third argument to the function

57

Demo: The arguments object

► Chapter: Functions

► Demos/arguments.js

58

59

Variable number of arguments

► JavaScript does not enforce function signatures● You can pass fewer or greater arguments than the

signature specifies

► Which means it is easy to handle a variable number of arguments

► This is most useful when writing functions that can take an unlimited number of arguments ● Think of a print function which takes a template and

an unlimited number of substitutions

60

Handling variable arguments

► Iterate over the arguments object, accessing arguments, until you run out of arguments

function printMultiple( template ) { var substitutions = []; for ( var x = 1; x < arguments.length; x++ ) { substitutions.push( arguments[x] ); }}

Exercise: The arguments object

► Let's build a function which will take multiple arguments

► Functions/Exercises/MultipleArguments.html

► Functions/Exercises/MultipleArguments.js

61

Functions as first-class citizens

► Unlike some languages we could name, JavaScript functions are first-class citizens (or members)

► What is a first-class citizen?● Can be constructed at run-time● Can be assigned to a variable● Can be passed to a function● Can be returned from a function

62

Passing functions around

► It's possible to pass one function to another

► The receiving function could customize the function argument, or simply run it, or do any number of things

► It's a very important tool, and without it, most JavaScript libraries would be very limited

63

Anonymous functions

► While passing functions around, it's not even necessary to name them!

► Functions can be passed in-line and anonymously

► Similar to the way that Numbers or Strings could be passed as literals or via variables

64

Demo: First-class functions

► Let's look at working with functions directly, specifically:

► Assigning functions to variables

► Passing functions in and out of functions

► Anonymous functions

► Functions/Demos/FirstClassFunctions.js

► Functions/Demos/FirstClassFunctions.html

65

Exercise: First-class functions

► A use case for passing functions back and forth

► As well as a few other cases of treating functions as first-class objects

► Chapter: Functions

► Exercises/working-with-functions.js

66

67

Overloading

► Many languages have a feature called "overloading" where you can have several definitions of a function, depending on the number and type of arguments passed to a function

► JavaScript does not have a native syntax for overloading a function

► Nonetheless, many libraries and examples seem to enjoy the overloading feature● jQuery, for instance, has many functions which do

different things depending on the type of arguments you pass to them

► Overloading is possible, but it has to be implemented "by hand" as it were

68

Overloading with typeof

► A very basic example of overloading could use typeof to distinguish between argument types

function overloaded( arg1 ) { if (typeof arg1 === 'string') { // Do something string-related here } else if (typeof arg1 === 'object') { // Do something object-related here }}

69

Overloading by type

► Using object types to overload functions is also possible

► It is more complicated than using typeof, as we need functions to distinguish a Date from a Car from an Account, for example

► JavaScript has the Object.prototype.isPrototypeOf function, which can determine if an object instance shares the same prototype as another object● If this sounds like gobbledygook, it will become

clearer in the Objects chapter!

► Use isPrototypeOf as you would typeof, in an if statement

70

Overloading for Arrays

► Arrays are a bit trickier to determine

► They do not have their own typeof entry

► But you do not have to use Array.prototype.isPrototypeOf either

► Instead, use the static function Array.isArray to determine if the argument is an array or not

71

Exercise: Overloading

► Chapter: Functions

► Exercises/overloading.js

72

Conclusion

Speeding Planet | Copyright © 2015

► Arrays

74

Chapter preview

► Basic array rules

► Generic access: splice and slice

► Manipulating: join, concat, reverse, sort,

► Finding: indexOf, lastIndexOf

► Accessing at the ends: push, pop, shift, unshift

► Iterating: forEach, every, some

► Processing: map, filter, reduce, reduceRight

75

Basic array rules

► Arrays are much like arrays in other languages, with a few exceptions

► Arrays are not typed in JavaScript, they can have elements of varying types● Keep this in mind when adding elements to an array● Arrays can contain other arrays!

► Arrays are not of a predefined size, and adding elements is usually low-cost

76

Generic array access

► array.slice(begin, [end]): Extract a slice of an array● If end is omitted, returns from begin to the actual

end of the array

► array.splice(begin, length, [item, item, item,....]): All-purpose array modifier● Start at begin, go length, possibly

inserting/replacing with item...● Insert: array.splice(begin, 0, item...)● Update: array.splice(begin, 3, item1, item2, item3)

● Delete: array.splice(begin, 2) Note that this is the only way to delete elements in an array before ECMAScript 2015• Returns the deleted elements as an array in this case

77

Manipulating arrays

► array.join(interString): Joins all elements on interString and returns a single string

► originalArray.concat(otherArray): returns an array consisting of originalArray with otherArray concatenated to it

► array.reverse(): Reverses the order of elements of an array in place

78

Sorting arrays

► array.sort([compareFn]): Sorts the elements of an array in place● If compareFn is not provided, elements are converted

to strings and compared by position on the Unicode table

► compareFn(a,b) can return the following: ● If a should be sorted before b, then a number

greater than zero● If a and b should stay in the same position, relative

to one another, then zero● If a should be sorted after b, then a number less

than zero

79

Demo: Accessing and sorting arrays

► Chapter: Arrays

► Demos/accessing.js

► Demos/sorting.js

80

Exercise: Sorting arrays

► Write a function which sorts an array of objects

► Chapter: Arrays

► Exercises/sort-objects.js

81

Searching arrays

► Search through arrays with indexOf

► array.indexOf(element, [start]): Returns the position of element if it is found in the array, -1 otherwise● Provide a starting index if you would prefer to start

at an index greater than zero● Searches left to right (index 0 and greater) normally● Equality is determined by triple equals

► array.lastIndexOf(element, [start]): As indexOf, but searches right-to-left (last index and descending)● Still returns -1 if the element is not found

82

Arrays as stacks

► JavaScript arrays have the traditional stack manipulation functions

► array.push(element): Adds element to the end of array

► array.pop(): Removes and returns the last element of array

► array.unshift(element): Adds element to the beginning of the array

► array.shift(): Removes and returns the first element of the array, all other elements shift down one index

83

Demo: Finding elements

► Finding and manipulating elements in a variety of different ways

► Chapter: Arrays

► Demos/finding-elements.js

84

Functional iteration

► You can iterate over an array with a simple for loop

► JavaScript arrays also have functional iterators, which are popular

► array.forEach(function(item, index, array) { ... },

[scope]): Iterate over array, calling function once for each element● Function has three arguments, the item, its index in

the array, and a reference to the original array● Provide an optional scope argument to have the

function operate in other than the current scope / context

● No return value● No way to break out of the iteration

85

Functional iteration with exits

► The array.some and array.every functional iterators take the same arguments as array.forEach

► But they can break if their processing function returns a value

► array.some breaks its loop if the processing function returns truthy, and itself returns true

► array.every breaks its loop if the processing function returns falsy and itself returns false

► Both are ideally suited for searching through an array

86

Processing arrays with map

► array.map(function(item, index, array) { ... }, [scope]): Iterates over the array, building a new array consisting of what function returns for each item● Put more simply, calls function against each item

and collects the return values into a new, returned array

var numbers = [1, 4, 9, 16, 25];var roots = numbers.map( Math.sqrt );

87

Filtering arrays

► array.filter(function(item, index, array) { ... },

[scope]): Returns a new array of filtered elements based on whether the processing function returns true (filtered in) or false (filtered out)

► The processing function can return truthy or falsy

► There is no way to break out of the loop once it has started, much like with forEach

88

Reducing arrays

► array.reduce(callback, [initialValue])

► Iterates over array, calling callback on each element, building an accumulating value for each element, until it returns the final accumulation of all elements

► The callback receives four arguments:● previousValue: The previously accumulated value● currentValue: The current element being examined● index: Position of currentValue● array: Reference back to the original array

► You can use initialValue to seed the first call of the callback

► reduceRight is the same, except it processes elements right-to-left

89

Demo: Processing arrays

► Examples of processing arrays

► Chapter: Arrays

► Demos/processing.js

90

Exercise: Processing arrays

► Chapter: Arrays

► Exercises/processing-arrays.js

91

Conclusion

Speeding Planet | Copyright © 2015

► Objects

93

Chapter preview

► Objects defined

► Access: Object.keys

► Object.toString

► Objects and properties: defineProperty, defineProperties

► Preventing change: preventExtensions, seal, freeze● State of the object: isExtensible, isSealed,

isFrozen, propertyIsEnumerable

► Prototypes: getPrototypeOf, isPrototypeOf, hasOwnProperty, create

Object literals

► There is sometimes some confusion in terms when referring to JavaScript objects

► Object literals are a JavaScript data structure● Relatively close to associative arrays or hashmaps

► Inherits from the JavaScript type Object● Also an instance of Object

► People also call these JavaScript Objects● But they are wrong● We will refer to them as object literals, configuration

objects, hashes, associative arrays, but not as Objects

Creating a JavaScript object literal

► JavaScript object literals are easy to create

► Long form:var myObj = new Object();

► Short (and preferred) form:var myObj = {};

► Used for configuration, to emulate associative arrays, and more

95

Assigning value to objects

► Add properties to objects at creation or on-the-fly

1. // Creation time2. var car = {3. wheels : 4,4. make : "Honda",5. model : "Civic"6. };7. 8. // On the fly9. car.color = red;

96

Objects and methods

► You can also add methods:

1. var car = {2. drive : function(speed) {3. if (speed > 55) {4. console.log("That's not safe.");5. }6. }7. }8. 9. car.getColor = function() {10. return this.color;11. }

97

Accessing methods and properties

► Accessing members is relatively simple

1. var car = { /* definition here */ }

2. console.log("The car's manufacturer is " + car.make);3. console.log("Current speed: " + car.getSpeed() );

98

Removing members

► If we need for a member to go away, we can simply delete it from the object● delete car.color;

► Works for both methods and properties!

► This has the side effect of making that member eligible for garbage collection

Demo: Creating objects

► Chapter: Objects

► Demos/object-literal.js

100

101

Object.keys

► Since object literals are JavaScript's version of maps, we need a way to access the keys of an object literal

► JavaScript provides a for ... in loop which is useful, but susceptible to being fooled by members added to the Object's prototype● More about prototypes in a later chapter

► Instead, prefer Object.keys, a static function which returns an array of keys of the object literal's own properties● And does not include properties from the object

literal's prototype

102

Object.toString

► JavaScript Objects have a default toString function which returns the typeof and instanceof values for the object in question● Usually this looks like [object Object]

► You can override this function to return a different value when your object literal is converted to a string

► Many JavaScript functions will automatically convert arguments to strings, which invokes toString implicitly

► So it is a good idea to provide your object literal with a toString method if it is going to be used in a situation where it is likely to be converted to a string

103

Defining properties

► Normally, properties added to Objects are readable, writable, and show up during enumeration

► It is possible to change the properties of properties, as it were

► Use the static function Object.defineProperty to define a property on your object like so: Object.defineProperty(destination, propertyName, properties)

► The properties you can define are listed on the next slide

104

Properties of properties

► configurable: true if this property can be (re)configured or deleted, defaults to false

► enumerable: true if this property should show up in enumeration (via Object.keys or for ... in), defaults to false

► writable: true if the property's value can be modified with the assignment operator, defaults to false

► value: The value of the property

► get: Function which returns the value of the property, defaults to undefined

► set: Function which sets the value of the property

105

Defining multiple properties

► It could be tedious to define multiple properties one at a time

► Use Object.defineProperties to define multiple properties at a time

► Object.defineProperties(destination, propConfig)

► propConfig takes the form { propertyName: {

enumerable: ...,writable: ...// etc.

}}

106

Demo: Defining properties

► Chapter: Objects

► Demos/defining-properties.js

107

Exercise: Defining properties

► Chapter: Objects

► Exercises/working-with-properties.js

108

Preventing changes

► JavaScript object literals (and Objects) can be modified at any time● Unless modified by Object.defineProperty to be

writable:false and configurable:false● Which could be tedious to do for all properties on an

Object

► You can change the configurability of an object literal (or Object) as a whole via a variety of convenience functions which prevent extensions, seal, or even freeze a target

109

Object.preventExtensions

► Use Object.preventExtensions(target) to prevent adding new properties to an Object

► Existing properties can still be modified

► Existing properties can be deleted

► Attempting to add new properties will silently fail, or throw an exception if in strict mode

► Detect if an Object is extensible via Object.isExtensible(target)

110

Object.seal

► Object.seal does everything that Object.preventExtensions does and more

► Object.seal prevents existing properties from being reconfigured

► Not only can you no longer add properties, the nature of existing properties as configured via Object.defineProperty / Object.defineProperties can no longer be changed

► That said, the value of properties on a sealed object can still be changed, as long as said properties were configured as writable

► Detect if an Object is sealed via Object.isSealed(target)

111

Object.freeze

► Object.freeze does everything that Object.seal does and more

► Frozen objects cannot be modified in any way, making them effectively immutable● Though the freeze is shallow, Objects which contain

other Objects have frozen references (cannot delete or change the reference) but the referenced Object is not, in turn, frozen)

► Attempting to change the Object will fail silently, or throw an error under use strict

► Detect a frozen Object with Object.isFrozen(target)

112

Demo: We fear change

► Chapter: Objects

► Demos/no-changes.js

113

Conclusion

Speeding Planet | Copyright © 2015

► Object-Oriented JavaScript

Chapter Preview

► Object-oriented JavaScript

► Types vs Classes

► Object literals

► Managing objects

► Creating a class

► Prototype-based languages

► Extending native objects

115

Object-oriented JavaScript

► JavaScript is an object-oriented language that is conflicted about it's prototypal nature● (Douglas Crockford said that)

► It is sometimes difficult to talk about JavaScript as an object-oriented language, because it does not completely fit into an OO pattern

► In some ways, it has superior features, and in other ways, it is missing features

Types vs Objects

► An object-oriented language has classes, which are the blueprints for instances, which are usually referred to as objects

► JavaScript has objects and instances, but does not really have classes

► It is more accurate to say that JavaScript has types, like Date, Array, RegEx and, yes, Object

► You can instantiate these types in the normal way (with the new keyword), but there is no corresponding class definition

Creating types

► Instead of classes, JavaScript allows you to use one of two types as the basis for an instance: Functions or Objects

► Each has its own syntax for defining the type, and its own syntax for instantiating the type

► The Object is the most natural base type for JavaScript, as we will soon see

► But many people use the Function as a base type because it feels more "classical" in nature

► We will look at both styles

Objects as types

► You can use a simple object as a type► Define the object, and then use Object.create() to

create instances of it1. var car = {2. make: 'Default make',3. model: 'Default model',4. mileage: 0,5. addMiles: function(moreMiles) {6. this.mileage += moreMiles7. }8. };

9. var honda = Object.create(car);10. honda.make = 'Honda';11. honda.model = 'Civic';12. honda.addMiles(500);

Object.create support

► Object.create has been supported by Webkit and Firefox for a long time

► It is supported in IE9 and later as well

► Thankfully, there is also a polyfill for IE8 and older

► Chapter: OOJS

► Demos\object-create-polyfill.js

Demo: Simple base object

► See a working example of the recent slide's code

► Chapter: OOJS

► Demos\object-create.js

Object.create

► Object.create allows you to use one object as a blueprint for another

► If that sounds like a class, it is not dissimilar

► But there is no class, the base object is still an object

► And, more importantly, the base object and instance are linked through a property called the prototype

Prototypes

► All objects in JavaScript have a prototype● Sometimes accessible as a property called,

appropriately, prototype● Always accessible as a property called __proto__

which will be standardized with ECMAScript 6 but is available on all modern browsers

► If you refer to a member on an object, and the member is not present on the object itself, the object's prototype is checked

► Object.create links the prototype of the object passed to it to the object it returns

Live prototypes

► In the case of Objects linked by Object.create, the prototype property is not explicitly linked

► But the parent/base object becomes the prototype of any child/instance objects

► Adding something to the parent object makes it available on the child

► Prototypes are writeable in JavaScript, and they are live, so that when a lookup reaches the prototype, it is possible that the prototype has changed

A better base object

► Our base object lacks some finesse, let's improve it a bit

► It should have a toString method

► And there should be an easier way to create instances, rather than using Object.create

► So we will add a factory method to generate instances

► Which will also allow us to use private variables

Demo: A better base object

► Chapter: OOJS

► Demos\better-base-object.js

Exercises: Objects and Object.create

► We will use Object.create to define a base object

► And then create instances of it

► Chapter: OOJS

► Exercises\base-object.js

Object-oriented features

► What object-oriented features do we need to have in JavaScript?

► Encapsulation? Already provided with our improved base class

► Type determination (whence polymorphism)

► Inheritance

► Overriding

► Let's look at these last three

Type determination

► JavaScript is a weakly typed language, so type doesn't matter as much and isn't as useful

► But there are some cases where we might want to know if an object is of a certain type

► In the prototypal style, use the isPrototypeOf function to determine type

► baseObject.isPrototypeOf(instanceObject)

► Also works for inheritance!

Inheritance

► Since we don't have proper classes, we cannot simply say that a child object inherits from a parent object

► But, we can re-use Object.create to build a child object, and then create instances of that child object

► So, is there a difference between using Object.create to build instances and to create child objects?

► Not really: the distinction is largely immaterial to JavaScript● Be careful of creating very large (in the hundreds)

prototype chains, as these can have an effect on performance

Demo: Inheritance

► Our Car object needs a parent class of a Vehicle

► Chapter: OOJS

► Demos\inheritance.js

Overriding

► JavaScript allows you to override parent methods, whether you do this at Object.create time or later on

► JavaScript does not provide an equivalent to Java's super, which allows access to the overridden method

► Many have tried to provide super, but the implementations are complex and inefficient

► Prefer linking to the parent method directly, if you really need it

► Yes, this is tight coupling, but on the other hand, that should make you think about how badly you need that super call

Demo: Overriding

► Inheritance with some overriding examples

► Chapter: OOJS

► Demos\override.js

Exercise: Inheritance and overriding

► Chapter: OOJS

► Exercises\object-inheritance.js

Functions as types

► Now we will look at using Functions as the basis for our types

► In general, this involves using a function as a constructor, and invoking that function with the new keyword

► In practice, there are some complications, of course

Creating new objects

► Instances of functions can be created via the new keyword

► Simply add new before the invocation of a function and assign the result to a variable

► It is a very simple syntax:● var Thingy = function(arg1) {

this.prop = arg1;}var foo = new Thingy("bar");

136

Instantiation with new

► Name functions-as-types with an initial capital letter● This is not enforced but it's a convention for types

► Don't instantiate without the new keyword

► Otherwise, the context of the keyword this will have shifted to the window/global namespace

► If you invoke a function-as-class without new, you will be populating the global namespace anytime you use this, which is bad….● (A problem we didn't have using Object.create)

137

Polymorphism

► Though JavaScript doesn't have the concept of classes, it has a rudimentary concept of types

► The typeof operator will tell you the primitive type of a variable● Instances are "object" and classes are "function"

► The instanceof operator will return true if the left-hand operand is an instance of the right-hand operand● Including inheritance, e.g., firstSon instanceof Parent

► Since JavaScript doesn't have function signatures, polymorphism is of limited use● Though it can be useful in implemented overloads

Demo: Creating "classes"

► Let's look at a low-level way to instantiate a pre-defined class

► OOJS/Demos/first-class.js

139

Exercise: Creating objects

► We'll define a few basic objects

► And then create instances of them

► OOJS/Exercises/create-objects.js

140

Functions and prototypes

► In the demo and the exercise, we added functions as part of the definition of the "class"

► This is somewhat problematic

► Because of the way that functions work in JavaScript, those "internal" functions in our classes are recreated for every instance of the class

► This can be quite the memory hog

► Prototypes can alleviate this problem

Prototype benefits

► Defining a function on a prototype has an additional benefit

► By doing so, that function is defined once, at what you might think of as the "class" or type level● Instead of being redefined for each instance of the

class

► Method invocations will trace back to the prototype

► Despite being defined at the prototype level, the this keyword will still refer to the instance at invocation time● (Though we didn't need this distinction in the Object.create style of doing things)

Demo: Objects with prototypes

► Working with prototypes of objects

► OOJS/Demos/prototypes.js

143

Overriding native objects

► Even the standard Java objects have prototypes

► So it's possible to add new methods to Dates or override methods in StringString.prototype.newFunc = function() { … }

► For some programmers this is difficult to grasp, others find it plain crazy! Welcome to JavaScript!

► This is sometimes known as monkey patching, and is … controversial in the world of JavaScript

► The upshot is that this is to be avoided where possible

144

Exercise: Enhancing objects

► We're going to make a few improvements to our own objects!

► OOJS/Exercises/prototyped-objects.js

145

Prototypes and inheritance

► Using functions as types in JavaScript adds some complexity to the inheritance pattern

► First, obviously, define a parent class

► Define a child class, where the child class invokes the function that is the parent class, using the call method

► Link the parent and child prototypes

► Reassign the child class its own constructor (wha?!)

► Add properties as needed

Demo: Prototypes and inheritance

► It may be the case that all of the details on the previous slide are not crystal clear

► Let's look at a demo to see in detail what has to happen

► OOJS/Demos/prototypal-inheritance.js

► If you're ever wondering why JavaScript did things this way, don't forget that we are bolting a class-based concept onto a prototype-based language

Exercise: Inheritance

► Ok, so we understand inheritance now, right? Right!

► Let's try an exercise to see how much of a grip we have on the practicalities

► OOJS/Exercises/inheriting-objects.js

What about super?

► We still don't have super, alas

Summary

► We looked at the two different styles for implementing object-oriented JavaScript

► Both are in wide use today, so it is good to be familiar with each

► For your code, prefer using Object.create where possible, as it is where JavaScript is heading (generally)

150

Speeding Planet | Copyright © 2015

► Exception Handling

Chapter Preview

► Exception handling in general

► try/catch/finally blocks

► Throwing your own exceptions

152

Exception handling in general

► There are a variety of things that can go wrong in a JavaScript program

► For particularly tricky operations, where you can anticipate an issue coming up, you may want to try to handle an exception programmatically

► Useful in cases where data is missing, unavailable, or otherwise difficult to find

153

try-catch

► JavaScript uses a try-catch structure to test for and catch errors:try {codeThatMayCauseProblems();

} catch(err) {console.log(err.message)

}

154

Errors

► Errors have few properties that are useful:

► name: The name of the Error, can be among the following:● EvalError: occurs during calls to eval()● RangeError: Numeric variable or parameter out of range● ReferenceError: Attempt to dereference an undeclared

variable● SyntaxError: language syntax issues, only trappable in eval● TypeError: value is of the wrong type● URIError: encodeURI or decodeURI errors

► message: The message associated with this error

155

finally

► The try-catch block can add a finally block

► This block of code is guaranteed to execute whether or not an error was caught

► Useful for clean-up purposes

156

Demo: Catching errors

► A variety of problems have come up in some code, let's see how to catch those issues

► Chapter: ErrorHandling

► Demos/try-catch.js

157

Exercise: Catching errors

► We have some input which is causing problems

► We'll need to gracefully handle errors, instead of simply failing

► Exercises/catching-errors.js

158

Throwing your own

► It's possible to throw your own errors as well

► Use the throw keyword, in addition to a new Error object

► Syntax:● throw new Error("something went wrong!");● throw "Something went wrong!";● throw new RangeError("value out of range!");

159

Demo: Throwing an error

► Our program has issues, and needs to report on them

► Chapter: ErrorHandling

► Demos/throwing-errors.js

160

Exercise: Throwing errors

► We've got an ugly problem we need to ameliorate

► We're going to wrap an existing error in another error, as well as customizing our own errors

► Chapter: ErrorHandling

► Exercises/throw-it.js

161

162

Conclusion

top related