CodeNewbie Community 🌱

Cover image for From Front Desk to Front End p.40 Three Pillars of JS
Tauri StClaire
Tauri StClaire

Posted on • Updated on

From Front Desk to Front End p.40 Three Pillars of JS

Cover photo by Andre William on Pexels

Hi, I'm Tauri!

I am a Front End Developer and a student (and enrollment counselor) with Skillcrush, the online coding and design school with a heart! I am open for employment with a company, and working on adding to my skillset every day! This blog is chronicling my most recent projects, so thank you for reading!

This past month, I've been continuing to study You Don't Know JavaScript by Kyle Simpson, using the course by Frontend Masters on the Three Pillars of JavaScript which goes over his first book Up&Going. It's honestly been a DOOZY and I needed to take a foray into studying the this keyword more before I could even begin to grasp what he was saying on that topic! To explore this more, I studied the notes by Wes Bos on Prototypes, this, new and Inheritance and by reading over and over again, practicing, and taking notes in a Github Repo, I began to grasp the basics.
Once I got through it, I did the exercise at the end of the course to practice the three pillars, but honestly I need to practice this exercise and others involving this stuff a LOT more. FOREVER. (joking, but not).

In very exciting news, I have started my first Chingu Voyage!! They are an AMAZING organization that gives the opportunity to get real "SCRUM"y team experience, and I would highly recommend them to any budding developers and designers!
I went from being VERY nervous about this voyage to SUPER STOKED! I have an amazing team of all women, all devs (I'm doubling as the Product Owner as well, and me and another dev are doubling ad Designers too bc we're super cool like that 😎), and we are working on a Recipe App! As someone who loves to cook, this is something I've always wanted to make for myself so I'm so excited to get it started in this setting!

So regarding this past month, checkout my Three Pillars of JavaScript notes, and I'll see you at the beginning of next month with a new team built app in hand!

Into JavaScript

and review class components in the Skillcrush React class under "Updating UIs with Stateful Components"

Intro to the 3 Pillars of JavaScript

  1. Types/Coercion
  2. Scopes/Closures
  3. this/Protypes

Types/Coercion

Types:

  1. Primitive Types
  2. Converting Types
  3. Checking Equality

Primitive Types:

  • Objects (non primitive data type)
    • Properties can either be accessed with dot notation (i.e., obj.a) or bracket notation (i.e., obj["a"]). Dot notation is shorter and generally easier to read
    • Bracket notation is useful if you have a property name that has special characters in it, like obj["hello world!"] – such properties are often referred to as keys when accessed via bracket notation. The [ ] notation requires either a variable (explained next) or a string literal (which needs to be wrapped in " .. " or ' .. ').
    • Of course, bracket notation is also useful if you want to access a property/key but the name is stored in another variable, such as:
    var obj = {
    a: "hello world",
    b: 42
};
    var b = "a";

    obj[b];         // "hello world"
    obj["b"];       // 42
Enter fullscreen mode Exit fullscreen mode
  • Retrieving values from the properties of objects:
var obj = {
    a: "hello world",
    b: 42,
    c: true
};

obj.a;      // "hello world"
obj.b;      // 42
obj.c;      // true

obj["a"];   // "hello world"
obj["b"];   // 42
obj["c"];   // true
Enter fullscreen mode Exit fullscreen mode
  • Methods used on properties of objects and subtypes of objects (arrays and functions):
var a = "hello world";
var b = 3.14159;

a.length;               // 11
a.toUpperCase();        // "HELLO WORLD"
b.toFixed(4);
Enter fullscreen mode Exit fullscreen mode
  • Symbol is a brand new primitive data type added several years ago
    • v = Symbol() and typeof v; would return "symbol"
    • "Symbols are often used to add unique property keys to an object that won't collide with keys any other code might add to the object" MDN docs on Symbol
  • Undefined is an empty type
    • A variable that has never been declared (also: undeclared)
    • A variable that has been declared but has no value
  • Null be behaves strangely depending on the operator applied,
    • Example: var v = null; typeof v; returns "object"
  • v = function(){}; and typof v; returns "function" where function isn't really a primitive data type, but this is useful bc it lets us know we have a VALUE that can be called as a function
  • NaN comes up if you try to apply a mathematical operator to a string, it signifies the invalid use of a mathematical operator more than it indicates that a particular value is "not a number"
    • ex:
var greeting= "Hello, class!"
var something = greeting / 2;
something; //NaN
Number.isNaN (something); //true
Number.isNaN(greeting); // false
Enter fullscreen mode Exit fullscreen mode
  • new keyword (very relevant for the discussion on inheritance or closure and to prototypes. This keyword is used with a constructor function to create an object with a proto property that can be used to add functions to the prototype of the object. Code Burst does a great job of breaking this down)
    • Use for these inbuilt objects:
      • Object()
      • ex:
var yesterday = new Date("March 6, 2019");
yesterday.toUTCString(); //"Wed, 06 Mar 2019 06:00:00 GMT"
Enter fullscreen mode Exit fullscreen mode
  • Array()
  • Function()
  • Date()
  • RegExp()
  • Error()
    • Not for these because if we call it with new it'll change the value of the type bc these built in objects are for type coercion:
      • String()
      • Number()
      • Boolean()
  • Truthy and Falsy - if we tried to convert a value to a Boolean would it return as true or false?
    • Falsy
      • "" Empty string
      • 0 and -0
      • null
      • NaN
      • false
      • undefined
    • Truthy
      • "foo" (string)
      • 23 (number)
      • {a:1} (object)
      • 1,3
      • true
      • function(){}
      • Everything else NOT falsy
  • Coercion Best Practices:
    • "If a feature is sometimes useful and sometimes dangerous and if there is a better option then always use the better option" -- "JS The Good Parts", Crockford
    • Interpretation comes in when defining what useful, dangerous, or better
    • Useful - when the read is focused on what's important
    • Dangerous - when the reader can't tell what will happen
    • Better - when the reader understands the code
  • Equality
    • == - allows for coercion
    • === - does not allow for coercion, can only be used when types are the same
    • In an instance where you are comparing "42" and 42 with ==, the "42" is coerced into 42.
    • <, >, <=, and >= are used for inequality and follow similar rules to == because there are no "strict inequality" operators
    • To decide which one to use, identify what types of data are being used and compared - If you can be certain about the values, and == is safe, use it! If you can’t be certain about the values, use ===. It’s that simple.
    • == should be about comparisons of KNOWN types (most ideally, don't let your types be unknown) and optionally where conversions are helpful
    • (From the Book):
      • If either value (aka side) in a comparison could be the true or false value, avoid == and use ===.
      • If either value in a comparison could be one of these specific values (0"", or [] – empty array), avoid == and use ===.
      • In all other cases, you’re safe to use ==. Not only is it safe, but in many cases it simplifies your code in a way that improves readability. ### Scope/Closure
  • if a variable is undeclared, then just referenced within a function, JS will automatically declare that variable in the global scope. As in this example:
var teacher = "Kyle";

function otherClass() {
    teacher = "Suzy";
    topic = "React";
    console.log("Welcome!");
}

otherClass(); // Welcome!
teacher; //Suzy
topic //React
Enter fullscreen mode Exit fullscreen mode
  • Undefined vs undeclared (emptiness)
    • undefined has been declared but doesn't have a value
    • Undeclared has never been declared
  • This function is assigned to a variable, but has not been given its own name so it is an "anonymous" function expression
var clickHandler = function() {
...
};
Enter fullscreen mode Exit fullscreen mode
  • This function is assigned to a variable AND is a named function expression
var keyHandler = function keyHandler () {
...
};
Enter fullscreen mode Exit fullscreen mode
  • Naming your function clearly allows you to understand exactly what a function is doing if it's named descriptively.

    • In this function, you can infer that the id property is being extracted from the person object
    var ids = people.map(person => person.id);
    
    • But the name of this function when applied makes it explicitly clear
    var ids = people.map(function getId(person) {
        return person.id;
    });
    
    • Another example from a "promise chain":
    getPerson()
    - then(person => getData(person.id))
    - then(renderData);
    
    • Is not as descriptive as:
    getPerson()
    - then (function getDataFrom(person) {
        return (getData(person.id);
    })
    - then(renderData);
    
  • IIFE ("iffys") = immediately invoked function expressions

    • They have a (); to immediately invoke the expression
    • This allows us to encapsulate the scope by wrapping a function around it so it doesn't affect outside scoped code
    • the set of parentheses wrapping around the function allow it to be a function expression and not a declaration. The parentheses at the end is the part that immediately invokes/executes the function
    • An example:
    var teacher = "Kyle";
    ( function anotherTeacher() {
        var teacher = "Suzy";
        console.log(teacher); //Suzy
    } ) ();
    
    console.log(teacher); //Kyle
    
  • Block scoping achieves the same thing. Let and a curly brace block will keep the block scoped

var teacher = "Kyle";
{
    let teacher = "Suzy";
    console.log(teacer); // Suzy
}

console.log(teacher); // Kyle
Enter fullscreen mode Exit fullscreen mode
  • Closure
    • when a function "remembers" the variables outside of it, even if you pass that function elsewhere
    • Example from the book:
function makeAdder(x) {
    // parameter 'x' is an inner variable

    //inner function 'add()' uses 'x', so it has "closure" over it
    function add(y) {
        return y + x;
    };

    return add;
}
Enter fullscreen mode Exit fullscreen mode
  • The reference to the inner add(..) function that gets returned with each call to the outer makeAdder(..) is able to remember whatever x value was passed in to makeAdder(..). Now, let’s use makeAdder(..)
var plusOne = makeAdder( 1 );

var plusTen = makeAdder ( 10 );

plusOne ( 3 ); // 4 <-- 1 + 3
plusOne ( 41 ); // 42 <-- 1 + 41

plusTen ( 13 ); // 23 <-- 10 + 13
Enter fullscreen mode Exit fullscreen mode
  1. When we call makeAdder(1), we get back a reference to its inner add(..) that remembers x as 1. We call this function reference plusOne(..).
  2. When we call makeAdder(10), we get back another reference to its inner add(..) that remembers x as 10. We call this function reference plusTen(..).
  3. When we call plusOne(3), it adds 3 (its inner y) to the 1 (remembered by x), and we get 4 as the result.
  4. When we call plusTen(13), it adds 13 (its inner y) to the 10 (remembered by x), and we get 23 as the result.
  5. we can observe closure when a function is treated as a value, like when it's called in a callback function, or returned elsewhere, or returned and treated as a prop where we pass the object around
function ask(question) {
    reutn function holdYourQuestion(){
        console.log(question);
    };
}

var myQuestion = ask("What is closure?");

myQuestion(); //What is closure?
Enter fullscreen mode Exit fullscreen mode

###this / Prototypes

  • a function's this , which is an "identifier" references the execution context for that call, determined entirely by how the function was called.
    • Reference the code in the js-playground repo under new-this for a code example of this
  • a this-aware function can thus have a different context each time it's called, which makes it more flexible and reusable. Kyle refers to it as "dynamic context"
    • Implicit binding
      • In this example, workshop.ask is implicitly binding "workshop" as the this keyword
var workshop = {
    teacher: "Kyle",
    ask(question) {
        console.log(this.teacher, question);
    },
};

workshop.ask("What is implicit binding?");
// Kyle What is implicit binding?
Enter fullscreen mode Exit fullscreen mode
  • Explicit binding
  • In this example, myContext is bound to be the this keyword. The ask function is called with .call and handed myContext to be the this keyword
function ask(question) {
    console.log(this.teacher, question);
}

function otherClass() {
    var myContext = {
        teacher: "Suzy"
    };
    ask.call(myContext, "Why?"); //Suzy Why?
}

otherClass();
Enter fullscreen mode Exit fullscreen mode
  • prototypes are what the class {} keyword is built on top of
  • the class {} keyword simplifies the prototype system, but using prototypes allows us to see what's going on under the covers for class {}
  • In this example, there is no ask method on deepJS or reactJS but it refers to the ask method on the prototype and deepJS and reactJS are handing the object that the this keyword will point to in the new instances of Workshop
function Workshop(teacher) {
    this.teacher = teacher;
}
Workshop.prototype.ask = function(question) {
    console.log(this.teacher, question);
};

var deepJS = new Workshop ("Kyle");
var reactJS = new Workshop("Suzy");

deepJS.ask("Is 'prototype' a class?")
//Kyle Is 'prototype' a class?

reactJS.ask("Isn't 'prototype' ugly?");
//Suzy Isn't 'prototype' ugly?
Enter fullscreen mode Exit fullscreen mode
  • When using the class {} keyword instead, we can do the same thing of creating and referencing to prototypes but while using cleaner syntax:
class Workshop {
    constructor(teacher) {
        this.teacher = teacher;
    }
    ask(question) {
    console.log(this.teacher, question);
    }
}

var deepJS = new Workshop("Kyle");
var reactJS = new Workshop("Suzy");

deepJS.ask("Is 'class' a class?");
// Kyle Is 'class' a class?

reactJS.ask("Is this class OK?");
// Suzy Is this class OK?
Enter fullscreen mode Exit fullscreen mode

Top comments (0)