└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript: Understanding the Weird Parts 2 | These are my notes from the briliant course by [Tony Alicea](https://twitter.com/anthonypalicea) about learning in-depth JavaScript. If you want to learn how JavaScript engine works under the hood I highly recommend you to check out this course which you can find at [Udemy](https://www.udemy.com/understand-javascript/). 3 | 4 | 5 | 6 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 7 | 8 | - [Define goals of success](#define-goals-of-success) 9 | - [5 - Conceptual Aside - Syntax Parser, Execution Context, and Lexical Environment](#5---conceptual-aside---syntax-parser-execution-context-and-lexical-environment) 10 | - [6 - Conceptual Aside - Name-Value Pairs and Objects](#6---conceptual-aside---name-value-pairs-and-objects) 11 | - [7 - The Global Environment and The Global Object](#7---the-global-environment-and-the-global-object) 12 | - [8 - The Execution Context - Creation & Hoisting](#8---the-execution-context---creation--hoisting) 13 | - [9 - Conceptual Aside - Javascript and undefined](#9---conceptual-aside---javascript-and-undefined) 14 | - [10 - The Execution Context - Code Execution](#10---the-execution-context---code-execution) 15 | - [11 - Conceptual Aside - Single Threaded, Synchronous Execution](#11---conceptual-aside---single-threaded-synchronous-execution) 16 | - [12 - Function Invocation and the Execution Stack](#12---function-invocation-and-the-execution-stack) 17 | - [13 - Functions, Context, and Variable Environments](#13---functions-context-and-variable-environments) 18 | - [14 - The Scope Chain](#14---the-scope-chain) 19 | - [15 - Scope, ES6, and `let`](#15---scope-es6-and-let) 20 | - [16 - What About Asynchronous Callbacks](#16---what-about-asynchronous-callbacks) 21 | - [17 - Conceptual Aside Types And Operators](#17---conceptual-aside-types-and-operators) 22 | - [18 - Primitive Types](#18---primitive-types) 23 | - [19 - Conceptual Aside - Operators](#19---conceptual-aside---operators) 24 | - [20 - Operator Precedence and Associativity](#20---operator-precedence-and-associativity) 25 | - [21 - Conceptual Aside Coercion](#21---conceptual-aside-coercion) 26 | - [22 - Comparison Operators](#22---comparison-operators) 27 | - [23 - Existence and Booleans](#23---existence-and-booleans) 28 | - [24 - Default Values](#24---default-values) 29 | - [25 - Framework Aside: Default Values](#25---framework-aside-default-values) 30 | - [26 - Objects and the Dot](#26---objects-and-the-dot) 31 | - [27 - Objects and Object Literals](#27---objects-and-object-literals) 32 | - [28 - Framework Aside: Faking Namespaces](#28---framework-aside-faking-namespaces) 33 | - [29 - JSON and Object Literals](#29---json-and-object-literals) 34 | - [30 - Functions are Objects](#30---functions-are-objects) 35 | - [31 - Function Statements and Function Expressions](#31---function-statements-and-function-expressions) 36 | - [32 - Conceptual Aside By Value vs By Reference](#32---conceptual-aside-by-value-vs-by-reference) 37 | - [33 - Objects, Functions, and `this`](#33---objects-functions-and-this) 38 | - [34 - Conceptual Aside - Arrays - Collections of Anything](#34---conceptual-aside---arrays----collections-of-anything) 39 | - [35 - `arguments` and spread](#35---arguments-and-spread) 40 | - [36 - Framework Aside Function Overloading](#36---framework-aside-function-overloading) 41 | - [37 - Conceptual Aside - Syntax Parsers](#37---conceptual-aside----syntax-parsers) 42 | - [38 - Dangerous Aside Automatic Semicolon Insertion](#38---dangerous-aside-automatic-semicolon-insertion) 43 | - [39 - Framework Aside Whitespace](#39---framework-aside-whitespace) 44 | - [40 - Immediately Invoked Functions Expressions (IIFEs)](#40---immediately-invoked-functions-expressions-iifes) 45 | - [41 - Framework Aside IIFEs and Safe Code](#41---framework-aside-iifes-and-safe-code) 46 | - [42 - Understanding Closures](#42---understanding-closures) 47 | - [43 - Understanding Closures Pt. 2](#43---understanding-closures-pt-2) 48 | - [44 - Framework Aside Function Factories](#44---framework-aside-function-factories) 49 | - [45 - Closures And Callbacks](#45---closures-and-callbacks) 50 | - [46 - `call()`, `apply()`, and `bind()`](#46---call-apply-and-bind) 51 | - [47 - Functional Programming](#47---functional-programming) 52 | - [48 - Functional Programming Pt. 2](#48---functional-programming-pt-2) 53 | - [49 - Conceptual Aside Classical vs Prototypal Inheritance](#49---conceptual-aside-classical-vs-prototypal-inheritance) 54 | - [50 - Understanding The Prototype](#50---understanding-the-prototype) 55 | - [51 - Everything is an Object (Or a primitive)](#51---everything-is-an-object-or-a-primitive) 56 | - [52 - Reflection and Extend](#52---reflection-and-extend) 57 | - [53 - Functions Contructors, `new` And The History Of JavaScript](#53---functions-contructors-new-and-the-history-of-javascript) 58 | - [54 - Function Constructors and `.prototype`](#54---function-constructors-and-prototype) 59 | - [55 - Dangerous Aside `new` and functions](#55---dangerous-aside-new-and-functions) 60 | - [56 - Conceptual Aside Built-In Function Constructors](#56---conceptual-aside-built-in-function-constructors) 61 | - [57 - Dangerous Aside Built-In Function Constructors 2](#57---dangerous-aside-built-in-function-constructors-2) 62 | - [58 - Dangerous Aside Arrays and `for`..`in`](#58---dangerous-aside-arrays-and-forin) 63 | - [59 - `Object.create` and Pure Prototypal Inheritance](#59---objectcreate-and-pure-prototypal-inheritance) 64 | - [60 - ES6 and Classes](#60---es6-and-classes) 65 | - [61 - Initialization](#61---initialization) 66 | - [62 - `typeof`, `instanceof`, and Figuring Out What Something Is](#62---typeof-instanceof-and-figuring-out-what-something-is) 67 | - [63 - Strict Mode](#63---strict-mode) 68 | - [64 - Learning From Other's Good Code](#64---learning-from-others-good-code) 69 | - [65 - Deep Dive into Source Code jQuery - Part 1](#65---deep-dive-into-source-code-jquery---part-1) 70 | - [66 - Deep Dive into Source Code jQuery - Part 2](#66---deep-dive-into-source-code-jquery---part-2) 71 | - [67 - Deep Dive into Source Code jQuery - Part 3](#67---deep-dive-into-source-code-jquery---part-3) 72 | - [68 - Requirements](#68---requirements) 73 | - [73 - Good Commenting](#73---good-commenting) 74 | - [76 - TypeScript, ES6, and Transpiled Languages](#76---typescript-es6-and-transpiled-languages) 75 | 76 | 77 | 78 | ## Define goals of success 79 | 1. Be able to read jQuery source code and able to understand what is happening. 80 | 2. Complete and understand final project of writing own library. 81 | 82 | ## 5 - Conceptual Aside - Syntax Parser, Execution Context, and Lexical Environment 83 | **Syntax parser** - a program that reads your code and determines what it does and if its grammar/syntax is valid. 84 | 85 | When you write JavaScript it isn't directly telling computer what to do. You're writing code, but then someone else built programs that convert your JS into something that computer can understand. Those programs are called compilers or interpreters. 86 | 87 | **Compilers** go character by character and translate your code into a set of instructions. Important to understand is that during that process programmers who wrote that compiler can choose to do extra stuff. Your code is not what actually is given to a computer but a translation of it. 88 | 89 | **Lexical environment** - where something sits physically in the code you write and what surrounds it. In JavaScript where you write something is important. 90 | 91 | **Execution context** - a wrapper to help manage the code that is running. 92 | There are lots of lexical environments, areas of the code that you look at physically, but which one is currently running is managed via execution contexts. 93 | Execution context contains your running code, but it can also contain things beyond what you've written in your code. Because remember that your code is being translated by a syntax parser. 94 | 95 | ## 6 - Conceptual Aside - Name-Value Pairs and Objects 96 | **Name value pair** - a name which maps to a unique value. The name may be defined more than once, but can only have one value in any given execution context. 97 | 98 | **Object** - is a collection of name value pairs. 99 | 100 | ## 7 - The Global Environment and The Global Object 101 | **Global execution context** - the base execution context. It creates global object and special variable called `this`. In a browser `this` global object is `window`. 102 | 103 | ## 8 - The Execution Context - Creation & Hoisting 104 | **Hoisting** - because of the way JS works, you can write in your code a call to a function before an actual function and it will execute without any errors. 105 | 106 | ```javascript 107 | b(); 108 | 109 | function b() { 110 | console.log('This works!'); 111 | } 112 | ``` 113 | 114 | When parser runs through code it recognizes where you created variables and functions and it sets up memory space for them. So before your code begins to be executed, JS engine has already set aside memory space for all the variables and functions you created. When the code begins to execute line by line it can access it. 115 | 116 | However, for variables JS engine puts a placeholder `undefined`, because it doesn't know what it's value will ultimately end up being until it starts executing that line of 117 | code. 118 | 119 | ```javascript 120 | console.log(a); 121 | 122 | var a = 'Hello World!'; 123 | ``` 124 | 125 | ## 9 - Conceptual Aside - Javascript and undefined 126 | **`undefined`** - is a special value, a keyword that JavaScript sets up to all variables during a creation phase of execution context. 127 | 128 | ## 10 - The Execution Context - Code Execution 129 | In the execution phase JS engine runs your code line by line. 130 | 131 | ## 11 - Conceptual Aside - Single Threaded, Synchronous Execution 132 | **Single threaded** - JavaScript is a single threaded, synchronous language. That means one command execution at a time. Maybe not under the hood of the browser but from our perspective as programmers it is single threaded. 133 | 134 | **Synchronous execution** - means one at a time and in order that it appears. 135 | 136 | ## 12 - Function Invocation and the Execution Stack 137 | **Invocation** - running or calling a function by using parenthesis `()`. 138 | 139 | **Execution Stack** - every time you invoke a function a new execution context is created for that function and is put on top of execution stack. 140 | 141 | ## 13 - Functions, Context, and Variable Environments 142 | **Variable environments** - where the variables live and how they relate to each other in memory. Every execution context has its own variable environment. 143 | 144 | ## 14 - The Scope Chain 145 | If JavaScript engine doesn't find variable in it's own environment it looks in the outer environment. That whole process of searching of variable in outer lexical environments down the chain is called the **scope chain**. 146 | 147 | So in this example `myVar` would actualy log `1` even though it sits inside a function which is inside another. `myVar` sits in the outer global environment so JS will go down the scope chain until it finds it. 148 | 149 | ```javascript 150 | function a() { 151 | 152 | function b() { 153 | console.log(myVar); 154 | } 155 | 156 | b(); 157 | } 158 | 159 | var myVar = 1; 160 | a(); 161 | ``` 162 | 163 | ## 15 - Scope, ES6, and `let` 164 | **Scope** - where a variable is available in your code. And if it's truly a new variable, or a new copy. 165 | 166 | **`let`** - allows JS engine block scoping. During execution context that variable is still placed in memory and set to `undefined`, however, you're not allowed to use it until the line of code is run during the execution phase. So if you try to use a variable before, you'll get an error. Also, it is declared within a block. A block is usually defined by `{}` (function, if statement etc). So if you're running `let` inside a loop a new variable will be placed in memory after each iteration. 167 | 168 | ## 16 - What About Asynchronous Callbacks 169 | **Asynchronous** - executed more than one at a time. What is happening inside JS engine is synchronous. Its just the browser is putting things asynchronously in the event queue. 170 | 171 | **Event queue** - events like click and others are placed in the queue. And this queue starts to get processed in the order it happened only when execution stack is empty. 172 | 173 | ## 17 - Conceptual Aside Types And Operators 174 | **Dynamic typing** - you don't tell the engine what type of data a variable holds, it figures out while your code is running. Variable can hold different types of values because it's all figured out during execution. 175 | 176 | ## 18 - Primitive Types 177 | **Primitive type** - a type of data that represents a single value. That is, not an object. 178 | 179 | Primitives: 180 | 181 | - **`undefined`** - represents lack of existence. You shouldn't set a variable to `undefined` yourself. 182 | - **`null`** - also represents lack of existence. You can set a variable to `null`. 183 | - **`boolean`** - `true` or `false`. 184 | - **Number** - floating point number (there's always some decimals). 185 | - **String** - a sequence of characters in 'single' or "double quotes". 186 | - **Symbol** - used in ES6. 187 | 188 | ## 19 - Conceptual Aside - Operators 189 | **Operator** - a special function that is written differently. Generally operators take two parameters and return result. 190 | 191 | ## 20 - Operator Precedence and Associativity 192 | **Operator precedence** - which operator function gets called first on the same line of code. Functions are called in order of precedence (higher precedence wins). 193 | 194 | **Associativity** - what order operator functions get called in: left-to-right or right-to-left when functions have the same precedence. 195 | 196 | Operator precedence table: [https://developer.mozilla.org/Operator_Precedence](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) 197 | 198 | ## 21 - Conceptual Aside Coercion 199 | **Coercion** - converting a value from one type to another. This happens quite often in JavaScript because it's dynamically typed. For example adding a number to a string would result in number being converted to a string: 200 | 201 | ```javascript 202 | 7 + '7'// would be = '77' 203 | ``` 204 | 205 | ## 22 - Comparison Operators 206 | When `true` is coerced to number it is `1`. 207 | 208 | When `false` is coerced to number it is `0`. 209 | 210 | When `null` is coerced to number it is `0`. 211 | 212 | When `undefined` is coerced to number it is `NaN`. 213 | 214 | `===` is a strict comparison operator and doesn't do conversion. So it's the best practice to always use it to prevent strange bugs due to conversion. 215 | 216 | ## 23 - Existence and Booleans 217 | `undefined`, `null` and `''`(empty strings) is converted to boolean `false`. 218 | 219 | We can use that to our advantage. This pattern is used in many JS libraries and good open source code. 220 | Whatever is in parenthesis of if statement it is converted to a boolean. 221 | So this statement returns `true` if `a` is set or `false` if not. 222 | 223 | ```javascript 224 | var a; 225 | 226 | if (a) { 227 | console.log('Something is there.'); 228 | } 229 | ``` 230 | Also worth mentioning that `false || true` returns `true.` 231 | 232 | ## 24 - Default Values 233 | If you pass two values to `||` operator it will return a first one which returns `true`. 234 | 235 | This pattern is used in many open source code: 236 | 237 | ```javascript 238 | var name = name || "your name"; 239 | ``` 240 | 241 | This way you can set a default parameter value in case no arguments are passed during invocation of a function. 242 | 243 | ## 25 - Framework Aside: Default Values 244 | When using a few libraries to avoid overwriting vars, most libraries use this pattern: 245 | 246 | ```javascript 247 | window.variableName = window.variableName || "String"; 248 | ``` 249 | 250 | ## 26 - Objects and the Dot 251 | **Objects** are name value pairs that are sitting in memory and have references to other things inside them like properties and methods. 252 | 253 | Object can have a primitive(string, boolean) and that will be called a **property**. It can have another object and it will also be a property. 254 | 255 | Object can also contain a function and it is called a **method**. 256 | 257 | 258 | ```javascript 259 | var person = new Object(); 260 | person['firstName'] = 'Jason'; 261 | 262 | person.address = "111 Main St."; 263 | ``` 264 | 265 | Since `firstName` doesn't exist on person object, we create it using brackets operator and give a value to it (property). 266 | Dot is an operator that works from left to right. It allows to access or set an object's properties. 267 | 268 | ## 27 - Objects and Object Literals 269 | Object literal syntax is more clean and preferred way to create objects. 270 | 271 | ```javascript 272 | var Jason = { 273 | firstname: 'Jason', 274 | lastname: 'Baciulis', 275 | address: { 276 | street: '111 Main St.', 277 | city: 'New York', 278 | state: 'NY' 279 | } 280 | }; 281 | ``` 282 | 283 | ## 28 - Framework Aside: Faking Namespaces 284 | **Namespace** - a container for variables and functions. Typically to keep variables and functions with the same name separate. 285 | 286 | You can prevent name collisions by using objects to store properties: 287 | 288 | ```javascript 289 | var english = {}; 290 | english.greet = 'hello'; 291 | ``` 292 | 293 | ## 29 - JSON and Object Literals 294 | **JSON** - JavaScript object notation is inspired by JS. In JSON property names must be wrapped in double quotes. 295 | 296 | `JSON.stringify(objectLiteral)` - converts object to JSON. 297 | 298 | `JSON.parse()` - converts to a JavaScript object. 299 | 300 | ## 30 - Functions are Objects 301 | In JavaScript functions are objects. 302 | 303 | **First class functions** - everything you can do with other types you can do with functions. Assign them to variables, pass them around as parameters to other functions, you can create functions on the fly. 304 | 305 | Just like any object, function object resides in memory. Though, it's a special type of object because it has all the features of a normal object but has some other special properties. It's hidden special properties: 306 | 307 | **Name** - though it can be anonymous ant not have a name. 308 | 309 | **Code property** - where the actual lines of code sit. 310 | 311 | The code that you write gets placed in the special property of the function object. So it isn't like the code you write *is* a function. The function *is* an object with other properties. And the code that you write is just one of those properties that you're adding onto it. What is special about that property that it's invocable. You can say run that code and that's when execution context creation and execution happens. 312 | 313 | It's important that you have this mental model of functions in your mind. You have to think of functions as objects whose code just happens to be one of the properties. 314 | There are other things that functions can have attached to it. And it can be moved around and copied just like other object. 315 | 316 | You have to think about **functions as more than just containers of code**. 317 | 318 | ## 31 - Function Statements and Function Expressions 319 | **Expression** - a unit of code that results in a value. Statements just do work, bet expressions end up creating value. That value doesn't necessarily have to be saved to a variable. 320 | 321 | E.g. `1 + 2` is a function expression that return a value of `3`. Do you remember how we covered that `+` operator is a function? 322 | 323 | This is regular function statement: 324 | 325 | ```javascript 326 | function greet() { 327 | console.log('hi'); 328 | } 329 | ``` 330 | 331 | It is put into memory. But it doesn't return a value until a function is invocated. 332 | 333 | This is expression: 334 | 335 | ```javascript 336 | var anonymousGreet = function() { 337 | console.log('hi'); 338 | } 339 | ``` 340 | 341 | Remember functions are objects. So it creates an object on the fly and sets it equal to the variable `anonymousGreet`. So when your code runs in the execution phase, sees the first function it just says "yeah there is function" and does nothing, just keeps going. But when it sees a variable it results in a value of a function object being created. 342 | That's why you can call function statement before it but function expression will throw an error as "undefined is not a function" because that function is not yet created. 343 | 344 | ## 32 - Conceptual Aside By Value vs By Reference 345 | **By value** (primitives): 346 | 347 | ```javascript 348 | var a = 3; b = a; 349 | ``` 350 | 351 | When you set `b` equals to `a`, equals operator sees these are primitives creates a new spot in memory and makes a copy of it. `b` and `a` will be both `3` but they are copies sitting on separate spots in memory. So if I change `a = 5` it doesn't affect `b`, it is still `3`, because after making a copy these values are on their own. 352 | 353 | **By reference** (all objects including functions): 354 | 355 | ```javascript 356 | var c = {greetings: 'hi'}; 357 | var d; 358 | d = c; 359 | ``` 360 | Equals operator sees there is an object so it simply points to the same spot in memory. 361 | 362 | After changing a value of an object: `c.greetings = 'hello'` `d` would change as well. 363 | 364 | **Mutate** means change something. 365 | 366 | ## 33 - Objects, Functions, and `this` 367 | 368 | `this` inside a function points to global object. 369 | 370 | `this` inside a method points to that object from which it is called. Left of the dot rule. 371 | 372 | But `this` inside a function which is inside a method will point to the global object. 373 | 374 | With ES5 JavaScript using `var` you could solve this by setting inside a method `var _this = this;` which is a very common pattern. 375 | 376 | ## 34 - Conceptual Aside - Arrays - Collections of Anything 377 | **Arrays** can hold a mix of anything: functions, primitives, objects. 378 | 379 | ## 35 - `arguments` and spread 380 | **Arguments** are the parameters you pass to a function. JS creates a keyword of the same name which is an array-like that contains all parameters that you passed. 381 | 382 | In ES6 we can do: `function greet(firstname, ...other)` and `other` will be an array that contains the rest of the arguments. 383 | 384 | ## 36 - Framework Aside Function Overloading 385 | You can call one function which inside calls another function with a certain set of parameters. 386 | 387 | ## 37 - Conceptual Aside - Syntax Parsers 388 | JavaScript engine is syntax parser in the browser. 389 | 390 | ## 38 - Dangerous Aside Automatic Semicolon Insertion 391 | Semicolons are optional in JS because JS engine injects them automatically. 392 | But it is a bad practice to not put them because you want to know what code you are writing. 393 | 394 | ## 39 - Framework Aside Whitespace 395 | **Whitespace** - invisible characters that create space in your code: returns, tabs, space. 396 | 397 | ## 40 - Immediately Invoked Functions Expressions (IIFEs) 398 | Using an Immediately Invoked Function Expression (IIFE): 399 | 400 | ```javascript 401 | var firstname = 'John'; 402 | 403 | (function(name) { 404 | 405 | var greeting = 'Inside IIFE: Hello'; 406 | console.log(greeting + ' ' + name); 407 | 408 | }(firstname)); // IIFE 409 | ``` 410 | 411 | Function statements can't be anonymous. 412 | 413 | Everything inside a parenthesis is considered expression. 414 | 415 | ## 41 - Framework Aside IIFEs and Safe Code 416 | **IIFE** creates a new execution context so it's safe code because it is wrapped in separate execution context and prevents variable names collision. 417 | Wrapping code libraries is very common pattern to not clash code with the global object. 418 | You can reference to global object by passing `window` as a parameter. 419 | 420 | ## 42 - Understanding Closures 421 | When a function runs and completes it is removed from execution stack, but variables created and saved in that execution phase are still stored in memory and can be accessed from down the scope. 422 | 423 | ```javascript 424 | function greet(whattosay) { 425 | 426 | return function(name) { 427 | console.log(whattosay + ' ' + name; 428 | } 429 | 430 | } 431 | 432 | var sayHi = greet('Hi'); 433 | sayHi('Jason'); 434 | ``` 435 | 436 | Inside the variable `sayHi` we run `greet` function which returns another function and passes string `'Hi'`. After that functions is finished and it is popped from the execution stack. But `whattosay` variable still sits saved in the memory with a value `Hi`. So when we call function `sayHi` it will go in the outer environment and look for whattosay variable and will find it and log "Hi Jason". 437 | We describe this proccess as execution context has closed in outer variables. 438 | 439 | ## 43 - Understanding Closures Pt. 2 440 | Pay attention when functions are executed to understand where it will look for variables down the scope chain. 441 | 442 | ## 44 - Framework Aside Function Factories 443 | Every time function is called it creates a new execution context and its variable environment which sits in that specific space in memory. So even if you call the same function again and it creates a new variable of the same name. It doesn't overwrite it, because it is created in a separate environment and sits in the different space in the memory. 444 | 445 | ## 45 - Closures And Callbacks 446 | **Callback function** - a function you give to another function to be run when the other function is finished. 447 | 448 | ## 46 - `call()`, `apply()`, and `bind()` 449 | Because functions are objects, all functions have access to built-in `call()`, `bind()` and `apply()` methods. 450 | 451 | **`bind()`** creates a copy of a function it is attached to. E.g. `name.bind(obj)` inherits `this` from the object you pass to it as a parameter. `bind()` can also bind permanent parameters to the function: `name.bind(this, 1, 2)`. So when you call `name()` it will have parameters `1` and `2` already passed. 452 | 453 | **`call()`** invokes the function but also lets you to decide what `this` variable will be, by passing an object: `call(object, 'param', 'param2')`. Unlike bind, it executes the function instead of copying it. 454 | 455 | **`apply()`** is almost the same as `call()` but instead you need to pass an array as a parameter: `.apply(object, [parameters])` 456 | 457 | In practice, you can use `call()` and `apply()` to borrow methods/functions from objects and use on another object with the same property names. 458 | 459 | **Function currying** - creating a copy of a function but with some preset parameters. 460 | 461 | ## 47 - Functional Programming 462 | A mapping function is a function which takes one array and outputs another array. It is very powerful and useful technique that you will see in codebases. 463 | 464 | ```javascript 465 | function mapForEach(arr, fn) { 466 | 467 | var newArr = []; 468 | for (var i=0; i < arr.length; i++) { 469 | newArr.push( 470 | fn(arr[i]) 471 | ) 472 | }; 473 | 474 | return newArr; 475 | } 476 | ``` 477 | 478 | You should avoid mutating/changing things. That's why it is better to return a new array than change existing one. 479 | 480 | ## 48 - Functional Programming Pt. 2 481 | Open source libraries are great educational tools. So take the time to read some of the most popular ones like jQuery, React. 482 | 483 | ## 49 - Conceptual Aside Classical vs Prototypal Inheritance 484 | **Inheritance** - one object gets access to properties and methods of another object. 485 | 486 | **Classical inheritance** is the way it's been done a long time, it's what Java, C# uses. It's very verbose. 487 | 488 | **Prototypal** is much simpler, flexible, extensible, easy to understand. 489 | 490 | ## 50 - Understanding The Prototype 491 | All objects have built-in prototype property, including functions. Each prototype can also have its own prototype. 492 | 493 | Each object inherits properties and methods of other objects through a prototype. So if you call a property on one object and it doesn't find it there it goes the prototype chain and looks for it on a prototype. 494 | 495 | ## 51 - Everything is an Object (Or a primitive) 496 | Functions, arrays, and objects all have their prototype that's why we say that everything is an object in JavaScript. 497 | 498 | All objects, functions, arrays have their prototype pointing to the special object where you can access methods like `call()`, `bind()`, `push()`. 499 | 500 | ## 52 - Reflection and Extend 501 | **Reflection** - an object can look at itself, listing and changing its properties and methods. 502 | 503 | `extend(obj, obj2, obj3)` takes all properties and methods of given objects and passes them to the first object. 504 | 505 | It is not a built in feature but many libraries have it and ES6 have `extends`. 506 | 507 | ## 53 - Functions Contructors, `new` And The History Of JavaScript 508 | **`new Function()`** creates an empty object and invokes a function. It also changes what `this` points to. It points to that empty object. 509 | 510 | `new` lets construct an object via function. 511 | 512 | **Function constructors** - a normal function that is used to construct objects. The `this` variable points to a new empty object, and that object is returned from the function automatically. 513 | 514 | `new` keyword creates an object and functions constructors are used for adding properties and methods to that object. 515 | 516 | ## 54 - Function Constructors and `.prototype` 517 | **`.prototype`** is a property that sits in every function in JavaScript but unless you use a function constructor with `new` operator it is never used. 518 | 519 | A `.prototype` is **not** *the* prototype of a function object. It is only a prototype of objects created with a `new` keyword. 520 | 521 | It's better to put your methods on the `prototype` to save memory space as it gets shared between all objects. 522 | 523 | ## 55 - Dangerous Aside `new` and functions 524 | Any function that we intend to use as a function constructor should be named with a first capital letter. This makes it easier to spot errors in case you would miss `new` keyword. 525 | 526 | Although worth mentioning that creating objects with function constructors is going away because of new methods and ES6. 527 | 528 | ## 56 - Conceptual Aside Built-In Function Constructors 529 | JavaScript has some built it function constructors like: `new Number(3)` and `new String('Jason')`. 530 | 531 | These constructors look like you're creating primitives but you are not. You are creating objects. 532 | 533 | When you use some methods like `.length` on a string, your string is boxed in a `String` object automatically to get access to all its methods. 534 | 535 | Although it doesn't work like that for numbers and you would need to create `Number` object first. 536 | 537 | All these built-in function constructors have a prototype and you can actually add your own methods to it. 538 | 539 | ```javascript 540 | String.prototype.isLengthGreaterThan = function(limit) { 541 | return this.length > limit; 542 | } 543 | 544 | console.log("John".isLengthGreaterThan(3)); 545 | ``` 546 | 547 | ## 57 - Dangerous Aside Built-In Function Constructors 2 548 | It's best to avoid using built-in function constructors to create primitives because you're not creating primitives but rather objects. 549 | 550 | ```javascript 551 | var a = 3; 552 | var b = new Number(3); 553 | 554 | a == b // will return true because of coersion 555 | a === b // will return false because we are comparing object with a primitive 556 | ``` 557 | 558 | ## 58 - Dangerous Aside Arrays and `for`..`in` 559 | For arrays use standard `for` loop or `forEach`, but don't use `for in`. Because arrays are objects with `for in` you could iterate into a prototype. 560 | 561 | ## 59 - `Object.create` and Pure Prototypal Inheritance 562 | ```javascript 563 | var person = { 564 | firstname: 'Default', 565 | lastname: 'Default', 566 | greet: function() { 567 | return 'Hi ' + this.firstname; 568 | } 569 | } 570 | 571 | var john = Object.create(person); 572 | ``` 573 | 574 | `Object.create(person)` - creates an empty object with its prototype pointing at whatever you passed in as a parameter. 575 | 576 | ```javascript 577 | john.firstname = 'John'; 578 | john.lastname = 'Doe'; 579 | ``` 580 | 581 | And you can override properties and methods by adding new ones to this object with the same names. 582 | 583 | **Polyfill** - code that adds a feature which the engine may lack. 584 | 585 | ## 60 - ES6 and Classes 586 | JavaScript has classes in ES6. However, it is not like a `class` in other languages. In other languages `class` is like a template. `class` in JS is an object by itself that you use to create other objects. 587 | 588 | `class` doesn't change anything how objects and prototypes work under the hood. It just gives you a different way to type. Because of it you may hear JavaScript classes being called syntactic sugar. 589 | 590 | **Syntactic sugar** - a different way to type something that doesn't change how it works under the hood. 591 | 592 | ## 61 - Initialization 593 | Large arrays of objects are useful for testing and initialization before you have an actual data to pull from, like a JSON file. 594 | 595 | ## 62 - `typeof`, `instanceof`, and Figuring Out What Something Is 596 | **`typeof`** is an operator (essentially a function) that excepts a parameter and returns a string. 597 | 598 | **`instanceof`** will tell you if it has something in its prototype chain by returning a boolean. 599 | 600 | ```javascript 601 | var a = 3; 602 | console.log(typeof a); // returns a string 'number' 603 | 604 | var b = "Hello"; 605 | console.log(typeof b); // returns a string 'string' 606 | 607 | var c = {}; 608 | console.log(typeof c); // returns a string 'object' 609 | 610 | var d = []; 611 | console.log(typeof d); // also returns a string 'object', weird! 612 | 613 | console.log(Object.prototype.toString.call(d)); // this little trick returns a string '[object Array]' 614 | 615 | function Person(name) { 616 | this.name = name; 617 | } 618 | var e = new Person('Jane'); 619 | console.log(typeof e); // also an object 620 | 621 | console.log(e instanceof Person); // returns true because Person is down the prototype chain of e 622 | 623 | console.log(typeof undefined); // returns undefined, makes sense 624 | console.log(typeof null); // returns an 'object', a bug since, like, forever... 625 | 626 | var z = function() { }; 627 | console.log(typeof z); // returns a 'function' 628 | ``` 629 | 630 | ## 63 - Strict Mode 631 | JavaScript is a more liberal of what it allows. 632 | 633 | **`"use strict";`** - enforces more strict rules. E.g. in this mode you must declare var first to use it. In not strict mode if you forget to type `var`, it will still be created on the global object `window`. 634 | 635 | You can use use strict at the top of the document or at the top of a function to use strict only inside it's execution context. 636 | 637 | ## 64 - Learning From Other's Good Code 638 | There are many aspects of improving as a developer. One of the most powerful is learning from other's good code. There is a fantastic treasure trove of good code out there to learn from. Tony calls it "an open source education". 639 | 640 | It may sound as fun as reading an encyclopedia, but you don't need to spend hours reading the source code. Find some area that's interesting to you. Don't get intimidated by famous libraries and what may seems complex patterns. Look at the structure, see what you could take away and imitate. 641 | 642 | This is a great way to learn advanced patterns and concepts in JavaScript. So make a practice to occasionally look at the source code of the library or framework you're using. 643 | 644 | ## 65 - Deep Dive into Source Code jQuery - Part 1 645 | When we're reading code we are not trying to understand how every feature is implemented. First, we'll try to see if we can read the code and learn how it is structured. And if we can learn some techniques and borrow some ideas. 646 | 647 | ## 66 - Deep Dive into Source Code jQuery - Part 2 648 | jQuery has some good code you could borrow for your own projects. It has been developed and watched by many developers so it has some of the best methods and practices. 649 | 650 | Inside jQuery there is Sizzle CSS Selector library for handling selectors. 651 | 652 | ## 67 - Deep Dive into Source Code jQuery - Part 3 653 | **Method chaining** - calling one method after another, and each method affects the parent object. 654 | 655 | So `obj.method1().method2()` where both methods end up with `this` variable pointing at `obj`. 656 | 657 | ## 68 - Requirements 658 | First of all, before building any application let's think of the requirements. What this app/library should do? 659 | 660 | ## 73 - Good Commenting 661 | Remember to write good comments for your code. Because even if you are the sole developer for a project you may need to come back after a year and you'll have to figure it out how everything works like it was someone else's code. 662 | 663 | ## 76 - TypeScript, ES6, and Transpiled Languages 664 | **Transpile** - convert the syntax of one programming language, to another. 665 | 666 | In this case, languages that don't really ever run anywhere, but instead are processed by transpilers that generate JavaScript. 667 | 668 | **TypeScript** - one of the most popular transpiled languages and is created by Microsoft. The biggest difference that it uses strict types for its variables instead of dynamic types like JavaScript. --------------------------------------------------------------------------------