
Advanced JS Fundamentals to jQuery & Pure DOM Scripting
Topics:
This course is out of date and does not reflect Frontend Masters current standards. We now recommend you take the JavaScript: The Hard Parts course.
Table of Contents
JavaScript Basics
Introduction
Justin Meyer begins this course by introducing himself and his fellow co-worker Alexis Abril. They work for Bitovi doing both JavaScript development and training. Justin walks through the setup of the course and how the exercises are organized.Basic JS
JavaScript is a dynamic weakly-typed, prototype-based language. The DOM, on the other hand, is a language-neutral interface for accessing and updating content. Justin uses a simple HTML example to illustrate how the DOM executes.JavaScript Features
Justin demonstrates some of the unique features of JavaScript that separate it from other languages. These features include a being dynamic, weakly-typed, and first-class functions.
Data Types, Operators & Primitives
Data Types & Operators
Alexis overviews a number of the most common data types in JavaScript. He differentiates between primitive types and object types. He also talks about the various Javascript operators.References
References and value types are often misunderstood. To better illustrate JavaScript references variables in memory, Alexis diagrams how assignment statements work with both primitive values and more complex objects.The delete Keyword
The delete keyword does not remove objects from memory. its primary use is to de-reference objects. Alexis demonstrates how the delete keyword affects variables and memory.typeof
The typeof keyword is useful for determining the type of a construct. However the results can occasionally be unexpected. Alexis explains how typeof is evaluated and runs through a few examples.Summary
Alexis summarizes his coverage of Data Types, Operators and Primitives and answers a few remaining audience questions.
Comparison
“==“ vs. “===“
The double-equal and triple-equal comparisons operators can behave very differently. Alexis begins his discussion on comparison by quizzing the audience with a few true/false statements.Comparison Operators Explained
Alexis dives into a detailed explanation about how the double-equal and triple-equal comparison operators work in memory. While the triple-equal operator compares positions in memory, the double-equal operator uses a very different process.
Closures
Types as Arguments
Justin begins his discussion on closures with an example to demonstrate that primitives are passed by value to functions while objects are passed by reference. He also answers a few audience questions regarding call objects.Counter Example 1
Using a closure that returns a counter, Justin demonstrates how subsequent calls to the function affect the returned data. Functions always have a references to call-object where they were created.Counter Example 2
Justin repeats the previous counter example to further reinforce the concept of closures. He also answers a number of audience questions.Closure Gotchas
Because closures retain access to their call-object and any variables within their call-object’s scope, modifications to the variables can affect all closures and produce undesirable results. Justin demonstrates how wrapping the closure in an immediately invoked function can remedy this problem.Exercise 1: Making a Tag Library
In this exercise, you will use the dynamic nature of JavaScript to create a tag library. This library will be able to generate tags like h1, h2, span, etc. - exercises/js/tags.htmlExercise 1: Solution
Justin walks through the solution to exercise 1. He also reviews what happens in memory when a function is declared and called.
Context
What is “this”?
Alexis begins the context unit with a few simple code examples to help explain the “this” keyword. Depending on how a function is invoked, the “this” keyword could reference a number of different objects. Alexis also explains the call() and apply() methods.The Dot(.) Operator
Alexis diagrams how an object is defined in memory and what happens when the dot(.) operator is used to call a method on that object. He also explains the difference between __proto__ and prototype.Exercise 2: Finding Properties
In this exercise, you will write the dot operator as if it was implemented in JavaScript. You will use the hasOwnProperty method to determine if an object has a certain property. - exercises/js/my_js.jsExercise 2: Solution
Alexis walks through the solutions to exercise 2.Exercise 3: Invoking Functions
In this exercise, you will write the dot [[call]] operator as if it was implemented in JavaScript. The DOTCALL method must retain the context of the original scope. - exercises/js/my_js.jsExercise 3: Solution
Alexis walks through the solutions to exercise 3. During the explanation, Justin joins him to diagram what is happening in memory with the DOTCALL method.
Prototypal Inheritance
Shared Properties & Prototype Methods
Shared properties of one object can be inherited by another object by using the prototype property. Similarly, methods can be added to an object’s prototype. These methods can be invoked by any object inheriting that prototype.Prototypal Inheritance
Adding more layers or constructs to the inheritance tree leads to more complexity. This is where proto-chaining is used. Alexis demonstrates proto-chaining to create an inheritance tree between Animals, Chordates, and Mammals. He also demonstrates how to set the context correctly.Exercise 4: Implementing the ‘new’ Keyword
In this exercise, you will implement the “new” keyword as if it was implemented in JavaScript. The NEW method you are implementing will be passed the constructor function and an array of arguments. - exercises/js/my_js.jsExercise 4: Solution
Alexis walks through the solution to Exercise 4.Object.create()
Object.create() can be used to spawn new objects with a prototype correctly set to a parent object. Alexis demonstrates this method of inheritance but cautions about performance implications. Object.create() is much slower than manually setting the prototype property.Exercise 5: Creating the instance Operator
In this exercise, you will write the instance operator as if it was implemented in JavaScript. Be sure to check the proto-chain for the constructor’s prototype. - exercises/js/my_js.jsExercise 5: Solution
Justin walks through the solutions to Exercise 5. Justin also further explains the behavior of the __proto__ property.
jQuery Functional Utils
$.extend()
The jQuery $.extend() method takes one set of properties and copies them into another object. It’s useful for writing cleaner code or extending default values.Exercise 6 and Solution: Implementing $.extend
In this exercise, you will implement your own extend method. After briefly describing the exercise, Justin dives into the solution. - exercises/js/my_jquery.jsDay 1 Recap
Justin begins with a recap of everything covered up to this point. This includes everything from creating variables to how new objects are managed in memory.Type Checking
Conventional type checking using the typeof operator will return a string for comparison. Similarly the typeof operator can be used to check an object’s prototype. Justin spends most of the time talking about how to type check edge cases.Exercise 7: Implementing $.isArray()
In this exercise, you will implement your own $.isArray() method for type checking Arrays. Justin also reviews how to use the toString() method for type checking.Exercise 7: Solution
Justin walks through the solution to exercise 7.Exercise 8: Implementing isArrayLike()
In this exercise, you will create an isArrayLike() method that will determine whether an argument is LIKE an array. Before beginning the exercise, Justin introduces the “in” operator which will be used instead the isArrayLike() method.Exercise 8 Solution
Justin demonstrates the solution to Exercise 8. He also answers a few audience questions about performance and the use of other operators.Exercise 9: $.each()
In this exercise, you will implement the $.each() method which will iterate over arrays or other objects.Exercise 9: Solution
Justin walks through the solution to exercise 9.Exercise 10: Implementing $.makeArray()
This exercise requires you to implement a $.makeArray() method that will convert an Array-like object into a true JavaScript Array.Exercise 10: Solution
Justin walks through the solution to exercise 10.Exercise 11: Implementing $.proxy()
In this exercise, you will implement the $.proxy() method. This method is passed one function and returns a function that calls the original with a particular context.Exercise 11: Solution
Justin demonstrates the solution to Exercise 11. He also diagrams what is happening in memory when the $.proxy() method is called.
Finding Elements
Finding from the Document
JavaScript provides an extensive API for finding elements in the DOM using the Document object. This API includes methods like getElementByID() and querySelector(). Justin gives a few code examples using these APIs.Exercise 12: Creating the $ function
In this exercise, you will create a function named “$”. This function will take a selector as an argument and return an Array-like object of DOM elements.Exercise 12: Solution
Justin explains the solution to exercise 12.Exercise 13: Implementing the html() method
In this exercise, you will add an html() method to get and set the innerHTML of all elements in a selection.Exercise 13: Solution
After giving a little context for why you need an html() function, Justin walks through the solution to exercise 13.Exercise 14 and Solution: val() function
This exercise requires you to implement the val() function. The val() function gets or sets the value of an element. Justin briefly sets up the exercise and then jumps into the solution.Exercise 15: Eliminating “new”
This exercise tasks you with removing the need to call the “new” operator to create new instance of the $ function. The $ function will now check to see if new has been called. If not, it will return a new instance.Exercise 15: Solution
Justin walks through the solution to exercise 15.Exercise 16: Implementing the text() method
The text() method gets or sets the text of an element. This exercise tasks you with implementing your own text() method.Exercise 16: Solution
Justin explains the solution to exercise 16.Exercise 16: Solution, continued
Justin continues his explanation of exercise 16 by finishing the getText() function.Exercise 17: Adding a find() method
Elements have the same query methods as the document object. In this exercise, you will implement a find() method that will return items within the current element.Exercise 17: Solution
Alexis is back to walk through the solution to exercise 17.
Traversing Elements
Exercise 18: Implementing the next() method
In this exercise, you will create a next() method that will traverse elements using nextSibling().Exercise 18: Solution
Alexis walks through the solution to exercise 18.Implementing the prev() method
The prev() method is very similar to the next() method except it goes in the other direction. Alexis implements the prev(), parent(), and children() methods.Refactoring Traversing Code
There are many similarities between the next(), prev(), parent() and children() methods. Alexis demonstrates how to create a makeTraverser() helper method that will simplify the code. He then refactors the existing methods to use makeTraverser().
Attributes & Properties
Implementing the attr() method
The DOM provides an API for getting and setting attributes of elements. Justin demonstrates how to implement a more versatile attr() method.Creating a css() method
Before implementing the css() method, Justin explains how styles are managed in JavaScript. By default style properties appear as empty strings because they must be accessed through the getPropertyValue method.DOM Layout & Positioning
Justin takes a break from JavaScript to talk briefly about how the browser lays out a page. He uses a simple div tag to explain how box-sizing affects vertical and horizontal margin/padding. He also explains some of the DOM layout properties and methods.Adding width() and offset methods
Justin implements a both the width() method and the offset() method. The width() method will return the clientWidth minus the padding. The offset() method will traverse the offsetParents property to calculate the total offset relative to the document.Adding show() and hide() methods
The last methods for Justin to implement are hide() and show(). The will set the display property to “none” and “” respectively.
Events
Event API
The addEventListener method is used to register an event to any DOM element. Conversely, removeEventListener will remove that event handler. Using the console Justin demonstrates how to use these methods.Adding bind() & unbind() methods
Like the addEventListener/removeEventListener methods in JavaScript, jQuery has bind and unbind. Justin demonstrates how to implement these methods. He also walks through the different event types in JavaScript.Event Propogation
There are three phases in event propagation: Capture, Target, and Bubble. Justin demonstrates these event phases and talks about how the order of the propagation can be controlled.Event Delegation
In jQuery, Event Delegation allows you to create one event handler on a parent element that will watch its child elements for an event. This is made possible through event propagation and is much more performant.