|
| 1 | +# Object Oriented Programming |
| 2 | + |
| 3 | +Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects". In this way, the data structure becomes an object that includes both data and functions. Data, in the form of fields (often known as attributes or properties), and functions, in the form of procedures (often known as methods). |
| 4 | + |
| 5 | +A feature of objects is an object's procedures that can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self"). In addition, programmers can create relationships between one object and another. For example, objects can inherit characteristics from other objects. |
| 6 | + |
| 7 | +In OOP, computer programs are designed by making them out of objects that interact with one another. OOP languages are diverse, but the most popular ones are class-based, meaning that objects are instances of classes, which also determine their types. |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +In OOP an object is a box containing information and operations that are supposed to refer to the same concept. It's like we're modeling real world objects and relationships. |
| 12 | + |
| 13 | +## Class-based vs Prototype-based |
| 14 | + |
| 15 | +When it comes to object oriented programming there are two main types of languages: |
| 16 | + |
| 17 | +- #### Class based |
| 18 | + |
| 19 | +In class-based languages the classes are defined beforehand and the objects are instantiated based on the classes. If two objects <i>apple</i> and <i>orange</i> are instantiated from the class <i>Fruit</i>, they are inherently fruits and it is guaranteed that you may handle them in the same way. E.g. a programmer can expect the existence of the same attributes such as <i>color</i> or <i>sugar_content</i> or <i>is_ripe</i>. |
| 20 | + |
| 21 | +- #### Prototype based |
| 22 | + |
| 23 | +In prototype-based languages the objects are the primary entities. No classes even exist. The prototype of an object is just another object to which the object is linked. Every object has one prototype link (and only one). |
| 24 | + |
| 25 | +New objects can be created based on already existing objects chosen as their prototype. You may call two different objects <i>apple</i> and <i>orange</i> a <i>fruit</i>, if the object <i>fruit</i> exists, and both <i>apple</i> and <i>orange</i> have <i>fruit</i> as their prototype. The idea of the <i>fruit</i> class doesn't exist explicitly, but as the equivalence class of the objects sharing the same prototype. The attributes and methods of the prototype are delegated to all the objects of the equivalence class defined by this prototype. The attributes and methods owned individually by the object may not be shared by other objects of the same equivalence class; e.g. the attribute <i>sugar_content</i> may be unexpectedly not present in <i>apple</i>. Only single inheritance can be implemented through the prototype. |
| 26 | + |
| 27 | +### <i>Example</i>: |
| 28 | + |
| 29 | +Let's create characters for a game using OOP: |
| 30 | + |
| 31 | + |
| 32 | + |
| 33 | +## Factory Functions |
| 34 | + |
| 35 | +Factory Functions, as the name suggests, are functions that act like factories. They create objects for us. |
| 36 | + |
| 37 | +```javascript |
| 38 | +function createElf(name, weapon) { |
| 39 | + return { |
| 40 | + name, // ES6 syntax (if prop & val are the same). Same as writing 'name: name' |
| 41 | + weapon, |
| 42 | + attack() { |
| 43 | + return 'attack with ' + weapon |
| 44 | + } |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +const peter = createElf('Peter', 'stones') |
| 49 | +peter.attack() // -> attack with stones |
| 50 | +``` |
| 51 | + |
| 52 | +#### Using `Object.create()`: |
| 53 | + |
| 54 | +The `Object.create()` method creates a new object, using an existing object as the prototype for the newly created object. |
| 55 | + |
| 56 | +```javascript |
| 57 | +const elfFunctions = { |
| 58 | + attack() { |
| 59 | + return 'attack with ' + this.weapon |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +function createElf(name, weapon) { |
| 64 | + let newElf = Object.create(elfFunctions) |
| 65 | + newElf.name = name; |
| 66 | + newElf.weapon = weapon; |
| 67 | + return newElf; |
| 68 | +} |
| 69 | + |
| 70 | +const peter = createElf('Peter', 'stones') |
| 71 | +peter.attack() // -> attack with stones |
| 72 | +``` |
| 73 | + |
| 74 | +#### Using Constructor Functions: |
| 75 | + |
| 76 | +Objects of the same type are created by calling the constructor function with the `new` keyword. By default the `new` keyword returns an object. |
| 77 | + |
| 78 | +In JavaScript, the thing called `this` is the object that "owns" the code. The value of `this`, when used in an object, is the object itself. This is because the execution context changes after an object is created. In a constructor function `this` does not have a value. It is a substitute for the new object. The value of `this` will become the new object when a new object is created. |
| 79 | + |
| 80 | +<i>Note that this is not a variable. It is a keyword. You cannot change the value of this.</i> |
| 81 | + |
| 82 | +As a rule all constructor functions should start with a capital letter to let other programmers know that you need to call this function using the `new` keyword. |
| 83 | + |
| 84 | +```javascript |
| 85 | +function Elf(name, weapon) { |
| 86 | + this.name = name; |
| 87 | + this.weapon = weapon; |
| 88 | +} |
| 89 | + |
| 90 | +Elf.prototype.attack = function() { |
| 91 | + return 'attack with ' + this.weapon |
| 92 | +} |
| 93 | + |
| 94 | +const peter = new Elf('Peter', 'stones') |
| 95 | +peter.name // -> Peter |
| 96 | +peter.attack() // -> attack with stones |
| 97 | + |
| 98 | +const sam = new Elf('Sam', 'fire') |
| 99 | +sam.attack() // -> attack with fire |
| 100 | +``` |
| 101 | + |
| 102 | +Constructor functions have access to the `prototype` property which we have the ability to attach methods to. |
| 103 | + |
| 104 | +Peter doesn't have `attack` as it's own method but when `Peter.attack()` gets called it's going to go up the prototype chain and access the `attack` method there. It can do this because the `Elf` constructor's prototype contains the `attack` method, so now both Peter and Sam are able to use it. |
| 105 | + |
| 106 | +This is efficient because `attack` now exists in the same location in memory and we now no longer have to copy it multiple times in order to use it. |
| 107 | + |
| 108 | +<i>Note: Remember, we can't use arrow functions in constructors because arrow functions are lexically scoped and will point the value of `this` back to the function itself where it was written.</i> |
0 commit comments