├── Best-Practices.md ├── LICENSE ├── Mocks_IntTesting_PairProgramming.md └── README.md /Best-Practices.md: -------------------------------------------------------------------------------- 1 | 2 | > This document contains JavaScript Best Practies 3 | 4 | #### Basics 5 | > These are JavaScript basics to be aware of. 6 | 7 | 1. `===` vs `==` 8 | 9 | ```javascript 10 | function incorrect() { 11 | var changeDue = "5.99"; 12 | if (changeDue == 5.99) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | // output: false 19 | 20 | function correct() { 21 | var changeDue = "5.99"; 22 | if (changeDue === 5.99) { 23 | return true; 24 | } else { 25 | return false; 26 | } 27 | } 28 | // output: true 29 | ``` 30 | 31 | 2. Lines of code per JS file and refactoring 32 | - JavaScript code should adhere to the SOLID principles just like with any other language. 33 | - As a general rule, you should strive to keep JS files down to the size of a screen display (i.e. no need to scroll). 34 | - As an absolute maximum, any file that goes beyond 300 lines of code should be considered for refactoring. 35 | 36 | 3. `
` vs `` 37 | 38 | ``` 39 | True or False: It is good practice to put your scripts within the tag of an HTML document. 40 | 41 | // output: False; browsers render pages more slowly when scripts are in the tag (as opposed to ). 42 | ``` 43 | 44 | 4. `'` vs `"` 45 | 46 | ``` 47 | Which of the following variable declarations will properly create a string in JavaScript? 48 | 49 | A) var message = "Choice A."; 50 | B) var message = 'Choice B.'; 51 | C) Both A) and B) will properly create a string. 52 | 53 | // output: C); Single and double quotes both work fine, but it is best practice to choose one or the other for your project and stick to it. 54 | ``` 55 | 56 | 5. Formatting 57 | - Whitespace 58 | - 1) Whitespace between keywords/operators and parameters 59 | ```javascript 60 | if (condition) { ... } 61 | ``` 62 | - 2) No whitespace 63 | ```javascript 64 | if(condition){ ... } 65 | ``` 66 | - 1) is preferred for readability purposes. 67 | - Curly bracket placement 68 | - 1) Inline placement 69 | ```javascript 70 | if (condition) { 71 | 72 | } else { 73 | 74 | } 75 | ``` 76 | - 2) Line break placement 77 | ```javascript 78 | if (condition) 79 | { 80 | 81 | } 82 | else 83 | { 84 | 85 | } 86 | ``` 87 | - 1) is good for reducing the number of lines in a file. 88 | - 2) more explicitly separates function/conditional statement definitions. 89 | - Be consistent with whichever you choose. 90 | - Line breaks 91 | - No general rules of thumb here. Be conscious about breaking up consecutive 92 | lines of statements into logical chunks. 93 | - Semi-colons (yes or no?) 94 | - Pros of using semicolons: 95 | - Consistent with popular languages 96 | - Promotes readability and writability if accustomed to languages that use them 97 | - Pros of omitting semicolons: 98 | - Less typing 99 | - Be consistent with whichever you choose. 100 | 6. Shorthand expressions 101 | - Although they can make trivial statements more concise, beware of nesting complicated logic 102 | inside shorthands. You will sacrifice readability for concision. 103 | - Good example 104 | ```javascript 105 | // Original 106 | var biggerThanFive; 107 | if (x > 5) { 108 | biggerThanFive = 'Yes'; 109 | } else { 110 | biggerThanFive = 'No'; 111 | } 112 | 113 | // Shorthand 114 | var biggerThanFive = x > 5 ? 'Yes' : 'No'; 115 | ``` 116 | - Comprehensive list: https://www.sitepoint.com/shorthand-javascript-techniques/ 117 | 7. Variable declaration 118 | - Good practice (locally scoped): 119 | ```javascript 120 | var myObj = {}; 121 | ``` 122 | - Bad practice (unintentional global scope) 123 | ```javascript 124 | myObj = {}; 125 | ``` 126 | * Writing 'use strict' at the top of a JS file will prevent this from being allowed. 127 | 8. `that` vs `thisView` vs `self` 128 | - You will often need to declare a local copy of the current view for the 129 | sake of scoping: 130 | ```javascript 131 | function myFunction() { 132 | var thisView = this; 133 | 134 | var anotherFunction = function() { 135 | thisView.outsideFunction(); 136 | }; 137 | } 138 | ``` 139 | - The name that you use for this copy is really a matter of preference, 140 | but to be more descriptive, thisView is usually a good choice for naming. 141 | - Arrow functions, one of ES6's new features, allows us to inherit scope from the immediate 142 | parent's scope inside a nested function. 143 | ```javascript 144 | function myFunction() { 145 | this.number = 1 146 | 147 | var anotherFunction = () => { 148 | this.number = 2 // Valid and cleaner! 149 | } 150 | } 151 | ``` 152 | 153 | #### Obsolete Practices 154 | > These are coding practices that were once good but have become dated and should be avoided. 155 | 156 | 1. Overusing jQuery 157 | 158 | Most modern applications use jQuery as an ancillary library, opting for a js framework with features that jQuery doesn't provide (data-binding, routing, etc.) as the primary front-end framework. Because of this, methods and functions provided by the primary framework should be used before jQuery usage is considered. Additionally: 159 | - Avoid making duplicate jQuery calls. Instead, store the result of the initial call in a variable. 160 | 161 | 162 | ```HTML 163 | 175 | ``` 176 | 177 | Bad Practice 178 | 179 | ```javascript 180 | function showErrorMessage() { 181 | $('form').find('#errorDiv').html('An error occurred.') 182 | $('form').find('#errorDiv').show(); 183 | } 184 | ``` 185 | 186 | Good Practice 187 | 188 | ```javascript 189 | function showErrorMessage() { 190 | var errorDiv = $('form').find('#errorDiv'); 191 | errorDiv.html('An error occurred.') 192 | errorDiv.show(); 193 | } 194 | ``` 195 | 196 | - Ensure that the most efficient jQuery call is used 197 | ```//I'm omitting this as there have been browser optimizations that make this less of a concern. Feel free to object . . . by populating this.``` 198 | 199 | 2. Relying on Comments to Clarify Overly Complex or Confusing Code 200 | 201 | Complex code should be self-documented and shoud not be dependent on comments. Comments can be used, but they should be used sparingly. 202 | 203 | 204 | Bad Practice 205 | ```javascript 206 | /*The code below sorts an array of ints, removes the largest and smallest ints from the array, and sums the remaining array. If the given array is empty, it returns 0.*/ 207 | sumArray = a => a ? a.sort((x, y) => x - y).slice(1, -1).reduce((s, e) => s + e, 0) : 0 208 | ``` 209 | 210 | 211 | Good Practice 212 | ```javascript 213 | if(a) { 214 | var sortedArray = a.sort((x, y) => x - y); 215 | var arrayWithoutBigSmallInts = sortedArray.slice(1, -1); 216 | var sumArray = arrayWithoutBigSmallInts.reduce((s, e) => s + e, 0); 217 | } 218 | ``` 219 | 3. Storing JavaScript Code in One File 220 | 221 | In the past, it was best practice to move embedded javascript found in HTML files to one external javascript file as, at the time, there wasn't much javascript code being used. Since the amount of javascript being used has significantly increased, that is no longer an acceptable approach. Javascript logic should be broken up into small files, in accordance with the best practices of whatever framework is in use in a given application. 222 | 223 | 4. Manipulating Globals 224 | 225 | ```\\Is it necessary to have this section since it's being referenced under best practices?``` 226 | 227 | 5. Manipulating Prototypes (manually or in frameworks like date.js) 228 | 229 | Manipulating prototypes is a bad practice because it changes the expected behavior of any instances of objects with updated prototypes. This is a particularly bad practices when done on built-in javascript objects. Instead, create a new, clearly-named object type. 230 | 231 | 232 | Bad Practice 233 | ```javascript 234 | Number.prototype.toString = function() { return 'the string of my choosing'; }; 235 | var t = new Number(4); 236 | 237 | //t.toString() === 'the string of my choosing'; 238 | ``` 239 | 240 | 241 | Good Practice 242 | ```javascript 243 | function MyNumber() { 244 | Number.call(this); 245 | } 246 | MyNumber.prototype = Object.create(Number.prototype); 247 | MyNumber.prototype.toString = function() { 248 | return 'the string of my choosing'; 249 | }; 250 | var myNum = new MyNumber(4); 251 | 252 | //myNum.toString() === 'the string of my choosing' 253 | ``` 254 | 6. Using Browser Detection Instead of Feature Detection 255 | 256 | Performing browser detection to determine whether specific features are available is prone to error because it's hard to account for every version of every browser over time. Instead, use feature detection, in which you test whether a feature is available. 257 | 258 | 259 | Bad Practice 260 | ```javascript 261 | var isSafari = navigator.userAgent.indexOf("Safari") > -1; 262 | if (isSafari) { 263 | var thisMouseEvent = new MouseEvent('typing'); 264 | } 265 | ``` 266 | 267 | 268 | Good Practice 269 | ```javascript 270 | if (typeof MouseEvent !== 'undefined') { 271 | var thisMouseEvent = new MouseEvent('typing'); 272 | } 273 | ``` 274 | 275 | #### Agile Engineering 276 | > These are Agile Engineering best practices 277 | 278 | 1. TDD: Test Driven Development 279 | 1. Red : write small failing tests 280 | 2. Green : write small amount of passing code 281 | 3. Refactor : improve the code 282 | 283 | 2. Unit Testing 284 | - Define the behavior of production code 285 | - Single module only 286 | - Isolates behavior 287 | - Reusable 288 | - Should be FIRST 289 | - **F**ast 290 | - **I**solated 291 | - **R**epeatable 292 | - **S**elf-verifying 293 | - **T**imely 294 | 295 | 3. SOLID Principles 296 | - Single Responsibility Principle 297 | - Each function should only have one responsibility as well as each module 298 | - Open Closed Principle 299 | - Software entities (functions) should be open for extension, but closed for modification 300 | - Liskov Substitution Principle (ES 2015+) 301 | - Derived classes must be substitutable for their base classes. Code to abstraction 302 | - Interface Segregation Principle (TypeScript) 303 | - Clients should not be forced to depend upon interfaces that they do not use 304 | - Interfaces are interchangeable with option hashes 305 | - Dependency Inversion Principle (TypeScript) 306 | - Depend on abstractions, not on concretions 307 | 308 | 4. Code Smells 309 | 1. Duplicate code 310 | 2. Long methods 311 | 3. Big classes/files 312 | 4. Empty catch clauses 313 | 5. Significant use of statics/globals 314 | 6. Variables with wide scope 315 | 7. Poorly named variables 316 | 8. Switch or with statements 317 | 9. Unnecessary complexity 318 | 10. Comments 319 | 320 | 5. Legacy Code 321 | - Identify SOLID principles that are violated by legacy code 322 | - Write unit tests for existing code 323 | - Refactor code without breaking functionality or unit tests 324 | - Note: applies to back end code, front end code might require integration tests 325 | 326 | 6. Continuous Integration & Deployment 327 | #### Continuous Integration 328 | _Team members integrate code together frequently, each integration being tested by an automated build to detect errors quickly_ 329 | 330 | - Build - automated, self-testing, everything included 331 | - Unit, integration, system, acceptance, UI, performance tests - run each build 332 | - Versioning - single source repository 333 | - Deployment - automated 334 | - Reports - visible to everyone 335 | - Notification 336 | - Git workflow with pull requests, etc. 337 | 338 | #### Continuous Deployment 339 | 340 | - “Build Once, Deploy many” 341 | - Development, Test, Production environments 342 | - Each check in by a developer, pipeline is run: 343 | - Unit tests 344 | - Static code analysis 345 | - Integration tests 346 | - Deploy 347 | - Acceptance tests 348 | 349 | 7. Technical Debt 350 | 351 | _Neglecting design = borrowing money 352 | Slower development = paying interest on the loan 353 | Time spent on bad code = interest on debt 354 | Refactoring = paying off principal debt_ 355 | - As time increases, more technical debt increases cost of change 356 | - Bad design pays off in short run, good design pays off in long run 357 | - Intentional “Good” debt 358 | - Cycle 359 | - pressure -> take debt -> fail to pay back -> debt accrual -> reduced velocity -> pressure -> etc 360 | 361 | #### Third-Party Libraries 362 | > Here are some things to ask yourself and your team before importing a third-party library. 363 | 364 | 1. Do you need the third-party library? 365 | 366 | Adding a third-party library dependency into your project comes with some inherit risk. Make sure that whatever functionality you are getting out of the third-party library is worth the risk and not something that you could easily and quickly implement yourself. 367 | 368 | 2. Do you have the rights to use it? 369 | 370 | Just because you were able to find the code for a third-party library online does not necessarily mean you can use it for your project. Make sure to read the license for the library to make sure that the agreements work for your project and future distribution plans. 371 | 372 | 3. Is the project well-maintained? 373 | 374 | Make sure that the project is well-maintained. This does not necessarily mean that the project is being constantly updated, but that bugs are addressed quickly, updates are made when needed to keep the library functioning, and that the code is well tested. 375 | 376 | 4. Is the project stable? 377 | 378 | Having stable working third-party libraries is crucial to development. If the project has a lot of bugs that it needs to address or is constantly adding new features that either break old functionality or require old code to be updated to use new standards, it may not be worth using. In particular, be wary of libraries that are in alpha or beta. 379 | 380 | 5. How active is the community and the dev team? 381 | 382 | It is helpful to have an active community or developer team associated with a third-party library. You may run into problems with the library that you will not be able to figure out without information from the library's developers. Being able to contact experienced users or the library's developers to ask questions can be invaluable. 383 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Excella Labs <> 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | -------------------------------------------------------------------------------- /Mocks_IntTesting_PairProgramming.md: -------------------------------------------------------------------------------- 1 | # Using Mocks 2 | When unit testing it is important to use mocks for other functionality for classes. This makes sure that the test is only testing the functionality for that one class and not the functionality of other classes. It also helps to reinforce the single responsibility principle by emphasizing separation of concerns. An additional benefit is that if there are changes to other classes, the unit test for the desired class will not break. 3 | - ie. If testing class Alpha in your project and class Alpha calls a function from class Beta, class Alpha's instance of class beta should be mocked out, and class Beta should have its own unit test for that function 4 | 5 | # Integration Testing 6 | Integration tests are used to test the full flow of an application and to make sure that all the components of work together properly. The goal of integration tests are to test that the full flow of an application works. This means that integration tests should usually just test the base cases of an application. As a result, most applications will have a large amount of unit tests, and a significantly smaller amount of integration tests. 7 | 8 | Integration Test Workflow: 9 | 1) Create database 10 | 2) Load Data 11 | 3) Run Test 12 | 4) Retrieve Data 13 | 5) Assert 14 | 6) Rollback changes from test 15 | 7) Go to c if more tests or destroy db if no more tests 16 | 17 | # Pair Programming 18 | Pair programming is the act of two programers simultaniously working together on a single peace of code. During pair programming, there is one Driver and one Observer. The Driver is the one in control of the mouse and keyboard and actually doing the programming. The Observer observes the drivers programming and gives input/help. It is sugguested to rotate frequently when using pair programming in order to keep both developers involved. 19 | 20 | Here is an example of a pair programming workflow using TDD 21 | 1) Developer A writes a unit test for a needed piece of functionality 22 | 2) Developer B writes the code that passes that piece of functionality 23 | 3) Developer B then writes a unit test for another piece of functionality 24 | 4) Developer A writes the code that passes that piece of functionality 25 | 5) Reapeat 1-4 as for duration of pair programming 26 | 27 | Studies have shown that pair programming produces code at a rate 15% lower then solo programming. However, pair programming also eliminates mistakes and reworks at a much higher rate and therefore ends up saving time overall. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The JavaScript Curriculum 2 | ## A JavaScript Curriculum for Active Learners 3 | 4 | ### About 5 | This curriculum is meant to equip you with the resources you need to get yourself up to speed with JavaScript as a language, and use it to create full and complete solutions. Motivating yourself to learn something new can be a challenge, thusly this curriculum is focused on the learning-by-doing methodology. 6 | 7 | This curriculum heavily realies on [NodeSchool.io](http://nodeschool.io) for the best self-learning experience. 8 | 9 | > Have lingering questions about why you should be doing JavaScipt? Check out this [presentation](http://slides.com/doguhanuluca/agile-done-right-using-javascript-and-node-3#/) on Why JavaScript? 10 | 11 | ### Before You Begin 12 | It is *highly recommended* that your `fork` this repository, keep track of your learning progress by adding `x`es inside the `[ ]` checkboxes and committing them to your own repository. 13 | 14 | ### New to Collaborative & Open Source Programming? 15 | - [ ] To collaborate with others and track your own progress, you'll need to create a GitHub account. [Create an account](https://github.com/) 16 | - [ ] Install a Git client, 17 | - Simple: 18 | - [GitHub for Windows](https://windows.github.com/) 19 | - [GitHub for Mac](https://mac.github.com/) 20 | - Advanced: 21 | - [GitExtensions (Windows)](http://sourceforge.net/projects/gitextensions/) 22 | - [Tower (Mac)](http://www.git-tower.com/) 23 | - [Github Desktop (Mac/Windows)](https://desktop.github.com/) *In pre-release* 24 | - [ ] Now you can `fork` this repo, by using the `fork` button on the top right hand of the GitHub page and start tracking your progress. 25 | 26 | ### Pre-Requisites 27 | - [ ] Install Node.js, so you can run the self-learning tools: [https://nodejs.org/](https://nodejs.org/) 28 | - If you're running on Windows, check out these [tips](https://johnpapa.net/tips-for-running-node-and-npm-on-windows/). 29 | - [ ] Visit and familiarize yourself with [npm](https://www.npmjs.com/) 30 | - [ ] Get a good text editor/IDE. 31 | - Text Editor 32 | - [Atom](http://www.atom.io/) 33 | - [Sublime Text](http://www.sublimetext.com/3) 34 | - [Textmate](http://macromates.com/download) 35 | - [Brackets](http://brackets.io/) 36 | - IDE (Integrated Development Environment) 37 | - [Visual Studio Code (Mac/Windows)](https://code.visualstudio.com/) 38 | - [WebStorm (Mac/Windows)](https://www.jetbrains.com/webstorm/) 39 | 40 | ### How to Ask for Help 41 | The Internet is a vast cache of information and if you know how to navigatge it well, you can become a very effective learner. 42 | 43 | - Always and always Google what you're looking for first. If what you're looking for isn't in the first page of results, then try again with different query. 44 | - Prefer [StackOverflow](http://stackoverflow.com) links or got there directly. 45 | - If the above strategies fail, then feel free the [create a GitHub issue](https://github.com/excellalabs/the-javascript-curriculum/issues) on this repo. 46 | - Always provide full and complete information when asking for help. 47 | - Specific questions are far more likely to get answered, than general/generic questions. 48 | 49 | ### Absolute Beginners 50 | - [ ] Don't how to work the console, command line, CLI or bash? Start with the basics [here](https://swcarpentry.github.io/shell-novice/01-intro/) 51 | - [ ] Open up command line/console. Type in `node`, do you see `> `? If yes *great*, hit `Ctrl+C` to terminate the currently running `node` process. If no, then see `How to ask for help`. 52 | - [ ] Type in `npm`, do you see `Usage: npm