Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to ECMAScript

Introduction to ECMAScript

Introduction slides for ECMAScript - language. Covers features from ES5, ES2015, ES2016 and ES2017. Focus mainly on CLI - apps (not browser) and core language.

Jussi Pohjolainen

September 20, 2017
Tweet

More Decks by Jussi Pohjolainen

Other Decks in Technology

Transcript

  1. Recommended Reading • Recommended reading • JavaScript: The Good Parts

    by Douglas Crockford • JavaScript: The Definite Guide by David Flanagan • JavaScript Patterns: Stoyan Stefanov • And Google.. 2
  2. JavaScript today • EcmaScript is standardized subset of JavaScript •

    JavaScript is key language to implement web applications • Possible candidate for cross-platform mobile development • React, Cordova / Phonegap, Ionic • Server side development • Replacing / Complementing XML for data transfer (REST + JSON) 3
  3. Responsive • Unified across experiences • Can be embedded as

    mobile app • Better deployment and & maintanence • Mobile users need to get access to everything Image: http://coenraets.org/blog/wp-content/uploads/2011/10/directory11.png 5
  4. Single-page Applications (SPA) • Web app that fits on a

    single web page • Fluid UX, like desktop app • Examples like Gmail, Google maps • Html page contains mini-views (HTML Fragments) that can be loaded in the background • No reloading of the page, better UX • Requires handling of browser history, navigation and bookmarks 6
  5. Rise of the REST and JSON • REST is a

    one way of communicating between computers over the internet • Data can be send via XML or JSON using HTTP • HTTP GET • http://something/employee/1 • Result • {id: 1, name: "jack"} • If both frontend and backend is JS, object sending and parsing extremely easy 7
  6. Rise of the JS Backend: NodeJS • Open source JS

    runtime environment • Uses V8 (Chrome) JS engine • Additional modules on top of JS to provide functionality • Web server, system i/o, networking, ... • Lot of third party modules available 8
  7. Native iOS App iOS WebView index.html app.js angularjs.js ionic.js cordova.js

    stylesheet.css Native Android App Android WebView index.html app.js angularjs.js ionic.js cordova.js stylesheet.css Using Cordova it's possible to access mobile device native features Web Server Node.js + Express + Mongo app.js package.json modules/express/ modules/mongodb/ MongoDB [{name: 'jack'}, {name: 'tina'}, {..}, {..}] HTTP GET (ajax) Request: http://server.com/employees/1 HTTP Response content-type: application/json {name: 'jack'} Frontend Ionic + Cordova + AngularJS Backend Node.JS + Express + Mongo HTTP POST Request: http://server.com/employees/ {name: 'amanda'} HTTP Response content-type: text/plain http://server.com/employees/3 Communication REST and JSON 9
  8. JavaScript, LiveScript, JScript, ECMAScript? • JavaScript • Developed by Netscape

    • Originally JavaScript, then LiveScript and then back to JavaScript. • JScript • Microsoft made their own version of the JavaScript • Lead to compatibility problems • => ECMAScript, effort to standardize different versions of the J(ava)Script 11
  9. ECMAScript • ECMAScript is a scripting language, standardized by Ecma

    International • In Browsers, ECMAScript is commonly called JavaScript • JavaScript = Native (EcmaScript) + Host objects (browser) • Java/ECMAscript is nowdays heavily used when creating web / mobile and even Desktop - apps 12
  10. Learning Path for Front-end Core EcmaScript Browser Host Objects JavaScript

    in Front-end HTML5 CSS Static Web-pages JavaScript Frameworks: React, AngularJS, ... 13
  11. EcmaScript Versions Year Edition Naming 1997 1 .. 1998 2

    .. 1999 3 Regex, better string handling, try/catch,... Abandoned 4 .. 2009 5 strict mode, getters and setters, JSON.. 2015 6 ES2015 classes, modules, arrow functions, collections ... 2016 7 ES2016 Math.pow => **, array.prototype.includes 2017 8 ES2017 await/async 14
  12. From JScript to TypeScript • TypeScript is a superset of

    EcmaScript developed by Microsoft • It has types! • When EcmaScript 6th Edition was working progress, typescript gave already classes, modules, arrow function syntax. • Now that the 6th Ed. is ready the additional benefit using TypeScript is types (and others like interfaces, generics...) • TypeScript is compiled to EcmaScript using compiler • It's first class language in Microsoft Visual Studio and in frameworks like Angular 2.0 15
  13. typescript.ts > cat typescript.ts var variable : string = "typescript";

    console.log(variable); > tsc typescript.ts > cat typescript.js var variable = "typescript"; console.log(variable); Notice that compiler compiles typescript to javascript and it loses the string type because that is not part of js! 16
  14. Benefit of using Compiler > 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
  15. Choose a Code-Editor / IDE • Atom by GitHub •

    Customizable free editor • Built-in package manager for installing new packages • Works across operating systems: OS X, Linux or Windows • Visual Studio Code by Microsoft • In addition to Atom... • Has built-in support for JavaScript, TypeScript and Node.js • Also extensible by plug-ins • Goes beyond syntax highlighting and provides autocomplete with IntelliSense and debugger • WebStorm by JetBrains • Full IDE • Support for: Angular, React, Ionic, Cordova, React Native, Electron, Node.js .. • Debugger, Unit testing 19
  16. Choose Runtime Environment • Forget the browser for now! •

    EcmaScript is a standard and there are multiple implementations for runtime environment; JavaScript Engines • Can be traditional interpreter or utilize just-in time compilation to bytecode • Different engines available • V8 by Google, powers Chrome • Nitro by Apple, powers Safari • Chakra by Microsoft, powers Edge • SpiderMonkey by Mozilla Foundation, powers Firefox • Rhino (Java Implementation) managed by Mozilla Foundation • ... 20
  17. Runtime Environment: Node.js • Easiest way to use V8 JS

    Engine is to install Node.js • https://nodejs.org/en/ • Node.js is built on top of V8 and is "the" technology to use when creating backend application using JS • Also provides package ecosystem, npm (node package manager), that can be used to manage js-libraries • npm is heavily used when creating JavaScript apps today • Node.js support for ES2015 is 99% -> Good JS environment for learning EcmaScript • http://node.green/ 21
  18. 23

  19. 24

  20. Visual Studio Code - tips • Install Code Runner -

    extension for easier running of node (and other) apps • Debugging Node apps is supported by default! • Install Node.js extension pack • ESLint • npm • JavaScript Snippets • ... 25
  21. npm package manager • Node.js contains a npm that can

    be used to install various extensions and packages • You can install packages • local (specific to your app) • ./node_modules • global (can be used everywhere) • /usr/local/lib/node_modules • When creating a node project, usually you will have a file package.json describing the project and it's dependencies 27
  22. ESLint • ESLint is linting utility (code quality) tool for

    JavaScript • To install • npm install --save-dev eslint • ESLint requires a configuration file • To create one, use • ./node_modules/eslint/bin/eslint.js --init • You can answer to questions about style guide or take popular style guides 36
  23. 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" ] } }; Add no- console: off to init file Lot of rules https://eslint.org/docs/rules/ 39
  24. Different Style Guides • AirBnb • Google • "Standard" Style

    • Crockford's Coding Standards for JavaScript • NodeJS Style Guide 41
  25. Standard Rules • 2 spaces for indentation • Single quotes

    for string • No unused variables • No semicolons • ... • https://standardjs.com/ 45
  26. References • EcmaScript 5.1 Language Spesification • http://www.ecma-international.org/ecma-262/5.1/ • EcmaScript

    6 Language Spesification (June 2015) • http://www.ecma-international.org/ecma-262/6.0/index.html • Really good JavaScript Reference from Mozilla • https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference • W3Schools have lot of JS stuff too but remember • http://meta.stackoverflow.com/questions/280478/why-not- w3schools-com 48
  27. ECMAScript Basics • Borrows most of the syntax from Java

    but influences from other languages also • Java and JavaScript are totally different as a technology! • ECMAScript is case-sensitive • Instructions are called statements and are separated typically using semicolon (;) • Standard JavaScript Linter avoids semicolon usage 50
  28. About semicolons • You can write • console.log("hello"); • console.log("world");

    • Or • console.log("hello") • console.log("world") 51
  29. Comments // One line /* multi- line */ /* No

    nested /* comments */ allowed */ 52
  30. Variables • To declare a variable use keyword var or

    let • var x = 99; • Variable naming has some rules • must start with a letter, underscore (_), dollar sign • A-Z is different from a-z (case sensitive) • After the first letter, digits can be used (0-9) 53
  31. Variable Scope • Global variable • Declare variable outside of

    function, available everywhere • Local variable • Declare variable inside of function, available in that function • Before ES2015, no block statement! 54
  32. 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 It is global! Function scope! 55
  33. Variable Hoisting This code is the same ... var globalVariable

    = "Hello"; function doIt() { console.log(globalVariable); if(true) { var globalVariable = "World"; } } doIt(); console.log(globalVariable); ... than this var globalVariable = "Hello"; function doIt() { var globalVariable; console.log(globalVariable); if(true) { globalVariable = "World"; } } doIt(); console.log(globalVariable); It is hoisted! 56
  34. ES2015 Variable Hoisting: let function doIt() { console.log(myVar); // myVar

    is not defined! if(true) { let myVar = "Hello World"; } } doIt(); It is not hoisted! 58
  35. Word About ES2015 • When developing to backend using Node.js

    developer can choose the version of Node.js and use freely most of ES2015 features • On the front-end things get complicated since user may have whatever browser and those may not support ES2015 • ES2015 can be compiled to older ES! 59
  36. ES2015: const • Constant cannot be changed through assignment •

    const variables are not hoisted const PI = 3.14; PI = 99; console.log(PI); 60
  37. ES2015 -> ES5 Object.defineProperty(typeof global === "object" ? global :

    window, "PI", { value: 3.141593, enumerable: true, writable: false, configurable: false }) console.log(PI); 61
  38. Data Types: Primitive types (6) Type Possible values boolean true

    or false null null undefined undefined number 41, 3.444 string "Hello World" symbol unique and immutable instances (ES2015) All other are objects! 62
  39. 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) Language design error! 63
  40. Primitive types vs Object types • Let's look at objects

    later on more carefully • Object in ES is just a variable containing properties: • var myObject = {"name": "Jack"}; • console.log(myObject.name); • Objects are passed by reference • Primitive types are passed by value 64
  41. String • String literal contains characters enclosed by "" or

    '' var x = "Hello World"; • In ES2015 also possibility to use template literals: ` 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.` • There is string primitive type and String object! • ES will make automatic casting between these two, so it is possible to access all the methods provided by the String: • console.log( x.charAt(0) ); 65
  42. Data Type Conversion 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
  43. About Numbers • Number(value), converts entire string • var i

    = Number("12"); • parseInt(value[, radix]), converts start of the string • var i = parseInt("12px”, 10); • Radix? • 10 => integer number, 8 => octal number, 16 => hexadecimal • NaN (Not a Number), check using isNaN(variable) • Result of erroneous operations 67
  44. Indexed Collection: Arrays • Arrays are objects but in addition

    they have more methods and auto- increment key-values • var stuff = ["a", "b", "c"] • The keys are now 0, 1 and 2 • The length of the array is 3 and it's linked to numerical properties 68
  45. Input & Output – Depends! • In Browsers • Input:

    HTML Forms or window.prompt("", ""); • Output: DOM manipulation, document.write("") or window.alert(""); • In V8/NodeJS or Rhino/Spidermonkey • Output to CLI: print(".."); • Input from CLI: Is not that easy... • Debugging • console.log(""); 69
  46. Conditional Statements if (condition_1) { statement_1; } else if (condition_2)

    { statement_2; } else if (condition_n) { statement_n; } else { statement_last; } 72
  47. False Values 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
  48. Comparison: true or false? let x = new Boolean(false); if(x)

    { console.log("true"); } else { console.log("false"); } 74
  49. Comparison: true or false? let x = new Boolean(false); if(x

    == false) { console.log("true"); } else { console.log("false"); } 75
  50. 77

  51. 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
  52. 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
  53. switch case switch (expression) { case label_1: statements_1 [break;] case

    label_2: statements_2 [break;] ... default: statements_def [break;] } 80
  54. for for(let i = 0; i < 10; i =

    i + 1) { console.log(i); } 83
  55. for ... of – for arrays let array = ["jack",

    "tina"]; // Traditional for for(let i = 0; i < array.length; i++) { console.log(array[i]); } // for - of for(let item of array) { console.log(item); } 84
  56. for ... of – for arrays let array = ["jack",

    "tina"]; // 0 => "jack", 1 => "tina", "key" => "value" array["key"] = "value"; // for - of for(let item of array) { console.log(item); // ?? } 85
  57. for ... in – for objects let array = ["jack",

    "tina"]; // 0 => "jack", 1 => "tina", "key" => "value" array["key"] = "value"; // for - in for(let item in array) { console.log(item); // ?? } 86
  58. for ... in – for objects let object = {"key1":

    "value1", "key2": "value2"}; for(let key in object) { console.log(key); console.log(object[key]) } 87
  59. About numbers • All numbers are double- precision 64-bit •

    Largest safe integer: 9007199254740991 • Safe? You can do calculations and display numbers correctly • No specific type for integers • Also symbolic values • +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
  60. Number // Largest integer value console.log(Number.MAX_SAFE_INTEGER); // Largest floating point

    value console.log(Number.MAX_VALUE); // Smallest floating point value console.log(Number.MIN_VALUE); // Same values console.log(Number.POSITIVE_INFINITY) console.log(+Infinity); console.log(Infinity); // Same values console.log(Number.NEGATIVE_INFINITY) console.log(-Infinity); // Same values console.log(Number.NaN); console.log(NaN); 90
  61. String objects • EcmaScript has String primitive type and object

    • Primitive type is casted to object when needed • Use primitive type! • String object has variety methods that you can use let s = new String('foo'); console.log(s); // [String: 'foo'] console.log(typeof s); // object 93
  62. Some String methods • charAt • startsWith • endsWith •

    split • slice • substring • match • replace • toLowerCase • toUpperCase • trim 94
  63. Date, Time and Number formatting • Intl namespace has language

    sensitive date, time and number formatting • For formatting dates and time • Intl.DateTimeFormat • For formatting numbers • Intl.NumberFormat • Note that Node.js is bundled only with English! var date = new Date(); var dateTimeFormatter = new Intl.DateTimeFormat('fi-FI'); console.log(dateTimeFormatter.format(date)); 95
  64. Creating an Array // 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
  65. Creating an Array with given size const ARRAY_LENGTH = 10;

    let arr1 = new Array(ARRAY_LENGTH); // OR let arr2 = []; arr2.length = ARRAY_LENGTH; 99
  66. 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
  67. .length • length will return last element index + 1

    • It is possible to change length at runtime • If giving shorter length, the array is truncated (removes items) 101
  68. forEach (EcmaScript 5th Edition) let colors = ['red', 'green', 'blue'];

    colors.forEach(function(color) { console.log(color); }); 103
  69. Array Methods • concat() • join() • push() • pop()

    • shift() • unshift() • slice() • splice() • reverse() • sort() • indexOf() • forEach() • map() • filter() • every() • some() • reduce() 104
  70. every and some - 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
  71. Map • Map object is a simple key/value map collection

    • You can iterate items in insertion order • Keys can be whatever value • Size is easily available 107
  72. Example var 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
  73. Set • Unique values • Insertion order is provided 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
  74. Functions • Fundamental building block in EcmaScript • Set of

    statements that performs a task or calculates a value • Functions are objects! 112
  75. Predefined Argument function multiply(a, b = 1) { return a

    * b; } console.log(multiply(5)); 116
  76. Functions are objects 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
  77. And because they are objects... let functionObject = new Function("a","b",

    "return a+b;"); let anotherObject = functionObject; console.log ( functionObject(5,5) ); console.log ( anotherObject(5,5) ); 118
  78. Passing Function Objects 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
  79. arguments function doIt() { for(let item of arguments) { console.log(item)

    } } doIt("a"); doIt("a", "b"); doIt("a", "b", "c"); Predefined property of functions. You can fetch all the arguments from the array 120
  80. Function Scoping: Does not Work! greeting("hello world"); var greeting =

    function (msg) { console.log(msg); } variable greeting is hoisted and the value is undefined 122
  81. Anonymous Function greeting("hello world"); var greeting = function (msg) {

    console.log(msg); } Anonymous function declaration 123
  82. Remember this? 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
  83. Remember this? 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); Instead of passing named functions we could use anonymous functions 125
  84. Anonymous functions 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); }); Passing anonymous functions 126
  85. ES2015: Arrow Syntax 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)); Passing anonymous functions using the arrow syntax: simpler syntax and lexical this - keyword 128
  86. Function that returns a Function function doIt() { function hello()

    { console.log("Hello World"); } return hello; } var func = doIt(); func(); 130
  87. 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
  88. Closures function outer() { let x = 20; function inner()

    { console.log(x); } return inner; } var innerFunction = outer(); // is x still in memory? innerFunction(); Yes! When returning inner function that uses outer functions variables, those variables are stored in memory. 132
  89. Pattern: Private member variables 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
  90. Objects • Object is collection of properties • property is

    a association between key and value • value can be for example a function -> also called method • Objects, like functions are a fundamental part of EcmaScript • The keys must be string, if numbers used, it will make a typecast • So keys can be whatever if they can be converted into a string 136
  91. Object Creation • Object initializer • let o = {};

    • Using Object constructor • let o = new Object(); • Using Custom constructor • let o = new Car(); • Object.create (used in inheritance) • let dog = Object.create(animal); 137
  92. Object Initializer // 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"]); Also possible to access using [] syntax In some cases [] syntax is mandatory.. if key is not a valid js identifier 138
  93. Object Constructor let object = new Object(); object.key = "value";

    object.hello = "world"; object["2"] = "another"; Possibility to add properties in runtime 139
  94. Dynamic key 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"} Must use brackets for dynamic key! 140
  95. EcmaScript 5: Prevent extensions, Seal, Freeze Add Delete Modify Object.preventExtensions

    NO YES YES Object.seal NO NO YES Object.freeze NO NO NO 141
  96. Prevent Extensions var obj1 = {id: 1}; Object.preventExtensions(obj1); obj1.name =

    "Jack"; obj1.id = 3; delete obj1["id"]; Fails silently unless in strict mode 142
  97. EcmaScript 5: 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
  98. Example var 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); } Cannot change Nothing in here 146
  99. Constructor Function function Person(name) { this.name = name; } var

    tina = new Person("Tina"); console.log(tina.name); Write the function name with capital (convention) Use new – keyword to create object this refers to tina 147
  100. What happens here? function Person(name) { this.name = name; }

    var tina = Person("Tina"); console.log(name) Forgot to use the new word! 148
  101. Pattern: Preventing misuse function Person(name) { if(!(this instanceof Person)) {

    throw new TypeError("Cannot call a constructor function without new."); } this.name = name; } var tina = Person("Tina"); Type checking of this if new is missing, throw error 149
  102. EcmaScript 2015: 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
  103. EcmaScript 2015: 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()); Has prebuilt support for checking if new keyword is used or not. If new keyword is missing, this will fail! 151
  104. Value can be anything, like functions let MyMath = {

    abs: function (value) { if (value < 0) { return value * -1; } else { return value; } } }; console.log ( MyMath.abs(-7) ); 152
  105. Usage of Arrow Function and Ternary Operation let MyMath =

    { abs: (value) => value < 0 ? value * -1 : value }; console.log ( MyMath.abs(-7) ); 153
  106. Enumerating: for...in var object = {key1: "value1", key2: "value2"}; for

    (var key in object) { console.log(key + " = " + object[key]); } 154
  107. Keyword this • Node.js is a little bit different to

    EcmaScript when it comes to the keyword this • When using this in browsers, you will different results than in Node • One major difference is that Node uses modules where one file is one scope. In browsers, there is one scope • For now let's see how keyword this behaves in browsers 157
  108. Keyword this in browsers console.log(this === window); console.log(doIt() == window);

    function doIt() { return this; } Both are true In functions and in global, this refers to a global main object which is window 158
  109. Global variables in Browsers this.variable = "Hello"; console.log(window.variable); doIt(); console.log(window.name);

    console.log(name); function doIt() { this.name = "Jack"; } You do not have to write the main object! It's global variable! 159
  110. This should work... 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()); When invoking the method, keyword this is "replaced" with c - object 161
  111. We have a problem 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()); No this does NOT refer to c – anymore... it will not work 162
  112. 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()); Create copy of that function where this refers to c 163
  113. 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 onSuccess onSuccess("<html>...</html>"); } obj.fetchUrl(); this? NOT working! 164
  114. The same but now using of anonymous functions var 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 onSuccess onSuccess("<html>...</html>"); } obj.fetchUrl(); this? NOT working! 165
  115. 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 onSuccess onSuccess("<html>...</html>"); } obj.fetchUrl(); Send a copy of that function! 166
  116. Pattern: Using Closure 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 onSuccess onSuccess("<html>...</html>"); } obj.fetchUrl(); It works! 167
  117. No need for Patterns when using Arrow Syntax var 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 onSuccess onSuccess("<html>...</html>"); } obj.fetchUrl(); It works! Lexical this 168
  118. About Strict Mode • Introduced in EcmaScript 5, strict mode

    makes changes in normal EcmaScript semantics • Differences 1. Strict mode can run faster in identical code than without strict 2. Silent errors -> Throw errors (will fail) 3. Prohibets some syntax • Enable globally or in function • Use it! 171
  119. Global: Use strict "use strict"; var obj1 = {id: 1};

    Object.preventExtensions(obj1); obj1.name = "Jack"; TypeError: Can't add property name, object is not extensible Enable strict mode. It's just a string! 174
  120. In functions: use strict function doIt() { "use strict"; console.log("This

    is under strict mode"); } Now only this function uses strict mode 175
  121. Variable without var function doIt() { variable = 4; }

    doIt(); console.log(variable); Forgot the var word here... it creates a global variable! Confusing 177
  122. In strict mode, you have to use the var "use

    strict"; function doIt() { variable = 4; } doIt(); console.log(variable); variable is not defined! 178
  123. Regex • Regular Expressions (Regex) are patterns used to match

    character combinations in strings • In EcmaScript, regex are objects of RegExp • var re = new RegExp('ab+c'); • Also regex literal available • var re = /ab+c/ 180
  124. Regex Literal: Loaded when Script is loaded var variable =

    "ab+c"; var regex1 = /variable/; var regex2 = /ab+c/ console.log(regex1.test("variable")); console.log(regex2.test("abbc")); Both are true! You cannot have dynamic content in regex literal 181
  125. Simple Regex 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
  126. Begin (^) and End ($) 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
  127. 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("")); // false console.log(regex1.test("hello")); // true console.log(regex1.test("hellohello")); // true console.log(regex2.test("")); // true console.log(regex2.test("hello")); // true console.log(regex2.test("hellohello")); // true console.log(regex3.test("")); // true console.log(regex3.test("hello")); // true console.log(regex3.test("hellohello")); // false console.log(regex4.test("")); // true console.log(regex4.test("hello")); // true console.log(regex4.test("hellohello")); // true 184
  128. Other Special Characters Character Meaning . Any character, for example

    /.n/ matches an and on \. equals to dot x|y Or, for example /black|white/ matches either black or white [xyz] or [a-z] Character set [^abc] Negated character set, cannot be a b or c. \d [0-9] \D [^0-9] \s Whitespace, space, tab ... \S Non whitespace \w [a-zA-Z0-9_] \W [^a-zA-Z0-9_] 185
  129. Working with Regex Method Meaning exec A RegExp method that

    returns array of information about the match test A RegExp method that returns true or false match A String method that returns array of information about the match search A String method that returns index of the match replace A String method that exercutes a search and replaces the matched substring split A String method that breaks a string into an array of substrings 186
  130. RegExp exec vs test 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
  131. String match, search, replace, split var 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
  132. Example of Flags var regex1 = /hello/i; var regex2 =

    new RegExp("hello", "i"); console.log( regex1.test("HelLo") ); console.log( regex2.test("HelLo") ); 189
  133. About Inheritance • Code reuse is important • Inheritance can

    help • JavaScript does not have classes, so no special keyword for extending • This can be very confusing for Java/C# developers • Objects inherit objects • Well ECMAScript 6 has classes. But in the end it's just syntactic sugar where underneath object inherites another object 192
  134. Object extends Object • In EcmaScript object extends other object

    • Every object has special __proto__ property that links to object that it inherites 193
  135. (Bad) example of __proto__ var parent = { method1: function()

    { console.log("A"); } } var child = { __proto__: parent, method2: function() { console.log("B"); } } child.method1(); // A child.method2(); // B child extends parent 194
  136. __proto__ • __proto__ is depricated, non-standard and should not be

    used! • To get the parent, use • Object.getPrototypeOf(child) • To set the parent, use (Only in EcmaScript 2015!) • Object.setPrototypeOf(child, parent) 195
  137. Testing var 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
  138. Object.setPrototypeOf(child, parent) • The Object.setPrototypeOf alters the object's __proto__ and

    this can be very slow operation • Also Object.setPrototypeOf is EcmaScript 2015 feature, so it won't work for example in older browsers • Instead of altering object's __proto__, create new object with desired parent using Object.create(obj, parent) • Supported from EcmaScript 5th edition -> 197
  139. 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(); // A child.method2(); // A Now new object is created which parent is parent 198
  140. Working with Constructors • When writing • function Animal() {

    } • Two objects are created! • 1) Animal • 2) Animal.prototype • These two objects are linked together! 199
  141. 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
  142. Constructor function and new • Constructor function is used with

    new – keyword • var spot = new Animal(); • By default the spot inherites Animal.prototype! Animal (Function – Object) Animal Parent prototype constructor spot __proto__ Parent object! 201
  143. Testing function Animal() { } var spot = new Animal();

    console.log(spot.__proto__ == Animal.prototype); console.log(Object.getPrototypeOf(spot) == Animal.prototype); Non-standard way spot extends Animal.prototype 202
  144. 203

  145. 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 and animal3 extend Animal.prototype 204
  146. 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" EcmaScript 2015 Feature, can be slow. Now Dog.prototype extends Animal.prototype. spot extends Dog.prototype true true 205
  147. 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" Use Object.create(..) instead 207
  148. 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); Creates a new object! We have a problem ... undefined 208
  149. 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); Dog Parent spot __proto__ Now spot extends Dog Parent which is accessed by Dog.prototype Dog prototype 209
  150. 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); This creates a new object! 210
  151. 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" The newObject here is the new object created! 211
  152. 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" Dog Parent spot __proto__ Dog prototype newObject __proto__ Animal.prototype 212
  153. 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" Dog Parent spot __proto__ Dog prototype newObject __proto__ Animal.prototype 213
  154. 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" Dog Parent spot __proto__ Dog prototype newObject __proto__ Animal.prototype Dog.prototype => newObject newObject.__proto__ => Animal.prototype = true! 214
  155. 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" Dog Parent spot __proto__ Dog prototype newObject __proto__ Animal.prototype spot__proto => Dog Parent false! 215
  156. Let's change order 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" Let's create first the newObject and then create the spot! 216
  157. 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 Parent Dog prototype 217
  158. 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 Parent Dog prototype newObject __proto__ Animal.prototype 218
  159. 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 Parent (garbage collector will delete this) Dog prototype newObject __proto__ Animal.prototype 219
  160. 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.prototype By default spot will extend Dog.prototype which is now the newObject spot __proto__ 220
  161. 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 New Dog Parent __proto__ Animal.prototype spot __proto__ We do not need the newObject pointer 221
  162. 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
  163. Constructors function Dog() {} var spot = new Dog(); console.log(spot.constructor

    == Dog); Dog prototype Dog Parent constructor spot __proto__ You can ask from an object what is it's constructor. The constructor property is built in the parent object Two objects are created! The Dog Parent object has a constructor property! 225
  164. Constructors function Animal() {} function Dog() {} Dog.prototype = Object.create(Animal.prototype);

    var spot = new Dog(); console.log(spot.constructor == Dog); Creates a new object which __proto__ points to Animal.protototype. The new object does not have constructor property! 226
  165. Dog prototype ( the new object ) __proto__ spot __proto__

    Animal prototype Animal Parent constructor console.log(spot.constructor); Constructor property is not found in spot. It will try to find it in the new object. It's not there either! Then it will fetch it from the X and end result is that spot is created from Animal! 227
  166. Dog prototype ( the new object ) __proto__ constructor spot

    __proto__ Animal prototype Animal Parent constructor Dog.prototype.constructor = Dog; Let's add this! 228
  167. 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); You can invoke the function and define what this means in runtime this now refers to spot-object 231
  168. When using Constructor - functions function 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
  169. 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); A lot nicer syntax for creating inheritance! 234
  170. 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); But it is syntactical sugar!! 235
  171. React - Example • React is a JavaScript framework for

    building UI in front-end • It is developed by Facebook and very popular • You create UI components in the framework • Uses EcmaScript 2015 and JSX • Compiled to older EcmaScript using Babel so it works on browsers class Welcome extends React.Component { render() { return <h1>Hello World</h1>; } } 237
  172. New Features • Arrow Functions • Parameter values • Object

    properties • Modules • Classes • Some new built methods 239
  173. Arrow Functions let 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
  174. Lexical this var object = { array: [0,1,2,3,4], doIt: function()

    { this.array.forEach(function(value) { this.array.push(value); }); } } object.doIt(); Cannot read property 'push' of undefined 241
  175. Lexical this var object = { array: [0,1,2,3,4], doIt: function()

    { var _this = this; this.array.forEach(function(value) { _this.array.push(value); }); } } object.doIt(); It works when using closure 242
  176. Lexical this var object = { array: [0,1,2,3,4], doIt: function()

    { this.array.forEach((value) => { this.array.push(value); }); } } object.doIt(); Works! 243
  177. Default Parameter values function printIt(text, amount = 1) { for(let

    i = 0; i < amount; i++) { console.log(text); } } printIt("text"); printIt("text", 7); 244
  178. Variadic Parameter Values 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
  179. Spread Operator var array1 = [ "hello", "world" ]; var

    array2 = [ 1, ...array1 ]; // [ 1, 'hello', 'world' ] console.log(array2); 246
  180. Interpolation of String var message = "hello"; var html =

    ` <div> <p>${message}</p> </div> `; console.log(html); 247
  181. Object Properties let x = 0; let y = 1;

    let obj = { x, y }; console.log(obj.x); console.log(obj.y); 248
  182. About Modules • Modules Systems 1. AMD Specification (RequireJS) 2.

    CommonJS Modules (NodeJS) 3. ES2015 official module • In EcmaScript 2105 for the first time it's built into language. Support is weak. • It's possible to compile ES6 Modules to AMD or CommonJS • Node will support ES2015 modules in the upcoming versions • Angular2 Framework uses ES2015 modules 250
  183. Babel • Since ES2015 module support is weak, install Babel

    transpiler • Transpiler will compile new ES2015 features to older ES that you can use in NodeJS or Browsers • To install globally • npm install -g babel-cli 252
  184. EcmaScript 2015: app.js import { generateRandom, sum } from 'utility';

    console.log(generateRandom()); // logs a random number console.log(sum(1, 2)); // 3 253
  185. EcmaScript 2015: utility.js function generateRandom() { return Math.random(); } function

    sum(a, b) { return a + b; } export { generateRandom, sum } 254
  186. CommonJS • CommonJS is a project with the goal of

    specifying ecosystem for JS outside of Browser • Was started by Mozilla engineer, inital name ServerJS • CommonJS described a lot of specifications, including modules • This module specification is implemented in NodeJS • require to include modules • exports to make things available 256
  187. app.js // import { generateRandom, sum } from 'utility'; require("./utility.js");

    console.log(generateRandom()); // logs a random number console.log(sum(1, 2)); // 3 257
  188. Example Module: 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; }; Uses JSdoc 259
  189. Exporting Object '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
  190. exports vs module.exports 'use strict'; var module = { exports:

    {} }; var exports = module.exports; module.exports.variable1 = "hello"; exports.variable2 = "world"; return module.exports; It will always return module.exports 264
  191. What Happens? '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
  192. Example function 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
  193. 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); } Better version, our own exception object 269
  194. 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); } Both of the exceptions go here 270
  195. 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."); } } Checking what exception was thrown 271
  196. Mocha • Install globally • npm install –globally mocha •

    Create test/test.js • You can run tests • mocha test/test.js • Or if you modify package.json • npm test 274
  197. MyMath module '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
  198. test/test.js var 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
  199. 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
  200. About Promises • Promises an alternative to callbacks delivering result

    of an async computation • Promises are part of EcmaScript 2015 • Previously you could use them as additional library • https://promisesaplus.com/ 280
  201. Problems with callbacks • When async done, do another async

    method (chaining) -> using callbacks can be messy • What is async fails? If you have chained async methods and one of them fails? • It is not standard, everyone can have they own version of doing callbacks 282
  202. Using Promises function promiseFunction(resolve, reject) { // time consuming async

    stuff if(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); You can do both here 283
  203. Node.JS callbacks 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'); } } } ); File I/O module 284
  204. Node.JS promise 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 SyntaxError console.error('An error occurred', error); }); util.promisify is Node 8 feature 285
  205. Simple Example function doSomeTimeConsumingStuff() { function asyncOperation(resolve, reject) { setTimeout(()

    => resolve("Done"), 1000); } return new Promise(asyncOperation); } doSomeTimeConsumingStuff().then(result => console.log('Result: ' + result)); 286
  206. function promiseFunction(resolve, reject) { // time consuming async stuff if(true)

    { resolve(4); } else { reject("First promise failed!"); } } function onSuccess(result) { let p = new Promise((resolve, reject) => { // time consuming async stuff if(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); Returns promise Chaining with then Can handle both errors! 287
  207. 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)); When invoking async function, end result is promise! 288
  208. EcmaScript 2017: 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)); The doIt – method is run parallel 289
  209. EcmaScript 2017: await function 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's wait until we get the number 290