├── ES6.md ├── OOP_notes.md └── README.md /ES6.md: -------------------------------------------------------------------------------- 1 | # ES6 / ES 2015 2 | 3 | ## [LET Declarations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) 4 | Let is a new way to declare variables and have them scoped to the nearest code block (and not to the nearest function, as with the standard `var` declaration). 5 | 6 | Consider this: 7 | ```javascript 8 | function regularFunction(){ 9 | if(true){ 10 | var trueBlockVariable = 'Hello'; 11 | } else { 12 | var falseBlockVariable = 'Goodbye!'; 13 | } 14 | 15 | console.log(falseBlockVariable); // undefined 16 | } 17 | 18 | regularFunction(); 19 | ``` 20 | 21 | In the above code, the console log will produce `undefined` rather than the normal 'not defined' error. To test this, you can try console logging any other made up variable, such as 'cats' on the very next line after the 'falseBlockVariable' console log. 22 | 23 | The reason for this is because of the 'var' declaration and hoisting. Hoisting will lift the variable declarations to the top of the function and set them to undefined. 24 | 25 | The answer of course, is a `let` declaration. 26 | 27 | Consider this: 28 | ```javascript 29 | function regularFunction(){ 30 | if(true){ 31 | let trueBlockVariable = 'Hello'; 32 | } else { 33 | let falseBlockVariable = 'Goodbye!'; 34 | } 35 | 36 | console.log(falseBlockVariable); // error: falseBlockVariable is not defined 37 | } 38 | 39 | regularFunction(); 40 | ``` 41 | 42 | This will produce an error of 'not defined'. This matches our expectation of what we would see in other programming languages. 43 | 44 | ### Instructor Notes 45 | * Make sure that students really understand scope, 46 | * Make sure that the students understand the difference between 'undefined' and 'not defined', 47 | * One of the considerations that need to be made is whether or not an error is actually better than undefined for the need of the application. 48 | 49 | ## [CONST Declarations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) 50 | Const declarations allow us to create variables that cannot change. Which on the surface seems like a bad idea, but it allows us to constrain and address 'magic numbers'. 51 | 52 | Consider this example that checks the number of toppings on a pizza order. If its over three toppings, then it does not qualify for a special: 53 | ```javascript 54 | var numOfToppings = 4; 55 | 56 | if(numOfToppings > 3){ 57 | // Does not qualify for deal. 58 | } else { 59 | // Qualifies for deal. 60 | } 61 | ``` 62 | 63 | The problem in the above, is that the number '3' would be a complete mystery without the explanation above it. This is what we call a `magic number`. Magic numbers are numbers that have meaning, but they are not described in the code at all. Typically they get used because they are meant to be unchanging values. This is where the `const` declaration can help. We use the const declaration to help us control the value, but also be descriptive about what that value represents. We can pair that with the `let` declaration on the `numOfToppings` for extra ES6'iness. 64 | 65 | Finally, naming convention for `const` variables uses capital letters with underscores in between. So for our pizza deal declaration, we would use something like this: `const TOPPINGS_FOR_DEAL` 66 | 67 | ```javascript 68 | let numOfToppings = 4; 69 | const TOPPINGS_FOR_DEAL = 3; 70 | 71 | if(numOfToppings > TOPPINGS_FOR_DEAL){ 72 | // Does not qualify for deal. 73 | } else { 74 | // Qualifies for deal. 75 | } 76 | ``` 77 | 78 | The code is now more readable in terms of being able to look at the code and quickly infer what the code is doing. Additionally, we know with the naming convention that the `TOPPINGS_FOR_DEAL` is a constant and that the value cannot be changed. 79 | 80 | ### Instructor Notes 81 | * Ensure that students understand what a Magic Number is. And even though it has a good name, it's actually a bad thing, 82 | * Sell the idea of code readability here, restate the if statement out loud, pointing to the variables. Example "If the number of toppings is greater than the toppings for the deal, then...", 83 | * Demonstrate that you cannot change the value of a const. Like the example below: 84 | ```javascript 85 | const SOME_CONST = 6; 86 | SOME_CONST = 5; 87 | ``` 88 | 89 | ## [Function Arguments](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/arguments) 90 | Javascript is very flexible when it comes to working with arguments within functions. We can pass in extra arguments or even omit arguments all together on functions that would normally accept arguments. In these cases, Javascript will not produce errors. 91 | 92 | Consider this: 93 | ```javascript 94 | function processArray(array){ 95 | console.log(array.length); 96 | //do things to the array 97 | } 98 | 99 | processArray( [1,2,3] ); // logs '3' 100 | processArray( ); //cannot read property '.length' of undefined. 101 | processArray( undefined ); //cannot read property '.length' of undefined. 102 | ``` 103 | 104 | The error of `cannot read property '.length' of undefined` comes from the fact that we are trying to read .length within the console log, not that we passed in nothing or undefined itself. Actually passing the arguments or not is something that Javascript allows us to do. 105 | 106 | ## [Default Parameter Values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters) 107 | We can now create and assign default parameters to our function arguments! If the value is supplied, it supplied value will override the default set. We simply assign the default value in the `function signature`. For example `function processArray(array = []){...}`. Note that supplying an undefined value *WILL NOT* override the default parameter value. Meaning that an undefined supplied value will become the default parameter value. 108 | 109 | Looking at the previous example, we can see how the logs will now be different: 110 | ```javascript 111 | function processArray(array = []){ 112 | console.log(array.length); 113 | //do things to the array 114 | } 115 | 116 | processArray( [1,2,3] ); // logs '3' 117 | processArray( ); //logs '0' 118 | processArray( undefined ); //logs '0' 119 | ``` 120 | 121 | ### Instructor Notes 122 | * Take a moment to clean up the phrase 'function signature' with students, 123 | * Point out that default parameters are available in other languages, 124 | * Type is implied with the default parameters, but another type could be entered at the time of the function call (so it does not fix everything) 125 | 126 | ## Configuration Objects and Named Parameters 127 | A common pattern in Javascript is to accept a configuration object as an argument to a function. 128 | 129 | For example: 130 | ```javascript 131 | function setupUser(configObject){ 132 | var name = configObject.name; 133 | var admin = configObject.admin; 134 | //do things 135 | } 136 | 137 | setupUser({name: 'Scott', admin: true}); 138 | ``` 139 | 140 | From what we learned about default parameters, we may be tempted to additionally use a default value for the `configObject` to at least check whether or not the supplied argument is an object. Problem is, we are still writting assignment code, Which might look something like this: 141 | ```javascript 142 | function setupUser(configObject = {}){ 143 | var name = configObject.name; 144 | var admin = configObject.admin; 145 | //do things 146 | } 147 | 148 | setupUser({name: 'Scott', admin: true}); 149 | ``` 150 | 151 | But we can take this up another step. We can instead use the declaration names within an object as an argument to the function itself. Check it out: 152 | 153 | ```javascript 154 | function setupUser( {name,admin} ){ 155 | //do things 156 | } 157 | 158 | setupUser({name: 'Scott', admin: true}); 159 | ``` 160 | 161 | Inside the function, we have access to the `name` and `admin` values, already declared as we did in the examples above. As a bonus, the function signature is more descript about that the function accepts! Note that as a final step, we can still assign a default parameter. 162 | 163 | ```javascript 164 | function setupUser( {name,admin} = {} ){ 165 | //do things 166 | } 167 | 168 | setupUser({name: 'Scott', admin: true}); 169 | ``` 170 | 171 | ## [Rest Parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) 172 | A Rest parameter allows us to accept an indefinite amount of arguments and puts them into an array. We access the rest parameter with the `...` leading syntax followed by what we would like to call the param. 173 | 174 | For example: 175 | ```javascript 176 | function restFunction(...list){ 177 | for(let i = 0; i < list.length; i++){ 178 | console.log(list[i]); 179 | } 180 | } 181 | 182 | restFunction('Scott', 'Fred', 'Mark', 'Taylor', 'Chris'); 183 | ``` 184 | 185 | Additionally, we can put arguments in front of the rest parameter to accepted needed arguments that should not be considered in the rest array. 186 | 187 | For example: 188 | ```javascript 189 | function restFunction(instructor = 'Unassigned', ...list){ 190 | for(let i = 0; i < list.length; i++){ 191 | console.log(list[i]); // Logs list without 'Scott' 192 | } 193 | 194 | console.log(instructor); // Logs 'Scott' 195 | } 196 | 197 | restFunction('Scott', 'Fred', 'Mark', 'Taylor', 'Chris'); 198 | ``` 199 | 200 | ## [Spread Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) 201 | Spread operators have a similar syntax as rest parameters, however instead of using the `...` syntax in a function argument, we use it in the function call. The functional difference is that it take an array of values and sends them to the function as individual arguments into the function. 202 | 203 | Consider this: 204 | ```javascript 205 | let atticus = ['Atticus', 392811, 94000]; 206 | 207 | function createEmployeeObject(array){ 208 | var name = array[0]; 209 | var employeeNumber = array[1]; 210 | var salary = array[2]; 211 | //Do things 212 | } 213 | 214 | createEmployeeObject(atticus); 215 | ``` 216 | 217 | In the above example, we see the array of information passed into the function call, then inside the function the array is accepted. That array is then used to assign value to variables created in the function. As we have seen in ES6 before, we know that this pattern of boilerplate variable assignment is not ideal. So instead, we can pair up the spread operator with stated arguments. For example: 218 | ```javascript 219 | let atticus = ['Atticus', 392811, 94000]; 220 | 221 | function createEmployeeObject(name = 'Un-named', employeeNumber = '00000', salary = '10000'){ 222 | //Do things 223 | } 224 | 225 | createEmployeeObject(...atticus); 226 | ``` 227 | 228 | In the example above, we can see that the variable creation is handled in the function signature. The spread operator can them separate them into different arguments. Additionally, we can pair both the rest and spread operator together for some great flexibility. Run the following code and notice how the console logs are different: 229 | ```javascript 230 | let atticus = ['Atticus', 392811, 94000]; 231 | 232 | function createEmployeeObject(name = 'Un-named', employeeNumber = '00000', salary = '10000', ...extras){ 233 | console.log(name, employeeNumber, salary); // logs Atticus, 392811, 94000 234 | console.log(extras); // logs [4, 5, 6] 235 | console.log(...extras); // logs 4, 5, 6 236 | } 237 | 238 | createEmployeeObject(...atticus, 4, 5, 6); 239 | ``` 240 | 241 | ## [Arrow Functions and Lexical Binding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) 242 | Arrow functions is one of the most exciting new features of ES6. At first glance, it seems like a fancy new way to create functions. But below the surface, is a very important consideration around the binding of 'this' as it relates to method calls. But more on that in a second. 243 | 244 | Lets take a look at the same function, defined in both ES5 and ES6: 245 | ```javascript 246 | // ES5 247 | var normalFunction = function(){ 248 | console.log('Normal function'); 249 | } 250 | 251 | //ES6 252 | var arrowFunction = () => { 253 | console.log('Arrow function'); 254 | } 255 | ``` 256 | 257 | First thing we notice is how the function is actually defined. Instead of using the keyword `function`, we use a set of `( )` followed by a `=>` then the regular code block. At a closer look, the other thing that we see, is that we need to use function expressions and anonymous functions to properly set up an arrow function in this regard. 258 | 259 | Let's look at the same example, but with an argument in the function as well: 260 | ```javascript 261 | // ES5 262 | var normalFunction = function(message){ 263 | console.log('Normal function: ', message); 264 | } 265 | 266 | //ES6 267 | var arrowFunction = (message) => { 268 | console.log('Arrow function: ', message); 269 | } 270 | ``` 271 | Now the short creation of functions is cool, but not the only point of arrow functions. One of the most common problems in Javascript, is the creation of Objects that have methods. More specifically, how that method is able to access the objects properties to which the method belongs. Let's look at an example of the problem below in ES5: 272 | ```javascript 273 | function PersonES5() { 274 | var that = this; // We need to bind 'this' to a new variable to preserve the context of 'this' for use inside the method. 275 | that.age = 0; 276 | 277 | setInterval(function growUp() { 278 | // The callback refers to the `that` variable of which 279 | // the value is the expected object. 280 | that.age++; // This iterates the value of 'age' properly on the object. 281 | console.log(that.age); // We can see that this increments correctly. 282 | this.age++; // This produces NaN 283 | console.log(this.age, this); // We discover that 'this' inside the method has a new context. That to the window. 284 | }, 1000); 285 | } 286 | 287 | var scott = new PersonES5(); 288 | ``` 289 | 290 | ### Lexical Binding 291 | In the previous example, we observed that once we were inside the method of the object, the context of `this` shifted from the object, to the window, as that is where the function is technically called. Something that we would not expect. Luckily, with Arrow Functions, it preserves the context of `this` to what we would expect. So lets look at how we can hook into Arrow Functions to help with the example from above, rewritten with ES6 and Arrow Functions: 292 | ```javascript 293 | function PersonES6(){ 294 | this.age = 0; 295 | 296 | setInterval(() => { 297 | this.age++; // |this| properly refers to the person object. 298 | console.log(this); // Iterates the age of the Person object as we would hope. 299 | }, 1000); 300 | } 301 | 302 | var scott = new PersonES6(); 303 | ``` 304 | Arrow functions bind to the scope of where they are defined, not where we are used. This is known as `Lexical Binding`. 305 | 306 | ## [Object Initialization Shorthand](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) 307 | 308 | We now have a shorthand method for creating objects that have key value pairs that match the same name. First, let's look at some ES5 syntax to understand where the upgrade comes from: 309 | ```javascript 310 | let name = 'Hamburger'; 311 | let price = 7.99; 312 | let sides = ['Fries', 'Coleslaw']; 313 | 314 | let order = {name: name, price: price, sides: sides}; 315 | console.log(order.name, order.price, order.sides); //logs 'Hamburger', 3.99, ['Fries', 'Coleslaw'] 316 | ``` 317 | 318 | As you can see, there is a little bit of repetition in the creation of the order variable. In the object we create, we find ourself repeating the key value pairs. If we want them key and the value to be the same (value pointing to another variable of course), we can use a shorthand: 319 | ```javascript 320 | let name = 'Hamburger'; 321 | let price = 7.99; 322 | let sides = ['Fries', 'Coleslaw']; 323 | 324 | let order = {name, price, sides}; 325 | console.log(order.name, order.price, order.sides); //logs 'Hamburger', 3.99, ['Fries', 'Coleslaw'] 326 | ``` 327 | 328 | ## [Object Destructing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) 329 | 330 | ### Array 331 | Object destructing allows us to assign multiple values based on returns of multiple values. Below are some examples of how this works: 332 | ```javascript 333 | let someArray = ['Hamburger', 3.99, ['Fries', 'Coleslaw']]; 334 | 335 | let [name, price, sides] = someArray; 336 | console.log(name, price, sides); //logs 'Hamburger', 3.99, ['Fries', 'Coleslaw'] 337 | ``` 338 | 339 | Above, you can see that we defined an array with three values, a String, a Number, and an Array. Then we use a variable declaration to create three new variables with bracket syntax and then set it equal to an array. The three new values then become equal to the three values from the array. 340 | 341 | We can also skip variables by omitting a variable name: 342 | ```javascript 343 | let someArray = ['Hamburger', 3.99, ['Fries', 'Coleslaw']]; 344 | 345 | let [name, , sides] = someArray; 346 | console.log(name, sides); //logs 'Hamburger', ['Fries', 'Coleslaw'] 347 | ``` 348 | 349 | ## [Method Initializer Shorthand](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) 350 | 351 | ```javascript 352 | //Old 353 | function Dog(name){ 354 | return { 355 | name, 356 | bark : function(){ 357 | alert('Bark!'); 358 | } 359 | } 360 | } 361 | 362 | //New 363 | //Old 364 | function Dog(name){ 365 | return { 366 | name, 367 | bark(){ 368 | alert('Bark!'); 369 | } 370 | } 371 | } 372 | ``` 373 | 374 | 375 | ## [Template Strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) 376 | 377 | ```javascript 378 | //Old 379 | function Person(first, last){ 380 | let fullname = first + ' ' + last; 381 | } 382 | 383 | //New 384 | function Person(first, last){ 385 | let fullname = `${first} ${last}`; 386 | } 387 | 388 | ``` 389 | 390 | Also, multiline strings are supported with the back ticks: 391 | ```javascript 392 | let scottsJoke = `Two muffins are sitting in an oven. 393 | 394 | The first muffin says to the second 'Its really hot in here'. 395 | 396 | The second muffin says 'AH! A TALKING MUFFIN!'` 397 | 398 | console.log(scottsJoke); 399 | ``` 400 | 401 | ## Array with Destructing Variables 402 | We can use destructing to assign multiple values from an array to local variables. Common case for variable assignment from Arrays: 403 | ```javascript 404 | let people = ['Scott', 'Chris', 'Kris']; 405 | let a = people[0]; 406 | let b = people[1]; 407 | let c = people[2]; 408 | console.log(a,b,c); 409 | ``` 410 | 411 | But we can use Destructing Variables to shorten the assignment: 412 | ```javascript 413 | let people = ['Scott', 'Chris', 'Kris']; 414 | let [a,b,c] = people; 415 | console.log(a,b,c); 416 | ``` 417 | 418 | ### Array with Function Returns and Destructing Variables 419 | Similar to the examples above, this also works with functions that return arrays as well: 420 | ```javascript 421 | function basePizzaToppings(){ 422 | let toppings = ['Sausage', 'Cheese', 'Pepperoni']; 423 | return toppings; 424 | } 425 | 426 | let [a,b,c] = basePizzaToppings(); 427 | console.log(a,b,c); 428 | ``` 429 | 430 | ## [For Of Loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) 431 | A very common task is to iterate over arrays to complete some task. Using a 'For In' loop allows us to go through each item in an array and do something with it, however it has an extra step: 432 | ```javascript 433 | let people = ['Scott', 'Chris', 'Kris']; 434 | 435 | for(let index in people){ 436 | console.log(people[index]); 437 | } 438 | ``` 439 | 440 | In the above step, we track the `index` and use it to get the specific person out of the people array. It would be much handier if we were able to drop a step since this is such a common set. Enter 'For Of' loops: 441 | ```javascript 442 | let people = ['Scott', 'Chris', 'Kris']; 443 | 444 | for(let person of people){ 445 | console.log(person); 446 | } 447 | ``` 448 | 449 | ## [Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) 450 | A common approach to encapsulation within Javascript is to use a combination of constructor functions and assigning methods to the prototype: 451 | 452 | ```javascript 453 | function AudioPlayer(currentSong){ 454 | this.currentSong = currentSong; 455 | this.currentTime = 0; 456 | } 457 | 458 | AudioPlayer.prototype.play = function(){ ... } ; 459 | AudioPlayer.prototype.stop = function(){ ... } ; 460 | 461 | let newAudioPlayer = new AudioPlayer('Sleep Apnea'); 462 | newAudioPlayer.play(); 463 | ``` 464 | 465 | But in ES6 syntax, we have a much more elegant way to define our classes. To those coming from other OOP languages, the syntax is much more familiar. It even comes with a `constructor` method that is invoked whenever an instance of the class created! 466 | 467 | Here is the same class defined above in the new syntax: 468 | ```javascript 469 | class AudioPlayer { 470 | 471 | constructor(currentSong){ 472 | this.currentSong = currentSong; 473 | this.currentTime = 0; 474 | } 475 | 476 | play(){ 477 | // ... 478 | console.log("Playing " + this.currentSong + "!"); 479 | } 480 | 481 | stop(){ 482 | // ... 483 | console.log("Stopping " + this.currentSong + "!"); 484 | } 485 | 486 | } 487 | 488 | let newAudioPlayer = new AudioPlayer('Sleep Apnea'); 489 | newAudioPlayer.play(); 490 | ``` 491 | 492 | Notice that we create the object just as we did before. Another thing to notice is that the `this` keyword is properly bound to the class scope. Meaning that we can access properties within the class with the `this` keyword. 493 | 494 | Note that Javascript does not have any access modifers, so we are unable to control `public` and `private` methods and variables through ES6 syntax. In fact, there is no addition "power" in the Class syntax above. Either the stated ES5 or ES6 methods are acceptable, but the ES6 syntax is closer to what you would see in other languages. 495 | 496 | ## Inheritance 497 | We can extend the functionality from one class to the next by using the `extend` keyword. This will cause the `subclass` (or`childclass`) to inherit its functionality from the `superclass` (or `parentclass`). Let's take a look at an example below: 498 | 499 | ```javascript 500 | class MarketItem { 501 | 502 | constructor(name, price, imgUrl){ 503 | this.name = name; 504 | this.price = price; 505 | this.imgUrl = imgUrl; 506 | } 507 | 508 | changePrice(){ 509 | this.price++; 510 | console.log('Price Changed! ', this.price); 511 | } 512 | } 513 | 514 | class Fruit extends MarketItem { 515 | 516 | constructor(name, price, imgUrl, freshness){ 517 | super(name, price, imgUrl); 518 | this.freshness = freshness; 519 | } 520 | 521 | changePrice(){ 522 | super.changePrice(); 523 | this.freshness--; 524 | if(this.freshness <=0){ 525 | this.price = 0; 526 | console.log('Food spoiled: ', this.price); 527 | } else { 528 | console.log('Freshness: ', this.freshness); 529 | } 530 | } 531 | } 532 | 533 | var apple = new Fruit('Apple', 1, 'something.jpg', 2); 534 | console.log(apple); 535 | apple.changePrice(); 536 | 537 | ``` 538 | 539 | ## [Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) 540 | `Waiting until to see if we have enough time to cover Babel. As module support is not native to browsers` 541 | -------------------------------------------------------------------------------- /OOP_notes.md: -------------------------------------------------------------------------------- 1 | ##### Note that these notes are intended for Javascript Learners looking at OOP for the first time. 2 | 3 | # Object Orientated Programming 4 | 5 | ## A Case for Object Orientated Programming 6 | In old languages, like Cobol and Assembly, programs were written in a monolithic manner. It had familiar components like Variables written at the top with functions and subroutines in the middle and so on, but when writing large applications, this proved to be problematic. In the 1980s, OOP languages started to gain popularity. 7 | 8 | OOP allowed programs to be written as ‘mini-programs’, each handling a specific part of functionality of the main application. Each object contained its own data and its own logic. The objects are then used to communicate with each other. Each of these objects represents groups of functionality within your application, such as videos, images, and employees, game pieces, and so on. 9 | 10 | Object Orientation is what is referred to as a ‘Programming Paradigm’. Not a language in itself, but rather a set of ideas all languages can use. 11 | 12 | ## An Object 13 | When describing Objects, it’s difficult to fall on a crutch like “What is an Object? Well, it’s a thing”, for example. In the real world, we understand very well what an object is. We can look at two Whiteboard Markers and know that they are the same “thing”, but are also very different. Each of the Markers can have a different color, different amount of ‘ink’, a different age since manufacturing, and so on. But we describe them both as Dry Erase Markers. 14 | 15 | The same could be said about the students in this room. We all fall under the categorization of ‘People’, but certainly have a different set of properties that all make us unique. While “Prime Academy Student” is one property that you all share, we all certainly have a different make up of properties that make us unique. Ones that in many ways make us completely different, but there are other properties that make us all the same. Tired might be one of those properties. 16 | 17 | When we look at other objects in the world, we also understand that what one object can do, other objects might not be able to do. For example, the Bird animal can ‘Fly’, where the Turtle animal cannot. But additionally, the same objects may have different values of the same property. One human can be more caffeinated than another. 18 | 19 | Objects generally have three important things that describe an object in programming. Identity, attributes, and behavior. 20 | 21 | Identity describes an object. 22 | Attributes define the state of an object. 23 | Behavior defines how the objects acts, or ‘things they can do’. 24 | 25 | In the real world, we quickly grasp to physical things that we can touch and see when describing objects. But in applications, we can take it further. A Bank Account is a thing that we cannot touch, but it certainly is an object. It has an Identity, “Scotts Bank Account”, it has properties, “$370 dollars”, and it has behaviors it can execute, “Collect Interested”, “Overdraft”, and so on. Each of those behaviors can change the state of itself, or other objects within the application. 26 | 27 | Perhaps a good way to think about what an object can be, is to latch onto the word “Noun”. Is the thing you are trying to describe a noun? Or, could you put the word “The” in front of it? 28 | 29 | ## Class 30 | Class and Objects go hand in hand. But Classes take it a level up. Classes describe what an object can be, but it is not the object itself. You can think of a class as a Blueprint for an Object. When I say the word ‘Apple’, you begin thinking about the look and characteristics of an Apple, but you are not thinking about a specific apple. Unless of course, it was a particularly good apple. 31 | 32 | For programmers, we build the Class (the blueprint) and we use that Class to build the object. Or in our Apple description, we might have the class for an apple, then create millions of apples from that class. 33 | 34 | ### Creating a Class 35 | When we approach the creation of the class, we think about those three things mentioned above: Identity, Attributes, and Behavior. 36 | 37 | * Identity - What is its name? Apple, Bank Account, Person, etc. 38 | * Attributes - Size, Color, Amount, Weight, Height, etc. 39 | * Behaviors - Grow, Deposit, Withdraw, Sleep, Eat, etc. 40 | 41 | But you may see different words associated to these three ‘things’. You may not see ‘Name’, but `Type` for example. Attributes may be described as `Properties`. And Behaviors may be referred to as `Methods` or `Operations`. 42 | 43 | If we were to ground this in the Javascript concepts we know, we could look at an example of a class with our current syntax like so: 44 | 45 | ```javascript 46 | function AudioPlayer(currentSong, currentTime = 0){ 47 | return { 48 | currentSong, 49 | currentTime, 50 | play(){}, 51 | stop(){} 52 | } 53 | } 54 | ``` 55 | 56 | We can actually diagram these as well. We can think of it almost as a card with three sections, broken apart by how we have been describing these three things. Identity on top, Attributes in the middle, and Behaviors at the bottom: 57 | 58 | | AudioPlayer | 59 | | ------------- | 60 | | currentSong 61 | currentTime| 62 | | ------------- | 63 | | play() | 64 | | stop() | 65 | 66 | In this example, we see that we have an Audio Player Class described above. If we were to deploy our application and allow users to paly their own songs on their own `instance` of an audio player, we would have different properties and names. 67 | 68 | | ScottsAudioPlayer | 69 | | ------------- | 70 | | Sleep Apnea 71 | 0:37| 72 | | ------------- | 73 | | play() | 74 | | stop() | 75 | 76 | | RachaelsAudioPlayer | 77 | | ------------- | 78 | | Everybody 79 | 1:24| 80 | | ------------- | 81 | | play() | 82 | | stop() | 83 | 84 | ### Instances 85 | An instance is an individual creation from a Class. While Whiteboard Marker might be the class, each of these markers are individual `instances` of the class. The process of creation of an instance from a class, is an `instantiation`. 86 | 87 | ### Types and Classes 88 | In most languages, the language itself comes with its own collection of Classes that are already available to us. In Javascript, we may be familiar with the term `type` or `object`. We work with these objects all the time and because of the ease of Javascript, we skip right past the parts that make us think of how they began as classes. For example, we instantiate Numbers, Strings, and Arrays all the time. But because of Javascript shorthand, we miss the critical clues that tell use we are using a Blueprint of sorts. 89 | 90 | ## Abstraction 91 | Abstraction has to do with the 'idea' of something. If I said to you the word 'House'. You would know what I am talking about. There are a ton of details that would need to be sussed out, but you ‘have the general idea’ of what I am talking about. 92 | 93 | Abstraction just focuses on the essentials, and discards the unimportant pieces of information. We are not focusing on the type of house, just rather what the word represents. We do this all the time in the real world. Chances are great, that as you came together this morning and asked the question “How was your weekend? What did you do?”, as the person described their weekend, you did not need to stop them every second to hop into the minutiae of every detail, but rather listened to the story and were able to track fine. 94 | 95 | The phrase “I went to my brothers house for Sunday brunch” prompts a general image in your mind that does not need the specific details of the brother, his house, and what was for brunch. 96 | 97 | Faction NEEDS this idea of abstraction to function at all. Often times we find ourselves drawn into faction because the writer does a great job describing the needed details to frame the story, but also allows the reader's imagination to fill in the blanks. 98 | 99 | If we were writing code, we do not write a class for each and every Bank Account let's say, but rather we establish a base in which all bank accounts derive from. 100 | 101 | Abstraction is at the core of the other fundamentals of Object Orientated Programming, and we will see how it plays a critical role. 102 | 103 | ## Encapsulation 104 | 105 | Surrounding something. Protecting contents. Taking attributes and behaviors, then bundling them up in a class. But it’s more than just the idea of class. It is about the protection of of those attributes and behaviors. This is referred to as ‘data hiding’. 106 | 107 | The main concept of data hiding, is that you are ONLY revealing attributes and behaviors that are ABSOLUTELY necessary in order for your application to work. 108 | 109 | A simple example of this is a Bank Account application. You should not be able to access the property of balance directly from any other part of the application. You should have to go through the deposit or withdraw methods in order to change the balance. This is because there are other considerations that need to be made. If you were able to subtract from the balance from anywhere in the application, then you would probably need to check for an overdraft in each place you made negative adjustments. It would be so much easier if you just went through one method to do it. 110 | 111 | This means that the balance cannot be changed directly, but rather just through the withdraw and deposit methods which can reach inside its own class to manipulate the balance, with the other considerations that go along with it. 112 | 113 | Another example is a toaster. A toaster is fairly simple. Adjust time, then push the handle down to toast. The time mechanism is something that you have direct access to, a property you can manipulate directly. But the inner workings of a toaster are not available to you. You actually have no idea how the time dial changes the inner workings of the toaster, or rather, how that dial fits into the mechanics of the toaster. Same for the handle. You push it down, but inside of the toaster, you could probably not speak to exactly what the toaster does to start the warming process of the bread. Changing the inner mechanisms of the toaster probably do not change the inputs of the toaster itself. Unless of course, you got a better toaster. 114 | 115 | ## Inheritance 116 | When it comes to working with Classes, we may run into situations where two objects could be similar, and even categorized under one one class, but they are different enough to each need special properties, methods, or both. Thinking about a Bike and a Motorcycle, we can conclude that they are very different, but have some common attributes and behaviors. Both have wheels, are used as modes of transportation, but there are also differences. Such as mode of power, the need for fuel, and so on. 117 | 118 | So in this case, we could create a ‘Vehicle’ class. We could then find the commonalities and draw out the properties and methods that the two share: 119 | 120 | | Vehicle | 121 | | ------------- | 122 | | numWheels | 123 | | ------------- | 124 | | moveForward() 125 | stop()| 126 | 127 | But in this example, we would want to create two different objects from this Vehicle class, but lets consider the need to create 100's of Bike and 100's of Motorcycles. We should have a class for each of those two. But luckily, we don't need to start from scratch when we do this. We do not need to create two different classes that share some things but not others. We can `extend` the Vehicle class we created, and allow the two new classes to automatically have the properties and methods of the Vehicle class. 128 | 129 | | Motorcycle : Vehicle | 130 | | ------------- | 131 | | engine 132 | fuelLevel| 133 | | ------------- | 134 | | startEngine() 135 | stopEngine()| 136 | 137 | 138 | | Bike : Vehicle | 139 | | ------------- | 140 | | hasKickstand| 141 | | ------------- | 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ES6 and OOP Instructor notes: 2 | 3 | [ES6 Notes](https://github.com/scottbromander/es6_notes/blob/master/ES6.md) 4 | 5 | [OOP Notes](https://github.com/scottbromander/es6_notes/blob/master/OOP_notes.md) 6 | --------------------------------------------------------------------------------