class: center, middle, lnu-background-yellow ### Introduction to Web programming (1DV525) # Introduction to JavaScript, pt 2 --- class: lnu-background-cc ### Licence for this work This work is produced by Johan Leitet for the course Introduction to web programming (1DV525) at Linnaeus University. All content in this work excluding photographs, icons, picture of course litterature and Linnaeus University logotype and symbol, is licensed under a
Creative Commons Attribution 4.0 International License.
#### You are free to - copy and redistribute the material in any medium or format - spread the whole or parts of the content - show the whole or parts of the content publicly and digital - convert the content to another format - change the content If you change the content do not use the photographs, icons, picture of the course literature or Linnaeus University logotype and symbol in your new work! At all times you must give credit to: ”Linnaeus university – Introduction to Web Programming (1DV525)” with the link https://coursepress.lnu.se/kurs/introduction-to-web-programming/ and to the Creative Common-license above. --- # Data structures --- # Arrays ``` const courseCodes = ['1DV525', '1DV523', '1DV021'] courseCodes.push('1DV022') console.log(courseCodes.length) // ➡ 4 ``` [MDN Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) --- # Iterator functions forEach ``` let courseCode = ['1DV525', '1DV523', '1DV021'] courseCode.forEach((node) => {console.log(node)}) // ➡ 1DV525 ➡ 1DV523 ➡ 1DV021 ``` filter ``` const courseCodes = ['1DV525', '1DV523', '1DV021'] const intCourses = courseCodes.filter((node) => node.charAt(3) === '5' ) console.log(intCourses) // ➡ [ '1DV525', '1DV523' ] ``` * [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) * [reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) * [sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) * ... --- # Rest parameters and the Spread operator (ES2015) ``` const registerStudent = function(name, age, ...courses){ console.log(courses) } registerStudent('Ellen', 30, '1DV525', '1DV523', '1DV021') const courses = ['1DV525', '1DV523', '1DV021', '2DV022'] registerStudent('Ellen', 30, ...courses) ``` Ex. Find highest number ``` // Math.max syntax: Math.max([value1[, value2[, ...]]]) const numbers = [2, 5, 2, 5, 10, 3, 1, 5, 7, 8, 3 ,1] console.log(Math.max(...numbers)) // ➡ 10 ``` --- # Objects ``` const objectLiteral = {} console.log(typeof objectLiteral) // ➡ object ``` With properties and methods ``` const student = { name : "Ellen", age : 30, greet: function() { console.log(this.name + ' is greeting you!') } } student.city = "Växjö" student['registered'] = true student.greet() // ➡ Ellen is greeting you! ``` --- # Example ``` const courses = [ { code: '1DV525', students: 55, type: 'distance', url: 'https://github.com/1dv525' }, { code: '1DV607', students: 104, type: 'campus', url: 'https://github.com/1dv607' }, { code: '1DV607', students: 67, type: 'distance', url: 'https://coursepress.lnu.se/1dv021'}, { code: '1DV523', students: 35, type: 'distance', url: 'https://github.com/1dv021' } ] ``` Problem: Count the number of students taking a distance
learning course using github.com as url .gray-text[.smaller[Heavily influenced (stolen) by [Arrow functions in JavaScript - What, Why and How - FunFunFunction ](https://youtu.be/6sQDTgOqh-I)]] --- # *Factory* pattern ``` const createStudent = function(name, age) { return { name : name, age : age, greet: function(){ console.log(this.name + ' is greeting you!') } } } const students = [] students.push(createStudent('Ellen', 30)) students.push(createStudent('Peter', 32)) students.forEach( (student) => {student.greet()}) ``` --- # *Constructor* pattern ``` function Student(name, age) { this.name = name this.age = age this.greet = function(){ console.log(this.name + ' is greeting you!') } return this //Default when called with new } const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students.forEach((student) => {student.greet()}) console.log(students[0].constructor) // ➡ [Function: Student] ``` --- # *Constructor/Prototpe* pattern ``` function Student(name, age) { this.name = name this.age = age } Student.prototype.greet = function(){ console.log(this.name + ' is greeting you!') } const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students.forEach((student) => {student.greet()}) ``` --- # Prototypes ![](https://docs.google.com/drawings/d/1Vbwe4NsQ5GZ-PcP9qHC1kSEo9zG0X5fpjZGMfq7jiS8/pub?w=849&h=568) --- # Prototype chain ``` let person = { name: "N.N", age: 17, greet: function() {console.log(this.name, 'says hi!')} } let student = Object.create(person) ``` Students will be a new object with person as prototype. "Prototypal inheritance" --- # "Public" / "Private" ``` function Student(name, age) { // "Private" this.name = name // "Public" this.age = age // "Public" } Student.prototype.greet = function(){ // "Public" console.log(this.name + ' is greeting you!') } const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students[0].name = "Foo" students.forEach((student) => {student.greet()}) ```` --- # "Getters" / "Setters" ``` function Student(name) { this.setName = function(_name){ // Do fancy validation here name = _name } this.getName = function(){ return name } this.setName(name) } Student.prototype.greet = function(){ console.log(this.getName() + ' is greeting you!') }; const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students.forEach((student) => {student.greet()}) ```` However... there is a better way of doing this... --- # *defineProperty* ``` function Student(name) { Object.defineProperty(this, "name", { get: function(){ return name }, set: function(value) { // Fancy validation here name = '--'+value+'--' } }) this.name = name // Don´t forget } Student.prototype.greet = function(){ console.log(this.name + ' is greeting you!') } const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students.forEach((student) => {student.greet()}) ```` --- # *Class* (ES2015) ``` class Student { constructor(name) { this.name = name // Will call the setter } greet(){ // Prototype function console.log(this.name + ' is greeting you!') } get name(){ // Shortcut to defineProperty return this._name } set name(value) { // Shortcut to defineProperty this._name = '--'+value+'--' } } const students = [] students.push(new Student('Peter', 32)) students.push(new Student('Ellen', 30)) students[0].name = "Johan" students.forEach((student) => {student.greet()}) ``` --- # Inheritance ``` class Polygon { constructor(height, width) { this.height = height this.width = width } } class Square extends Polygon { constructor(sideLength) { super(sideLength, sideLength) } get area() { return this.height * this.width } set sideLength(newLength) { this.height = newLength this.width = newLength } } var square = new Square(2) ``` --- # Composition ``` const supervisor = (state) => ({ supervise: (student) => {console.log(state.name + ' is supervising ' + student.name + '...')} }) const examinate = (student) => { console.log('Examinating ' + student.name + '...'); } const student = (name = 'N.N', age = '18') => { let state = { name, age } return Object.assign( state, supervisor(state) ) } var mj222sa = student("Nils") var el222sa = student("Ellen") el222sa.supervise(mj222sa) ``` --- # Node.js Modules greetings.js ``` module.exports.sayHelloInEnglish = () => "Hello" module.exports.sayHelloInSpanish = () => "Hola" module.exports.sayHelloInSwedish = () => "Hej" ``` app.js ``` var greet = require('./greetings') console.log(greet.sayHelloInSpanish()) // ➡ Hola ``` --- # Export a class Student.js ``` class Student { constructor(name) { this.name = name } greet() { console.log(this.name + ' is greeting you!') } get name() { return this._name } set name(value) { this._name = '--'+value+'--' } } module.exports = Student ``` app.js ``` var Student = require('./Student') console.log(new Student('Ellen', 32)) ``` ---