JAVASCRIPT NOTES: Taken from Youtube tutorial by Bucky Roberts (thenewboston), and Udemy course JS: Understanding the Weird Parts ------------- Good examples of popular and good clean JS code: Underscore.js library - famous library for JS. You can download the development versions with comments or go to the annoted source link which lists the comments next to the code Lodash.com - similar to Underscore.js, but has extra features. GREAT SITE WITH EXPLANATIONS: http://jsforallof.us use code lint cleaners to make code format professional: https://github.com/collections/clean-code-linters Check Wes Bos for tutorials - very popular javascript teacher https://javascript30.com/ ---------------- Fundamental concepts of/notes for JS: -EVERYTHING IN Javascript IS AN OBJECT OR A PRIMTIVE -the two pillars of JavaScript: prototypal inheritance and functional programming. Both are used extensively in every large JS app I’ve ever seen. A working knowledge of both is essential to every JS developer. Note: Place script tags and links at the bottom of the head after style links and tags for faster load (you want the style to load first and then the scripts later). NOTE: Javascript engine and program has two phases: 1) Creation Phase: variables (just the names and are set to undefined until the execution phase where they are assigned), and functions are stored in memory, including Global Object (window in the browser) which the engine attaches defined variables and functions to, as well as the 'this' built in value, and the outer environment. It also sets up the built in keyword 'arguments' - which is becoming outdated but still used in some code. 2) Execution Phase: Code is run. Note: Placing scripts at the bottom of the element improves the display speed, because script compilation slows down the display. ***Place Scripts at the bottom if they reference elements in the body - these elements need to be loaded before the script will recognize them. -------------- HOW JAVASCRIPT EXECUTES CODE: EXECUTION CONTEXT = 1) Creation Phase (variables and functions stored in memory), 2) Execution Phase (code executed line by line). **If a variable is used in a function and a value is not found for it, then JS will look for it's value in the function's outer environment (which depends on where the code is written lexically). THE EXECUTION STACK: For every function that is called, a new execution context is created (which runs through the create phase and execution phase). When the execution is completed, the function execution context is popped off the top of the stack. 1) Global Execution Context is created by the compiler (the variable 'this', a global object, and window object is created, and then functions are attached to it). 2) When a Function is called with the parentheses() in the code, a new execution context is created on top of the Global Execution Context (it's put on top of it in the stack). A create phase occurs, and then the code is executed line by line within the function. **If another function is called inside that function, then another Execution context is created on top of that and put at the top of the stack. Note: During the Creation Phase, an outer environment reference is created as well for JS to search for values if needed. ------------------- TYPES OF DATA IN JAVASCRIPT: DYNAMIC TYPING: JS figures out what type of data a variable holds while the code is running. It's possible for a variable to hold different types of values while the code is running. You don't specify what type of data is in a variable (you just use var, and JS figures out what it is - a numeric, boolean, string, etc.). -PRIMITIVE TYPE (represents a single value and is not an object): 6 primitive types: -Undefined: lack of existence (don't use this or set variables to this) -Null: lack of existence - use this to set variables to nothing (let the engine use undefined). Null is not coerced by JS to 0 for comparisons, but coerced to 0 in other contexts (i.e. with Number() function). -Boolean: true or false -Number: only one type of number data (it is a floating point number-with decimals) -String: sequence of characters inside quotes (single or double) -Symbol (used in ES6 version of JS): may not be supported by some browsers. ===== Tutorial 1 - loops - need to review this more and watch other vids on it JAVASCRIPT - Used in conjunction with xhtml/CSS to make website more interactive. Many different script languages on the internet - Javascript is one of them. Note: to protect against older browsers trying to read Javascript (if you have users with older browsers), add around the code. Ex: 1. To use Javascript, under body tag, add the tag Tutorial 2: COMMENTS Comment: a line of text that browser ignores - use it to leave yourself or others notes about the code. To add a comment: // comment goes here To make multiple line comments: use /* and */, Ex.: /* Comment here second line comment here, etc. */ PRINT TEXT: document.write ("Write text here"); --------------------- Tutorial 2: VARIABLES (placeholder to represent something else, e.e. x=ham, x comes from a pig). **Note: all variables are either global scope or local scope (entire function) - Javascript doesn't have a "block scope" where variables are only available with a smaller block of the local scope (function). To make a variable: under -This will print out Jay on the screen. Note: make sure to capitalize the A in Array, and also don't forget quote marks on all of the item values in the array. .forEach loop: ------------------ Tutorial 29: Other ways to create Arrays 1) indicate how many items to store in it. Tells computer to set aside space for an array and then you can code after that and define the index later. Used when you can't add the information into your array as soon as you create it (maybe the user needs to input information that will be inputed later, etc.). Create a new array name with var and include the number of items in the index in the parameter. Then you write the name of the array followed by the number of the index item in brackets, and then equal to the item value in quotes followed by a semicolon. Ex: -this will print thing3 on the screen from the array index. 2) Creating an Empty Array - you can change the size as needed dynamically. Used when the size of an array is initially unknown (when user has to add an unknown number of items, for example). You can define a dynamic Array and continue to code and then add values to the index as needed without a specified number of items. Syntax: create an array name with var and leave the parameters empty ending with a semicolon: Ex: ------------------- Tutorial 30: Array Properties and Methods Note: methods always need paramters () parentheses with them. Properties do not need parameters. Built in properties: 1) The most common is the length property (tells you how many items are in the array). example after array is created: document.write(arrayname.length); -this will list the number of elements in the array. 2) Concat method (short for concatenate) - add/combine arrays together to create a new array. create a new array name with var and make it equal to the name of the array you want at the beginning, with a dot seperator and concat method keyword, and the array you want to attach to the end of it in the paramter ended with a semicolon. Ex: -this would print out chick3 on screen - the last in the combined array. TO ADD NUMBERS TOGETHER IN AN ARRAY: Use the built in reduce() function. use the array name and a dot seperator to access the reduce method, which manipulates a function(you can name it) to start at the beginning of the array and loop through the values to the end. You can name all variables and function name in the reduce paramter - it knows what to do with the elements regardless of their name - be sure to return the two elements in the function by using any math operator you want with them in the function code. note that currentIndexValue starts at the beginning Syntax: arrayName.reduce(function(initialValueOrTotal,currentIndexValue){return InitialorTotal + indexValue;}, InitialValue) reduced syntax: array.reduce(function(a,b){return a + b;}, InitVal); Notes: -InitialValue is passed in to the first parameter of the function (it is usually 0). -The arguments in the parameter of the function can be called anything, they are just placeholders for the 2 values represented. the second argument is a placeholder for the current index value being iterated in the array you are reducing. Ex: var numbers = [65, 44, 12, 4]; function getSum(total, num) { return total + num; } function myFunction(item) { document.getElementById("demo").innerHTML = numbers.reduce(getSum); } -ALTERNATIVE to Adding up totals in Array using for loop: create variable of 0, then a for loop to go through index and add it and assign it to the variable: Ex: var aSum = [numbers in here]; var aTotal = 0; for(i = 0; i < aSum.length; i++){ aTotal += aSum[i]; ------------------------- Tutorial 31: Join and Pop methods for Arrays JOIN METHOD: Converts an array to a string. Useful when you want to show a complete list of an index in an array. The list is seperated by a comma by default, but you can pass in a different seperator in the paramter. Create an array, then create a string name with var and set it equal to the array name with a dot seperator and then the join method with empty parameters (for comma), or pass in a different seperator in quotes with spaces. Ex: To make the list seperated by dashes instead of commas: var string1 = composers.join(" - "); POP METHOD: Removes the last element from an array. Can be called more than one time to remove the last item of the previously shortened list. Syntax: nameofarray.pop(); Ex: -this will print out Mozart, then two undefined as the pop removed the last item in the list twice. ------------------- Tutorial 32: Reverse, Push, Sort Methods for Arrays -Reverse: thise reverses the order of the array. use a dot seperator and then the reverse keyword: ex - create an array (i.e. bodyparts), then write the name and the keyword with a dot seperator: bodyparts.reverse(); -Push Method: adds one or multiple elements to the array at the end. bodyparts.push("tongue", "optional second part"); This adds the elements to the array. -Sort Method: Puts the Array into alphabetical order. ex: bodyparts.sort(); ---------------- Tutorial 33: Add Array Elements using a Loop Technique that is useful in Web Design. Useful when entering and printing out information. Prompt: similar to an alert box, but the user can enter text into it and the client can take that and turn it into a variable. Takes 2 Parameters - 1: Text the user sees (i.e. "Enter Your Name"), 2: What appears in the text box by default. Whatever is entered into the text box is stored in the variable created in javascript: Ex: under javascript script tag: var pie = prompt("Enter your Name:", ""); document.write("Hello " + pie); This will make a prompt box and when the user enters their name, the text "Hello" with their name will be displayed on the page. To Make a Loop: Use the for loop keyword and for the counter, use the array index. Ex: This makes a prompt appear 3 times where the user adds an item to the array, and then it is printed out. The array index is used as the counter (starts at 0 and ends before reaching 3, increments by one.). ----------------- Tutorial 34: Cool Tenchnique for Printing Array Elements use the stuff.length property in the for-loop so that you don't need to count the items in the index if an item is removed or added. Ex: -If you add 3 or remove 3 or any of the index elements, the for loop will operate completely without having to change the number of items in the index (the stopper counter). NOte: usually you can sort the array after creating it before making the for-loop using arrayname.sort command. --------------- Tutorial 35: Associative Array Not used as often as the other type of Arrays. In an associative Array, you can use text string as the index placeholder instead of a number to represent a value in the array. -Create the Array -write name of array and then the placeholder text in brackets and in quotes -make it equal to the value in quotes and end with a semicolon Ex: var Brent = new Array(); Brent["color"] = "blue"; Brent["food"] = "chicken"; document.write("Brent's favorite food is " + Brent["food"]); ---------------------- Tutorial 36: Math Object (built in to Javascript) -another built in object in Javascript. -Has built in properties such as pi, Euler's Constant, etc. (PI and E) (Use capital letters for these) Ex: Math.PI, Math.E -Useful for making a calculator or a program that runs calculations Built-in Methods include calculating the square root, rounding up or down, etc. Ex of using the square root method: var n = prompt("Enter a Number", ""); var answer = Math.sqrt(n); alert("The square root of " + n + "is " + answer+ "."); This will create a pop up of the square root of the number the user enters into the intial prompt box. --------------------------- Tutorial 37: Date Object (built in to Javascript) -the Date object grabs the current date and time. The Set Interval function: runs a function by a certain time interval increment (for ex. run the function every second, or every 5 seconds, etc.) Syntax: function nameoffunction(){code that runs for function;}\ setInterval("nameoffunction()", numberofmilliseconds); Ex: function doSomething(){ document.write("stuff "); } setInterval("doSomething()", 1000); This will print stuff every second (1000 milliseconds) on the screen. -Methods of the date object include information such as getHours, getMinutes, getSeconds, etc. Example of a time clock printing every 1 second on screen: function printTime(){ var now = new Date(); var hours = now.getHours(); var mins = now.getMinutes(); var seconds = now.getSeconds(); document.write(hours+":"+mins+":"+seconds+"
"); } setInterval("printTime()", 1000); ------------------ Tutorial 38: Accessing Forms -Javascript is very useful for form validation (to ensure that data entered by the user is in the correct format, etc. and is verified.) ***Note: Create forms outside of Javascript in regular xhtml. When you enter a form object in html, it is automatically created and recognized as an object in javascript. -The way Javascript automatically creates an array with the forms you've created in html (if you have 8 different forms in your html code, Javascript will store those in a form array). if you have 2 forms, then the first is stored as form 0, and the second as form 1 in the array index. -forms are accessed as an Array Object of the Document (i.e. document.forms[]) Example of how to access a form from html code: 1) create the form in html 2) create a variable which is assigned to a property of the form (accessed by using the syntax document.forms[numberofform].property)
Username: Password:
This will print out 3 (the number of elements in your created form) -------------------- Tutorial 39: Accessing Form Elements -elements of forms are also stored in built in array objects in Javascript. Access them by using the elements object keyword and a dot seperator. Syntax: document.forms[numberofform].elements[numberofelement].elementname Ex: var x = document.forms[0].elements[0].name; document.write(x); This would print username on screen if the first element of the first form had a name of username. -An Alternative way of accessing forms without referring to the array is to name the form in html (inputing a value to the name property in the form tag), and write the name instead of forms after document. can also access the element by name. syntax: document.nameofform.nameofelement.propertyofelement Ex.:
Username: Password:
---------------------- Tutorial 40: Basic Form Validation Steps: 1) Make a form 2) Make a function to validate an element in the form (made in the head) Ex:
---------------------------------- From DOM tutorial on Traversy Media: -To create an element: var nameofElementvariable = document.createElement('elementselectorname'); Ex: var newDiv = document.createElement('div'); -this creates a new div with the open/close tags. can set id with .id: newDiv.id = 'idname'; to change attributes, etc. of the new element: class: use .className Ex: newDiv.className = 'yourclassname'; can use .setAttribute, Ex: newDiv.setAttribute('title', 'titletext'); -- To input into the newly created element and insert it into the DOM: 1)create a text node for the input information: create a new variable for the text node and use syntax: var varName = document.createTextNode('text to enter'); Ex: var newDivText = document.createTextNode('text here'); 2) Append the new text node variable as a child to the desired element to insert it into: Syntax: nameOfElementToInsertInto.appendChild(nameOfTextNodeVar); Ex: newDiv.appendChild(newDivText); 3) create two variables to grab the section you want to insert the new elements/info into with .querySelector, and grab the element you want to insert the new object before with querySelector as well. var nameOfVar = document.querySelector('sectionSelector elementSelector); var nameOfVar = document.querySelector('sectionSelector ElementSelector'); var container = document.querySelector('header .container'); var h1 = document.querySelector('header h1'); 4) Insert the new element data into the DOM by using the insertBefore method for the parent element variable created and passing in two paramters: nameOfElement(whatYourInserting, whatYourInsertingBefore); --------------------------------- TRUTHY AND FALSEY CONCEPT: Reasons to use the ! operator in conditional statements: ! = NOT OPERATOR: The logical not operator forces the variable it’s in front of to be read as a boolean. Can be used in if conditionals to check if a variable or object is falsey (6 values: undefined, null, NaN, 0, "" (empty string), false) TRUTHY AND FALSEY VALUES: An object of any kind (including functions, arrays, RegExp objects, etc.) is always truthy. The easiest way to determine if something is truthy is to determine that it’s not falsey(with a not operator[!]). The reason: It is possible to explicitly wrap a primitive (string, number, null, undefined, boolean) in an object, which will make it truthy. For example, 0 (zero) is falsey, but new Number(0) is truthy. A scarier example is new Boolean(false) which is also truthy! Be careful. **Because an object of any kind that has a value of any kind (including false equivalents, such as 0 or false which are defined as values for the object) becomes truthy, a variable or object with a null or undefined/empty string value, etc. will be considered truthy, because it is an object that exists. How an if statement works: 1. Evaluate Expression. 2. Call GetValue(Result(1)). 3. Call ToBoolean(Result(2)). 4. If Result(3) is false, return (normal, empty, empty). //just means proceed with program in the normal fashion - don't do anything. 5. Evaluate Statement. 6. Return Result(5). To check an object or value for truthy or falsey value: call the Boolean constructor as a function: Ex: Boolean(0); // => false It will return a boolean value — either true or false, and is a really quick way of finding out whether a value is truthy of falsey. well-known and widely used shortcut is to use the logical-NOT operator twice, like so: !!null; // => false !!0; // => false !!123; // => true !!'foo'; // => true More examples and idiosyncracies: *the only string that is falsy is an empty string. The string “0” is truthy, whereas the number 0 is falsy. "0" == 0 // coercion makes them equal even though... !!"0" === true // "0" is truthy !!0 === false // 0 is falsy *Another oddity that can be confusing is that null is not coerced into a bool: (null == false) === false // null cannot be coerced into a bool !!null == false // .. but null is evaluated as a bool in conditionals typeof null === 'object' // even worse, null is an object *Null is an object, but is inherently falsey and cannot be given a false boolean value manually as demonstrated above. *these two things ARE NOT equivalent because type coercion has different rules than truthiness: if (!val) {} //evaluates the truthiness or falsiness of val as the condition. if (val==false) {} //evaluates the boolean value of val (after the value has been coerced to a boolean. The first one does ToBoolean coercion, while the second one does ToPrimitive coercion. More info: https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/ ------------------------------- ================================================================================ FROM UDEMY COURSE: JAVASCRIPT: UNDERSTANDING THE WEIRD PARTS: SETTING A DEFAULT VALUE WITH JS: Note on || operator: this function returns the first value that can coerce to true. i.e. "" || "hi" returns "hi". "hello" || "hi" returns "hello" because it is the first value that can be coerced to true. Ex: function greet(name){ name = name || ""; //the || operator returns the first value that can be coerced to true - so if no value is passed into the function (makes it undefined-false), then it will use the string specified alert ("hello" + name); } greet(); //no parameter passed through results in undefined. ---------------------------------- The 'arguments' Variable keyword: 'arguments' contains and stores all the values of the parameters passed to functions that are called. JS Engine stores all of the parameter variables in the creation phase when a function is called and if they are not set, then they are set automatically to undefined. Note: arguments is becoming deprecated (not the best way to do something). The new better method is to use SPREAD method. write '...other' in the parens. ex: function greet(name, address, ...other){}; This allows for any number of additional arguments to be passed in that were not set in the first place. the '...' before other means to take every additional new parameter/argument and put it in an array containing all those values. Note: Spread method is not yet available in all browsers, but eventually will be and be the preferred method over using 'arguments' Ex: function greet(name, address){ alert ("hello " + name + address); console.log(arguments); //<---this displays an arraylike collection of the values of name and address or any other parameters of the function. note: some of the features of arrays are not applicable to the arraylike collection. } ex to check for parameters: function greet(name, address){ if (arguments.length === 0) { //<--------check if the arraylike collection of arguments has no entries. console.log('parameters are empty!'); return; //<--- this stops the rest of the code from running and leaves the function. } alert ("hello " + name + address); } -------------------------------- DANGER TO WATCH OUT FOR IN JAVASCRIPT: Automatic Semicolon Insertion Syntax Parser: JS goes character by character in your code and anticipates what it expects to see in the next space to anticipate what you want to do and can even change your code (coersion, etc., adding semicolons, etc.). Automatic Semicolon Insertion: The JS Engine will insert semicolons where it think they should be if they are missing. ***ALWAYS PUT YOUR OWN SEMICOLONS IN AND DO NOT PRESS ENTER FOR A CARRIAGE RETURN AFTER 'return' KEYWORD!!*** Most common problems occur when using the 'return' keyword in code and then using a carriage return (pressing enter to go to the next line). JS sees the carriage return after the keyword 'return', but expects a semicolon - so it inserts one, making the code after 'return' disacossiated with it. ex: return <---because there is a carriage return here, JS enters a semicolon automatically. { code here; } *Put the curly brace on the same line as return: return { } -------------------------- CLOSURES: A feature of Javascript Engine that ensures that all the variable information needed for a function to run is available in memory even after it is taken off of the execution stack and is finished running. If there is a function inside another function that is called after the first function has been executed, then after the first function is cleared from the execution stack, the variables that were created in that scope are still stored in memory and can be referenced by the inner/child function, even though the execution context has been removed - the variables are still in memory and accessible by the child function. ------------- FUNCTION FACTORY: *Principle: Every time you call a function, it gets it's own execution Context. Any function created inside of it will point to andhave access to that execution context (stored variables and data in memory). ****Can be used to create functions that have default parameters that you don't have to pass in every time. -Creating a function 'wrapper' that returns a function that has access to the passed in variables when called after the function 'wrapper' has been executed (because the passed in data is stored in memory which can be accessed by the inner function by referencing the outer environment). This means that the same function can be called multiple times with access to different passed in values created by each initial execution context when it is called and assigned to a variable. 1-create function wrapper with parameter, that returns a function. 2-assign variables to the function wrapper passing in arguments as desired and call the function wrapper with (), which returns the function wrapped inside with access to the passed in argument specified in that particular variable 3-call the variable (since it is a function) with (), and pass in desired arguments - the new function variable will have access to the arguments assigned to it when declaring it and assigning it to the wrapper function. Ex: function makeGreeting(language) { return function(firstName, lastName) { if (language === 'en') { console.log('Hello' + firstName + lastName); } if (language === 'es') { console.log('Hola' + firstName + lastName); } } } var greetEnglish = makeGreeting('en'); <--returns function with en passed into language parameter. var greetSpanish = makeGreetin('es'); <--returns a function with es passed into language paramter. greetEnglish('Jon','Doe'); <--logs Hello Jon Doe greetSpanish('Jon','Doe'); <--logs Hola Jon Doe greetEnglish has access to the memory stored in the execution context created when makeGreeting was called with the greetEnglish variable call. ------------------------- CLOSURES AND CALLBACKS: built in JS Function setTimeout() -- used when you want something to happen after a certain wait time. Syntax: two arguments - (what you want to happen after waiting as a function, how long to wait in milliseconds): setTimeout(function() {code to execute after wait}, milliseconds to wait); CALLBACK FUNCTION: A function that is called to run which is created or passed inside another function which calls it as part of the code. in other words: function A is called which contains function B, then function B 'calls back' after you called Function A. Ex: function tellMeWhenDone(callback) { var a = 1000; callback(); //<--the callback function(can be named anything) } tellMeWhenDone(function() { console.log('I am done'); }); // the function is defined and passed in and becomes the callback function in the parent function. ---------------------------- call(),apply(),bind() BUILT IN JS FUNCTIONS: Used to control what builtin 'this' keyword points to. *All function objects in JS have access to these 3 builtin methods. -- 1) .bind METHOD: Syntax: functionName or functionVar.bind(object you want to be the 'this', optional parameter values to pass in); Ex: logName.bind(person); <--this sets the 'this' inside of logName function to the object 'person'. Note: .bind creates a copy of the function you call it on and assigns the this in that function to the passed in object, as well as any parameter values to pass in after that. ***BIND DOES NOT CALL THE FUNCTION (unlike call() and apply() methods). -can use with function currying (see below practical methods) --- 2) .call() METHOD: -call() actually executes the function instead of creating a copy (like bind()). It passes in the object to set this to and also accepts additional parameters for the function. Ex: functionName.call(objectThis, arg1, arg2, etc.); <--you can use call to just access the function directly and input parameters instead of using bind to create a copy and then insert the parameters. ------ 3) .apply METHOD: Similar to call, but wants an array for the additional parameters. Ex: functionName.apply(objectThis, [array items]); Ex: (using a function expression and apply method to immediately call it: (function(numA, numB, numC) { return numA + numB + numC; }).apply(objectThis, [1, 2, 3]); //<--the array fills the parameters of the function. ---- PRACTICAL USES FOR CALL, APPLY, BIND METHODS: *use FUNCTION BORROWING using call() or apply(): var person1 = { name: 'Joe', getName: function() { var objName = this.name; return objName; } } var person2 = { name: 'Jane' } person1.getName.apply(person2); <--this returns 'Jane' because it borrows the getName function from person1 and replaces the 'this' value context with that of the passed in object using apply(). The apply() method calls the borrowed function and passes in the object to point this towards. ------- *use FUNCTION CURRYING using bind(): Function Currying: creating a copy of a function (with bind method), but with some preset paramters. Very useful in functional programming and mathematical situations (for ex you can have fundamental functions you can build on with some other default parameters). Syntax for using Currying: var x = functionObj.bind(this, arg1value, arg2value); ex: function multiply(a, b) { return a * b; } var multiplyNum = multiply.bind(this, 2); //<--this passes in 2 to the first parameter of multiply. multiplyByTwo(4); //<--this calls multiply function which uses the passed in set parameter of 2 for a and then 4 is passed into b. var multiplyNum = multiply.bind(this, 2, 4); //<--this passes in 2 to parameter a and 4 to parameter b. multiplyNum(); <--this calls multiply with the automatically passed in 2 and 4 for a and b from the bind method and returns 8. ------------------------------------------------ FUNCTIONAL PROGRAMMING: Lecture 51 in Js: Understanding the Weird Parts course on Udemy Because Javascript functions are first class functions (they are objects), code can be written entirely with functions (results in cleaner more concise and organized code) by passing them into other functions as objects. The purpose of functions is to limit repitition by putting work into functions that would otherwise require more code lines to execute. ---------------- Classic Example of functional programming: note: to 'map' an array means to take it, do something to it and get a new array out of it. the following function takes each item in the array and maps it - modifies it to return a modified value, each put into a new array. //the following function loops through a passed in array and performs a passed in funtion on each item which returns a result that is pushed into a new array: ---Format and Structure: --- function (passedinArray,passedinFunction) { for loop using passed in array { pushtoNewArray (passedinfunction(passed in array[i] item)) }; returns the new array } --- ACTUAL FUNCTION: --- function mapForEach(arr, fn) { var newArray = []: for (var i=0; i 2;}); //returns arr3[false,false,true]; //the functions passed into mapForEach do the work on the array and reduce the amount of code necessary to complete each function on the array. ---using bind and currying: var checkPastLimit = function(limiter, item){ return item > limiter;} //this function will allow for a parameter to be specified as the limiter to compare the array item passed in to instead of having it preset as in the arr3 example. var arr4 = mapForEach(arr1, checkPastLimit.bind(this, 1)); //returns arr4[false,true,true]; *Note on functional prgramming: you want to try to avoid mutating the original data (in this case arr1) throughout the process of functional programming and instead focus on returning new data from the original. This can prevent confusing and jumbled processes. ------------------------------------ FAMOUS LIBRARIES THAT USE FUNCTIONAL PROGRAMMING: Great for learning about the source code. Underscore.js library - famous library for JS. You can download the development versions with comments or go to the annoted source link which lists the comments next to the code Lodash.com - similar to Underscore.js, but has extra features. ----------------------------------------- OBJECT ORIENTED JS AND PROTOTYPAL INHERITANCE: Lecture 53: ----- Classical vs. Prototypal Inheritance --------------- Terms: -Inheritance: one object gets access to the properties and methods of another object. Classical Inheritance: -the current and most popular type of inheritance in languages like Java, C# etc. Drawbacks: -is Verbose, can be hard to keep track of the connections and which objects inherit what. Prototypal Inheritance: -simpler than Classical Inheritance -flexible, extensible and easy to understand ----Lecutre 54----- PROTOTYPES: PROTOTYPE PROPERTY in Javascript KEY POINTS: -All Objects (including functions) have the prototype property(proto{}) built in. Primitives do not have a prototype. Note: Only one object does not have a prototype: the BASE OBJECT in JS. The base object is at the bottom of the prototype chain and is Object{} //<---(this may not be true, Object.prototype exists.) -The prototype property is a reference to another built-in object (an object called 'proto'). -the object proto{} is the reference for the prototype property of the original object. -Objects can share a prototype if they are set to. -the proto object can have a prototype, and that prototype can have a prototype, etc. ------------ When a property is called on an object, the JS engine first looks for it on the object itself. If it is not there, then it looks for it on the built in prototype property to see if there is a reference to it in the property that is attached to the proto{} object. *Note: the prototype object proto{} contained in the prototype property of an object can also have it's own prototype (property/object) attached to it. Ex: if a property is called on an object and JS Engine can't find it, it will also look to it's prototype object, and if it can't find it there, then it will check the prototype of the prototype of the original object, etc. *this is called the 'Prototype Chain': the succession of prototypes of prototypes. at the bottom of the prototype chain is the Base Object (discussed in later lecture). So, to access prop3 on the prototype of the prototype of an object, you don't have to write: obj.proto.proto.prop3; you can just write: obj.prop3; and JS Engine will search down the prototype chain for obj until it finds it. -Different objects can share the same prototype if you want them to. i.e. Obj1 and Obj2 can both point and reference the proto{} of Obj1. Obj2 can search down the same prototype chain as Obj1. NOTE: Modern Browsers provide a way to access the prototype object, but DO NOT USE IT! It causes performance problems. ***DON'T THE FOLLOWING METHOD!!!***: var person = { firstname: 'Default', lastname: 'Default', getFullName: function() { return this.firstname + this.lastname; } } var john = { firstname: 'john', lastname: 'doe' } john.__proto__ = person; //DON'T DO THIS! this sets 'person' as the prototype object reference for 'john' note - the method in question is typing two underscores 'proto' and two underscores to set the prototype. Note: when you call a property or method from another object (referencing the prototype of that different object) 'this' is set to the object that is calling the property from the prototype of the other object. Ex: john.getFullName(); //returns 'john' 'doe' and uses john as the 'this' object. Use this way to set where an object looks to as it's prototype: john.prototype = person; //do not use .__proto__ ------------------------------------------------- Lecture 55: EVERYTHING IN JS IS AN OBJECT OR A PRIMTIVE; the Base Object The base object is a builtin object that is at the bottom of the prototype chain for any object/function in javascript: *Only Base Objects (and primitives) do not have prototypes in JS. All data types except primitives have a base prototype, and at the bottom of the prototype chain is the prototype of the base prototypes, which is Object{} The base object is Object{}. If you log the prototype of the first prototype of any object, then you will get the base object - Object{}. Ex. c = arr[] c.__proto__; returns [] (initial prototype of an array) c.__proto__.__proto__; returns Object{} (this is the base object and at the bottom of the prototype chain Examples: The base prototype object of a variable is Object{} The base prototype object of a function is an empty function: function empty() {} The base prototype object of an array is an empty array object: [] These base objects have builtin properties and methods that you can call on that are available to all objects of that type. i.e. any array has access to the .length property because the prototype base object of array ('[]') has the builtin property 'length' and the builtin method 'push' attached to it for reference. When you create any array, it has this builtin prototype base object with these built in methods/properties that can be referenced. Javascript automatically sets the base prototype with builtin methods/properties to the corresponding data type (i.e. array, variable object, function, etc.) --------------- Lecture 56: REFLECTION AND EXTEND: Reflection: an object can look at it's own properties and methods and list and change them. An example of this is the _extend function in undersore.js library - look at the source code. An objects properties is looped through and assigned to another object as properties. ------------------ Lecture 57: FUNCTION CONSTRUCTORS Note: always capilatize the first letter of a function constructor (best practice to prevent confusion with a regular function - the function constructor needs the keyword 'new' with assignment, so if you see a function with a capital first letter, and not the word 'new' with it, you know that it's missing.) Note2: you will see function constructors in legacy code - they are not being used in newer Javascript code. History of Javascript: the language was named Javascript to attract Java developers. Java was popular at the time, and the goal was to get as many developers using the language as possible. It was a marketing technique. Note: Javascript looks like Java, but is nothing like Java. Function constructors: (this way exists becauses the code looks similar to Java) function Person(firstName) { this.firstname = firstName; } var John = new Person('John'); <---this looks like Java code and was builtin to attract Java developers var Jane = new Person('Jane'); <---constructor function creates a new person object Jane When you use this method, the 'new' is a builtin operator in JS that creates an object that can be modified using the 'this' variable (a Person{} object is created by the new operator using Person()) from the Person() function as long as Person() does not return a value. Note: function constructors are imitating how classes work in other languages. In other languages, you create a class which describes what the object looks like, and then assign the object blueprint using a keyword. --------------------- Lecture 58: Function constructors and Prototypes *Objects created in a function constructor reference the prototype property of that function. methods and properties created with the .prototype property of the function will be accessible by all objects created with it. Ex using the constructor function Person() from previous lecture: Person.prototype.address = '5555 elm st.'; **This adds the address property to the prototype of the Person function constructor - now all objects created with this function constructor will have access to this property. Both John and Jane objects now have access to the address property because the prototype that they reference is actually the prototype of the function constructor they were created in. ****What this allows you to do is to make many different objects with a function constructor and then you are able to create methods and properties on the fly that all of those objects have access to. *Best Practice: put properties in the object, but put methods on the prototype of the function constructor. This way less memory space is taken up. Ex. you have have 1,000 Person objects and each one has a method in it. If you just added the method to the prototype object of Person, then the one method takes up one space in memory and all of the Person objects can reference it. Ex. Person.prototype.getFullName = function () { return this.firstname + ' ' + this.lastname; } All objects created with Person() will have access to this method. -------------------------------------- Lecture 59: WARNING: 'new' and Functions: CAREFUL: if you do not use 'new' with function constructors when creating new objects, the value will be set to undefined: var John = Person('John'); //<-----xxxxx this returns undefined because Person() doesn't return anything var John = new Person('John'); //<--- correct: the new keyword makes the function a function constructor **** BEST PRACTICE: Always capitalize the first letter of constructor functions!! **** -------------------------- Lecture 60: Built in Function Constructors with the builtin function constructors, it looks like you're creating primitives, but you are creating objects that contain primitives a = new Number(3); you can now access the prototype property of Number to add properties and methods to a. a has access to all the properties and methods of the built in Number.prototype (includes methods like toFixed etc.) a is now an object as well. It's prototype is pointing towards the prototype of Number() which is the builtin function constructor that it was created with. So, you can use built in properties and methods of Numbers like so: a.toFixed(2); //returns 3.00 a = new String('John'); This turns a into an array object with the characters in it (a['J','o','h','n']). Inside the array the String function constructor also boxes in the primitive "John" in addition to the array of primitives, in case you want to reference it to add properties, i.e. "John".address = '555 Elm st.'; for ex. a has access to methods/properties of String.prototype. i.e. a.indexOf('o'); //returns [1] You can add methods and properties to the prototype of the builtin function constructors, and all objects created with them will have access to them. Ex.: String.prototype.addLastname = function(lastname) { return this + ' ' + lastname; //'this' points to the object calling the method. } //Now all objects created with new String function constructor will have access to this method because they are pointing at the prototype property of the function constructor they were created in. ex. a.lastname('Smith'); //returns "John Smith"; Note: with Number function constructor, you cannot access the prototype methods using a primitive number, because Javascript will not automatically convert the primitive to an object. 3.toFixed(2); //returns error instead of 3.00 because primitives do not have a prototype and can't reference but, if you do: a = new Number(3); //function constructor turns 3 into an object that then has reference to Number.prototype a.toFixed(2); //now it returns 3.00 (though it is not an actual primitive - '3'(a) is an object with a primitive boxed up in it. Generally you don't want to use builtin function constructors with these primitive types - can lead to confusing situations. ------------------------------------ WARNING: Function Constructors with primitives a = 3; b = new Number(3); a === b; //false, a is a primitive and b is an object; In general do not use builtin function constructors, use literals and actual values instead. Note: if dealing with a lot of Date work use moment.js - library with lots of functions for doing math with dates. Number() can be useful as a regular builtin function when converting numbers in string format to a number primitive type: c = Number("3"); //returns the numeric primitive 3 and converts the string to a number type. --------------------------------------- WARNING: Arrays in JS **Avoid using 'for...in' loops with arrays: Arrays are objects in JS and contain an index of properties (the items are name/value pairs). arr = ['john', 'joe', 'bart']; the array is actually: arr {0: 'john', 1: 'joe', 2: 'bart'} //0,1,2 are property names with values. Because of this do not use'for...in' loops (they iterate through properties, which could iterate into the prototype that the array references), instead use the regular for loops which are safe. ---------------------------------------------- Lecture 63: Object.create and Pure Prototypial Inheritance Pure Prototypal Inheritance: 1) create an Object, 2) Use that Object as the prototype for other objects. var person = { firstname = 'Default', lastname = 'Default', greet: function() { return 'Hi ' + this.firstname; //*see note } } *note: remember to include 'this' to reference the object when making methods in object literals! using Object.create: syntax: var varName = Object.create(objectToPassIn); Ex: var john = Object.create(person); //the object john is created (which is empty), but points to the passed in person object as it's prototype. john's prototype references the 'person' object. You can then assign properties that are in the prototype referenced to whatever you want which will overwrite the 'Default' values that would be shown from the passed in object ('person'). //Object is the base object in JS. create is a builtin method on the base Object. This method creates an empty object whose prototype points to the object passed in. (so even though it's empty, it finds and inherits the properties and methods by looking down the prototype chain and finds what's in the object that's passed in('Person' in this case). you can then assign new values to the properties/methods by creating them in 'john' object. john.firstname = 'John'; john.lastname = 'Doe'; //this assigns values to the properties necessary to use the inherited method in the 'Person' object. i.e. john.greet(); //returns "Hi John"-- the method is accessible in John and uses the values assigned that were created above. John is 'borrowing' the method greet() from 'Person' because JS looks for greet down the prototype chain and finds it being referenced (becuase the prototype was assigned with the Object.create method). ***The crux of it is: -You define an object (that other objects will be created from-it is like a blueprint) -You create other objects which reference the defined object as a prototype and have access to their properties and methods -You can reassign the properties and method values by creating them (the same ones) in the new object if desired, and you still have access to all the other properties and methods in the prototype object. -you can then modify the defined object if you want all other objects created from it to have access to other/new properties/methods. ---------- Some browsers may not support Object.create; Use a POLYFILL: Polyfill: code that adds a feature that a browser or engine may not support. can copy and paste polyfills for Object.create if it needs to be used on older browsers ------- Lecture 64: ES 6 version of Javascript New way to create objects and set the prototype. Class keyword will be added - in other languages, classes are not objects, but templates that are used when you create an object and use the 'new' keyword. *** In JS ES6, classes are objects *** To set the prototype use the keyword 'extends' ex: class InformalPerson extends Person Syntactic Sugar: A different way to type something (code) that doesn't change how it works under the hood. i.e. class feature is just a different way of using prototypal inheritance - the engine work is not changed. --------------------------------------- Lecture 65: Odds and Ends Initialization: Big initializations (of a large number of objects in an array): Common mistakes are syntax errors (forgotten commas, using = instead of : for assigning properties/methods, etc.) ex: //an array of object literals: var people = [ { firstname: 'John', lastname: 'Doe; }, //<---commas b/w object literals are often forgotten using this method. { firstname: 'Jane', lastname: 'Doe' } ] //<--closing of array of object literals. ------------------------------------------------- Lecture 66: 'typeof', 'instanceof', Figuring out what something is (data type): typeof - tells you the type of data: Ex: a = 1; console.log(typeof a); //returns number; b = []; console.log(typeof b); //returns object; Note: for arrays use this to check if it is an array: console.log(Object.prototype.toString.call(b)); var z = function(){}; console.log(z); //returns 'function' -useful to check if an object is a function. --- 'instanceof' -checks if an object is located on the prototype chain of another object: syntax: console.log(objA instanceof ObjB); //returns true if the prototype of objA points towards ObjB. ***Bug to be aware of in Javascript: (typeof null) returns 'object'; this is a bug! --------------------------------------------- Lecture 67: STRICT MODE "use strict"; //<--this command tells Javascript to be strict when parsing code and be less flexible. ex.: without strict mode: var person; persom = {}; //typo in person; Javascript will make this variable and set it to object without strict mode. *with strict mode on, JS will not create persom and return an error. -You can also use "use strict" inside a function and inside nonglobal execution contexts. Note: must be used on the first line of code in the function. Note: be careful when concatenating Javascript files when pushing code to production - if the first file has "use strict" then it will apply to all the rest of your concatenated code. Browsers will use the feature strict mode in different ways - consult documentation for details. -------------------------------------------------- Lecture 69: Learning from other's good code: Opensource education: looking at open source code from popular programs that are used by millions of people. Ex: AngularJS, JQuery etc. find something in the source code you find interesting and study the structure of the code to imitate it - good way to learn. check Github.com to check out source code. Go to Explore-->see all-->frontend Javascript Frameworks. Then read the libraries - usually located in /src/ folder (stands for 'source') Check out the uncompressed development versions of code for comments and explanations of the code. Be sure to look at source code and study it. --------------------------------------------------- Lecture 70: JQuery Source Code JQuery is the most famous JS library. JQuery is just a library of a bunch of JS methods. JQuery handles the different quirks of various browsers and mobile renderers for you. JQuery makes it easy to look at the DOM and find elements to manipulate. --- use $ to represent JQuery in code and then pass it a string: syntax: var q = $("stringGoesHere"); Ex. var q = $("ul.people li"); <--this finds all the