Intro to OOP
class: center, middle .title[ Front-end training # Intro to OOP ] --- # OOP The OOP programming style in Javascript consist of three fundamental features: * ### Encapsulation A language mechanism for restricting access to some of the object's components. * ### Polymorphism Is the ability to create a variable, a function, or an object that has more than one form. * ### Inheritance Is a way to reuse code of existing objects, or to establish a subtype from an existing object, or both, depending upon programming language support. --- class: center, middle .title[ Front-end training # This, that, self ] --- class: center, middle # What's this? --- class: middle > One of the most confused mechanisms in JavaScript is the `this` keyword. It's a special identifier keyword that's automatically defined in the scope of every function, but what exactly it refers to bedevils even seasoned JavaScript developers. -- Kyle Simpson --- # Context "this" ```javascript var user = { firstName: 'Petya' }; var admin = { firstName: 'Vasya' }; function getName() { return this.firstName; } user.a = getName; user.a(); // returns 'Petya' showName.call(admin); // returns 'Vasya' showName(); // returns undefined // in case 'srict mode' will throw TypeError: `this` is `undefined` ``` --- class: middle > `this` is actually a binding that is made when a function is invoked, and what it references is determined entirely by the call-site where the function is called. -- Kyle Simpson --- # Context "this" There are 4 invocation patterns in JS: * Default Binding ```javascript function func() { console.log(this.a); } func(); // this is bond to the global object. ``` * Implicit Binding ```javascript var a = { func: // some function } a.func(); // this refers to the object, i.e., a. ``` * Explicit Binding ```javascript func.apply(thisArg, argArray); // this is bond to the first argument ``` * `new` Binding ```javascript var func = new Func(); // this refers to func while in Func constructor ``` --- class: center, middle # Constructor --- class: middle When a function is invoked with `new` in front of it, otherwise known as a constructor call, the following things are done automatically: 1. a brand new object is created (aka, constructed) out of thin air 2. *the newly constructed object is `[[Prototype]]`-linked* 3. the newly constructed object is set as the `this` binding for that function call 4. unless the function returns its own alternate **object**, the `new`-invoked function call will *automatically* return the newly constructed object. --- # Constructor Constructor is a function that creates and initializes the newly created object according to the template. ```javascript function Animal(name) { this.name = name; this.canWalk = true; } var dog = new Animal("dog"); // dog = { // name: "dog", // canWalk: true // } ``` The names of the functions that are designed to create objects, as a rule, begin with a capital letter. --- # "Classes" in JS Objects with identical methods of behavior creates class or object type (javascript). Class retains constructive plan of own objects. Each object - a member of a class, is an instance of class or object. ```javascript function Clock(hours, minutes) { this.hours = hours; this.minutes = minutes; this.setTime = function(hours, minutes) { this.hours = hours; this.minutes = minutes; } this.displayTime = function () { console.log(this.hours + ":" + this.minutes); } } var clock = new Clock(12, 30); var secondClock = new Clock(11, 45); clock.setTime(12, 45); clock.displayTime(); // 12:45 secondClock.displayTime(); // 11:45 console.log(clock instanceof Clock); // true ``` --- # "Classes" in ES2015 ES6 classes are a simple sugar over the prototype-based OOP pattern. ```javascript class Clock { constructor (hours, minutes) { this.hours = hours; this.minutes = minutes; } setTime (hours, minutes) { this.hours = hours; this.minutes = minutes; } displayTime () { console.log(`${this.hours}:${this.minutes}`); } } var clock = new Clock(12, 30); var secondClock = new Clock(11, 45); clock.setTime(12, 45); clock.displayTime(); // 12:45 secondClock.displayTime(); // 11:45 console.log(clock instanceof Clock); // true ``` --- class: center, middle .title[ Front-end training # Now lets talk about OOP ] --- class: center, middle .title[ Front-end training # Encapsulation ] --- # Encapsulation in JS Encapsulation is an increasing of abstraction, but not a paranoid hiding from “malicious hackers” which, “want to write something directly into fields of your classes”. It is a big (and widespread) mistake to use hiding for the sake of hiding. ECMAScript 5, does not define private, protected, and private modifiers how it is in other OOP languages. However, on practice it is possible to see something that is named “imitation of encapsulation in JS”. ```javascript function Clock(hours, minutes) { var _hours = hours; var _minutes = minutes; this.setHours(hours) { _hours = hours; } this.getHours() { return _hours; } } var clock = new Clock(12, 30); alert(clock._hours); // undefined, "private" alert(clock.getHours()); // 12 ``` --- # Encapsulation in ES2015 ```javascript const _hours = Symbol('hours'); const _minutes = Symbol('minutes'); class Clock { constructor (hours = 0, minutes = 0) { this[_hours] = hours; this[_minutes] = minutes; } set hours(hours) { this[_hours] = hours; } get hours () { return this[_hours]; } } var clock = new Clock(12, 30); console.log(clock.hours); // 12 clock.hours = 10; console.log(clock.hours); // 10 console.log(clock._hours); // undefined //But... console.log(clock[_hours]); // 10 :( maybe WeakMap? ``` --- # Encapsulation in ES2015 ```javascript // clock.js const _hours = Symbol('hours'); const _minutes = Symbol('minutes'); export default class Clock { constructor (hours = 0, minutes = 0) { this[_hours] = hours; this[_minutes] = minutes; } set hours(hours) { this[_hours] = hours; } get hours () { return this[_hours]; } } // main.js import Clock from './clock' var clock = new Clock(12, 30); console.log(clock.hours); // 12 clock.hours = 10; console.log(clock.hours); // 10 console.log(clock._hours); // undefined ``` --- class: center, middle .title[ Front-end training # Polymorphism ] --- # Polymorphism in JS Objects in ECMAScript are polymorphic in several meanings. "polymorphism" describes the idea that a general behavior from a parent class can be overridden in a child class to give it more specifics. In fact, relative polymorphism lets us reference the base behavior from the overridden behavior. # Example ```javascript class Cat { voice() { console.log('meow') } } class Tiger extends Cat { voice() { console.log('meow !!!') } } ``` This technique is called "polymorphism", or "virtual polymorphism". --- # Polymorphism in JS Another aspect of polymorphism is that a method name can have multiple definitions at different levels of the inheritance chain, and these definitions are automatically selected as appropriate when resolving which methods are being called. For example, one function can be applied to different objects, just like it would be the native characteristic of an object (because `this` value determinate on entering the execution context): ```javascript function test(o) { alert(this.a, this.b); } var o1 = { a: 10, b: 20 }; var o2 = { a: 100, b: 200 }; test.call(o1); // 10, 20 test.call(o2); // 100, 200 var a = 1; var b = 2; test(); // 1, 2 ``` --- # Must see - https://youtu.be/Qn3Qah7W6Vs --- class: center, middle .title[ ## Thanks ## The End ]