ecmascript all current · app.js angularjs.js ionic.js cordova.js stylesheet.css native android app...

Post on 20-Jul-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ECMAScriptJussiPohjolainen

1

RecommendedReading

• Recommendedreading• JavaScript:TheGoodPartsbyDouglasCrockford• JavaScript:TheDefiniteGuidebyDavidFlanagan• JavaScriptPatterns:Stoyan Stefanov

• AndGoogle..

2

JavaScripttoday

• EcmaScript isstandardizedsubsetofJavaScript• JavaScriptiskeylanguagetoimplementwebapplications• Possiblecandidateforcross-platformmobiledevelopment

• React,Cordova/Phonegap,Ionic• Serversidedevelopment• Replacing/ComplementingXMLfordatatransfer(REST+JSON)

3

RiseoftheResponsiveSinglePageApp

Image:http://johnpolacek.github.io/scrolldeck.js/decks/responsive/4

Responsive

• Unifiedacrossexperiences• Canbeembeddedasmobileapp• Betterdeploymentand&maintanence• Mobileusersneedtogetaccesstoeverything

Image:http://coenraets.org/blog/wp-content/uploads/2011/10/directory11.png 5

Single-pageApplications(SPA)

• Webappthatfitsonasinglewebpage• FluidUX,likedesktopapp• ExampleslikeGmail,Googlemaps

• Htmlpagecontainsmini-views (HTMLFragments) thatcanbeloadedinthebackground• Noreloadingofthepage,betterUX• Requireshandlingofbrowserhistory,navigationandbookmarks

6

RiseoftheRESTandJSON

• RESTisaonewayofcommunicatingbetweencomputersovertheinternet• DatacanbesendviaXMLorJSONusingHTTP• HTTPGET

• http://something/employee/1• Result

• {id: 1, name: "jack"}• IfbothfrontendandbackendisJS,objectsendingandparsingextremelyeasy

7

RiseoftheJSBackend:NodeJS

• OpensourceJSruntimeenvironment• UsesV8(Chrome)JSengine

• AdditionalmodulesontopofJStoprovidefunctionality• Webserver,systemi/o,networking,...

• Lotofthirdpartymodulesavailable

8

Native iOS App

iOS WebView

index.htmlapp.js

angularjs.jsionic.jscordova.js

stylesheet.css

Native Android App

Android WebView

index.htmlapp.js

angularjs.jsionic.jscordova.js

stylesheet.css

UsingCordovait'spossibletoaccessmobiledevicenativefeatures

WebServerNode.js+Express+Mongo

app.jspackage.json

modules/express/modules/mongodb/

MongoDB

[{name: 'jack'}, {name: 'tina'}, {..}, {..}]

HTTP GET (ajax) Request: http://server.com/employees/1

HTTP Responsecontent-type: application/json {name: 'jack'}

FrontendIonic+Cordova+AngularJS

BackendNode.JS+Express+Mongo

HTTP POST Request: http://server.com/employees/{name: 'amanda'}

HTTP Responsecontent-type: text/plainhttp://server.com/employees/3

CommunicationRESTandJSON

9

Frontend

10

JavaScript,LiveScript,JScript,ECMAScript?

• JavaScript• DevelopedbyNetscape• OriginallyJavaScript,thenLiveScriptandthenbacktoJavaScript.

• JScript• MicrosoftmadetheirownversionoftheJavaScript

• Leadtocompatibilityproblems• =>ECMAScript,efforttostandardizedifferentversionsoftheJ(ava)Script

11

ECMAScript

• ECMAScript isascriptinglanguage,standardizedbyEcmaInternational• InBrowsers,ECMAScript iscommonlycalledJavaScript

• JavaScript=Native(EcmaScript)+Hostobjects(browser)

• Java/ECMAscript isnowdays heavilyusedwhencreatingweb/mobileandevenDesktop- apps

12

LearningPathforFront-end

CoreEcmaScript

BrowserHostObjectsJavaScriptinFront-end

HTML5

CSSStatic

Web-pages

JavaScriptFrameworks:React,AngularJS,...

13

EcmaScriptVersions

Year Edition Naming

1997 1 ..

1998 2 ..

1999 3 Regex,betterstringhandling,try/catch,...

Abandoned 4 ..

2009 5 strictmode,gettersandsetters,JSON..

2015 6 ES2015 classes, modules,arrowfunctions,collections...

2016 7 ES2016 Math.pow =>**,array.prototype.includes

2017 8 ES2017 await/async

14

FromJScripttoTypeScript

• TypeScript isasuperset ofEcmaScriptdevelopedbyMicrosoft• Ithastypes!

• WhenEcmaScript6th Editionwasworkingprogress,typescriptgavealreadyclasses,modules,arrowfunctionsyntax.• Nowthatthe6th Ed.isreadytheadditionalbenefitusingTypeScriptistypes(andotherslikeinterfaces,generics...)• TypeScriptiscompiledtoEcmaScriptusingcompiler• It'sfirstclasslanguageinMicrosoftVisualStudioandinframeworkslikeAngular2.0

15

typescript.ts

> cat typescript.ts

var variable : string = "typescript";

console.log(variable);

> tsc typescript.ts

> cat typescript.js

var variable = "typescript";

console.log(variable);

Noticethatcompilercompilestypescripttojavascriptanditlosesthestringtypebecausethatisnotpartofjs!

16

BenefitofusingCompiler

> cat typescript.ts

var variable : string = "typescript";

variable = 8;

console.log(variable);

> tsc typescript.ts

typescript.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

17

ToolsforLearningEcmaScript

18

ChooseaCode-Editor/IDE

• AtombyGitHub• Customizablefreeeditor• Built-inpackagemanagerforinstallingnewpackages• Worksacrossoperatingsystems:OSX,LinuxorWindows

• VisualStudioCodebyMicrosoft• InadditiontoAtom...• Hasbuilt-insupport forJavaScript,TypeScriptandNode.js• Alsoextensiblebyplug-ins• GoesbeyondsyntaxhighlightingandprovidesautocompletewithIntelliSenseanddebugger

• WebStormbyJetBrains• FullIDE• Supportfor:Angular,React,Ionic,Cordova,ReactNative,Electron,Node.js..• Debugger,Unittesting

19

ChooseRuntimeEnvironment

• Forgetthebrowserfornow!• EcmaScriptisastandardandtherearemultipleimplementationsforruntimeenvironment;JavaScriptEngines• Canbetraditionalinterpreterorutilizejust-intimecompilationtobytecode

• Differentenginesavailable• V8byGoogle,powersChrome• NitrobyApple,powersSafari• ChakrabyMicrosoft,powersEdge• SpiderMonkey by MozillaFoundation,powersFirefox

• Rhino(JavaImplementation)managedbyMozillaFoundation• ...

20

RuntimeEnvironment:Node.js

• EasiestwaytouseV8JSEngineistoinstallNode.js• https://nodejs.org/en/

• Node.jsisbuiltontopofV8 andis"the"technologytousewhencreatingbackendapplicationusingJS• Alsoprovidespackageecosystem,npm(nodepackagemanager),thatcanbeusedtomanagejs-libraries

• npmisheavilyusedwhencreatingJavaScriptappstoday

• Node.js supportforES2015is99%->GoodJSenvironmentforlearningEcmaScript• http://node.green/

21

HelloWorld

22

23

24

VisualStudioCode- tips

• InstallCodeRunner- extensionforeasierrunningofnode(andother)apps• Debugging Nodeappsissupportedbydefault!• InstallNode.jsextensionpack

• ESLint• npm• JavaScriptSnippets• ...

25

Lab

26

npmpackagemanager

• Node.jscontainsanpm thatcanbeusedtoinstallvariousextensionsandpackages• Youcaninstallpackages

• local(specifictoyourapp)• ./node_modules

• global(canbeusedeverywhere)• /usr/local/lib/node_modules

• Whencreatinganodeproject,usuallyyouwillhaveafilepackage.jsondescribingtheprojectandit'sdependencies

27

Packages

28

Tryingtousepackage

29

npm init

Createspackage.json

withinformationaboutourproject

30

npm install project-name-generator --save

Now dirfordownloadedpackages

31

catpackage.json

package.jsonisupdated

32

cdnode_modules

Theproject-name-generatordependsonotherpackagewhichisdownloadedalso!

33

catproject-name-generator/package.json

34

nodemyapp.js

35

ESLint

• ESLintislintingutility(codequality)toolforJavaScript• Toinstall

• npm install --save-dev eslint• ESLintrequiresaconfigurationfile• Tocreateone,use

• ./node_modules/eslint/bin/eslint.js --init• Youcananswertoquestionsaboutstyleguideortakepopularstyleguides

36

AnsweringtoStyleGuideQuestions

37

RunningESLint

Addno-console:offtoinitfile

38

module.exports = {"env": {

"es6": true,"node": true

},"extends": "eslint:recommended","parserOptions": {

"sourceType": "module"},"rules": {

"no-console": "off","indent": [

"error",4

],"linebreak-style": [

"error","unix"

],"quotes": [

"error","double"

],"semi": [

"error","always"

]}

};

Addno-console:offtoinitfile

Lotofruleshttps://eslint.org/docs/rules/

39

VSCodehasalsoESLintpluginfor

integratinglintingincodeeditor

40

DifferentStyleGuides

• AirBnb• Google• "Standard"Style• Crockford'sCodingStandardsforJavaScript• NodeJSStyleGuide

41

HolyWaraboutStyles:Indentation

https://hackernoon.com/what-javascript-code-style-is-the-most-popular-5a3f5bec1f6f 42

HolyWaraboutStyles:Linttool?

https://hackernoon.com/what-javascript-code-style-is-the-most-popular-5a3f5bec1f6f 43

ESLint:ChoosingStyleGuide

44

StandardRules

• 2spacesforindentation• Singlequotesforstring• Nounusedvariables• Nosemicolons• ...• https://standardjs.com/

45

Lab

46

QuickintrotoECMAScript

47

References

• EcmaScript5.1LanguageSpesification• http://www.ecma-international.org/ecma-262/5.1/

• EcmaScript6LanguageSpesification(June2015)• http://www.ecma-international.org/ecma-262/6.0/index.html

• ReallygoodJavaScriptReferencefromMozilla• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference

• W3SchoolshavelotofJSstufftoobutremember• http://meta.stackoverflow.com/questions/280478/why-not-w3schools-com

48

GrammarandTypes

49

ECMAScriptBasics

• BorrowsmostofthesyntaxfromJavabutinfluencesfromotherlanguagesalso• JavaandJavaScriptaretotallydifferentasatechnology!

• ECMAScriptiscase-sensitive• Instructionsarecalledstatements andareseparatedtypically usingsemicolon (;)• StandardJavaScriptLinteravoidssemicolonusage

50

Aboutsemicolons

• Youcanwrite• console.log("hello");• console.log("world");

• Or• console.log("hello")• console.log("world")

51

Comments

//Oneline

/*multi-line*/

/*Nonested/*comments*/allowed*/

52

Variables

• Todeclareavariableusekeywordvarorlet• var x = 99;

• Variablenaminghassomerules• muststartwithaletter,underscore(_),dollarsign

• A-Zisdifferentfroma-z(casesensitive)• Afterthefirstletter,digitscanbeused(0-9)

53

VariableScope

• Globalvariable• Declarevariableoutsideoffunction,availableeverywhere

• Localvariable• Declarevariableinsideoffunction,availableinthatfunction

• BeforeES2015,noblockstatement!

54

var globalVariable = 1;

function doIt() {

var functionVariable = 4;

if(true) {

var anotherFunctionVariable = 5;

}

console.log(functionVariable); // 4

console.log(anotherFunctionVariable); // 5

}

if(true) {

var anotherGlobalVariable = 3;

}

console.log(globalVariable); // 1

console.log(anotherGlobalVariable); // 3

doIt(); // 4

// 5

Itisglobal!

Functionscope!

55

VariableHoisting

Thiscodeisthesame...var globalVariable = "Hello";

function doIt() {

console.log(globalVariable);

if(true) {

var globalVariable = "World";

}

}

doIt();

console.log(globalVariable);

...thanthisvar globalVariable = "Hello";

function doIt() {

var globalVariable;

console.log(globalVariable);

if(true) {

globalVariable = "World";

}

}

doIt();

console.log(globalVariable);

Itishoisted!

56

VariableHoisting

function doIt() {

console.log(myVar); // undefined

if(true) {

var myVar = "Hello World";

}

}

doIt();

57

ES2015VariableHoisting:let

function doIt() {

console.log(myVar); // myVar is not defined!

if(true) {

let myVar = "Hello World";

}

}

doIt();

Itisnothoisted!

58

WordAboutES2015

• WhendevelopingtobackendusingNode.jsdevelopercanchoosetheversionofNode.jsandusefreelymostofES2015features• Onthefront-endthingsgetcomplicatedsinceusermayhavewhateverbrowser andthosemaynotsupportES2015• ES2015canbecompiledtoolderES!

59

ES2015:const

• Constantcannotbechangedthroughassignment• constvariablesarenothoisted

const PI = 3.14;

PI = 99;

console.log(PI);

60

ES2015->ES5

Object.defineProperty(typeof global === "object" ? global: window, "PI", {

value: 3.141593,

enumerable: true,

writable: false,

configurable: false

})

console.log(PI);

61

DataTypes:Primitivetypes(6)

Type Possiblevalues

boolean true orfalsenull null

undefined undefined

number 41, 3.444

string "Hello World"

symbol uniqueandimmutableinstances(ES2015)

Allotherareobjects!

62

var booleanValue = true;

var stringValue = "some text";

var undefinedValue;

var numberValue = 4;

var nullValue = null;

// boolean

console.log(typeof booleanValue)

// string

console.log(typeof stringValue)

// undefined

console.log(typeof undefinedValue)

// number

console.log(typeof numberValue)

// object

console.log(typeof nullValue)

// false

console.log(null instanceof Object)

Languagedesignerror!

63

PrimitivetypesvsObjecttypes

• Let'slookatobjectslateronmorecarefully• ObjectinESisjustavariablecontainingproperties:

• var myObject = {"name": "Jack"};• console.log(myObject.name);

• Objectsarepassedbyreference• Primitivetypesarepassedbyvalue

64

String

• Stringliteralcontainscharactersenclosedby""or''var x = "Hello World";

• InES2015alsopossibilitytousetemplateliterals:`var mystring = `Lorem ipsum dolor sit amet,

consectetur adipiscing elit. Integer quis ante at

urna commodo dapibus. Aenean blandit, neque eget pellentesque

viverra, arcu nulla volutpat justo, ut congue est odio id justo.`

• ThereisstringprimitivetypeandStringobject!• ESwillmakeautomaticcastingbetweenthesetwo,soitispossibletoaccessallthemethodsprovidedbytheString:• console.log( x.charAt(0) );

65

DataTypeConversion

5 + null // returns 5 because null is converted to 0

"5" + null // returns "5null" because null is converted to "null"

"5" + 1 // returns "51" because 1 is converted to "1"

"5" - 1 // returns 4 because "5" is converted to 5

66

AboutNumbers

• Number(value),convertsentirestring• var i = Number("12");

• parseInt(value[, radix]), convertsstartofthestring• var i = parseInt("12px”, 10);• Radix?

• 10=>integernumber,8=>octalnumber,16=>hexadecimal

• NaN (Not a Number),checkusingisNaN(variable)• Resultoferroneousoperations

67

IndexedCollection:Arrays

• Arraysareobjectsbutinadditiontheyhavemoremethodsandauto-incrementkey-values• var stuff = ["a", "b", "c"]

• Thekeysarenow0,1and2• Thelengthofthearrayis3andit'slinkedtonumericalproperties

68

Input&Output– Depends!

• InBrowsers• Input:HTMLFormsorwindow.prompt("", "");• Output:DOMmanipulation,document.write("") orwindow.alert("");

• InV8/NodeJSorRhino/Spidermonkey• OutputtoCLI:print("..");• InputfromCLI:Isnotthateasy...

• Debugging• console.log("");

69

Lab

70

ControlFlow,LoopsandIteration

71

ConditionalStatements

if (condition_1) {

statement_1;

} else if (condition_2) {

statement_2;

} else if (condition_n) {

statement_n;

} else {

statement_last;

}

72

FalseValues

let array = [false, undefined, null, 0, NaN, ""];

for(let i=0; i<array.length; i++) {

if(array[i]) {

console.log("true");

} else {

console.log("false");

}

}

73

Comparison:trueorfalse?

let x = new Boolean(false);

if(x) {

console.log("true");

} else {

console.log("false");

}

74

Comparison:trueorfalse?

let x = new Boolean(false);

if(x == false) {

console.log("true");

} else {

console.log("false");

}

75

Equality

• Strictequality• ===

• Looseequality• ==

• ES2015• Object.is

76

77

Testing

console.log(Object.is(0, -0)); // false

console.log(0 === -0); // true

console.log(Object.is(-0, -0)); // true

console.log(Object.is(NaN, NaN)); // true

console.log(NaN === NaN); // false

78

Testing:NaN// cast String -> Number

let variable = Number("hello world");

if(variable == NaN) { // false

console.log("0) It was not a number")

}

if(variable === NaN) { // false

console.log("1) It was not a number")

}

if(Object.is(variable, NaN)) { // true

console.log("2) It was not a number");

}

if(isNaN(variable)) { // true

console.log("3) It was not a number");

}

79

switchcase

switch (expression) {

case label_1:

statements_1

[break;]

case label_2:

statements_2

[break;]

...

default:

statements_def

[break;]

}

80

while

let i=0;

while(i < 10) {

console.log(i);

i = i + 1;

}

81

do-while

let i=0;

do {

console.log(i);

i = i + 1;

} while(i < 10);

82

for

for(let i = 0; i < 10; i = i + 1) {

console.log(i);

}

83

for...of– forarrays

let array = ["jack", "tina"];

// Traditional forfor(let i = 0; i < array.length; i++) {

console.log(array[i]);}

// for - offor(let item of array) {

console.log(item);}

84

for...of– forarrays

let array = ["jack", "tina"];

// 0 => "jack", 1 => "tina", "key" => "value"

array["key"] = "value";

// for - of

for(let item of array) {

console.log(item); // ??

}

85

for...in– forobjects

let array = ["jack", "tina"];

// 0 => "jack", 1 => "tina", "key" => "value"

array["key"] = "value";

// for - in

for(let item in array) {

console.log(item); // ??

}

86

for...in– forobjects

let object = {"key1": "value1", "key2": "value2"};

for(let key in object) {

console.log(key);

console.log(object[key])

}

87

NumbersandText

88

Aboutnumbers

• Allnumbersaredouble-precision64-bit• Largestsafeinteger:9007199254740991

• Safe?Youcandocalculationsanddisplaynumberscorrectly

• Nospecifictypeforintegers• Alsosymbolicvalues

• +Infinity, -Infinity, NaN

let largeNumber = Math.pow(2, 53) - 1;

console.log(largeNumber == Number.MAX_SAFE_INTEGER); // true

console.log(largeNumber + 1 == largeNumber + 2); // true

89

Number// Largest integer valueconsole.log(Number.MAX_SAFE_INTEGER);

// Largest floating point valueconsole.log(Number.MAX_VALUE);

// Smallest floating point valueconsole.log(Number.MIN_VALUE);

// Same valuesconsole.log(Number.POSITIVE_INFINITY) console.log(+Infinity);console.log(Infinity);

// Same valuesconsole.log(Number.NEGATIVE_INFINITY)console.log(-Infinity);

// Same valuesconsole.log(Number.NaN);console.log(NaN);

90

Number

Number.parseFloat(..)

Number.parseInt(..)

Number.isFinite(..)

Number.isInteger(..)

Number.isNaN(..)

Number.isSafeInteger(..)

91

Math

Math.PI

Math.abs(..)

Math.min(..)

Math.max(..)

Math.random()

Math.round(..)

Math.sqrt(..)

...

92

Stringobjects

• EcmaScripthasStringprimitivetypeandobject• Primitivetypeiscastedtoobjectwhenneeded

• Useprimitivetype!

• Stringobjecthasvarietymethodsthatyoucanuse

let s = new String('foo');

console.log(s); // [String: 'foo']

console.log(typeof s); // object

93

SomeStringmethods

• charAt• startsWith• endsWith• split• slice• substring• match• replace

• toLowerCase• toUpperCase• trim

94

Date,TimeandNumberformatting

• Intlnamespacehaslanguagesensitivedate,timeandnumberformatting• Forformattingdatesandtime

• Intl.DateTimeFormat• Forformattingnumbers

• Intl.NumberFormat• NotethatNode.jsisbundledonlywithEnglish!

var date = new Date();

var dateTimeFormatter = newIntl.DateTimeFormat('fi-FI');

console.log(dateTimeFormatter.format(date));

95

Lab

96

IndexedCollectionsArrays...

97

CreatinganArray

// These all are equal...

let arr1 = new Array("hello", "world");

let arr2 = Array("hello", "world");

// But this is usually preferred:

let arr3 = ["hello", "world"];

98

CreatinganArraywithgivensize

const ARRAY_LENGTH = 10;

let arr1 = new Array(ARRAY_LENGTH);

// OR

let arr2 = [];

arr2.length = ARRAY_LENGTH;

99

var stuff = ["a", "b", "c"]

console.log(stuff[0]); // a

console.log(stuff[1]); // b

console.log(stuff[2]); // c

console.log(stuff.length); // 3

// Array's length and numerical properties are connected

stuff.push("d")

console.log(stuff.length); // 4

stuff["key"] = "value";

console.log(stuff); // [ 'a', 'b', 'c', 'd', key: 'value' ]

console.log(stuff.length); // 4!

delete stuff["key"];

console.log(stuff); // [ 'a', 'b', 'c', 'd' ]

stuff[4] = "e";

console.log(stuff); // [ 'a', 'b', 'c', 'd', 'e' ]

console.log(stuff.length); // 5

stuff = ["a", "b", "c"];

stuff[9] = "e";

console.log(stuff); // [ 'a', 'b', 'c', , , , , , , 'e' ]

console.log(stuff.length); // 10

100

.length

• lengthwillreturnlastelementindex+1• Itispossibletochangelengthatruntime• Ifgivingshorterlength,thearrayistruncated(removesitems)

101

IteratingoverArrays

1. Traditionalfor2. for of

3. forEach

4. for in (DON'T)

102

forEach(EcmaScript5th Edition)

let colors = ['red', 'green', 'blue'];

colors.forEach(function(color) {

console.log(color);

});

103

ArrayMethods

• concat()• join()• push()• pop()• shift()• unshift()• slice()• splice()

• reverse()• sort()• indexOf()• forEach()• map()• filter()• every()• some()• reduce()

104

everyandsome- example

let arr = ["apple", "banana", "carrot", "apple"];

// Checks all the values, if one of them does not// match with given condition, return value is false.let returnValue1 = arr.every(function (value, index, array) {

return value.length > 1; }

); console.log(returnValue1); // true

// Checks all the values, if one of them matches with// given condition, return value is true.let returnValue2 = arr.some(function (value, index, array) {

return value === "apple"; }

);

console.log(returnValue2); // true

105

KeyedCollections:MapandSet

106

Map

• Mapobjectisasimplekey/valuemapcollection• Youcaniterateitemsininsertionorder• Keyscanbewhatevervalue• Sizeiseasilyavailable

107

Examplevar animals = new Map();

animals.set('dog', 'woof');

animals.set('cat', 'meow');

console.log(animals.size); // 2

animals.delete('dog');

console.log(animals.has('dog')) // false

for (var [key, value] of animals) {

console.log(key + ' goes ' + value);

}

animals.clear();

console.log(animals.size);

108

Set

• Uniquevalues• Insertionorderisprovided

var mySet = new Set();

mySet.add(1);

mySet.add(1);

mySet.add(2);

// 1 2

for (let item of mySet) {

console.log(item);

}

// casting

let array = Array.from(mySet);

console.log(array);

109

Lab

110

Functions

111

Functions

• FundamentalbuildingblockinEcmaScript• Setofstatementsthatperformsataskorcalculatesavalue• Functionsareobjects!

112

SimpleFunction

function doIt() {

console.log("Hello World");

}

doIt();

113

PassingArgument

function doIt(value) {

console.log(value);

}

doIt("Hello World");

114

Passingargumentsandreturningvalue

function doIt(a, b) {

return a + b;

}

console.log( doIt(5,5) );

115

PredefinedArgument

function multiply(a, b = 1) {

return a * b;

}

console.log(multiply(5));

116

Functionsareobjects

function doIt1(a, b) {

return a + b;

}

console.log( doIt1(5,5) );

// The same than

var doIt2 = new Function("a","b", "return a+b;");

console.log ( doIt2(5,5) );

117

Andbecausetheyareobjects...

let functionObject = new Function("a","b", "return a+b;");

let anotherObject = functionObject;

console.log ( functionObject(5,5) );

console.log ( anotherObject(5,5) );

118

PassingFunctionObjects

function divide(a, b, success, error) {if(b === 0) {

error("Cannot divide with zero");} else {

let result = a / b;success(result);

}}

function onSuccess(result) {console.log(result);

}

function onError(message) {console.log(message);

}

divide(5, 0, onSuccess, onError);

119

arguments

function doIt() {

for(let item of arguments) {

console.log(item)

}

}

doIt("a");

doIt("a", "b");

doIt("a", "b", "c");

Predefinedpropertyoffunctions.Youcanfetchallthe

argumentsfromthearray

120

FunctionScoping:Works!

greeting("hello world");

function greeting(msg) {

console.log(msg);

}

121

FunctionScoping:DoesnotWork!

greeting("hello world");

var greeting = function (msg) {

console.log(msg);

}

variablegreetingishoistedandthe

valueisundefined

122

AnonymousFunction

greeting("hello world");

var greeting = function (msg) {

console.log(msg);

}

Anonymousfunction

declaration

123

Rememberthis?

function divide(a, b, success, error) {if(b === 0) {

error("Cannot divide with zero");} else {

let result = a / b;success(result);

}}

function onSuccess(result) {console.log(result);

}

function onError(message) {console.log(message);

}

divide(5, 0, onSuccess, onError);

124

Rememberthis?

function divide(a, b, success, error) {if(b === 0) {

error("Cannot divide with zero");} else {

let result = a / b;success(result);

}}

function onSuccess(result) {console.log(result);

}

function onError(message) {console.log(message);

}

divide(5, 0, onSuccess, onError);

Insteadofpassingnamedfunctionswecoulduseanonymous

functions

125

Anonymousfunctions

function divide(a, b, success, error) {

if(b === 0) {

error("Cannot divide with zero");

} else {

let result = a / b;

success(result);

}

}

divide(5, 0, function(result) {

console.log(result);

}, function(message) {

console.log(message);

});

Passinganonymousfunctions

126

Pattern:AvoidGlobals

(function() {

var thisIsNotGlobalVariable = "hello";

console.log(thisIsNotGlobalVariable);

})()

127

ES2015:ArrowSyntax

function divide(a, b, success, error) {

if(b === 0) {

error("Cannot divide with zero");

} else {

let result = a / b;

success(result);

}

}

divide(5, 0, result => console.log(result),

message => console.log(message));

Passinganonymousfunctionsusingthearrowsyntax:simplersyntaxandlexicalthis

- keyword

128

Lab

129

FunctionthatreturnsaFunction

function doIt() {function hello() {

console.log("Hello World");}

return hello;}

var func = doIt();func();

130

function doIt(condition) {

let myFunc;

if(condition) {

myFunc = function() {

console.log("Hello");

}

} else {

myFunc = function() {

console.log("World");

}

}

return myFunc;

}

doIt(true)();

doIt(false)();

131

Closures

function outer() {let x = 20;function inner() {

console.log(x);

}return inner;

}

var innerFunction = outer();// is x still in memory?innerFunction();

Yes!Whenreturninginnerfunctionthatusesouterfunctionsvariables,thosevariablesarestoredin

memory.

132

Pattern:Privatemembervariables

function createObject() {let privateName = "Jack";let object = {

getName: function() {return privateName;

},setName: function(name) {

privateName = name;}

}return object;

}

var person = createObject();console.log(person.getName());person.setName("Tina");console.log(person.getName());

133

Lab

134

Objects

135

Objects

• Objectiscollectionofproperties• propertyisaassociationbetweenkeyandvalue• valuecanbeforexampleafunction->alsocalledmethod

• Objects,likefunctionsareafundamentalpartofEcmaScript• Thekeysmustbestring,ifnumbersused,itwillmakeatypecast

• Sokeyscanbewhateveriftheycanbeconvertedintoastring

136

ObjectCreation

• Objectinitializer• let o = {};

• UsingObjectconstructor• let o = new Object();

• UsingCustomconstructor• let o = new Car();

• Object.create (usedininheritance)• let dog = Object.create(animal);

137

ObjectInitializer

// Object initializer syntax {}

let object = { key: "value",

"hello": "world",

2: "another" };

console.log(object.key);

console.log(object["key"]);

console.log(object.hello);

console.log(object["2"]);

Alsopossibletoaccessusing[]syntax

Insomecases[]syntaxismandatory..ifkeyisnot

avalidjsidentifier138

ObjectConstructor

let object = new Object();

object.key = "value";

object.hello = "world";

object["2"] = "another";

Possibilitytoaddpropertiesinruntime

139

Dynamickey

let random = Math.random() * 100;

let object = {};

object.mykey = "value1"; // {mykey: "value1"}

object.random = "value2"; // {mykey: "value1", random: "value2"}

object[random] = "value3"; // {mykey: "value1", random: "value2", 46.123: "value3"}

Mustusebracketsfordynamickey!

140

EcmaScript5:Preventextensions,Seal,Freeze

Add Delete Modify

Object.preventExtensions NO YES YES

Object.seal NO NO YES

Object.freeze NO NO NO

141

PreventExtensions

var obj1 = {id: 1};

Object.preventExtensions(obj1);

obj1.name = "Jack";

obj1.id = 3;

delete obj1["id"]; Failssilentlyunlessinstrictmode

142

Seal

var obj = {id: 1};

Object.seal(obj);

obj2.name = "Jussi";

obj2.id = 4;

delete obj2["id"];

143

Freeze

var obj = {id: 1};

Object.freeze(obj);

obj.name = "Jussi";

obj.id = 4;

delete obj["id"];

144

EcmaScript5:Object.defineProperty

var obj = {};

Object.defineProperty( obj, "name", {

value: "something", // Notice: you cannot have value and get + set

get: someFunction,

set: someOtherFunction,

writable: false, // property cannot be changed

enumerable: true, // will be iterated in for in

configurable: true // can be deleted

});

console.log( obj.name );

145

Examplevar obj = {};

Object.defineProperty( obj, "name", {

value: "jeppe",

writable: false, // property cannot be changed

enumerable: false, // will NOT be iterated in for in

configurable: true // can be deleted

});

obj.name = "tina";

console.log(obj.name);

for(var key in obj) {

console.log(key);

}

Cannotchange

Nothinginhere146

ConstructorFunction

function Person(name) {

this.name = name;

}

var tina = new Person("Tina");

console.log(tina.name);

Writethefunctionnamewithcapital(convention)

Usenew– keywordtocreateobject

this referstotina

147

Whathappenshere?

function Person(name) {

this.name = name;

}

var tina = Person("Tina");

console.log(name)

Forgottousethenewword!

148

Pattern:Preventingmisuse

function Person(name) {

if(!(this instanceof Person)) {

throw new TypeError("Cannot call a constructor function without new.");

}

this.name = name;

}

var tina = Person("Tina");

Typecheckingofthis

ifnewismissing,throwerror

149

EcmaScript2015:Class

class Circle {constructor (radius) {

this.radius = radius;}

getArea() {return Math.PI * this.radius * this.radius;

}}

var c = new Circle(5);console.log(c.getArea());

150

EcmaScript2015:Class

class Circle {constructor (radius) {

this.radius = radius;}

getArea() {return Math.PI * this.radius * this.radius;

}}

var c = new Circle(5);

console.log(c.getArea());

Hasprebuiltsupportforcheckingifnewkeywordis

usedornot.Ifnewkeywordismissing,this

willfail!

151

Valuecanbeanything,likefunctions

let MyMath = {abs: function (value) {

if (value < 0) {return value * -1;

} else {return value;

}}

};

console.log ( MyMath.abs(-7) );

152

UsageofArrowFunctionandTernaryOperationlet MyMath = {

abs: (value) => value < 0 ? value * -1 : value

};

console.log ( MyMath.abs(-7) );

153

Enumerating:for...in

var object = {key1: "value1", key2: "value2"};

for (var key in object) {

console.log(key + " = " + object[key]);

}

154

Lab

155

Keywordthis

156

Keywordthis

• Node.jsisalittlebitdifferenttoEcmaScriptwhenitcomestothekeywordthis• Whenusingthisinbrowsers,youwilldifferentresultsthaninNode• OnemajordifferenceisthatNodeusesmoduleswhereonefileisonescope. Inbrowsers,thereisonescope• Fornowlet'sseehowkeywordthis behavesinbrowsers

157

Keywordthis inbrowsers

console.log(this === window);

console.log(doIt() == window);

function doIt() {

return this;

}

Botharetrue

Infunctionsandinglobal,thisreferstoaglobalmainobjectwhichiswindow

158

GlobalvariablesinBrowsers

this.variable = "Hello";console.log(window.variable);

doIt();console.log(window.name);console.log(name);

function doIt() {this.name = "Jack";

}

Youdonothavetowritethemainobject!It'sglobalvariable!

159

Bindingandkeywordthis

160

Thisshouldwork...

function Circle(radius) {this.radius = radius;this.getArea = function() {

return Math.PI * this.radius * this.radius;}

} var c = new Circle(5);console.log(c.getArea());

Wheninvokingthemethod,keywordthis is"replaced"withc - object

161

Wehaveaproblem

function Circle(radius) {this.radius = radius;this.getArea = function() {

return Math.PI * this.radius * this.radius;}

}

var c = new Circle(5);var theFunctionObject = c.getArea;console.log(theFunctionObject());

NothisdoesNOTrefertoc– anymore...itwillnot

work

162

Function:bind

function Circle(radius) {

this.radius = radius;

this.getArea = function() {

return Math.PI * this.radius * this.radius;

} } var c = new Circle(5);

var theFunctionObject = c.getArea;

var newBindedFunctionObject = theFunctionObject.bind(c);

console.log(newBindedFunctionObject());

Createcopyofthatfunctionwherethisrefers

toc

163

Example

var obj = {url: "./test.html",fetchUrl: function() {

fetchIt(this.url, whenReady);}

};

function whenReady(content) {console.log("Fetched from " + this.url);console.log("With content of " + content);

}

function fetchIt(myurl, onSuccess) {// Fetching from myurl the content, when ready invoke// the onSuccessonSuccess("<html>...</html>");

}

obj.fetchUrl();

this?NOTworking!

164

Thesamebutnowusingofanonymousfunctionsvar obj = {

url: "./test.html",fetchUrl: function() {

fetchIt(this.url, function(content) {console.log("Fetched from " + this.url);console.log("With content of " + content);

});}

};

function fetchIt(myurl, onSuccess) {// Fetching from myurl the content, when ready invoke// the onSuccessonSuccess("<html>...</html>");

}

obj.fetchUrl();

this?NOTworking!

165

Binding

var obj = {url: "./test.html",fetchUrl: function() {

fetchIt(this.url, (function(content) {console.log("Fetched from " + this.url);console.log("With content of " + content);

}).bind(this));}

};

function fetchIt(myurl, onSuccess) {// Fetching from myurl the content, when ready invoke// the onSuccessonSuccess("<html>...</html>");

}

obj.fetchUrl();

Sendacopyofthatfunction!

166

Pattern:UsingClosure

var obj = {url: "./test.html",fetchUrl: function() {

var _this = this;fetchIt(this.url, function(content) {

console.log("Fetched from " + _this.url);console.log("With content of " + content);

});}

};

function fetchIt(myurl, onSuccess) {// Fetching from myurl the content, when ready invoke// the onSuccessonSuccess("<html>...</html>");

}

obj.fetchUrl();

Itworks!

167

NoneedforPatternswhenusingArrowSyntaxvar obj = {

url: "./test.html",fetchUrl: function() {

fetchIt(this.url, (content) => {console.log("Fetched from " + this.url);console.log("With content of " + content);

});}

};

function fetchIt(myurl, onSuccess) {// Fetching from myurl the content, when ready invoke// the onSuccessonSuccess("<html>...</html>");

}

obj.fetchUrl();

Itworks!Lexicalthis

168

Lab

169

EcmaScript5:Strictmode

170

AboutStrictMode

• IntroducedinEcmaScript5,strictmodemakeschangesinnormalEcmaScriptsemantics• Differences

1. Strictmodecanrunfasterinidenticalcodethanwithoutstrict2. Silenterrors->Throwerrors(willfail)3. Prohibetssomesyntax

• Enableglobally orinfunction• Useit!

171

Silenterror

Infinity = 9;

NaN = 12;

console.log(Infinity);

console.log(NaN);Willfailbutit

issilent

172

Silenterror

var obj1 = {id: 1};

Object.preventExtensions(obj1);

obj1.name = "Jack";Willfailbutit

issilent

173

Global:Usestrict

"use strict";

var obj1 = {id: 1};

Object.preventExtensions(obj1);

obj1.name = "Jack";

TypeError:Can'taddpropertyname,objectisnotextensible

Enablestrictmode.It'sjustastring!

174

Infunctions:usestrict

function doIt() {

"use strict";

console.log("This is under strict mode");

}

Nowonlythisfunctionusesstrictmode

175

Enablingstrict

"use strict";

var obj1 = {id: 1};

Object.preventExtensions(obj1);

obj1.name = "Jack";

176

Variablewithoutvar

function doIt() {

variable = 4;

}

doIt();

console.log(variable);

Forgotthevarwordhere...itcreatesaglobal

variable!Confusing

177

Instrictmode,youhavetousethevar

"use strict";

function doIt() {

variable = 4;

}

doIt();

console.log(variable);

variableisnotdefined!

178

RegularExpressions

179

Regex

• RegularExpressions(Regex)arepatternsusedtomatchcharactercombinationsinstrings• InEcmaScript,regexareobjectsofRegExp

• var re = new RegExp('ab+c');• Alsoregexliteralavailable

• var re = /ab+c/

180

RegexLiteral:LoadedwhenScriptisloaded

var variable = "ab+c";

var regex1 = /variable/;

var regex2 = /ab+c/

console.log(regex1.test("variable"));

console.log(regex2.test("abbc"));

Botharetrue!Youcannothavedynamiccontentinregexliteral

181

SimpleRegex

var regex = /hello/;

console.log(regex.test("hello world")); // true

console.log(regex.test("world hello world")); // true

console.log(regex.test("world helxlo world")); // false

182

Begin(^)andEnd($)

var regex1 = /^hello/;

var regex2 = /hello$/;

var regex3 = /^hello$/;

console.log(regex1.test("hello world")); // true

console.log(regex2.test("world hello")); // true

console.log(regex3.test("hello")); // true

console.log(regex3.test("hellohello")); // false

183

Amount:+,*,?,{}var regex1 = /^(hello)+$/; // [1,n]var regex2 = /^(hello)*$/; // [0,n]var regex3 = /^(hello)?$/; // [0,1]var regex4 = /^(hello){0,3}$/; // [0,3]

console.log(regex1.test("")); // falseconsole.log(regex1.test("hello")); // trueconsole.log(regex1.test("hellohello")); // true

console.log(regex2.test("")); // trueconsole.log(regex2.test("hello")); // trueconsole.log(regex2.test("hellohello")); // true

console.log(regex3.test("")); // trueconsole.log(regex3.test("hello")); // trueconsole.log(regex3.test("hellohello")); // false

console.log(regex4.test("")); // trueconsole.log(regex4.test("hello")); // trueconsole.log(regex4.test("hellohello")); // true

184

OtherSpecialCharacters

Character Meaning

. Anycharacter,forexample/.n/matchesanandon

\. equals todot

x|y Or,forexample /black|white/matcheseitherblackorwhite

[xyz] or [a-z] Character set

[^abc] Negatedcharacterset,cannotbeaborc.

\d [0-9]

\D [^0-9]

\s Whitespace, space,tab...

\S Nonwhitespace

\w [a-zA-Z0-9_]

\W [^a-zA-Z0-9_]185

WorkingwithRegex

Method Meaning

exec ARegExpmethodthatreturnsarrayofinformationaboutthematch

test ARegExpmethodthatreturnstrueorfalse

match AStringmethodthatreturnsarrayofinformation aboutthematch

search AStringmethodthatreturnsindex ofthematch

replace AStringmethodthatexercutesasearchandreplacesthematchedsubstring

split AStringmethodthatbreaksastringintoanarrayofsubstrings

186

RegExpexecvstest

var regex = /hello/; // [1,n]

// [ 'hello', index: 8, input: 'testing hello does it work?' ]

console.log( regex.exec("testing hello does it work?") );

// null

console.log( regex.exec("mickeymouse") );

// false

console.log( regex.test("mickeymouse") );

// true

console.log( regex.test("hello") );

187

Stringmatch,search,replace,splitvar regex = /hello/;

var mj = "testing hello does it work?";

// [ 'hello', index: 8, input: 'testing hello does it work?' ]

console.log( mj.match(regex) );

// 8

console.log( mj.search(regex) );

// testing world does it work?

console.log( mj.replace(regex, "world") );

// [ 'testing ', ' does it work?' ]

console.log( mj.split(regex) );

188

ExampleofFlags

var regex1 = /hello/i;

var regex2 = new RegExp("hello", "i");

console.log( regex1.test("HelLo") );

console.log( regex2.test("HelLo") );

189

Lab

190

InheritanceinEcmaScript

191

AboutInheritance

• Codereuseisimportant• Inheritancecanhelp

• JavaScriptdoesnothaveclasses,sonospecialkeywordforextending• ThiscanbeveryconfusingforJava/C#developers• Objectsinheritobjects

• WellECMAScript6hasclasses.Butintheendit'sjustsyntacticsugarwhereunderneathobjectinheritesanotherobject

192

ObjectextendsObject

• InEcmaScriptobjectextendsotherobject• Everyobjecthasspecial__proto__ propertythatlinkstoobjectthatitinherites

193

(Bad)exampleof__proto__

var parent = {method1: function() { console.log("A"); }

}

var child = {__proto__: parent,method2: function() { console.log("B"); }

}

child.method1(); // Achild.method2(); // B

childextendsparent

194

__proto__

• __proto__ isdepricated,non-standard andshouldnotbeused!• Togettheparent,use

• Object.getPrototypeOf(child)• Tosettheparent,use(OnlyinEcmaScript2015!)

• Object.setPrototypeOf(child, parent)

195

Testingvar parent = {

method1: function() { console.log("A"); }

}

var child = {

method2: function() { console.log("B"); }

};

Object.setPrototypeOf(child, parent);

console.log(Object.getPrototypeOf(child) == parent); // true

child.method1(); // A

child.method2(); // B

196

Object.setPrototypeOf(child, parent)

• TheObject.setPrototypeOf alterstheobject's__proto__ andthiscanbeveryslowoperation• AlsoObject.setPrototypeOf isEcmaScript2015feature,soitwon'tworkforexampleinolderbrowsers

• Insteadofalteringobject's__proto__,createnewobjectwithdesiredparentusingObject.create(obj, parent) • SupportedfromEcmaScript5th edition->

197

Object.create(obj)

var parent = {method1: function() { console.log("A"); }

}

var child = Object.create(parent);child.method2 = function() { console.log("B"); }

console.log(Object.getPrototypeOf(child) == parent); // true

child.method1(); // Achild.method2(); // A

Nownewobjectiscreatedwhichparentis

parent

198

WorkingwithConstructors

• Whenwriting• function Animal() { }

• Twoobjectsarecreated!• 1)Animal• 2)Animal.prototype

• Thesetwoobjectsarelinkedtogether!

199

Example

function Animal() {

}

console.log(Animal instanceof Function); // true

console.log(Animal.prototype instanceof Object); // true

console.log(Animal.prototype.constructor == Animal) // true

Animal(Function– Object)

X

prototype

constructor

200

Constructorfunctionandnew

• Constructorfunctionisusedwithnew– keyword• var spot = new Animal();

• Bydefaultthespot inheritesAnimal.prototype!

Animal(Function– Object)

AnimalParent

prototype constructor

spot

__proto__

Parentobject!

201

Testing

function Animal() { }

var spot = new Animal();

console.log(spot.__proto__ == Animal.prototype);

console.log(Object.getPrototypeOf(spot) == Animal.prototype);

Non-standardway

spot extendsAnimal.prototype

202

203

Example

function Animal() { }

var animal1 = new Animal();var animal2 = new Animal();

var animal3 = new Animal();

Animal.prototype.name = "Jack";

console.log(animal1.name); // "Jack"console.log(animal2.name); // "Jack"console.log(animal3.name); // "Jack"

animal1,animal2 andanimal3 extend

Animal.prototype

204

function Animal() {}

function Dog() {}

var spot = new Dog();

Object.setPrototypeOf(Dog.prototype, Animal.prototype);

console.log(Dog.prototype.__proto__ == Animal.prototype);

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(spot.__proto__.__proto__ == Animal.prototype); console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

EcmaScript2015Feature,canbeslow.NowDog.prototype extendsAnimal.prototype.spotextends

Dog.prototype

true

true

205

Animal.prototype

Dog.prototype

spot1

animal1

spot2 spot3

animal2

206

function Animal() {}

function Dog() {}

var spot = new Dog();

Object.setPrototypeOf(Dog.prototype, Animal.prototype);

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

UseObject.create(..) instead

207

function Animal() {}

function Dog() {}

var spot = new Dog();

Dog.prototype = Object.create(Animal.prototype);

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name);

Createsanewobject!Wehaveaproblem...

undefined

208

function Animal() {}

function Dog() {}

var spot = new Dog();

Dog.prototype = Object.create(Animal.prototype);

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name);

DogParent

spot

__proto__NowspotextendsDogParentwhichisaccessedbyDog.prototype

Dog

prototype

209

function Animal() {}

function Dog() {}

var spot = new Dog();

Dog.prototype = Object.create(Animal.prototype);

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name);

Thiscreatesanewobject!

210

function Animal() {}

function Dog() {}

var spot = new Dog();

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

ThenewObject hereisthenewobjectcreated!

211

function Animal() {}

function Dog() {}

var spot = new Dog();

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParent

spot

__proto__

Dog

prototype

newObject

__proto__

Animal.prototype

212

function Animal() {}

function Dog() {}

var spot = new Dog();

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParent

spot

__proto__

Dog

prototype

newObject

__proto__

Animal.prototype

213

function Animal() {}

function Dog() {}

var spot = new Dog();

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParent

spot

__proto__

Dog

prototype

newObject

__proto__

Animal.prototype

Dog.prototype=>newObjectnewObject.__proto__=>Animal.prototype

=true!

214

function Animal() {}

function Dog() {}

var spot = new Dog();

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParent

spot

__proto__

Dog

prototype

newObject

__proto__

Animal.prototypespot__proto=>DogParent

false!

215

Let'schangeorderfunction Animal() {}

function Dog() {}

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

Let'screatefirstthenewObjectandthencreatethespot!

216

function Animal() {}

function Dog() {}

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParentDog

prototype

217

function Animal() {}

function Dog() {}

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParentDog

prototype

newObject

__proto__

Animal.prototype

218

function Animal() {}

function Dog() {}

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

DogParent(garbagecollectorwilldeletethis)

Dog

prototype

newObject

__proto__

Animal.prototype

219

function Animal() {}

function Dog() {}

let newObject = Object.create(Animal.prototype);

Dog.prototype = newObject;

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

Dog

prototype

newObject

__proto__

Animal.prototypeBydefaultspotwillextend

Dog.prototypewhichisnowthenewObject

spot

__proto__

220

function Animal() {}

function Dog() {}

Dog.prototype = Object.create(Animal.prototype);

var spot = new Dog();

console.log(Object.getPrototypeOf(Dog.prototype) == Animal.prototype);

console.log(Object.getPrototypeOf(Object.getPrototypeOf(spot)) == Animal.prototype);

Animal.prototype.name = "jack";

console.log(spot.name); // "jack"

Dog

prototype

NewDogParent

__proto__

Animal.prototype

spot

__proto__

WedonotneedthenewObjectpointer

221

Object.create(..)- recap

function Animal() {}

function Dog() {}

// EcmaScript 5

// Create new object that extends Animal.prototype

Dog.prototype = Object.create(Animal.prototype);

// Now spot -> Dog.prototype -> Animal.prototype

var spot = new Dog();

console.log(spot.__proto__ == Dog.prototype); // true

console.log(spot.__proto__.__proto__ == Animal.prototype); // true

222

Animal.prototype

Dog.prototype

spot1

animal1

spot2 spot3

animal2

223

Wearenotdoneyet...

224

Constructors

function Dog() {}

var spot = new Dog();

console.log(spot.constructor == Dog);

Dog

prototype

DogParent

constructor

spot

__proto__

Youcanaskfromanobjectwhatisit'sconstructor.Theconstructorpropertyisbuiltintheparent

object

Twoobjectsarecreated!TheDogParentobjecthasaconstructor

property!

225

Constructors

function Animal() {}

function Dog() {}

Dog.prototype = Object.create(Animal.prototype);

var spot = new Dog();

console.log(spot.constructor == Dog);

Createsanewobjectwhich__proto__pointstoAnimal.protototype.The

newobjectdoesnothaveconstructorproperty!

226

Dog

prototype

(thenewobject)

__proto__

spot

__proto__

Animal

prototype

AnimalParent

constructor

console.log(spot.constructor);

Constructorpropertyisnotfoundinspot.Itwilltrytofinditinthenewobject.It'snotthereeither!ThenitwillfetchitfromtheXandendresultisthatspotiscreatedfromAnimal!

227

Dog

prototype

(thenewobject)

__proto__constructor

spot

__proto__

Animal

prototype

AnimalParent

constructor

Dog.prototype.constructor = Dog;

Let'saddthis!

228

Done!

function Animal() {}

function Dog() {}

Dog.prototype = Object.create(Animal.prototype);

Dog.prototype.constructor = Dog;

var spot = new Dog();

229

InvokingBaseConstructor

230

Function.call- method

function Dog(name) {this.name = name;

}

let spot = new Dog("Spot");console.log(spot.name);

let obj = {};Dog.call(obj, "Vilma");console.log(obj.name);

Youcaninvokethefunctionanddefinewhatthismeansin

runtime

thisnowreferstospot-object

231

WhenusingConstructor- functionsfunction Shape(x, y, color) {

this.x = x;

this.y = y;

this.color = color;

}

function Circle(x, y, color, radius) {

Shape.call(this, x, y, color);

this.radius = radius;

}

let circle = new Circle(0, 0, "red", 5);

console.log(circle.color);

232

EcmaScript2015:Classes

233

class Shape {constructor(x, y, color) {

this.x = x;this.y = y;this.color = color;

}}

class Rectangle extends Shape {constructor (x, y, color, width, height) {

super(x, y, color);this.width = width;this.height = height;

}}class Circle extends Shape {

constructor (x, y, color, radius) {super(x, y, color);this.radius = radius;

}}

let circle = new Circle(0,0,"red",5);console.log(circle);

Alotnicersyntaxforcreatinginheritance!

234

class Shape {constructor(x, y, color) {

this.x = x;this.y = y;this.color = color;

}}

class Rectangle extends Shape {constructor (x, y, color, width, height) {

super(x, y, color);this.width = width;this.height = height;

}}class Circle extends Shape {

constructor (x, y, color, radius) {super(x, y, color);this.radius = radius;

}}

Shape.prototype.hello = "world";

let circle = new Circle(0,0,"red",5);

console.log(circle.hello);

Butitissyntacticalsugar!!

235

Let'scompilethissyntaxtoolder

EcmaScriptà (OhDear....)

236

React- Example

• ReactisaJavaScriptframeworkforbuildingUIinfront-end• ItisdevelopedbyFacebookandverypopular

• YoucreateUIcomponentsintheframework• UsesEcmaScript2015andJSX

• CompiledtoolderEcmaScriptusingBabelsoitworksonbrowsers

class Welcome extends React.Component {

render() {

return <h1>Hello World</h1>;

}

}

237

EcmaScript2015(6th edition)

238

NewFeatures

• ArrowFunctions• Parametervalues• Objectproperties• Modules• Classes• Somenewbuiltmethods

239

ArrowFunctionslet array = [0,1,2,3,4];

array.forEach(doIt);

function doIt(value) {

console.log(value);

}

array.forEach(function(value) {

console.log(value);

});

array.forEach((value) => {

console.log(value);

});

array.forEach((value) => console.log(value) );

240

Lexicalthis

var object = {array: [0,1,2,3,4],doIt: function() {

this.array.forEach(function(value) {this.array.push(value);

});}

}

object.doIt();

Cannotreadproperty'push'ofundefined

241

Lexicalthis

var object = {

array: [0,1,2,3,4],

doIt: function() {

var _this = this;

this.array.forEach(function(value) {

_this.array.push(value);

});

}

}

object.doIt();

Itworkswhenusingclosure

242

Lexicalthis

var object = {array: [0,1,2,3,4],doIt: function() {

this.array.forEach((value) => {this.array.push(value);

});}

}

object.doIt();

Works!

243

DefaultParametervalues

function printIt(text, amount = 1) {

for(let i = 0; i < amount; i++) {

console.log(text);

}

}

printIt("text");

printIt("text", 7);

244

VariadicParameterValues

function printIt(amount, ...text) {for(let i = 0; i < amount; i++) {

for(let j = 0; j < text.length; j++) {console.log(text[i]);

}}

}

printIt(1, "text");printIt(2, "hello", "world");

245

SpreadOperator

var array1 = [ "hello", "world" ];

var array2 = [ 1, ...array1 ];

// [ 1, 'hello', 'world' ]

console.log(array2);

246

InterpolationofString

var message = "hello";

var html = `

<div>

<p>${message}</p>

</div>

`;

console.log(html);

247

ObjectProperties

let x = 0;

let y = 1;

let obj = { x, y };

console.log(obj.x);

console.log(obj.y);

248

Modules

249

AboutModules

• ModulesSystems1. AMDSpecification(RequireJS)2. CommonJSModules(NodeJS)3. ES2015officialmodule

• InEcmaScript2105forthefirsttimeit'sbuiltintolanguage.Supportisweak.• It'spossibletocompileES6ModulestoAMDorCommonJS• NodewillsupportES2015modulesintheupcomingversions• Angular2FrameworkusesES2015modules

250

ES2015Modules

251

Babel

• SinceES2015modulesupportisweak,installBabeltranspiler• TranspilerwillcompilenewES2015featurestoolderESthatyoucanuseinNodeJSorBrowsers• Toinstallglobally

• npm install -g babel-cli

252

EcmaScript2015:app.js

import { generateRandom, sum } from 'utility';

console.log(generateRandom()); // logs a random number

console.log(sum(1, 2)); // 3

253

EcmaScript2015:utility.js

function generateRandom() {

return Math.random();

}

function sum(a, b) {

return a + b;

}

export { generateRandom, sum }

254

CommonJS

255

CommonJS

• CommonJSisaprojectwiththegoalofspecifyingecosystemforJSoutsideofBrowser• WasstartedbyMozillaengineer,initalnameServerJS

• CommonJSdescribedalotofspecifications,includingmodules• ThismodulespecificationisimplementedinNodeJS• require toincludemodules• exports tomakethingsavailable

256

app.js

// import { generateRandom, sum } from 'utility';

require("./utility.js");

console.log(generateRandom()); // logs a random number

console.log(sum(1, 2)); // 3

257

utility.js

generateRandom = function() {

return Math.random();

}

sum = function (a, b) {

return a + b; }

258

ExampleModule:randomModule.js

'use strict';

/*** Returns random integer number between [min, max].

* @param {number} min* @param {number} max* @return {number}*/

module.exports = function(min, max) {return Math.floor(Math.random() * (max - min + 1)) + min;

};

UsesJSdoc

259

ExampleModule

'use strict';

var random = require("./randomModule");

console.log(random(1,10));

260

ExportingObject

'use strict';

var MyMath = {

random: function(min, max) {

return Math.floor(Math.random() * (max - min + 1)) + min;

},

abs: function(value) {

return (value < 0) ? value * -1: value;

}

};

module.exports = MyMath;

261

ImportingObject

'use strict';

var MyMath = require("./mathModule");

console.log(MyMath.random(1,10));

console.log(MyMath.abs(-7));

262

exportsvsmodule.export

'use strict';

module.exports.variable1 = "hello";

exports.variable2 = "world";

thesepointtothesameobject

263

exportsvsmodule.exports

'use strict';

var module = { exports: {} };

var exports = module.exports;

module.exports.variable1 = "hello";

exports.variable2 = "world";

return module.exports;

Itwillalwaysreturn

module.exports

264

WhatHappens?

'use strict';

var user = {name: "Jack"};

module.exports = user;

exports.variable = "hello";

var object = require("./randomModule");

console.log(object.name);

console.log(object.variable);

265

NowTwoDifferentObjects!

module.exports

exports

{name: "jack"}

{variable: "hello"}

266

ExceptionHandling

267

Examplefunction divide(a, b) {

if(!(typeof a == 'number' && typeof b == 'number')) {

throw "You must give number variables";

} else {

return a / b;

}

}

try {

console.log( divide(1, 5) );

console.log( divide("do", "this?") );

} catch(e) {

console.log(e);

}

268

function MustBeNumbersException(message) {

this.message = message;

this.name = "MustBeNumbersException";

}

function divide(a, b) {

if(!(typeof a == 'number' && typeof b == 'number')) {

throw new MustBeNumbersException("You must give number variables");

} else {

return a / b;

}

}

try {

console.log( divide("does not work", 0) );

} catch(e) {

console.log(e.name);

console.log(e.message);

}

Betterversion,ourown

exceptionobject

269

function MustBeNumbersException(message) {this.message = message;this.name = "MustBeNumbersException";

}

function ZeroDivisionException(message) {this.message = message;this.name = "ZeroDivisionException";

}

function divide(a, b) {if(!(typeof a == 'number' && typeof b == 'number')) {

throw new MustBeNumbersException("You must give number variables");} else if(b == 0) {

throw new ZeroDivisionException("Cannot divide with 0");} else {

return a / b;}

}

try {console.log( divide(1, 0) );

} catch(e) {console.log(e.name);console.log(e.message);

}

Bothoftheexceptionsgo

here

270

function MustBeNumbersException(message) {this.message = message;this.name = "MustBeNumbersException";

}

function ZeroDivisionException(message) {this.message = message;this.name = "ZeroDivisionException";

}

function divide(a, b) {if(!(typeof a == 'number' && typeof b == 'number')) {

throw new MustBeNumbersException("You must give number variables");} else if(b == 0) {

throw new ZeroDivisionException("Cannot divide with 0");} else {

return a / b;}

}

try {console.log( divide(1, "k") );

} catch(e) {if (e instanceof MustBeNumbersException) {

console.log("annapa numeroita.");} else if (e instanceof ZeroDivisionException) {

console.log("ei nollalla saa jakaa.");}

}

Checkingwhatexceptionwas

thrown

271

UnitTesting

272

UnitTestingFrameworks

• Mocha• Jasmine• Should• NodeUnit• jsUnit

273

Mocha

• Installglobally• npm install –globally mocha

• Createtest/test.js• Youcanruntests

• mocha test/test.js• Orifyoumodifypackage.json

• npm test

274

MyMathmodule

'use strict';

var MyMath = {

abs: function(value) {

return (value < 0) ? value * -1: value;

},

max: function(number1, number2) {

return (number1 < number2) ? number2: number1;

}

};

module.exports = MyMath;

275

test/test.jsvar assert = require('assert');var MyMath = require("../mathmodule");

describe('MyMath', function() {describe('#abs(number)', function() {

it('It should return positive values when given negative values.', function() {assert.equal(1, MyMath.abs(-1));assert.equal(2, MyMath.abs(-2));assert.equal(3, MyMath.abs(-3));

});it('It should return positive values when given positive values.', function() {

assert.equal(1, MyMath.abs(1));assert.equal(2, MyMath.abs(2));assert.equal(3, MyMath.abs(3));

});

});describe('#max(number1, number2)', function() {

it('should return number1 if number1 > number2', function() {assert.equal(2, MyMath.max(2, 1));assert.equal(3, MyMath.max(3, 1));assert.equal(4, MyMath.max(4, 1));

});});

});

276

Exceptions

describe('ExceptionTest', function() {describe('#divide(number, number)', function() {

it('Exception tests', function() {assert.throws(() => { divide(2,0) }, ZeroDivisionException);assert.throws(() => { divide("k","h") }, MustBeNumbersException);

});});

});

277

TDD

• Designthetestsfirst!• Afterthisimplementthemodule!

278

AsyncandPromises

279

AboutPromises

• Promisesanalternativetocallbacksdeliveringresultofanasynccomputation• PromisesarepartofEcmaScript2015

• Previouslyyoucouldusethemasadditionallibrary• https://promisesaplus.com/

280

Typicalasyncfunctionwithcallback

asyncFunction(arg1, arg2,

result => {

console.log(result);

});

281

Problemswithcallbacks

• Whenasyncdone,doanotherasyncmethod(chaining)->usingcallbackscanbemessy• Whatisasyncfails?Ifyouhavechainedasyncmethodsandoneofthemfails?

• Itisnotstandard,everyonecanhavetheyownversionofdoingcallbacks

282

UsingPromisesfunction promiseFunction(resolve, reject) {

// time consuming async stuffif(true) {

resolve("OK!");} else {

reject("Failed!");}

}

function onSuccess(msg) {console.log(msg);

}

function onError(msg) {console.log(msg);

}

let promise = new Promise(promiseFunction);promise.then(onSuccess, onError);promise.then(onSuccess).catch(onError);

Youcandobothhere

283

Node.JScallbacks

const fs = require('fs');

fs.readFile('mytest.json',function (error, text) {

if (error) {console.error('Error while reading config file');

} else {try {

const obj = JSON.parse(text);console.log(JSON.stringify(obj));

} catch (e) {console.error('Invalid JSON in file');

}}

});

FileI/Omodule

284

Node.JSpromise

const util = require('util');const fs = require('fs');

const promiseReadFile = util.promisify(fs.readFile);

promiseReadFile('mytest.json').then(function (text) { //

const obj = JSON.parse(text);console.log(JSON.stringify(obj));

}).catch(function (error) { //

// File read error or JSON SyntaxErrorconsole.error('An error occurred', error);

});

util.promisifyisNode8feature

285

SimpleExample

function doSomeTimeConsumingStuff() {

function asyncOperation(resolve, reject) {

setTimeout(() => resolve("Done"), 1000);

}

return new Promise(asyncOperation);

}

doSomeTimeConsumingStuff().then(result => console.log('Result: ' + result));

286

function promiseFunction(resolve, reject) {// time consuming async stuffif(true) {

resolve(4);} else {

reject("First promise failed!");}

}

function onSuccess(result) {let p = new Promise((resolve, reject) => {

// time consuming async stuffif(true) {

resolve(result + 4);} else {

reject("Second promise failed");}

} );return p;

}

function onError(msg) {console.log(msg);

}

let promise = new Promise(promiseFunction);promise.then(onSuccess).then((result) => console.log("sum = " + result)).catch(onError);

Returnspromise

Chainingwiththen

Canhandlebotherrors!

287

async

async function doIt() {let sum = 0;for(let i=0; i<10; i++) {

console.log(i);sum = sum + i;

}return sum;

}

doIt().then((result) => console.log("result = " + result));

Wheninvokingasyncfunction,endresultis

promise!

288

EcmaScript2017:async

async function doIt() {let sum = 0;for(let i=0; i<10; i++) {

console.log(i);

sum = sum + i;}return sum;

}

doIt().then((result) => console.log(result));doIt().then((result) => console.log(result));

ThedoIt– methodisrunparallel

289

EcmaScript2017:awaitfunction fetchNumber() {

function asyncOperation(resolve, reject) {

let n = Math.round(Math.random() * 10); setTimeout(() => resolve(n), 1000);

}return new Promise(asyncOperation);

}

async function doIt1() {let a = await fetchNumber();console.log(a);let b = await fetchNumber();console.log(b);

let sum = a + b;return sum;

}

doIt1().then((result) => console.log(result));

Let'swaituntilwegetthenumber

290

top related