Reading: YDKJSY 1 - Getting Start draft

Last modified 1 months ago / Edit on Github
Warning
This is a draft, the content is not complete and of poor quality!

Note: This note is for those who have already read the book. The book is really compact, this note cannot replace it (and I do not want to). The book is not short, neither is this note!

πŸ‘‰ My github repository.
πŸ‘‰ Other notes in this book series.

Infor & Preface

  • Full name: You Don't Know JS Yet (2nd edition)
  • Author: Kyle Simpson
  • getify/You-Dont-Know-JS on Github
  • It's not just for starters, but for all developers who want to understand deeper.
  • "The primary point of the title β€œYou Don’t Know JS Yet” is to point out that most JS developers don’t take the time to really understand how the code that they write works."
  • "My suggestion is you take your time going through YDKJSY. Take one chapter, read it completely through start to finish, and then go back and re-read it section by section. Stop in between each section, and practice the code or ideas from that section. For larger concepts, it probably is a good idea to expect to spend several days digesting, re-reading, practicing, then digesting some more."

Chap 1 β€” What is JS?

What's With That Name?

  • Not related with Java at all, not just a script but a programming language.
  • "Java" β†’ attract mostlty Java programmers, "Script" β†’ lighweight.
  • Official name specified by TC39 as "ECMAScript" (ES).
  • JS in browsers or Node.js is an implementation of ES2019 standard.
  • Hosted by ECMA.
  • Don't use "JS6" or "ES8", use "ES20xx" or "JS".

Language Specification

  • Who decides a new version of JS? β†’ TC39 (~50-100 members) by votes via 5 stages.
  • There is just one JS in the wild (not multiple versions).
  • Environments run JS: browsers, servers, robots, lightbulbs,....
  • Not all are JS, eg. alert("Hello, JS!") or console.log() ← they're just APIs of JS environments.
    • There are many "JS-looking" APIs: fetch(), getCurrentLocation(), getUserMedia(),...
    • They follow JS rules but just "guests", not official JS specifications.
  • Complain "JS is so inconsistent!" ← it's because the environment hehaviors work, not because of JS itself!
  • Developer Tools (Inspect Element in Chrome, for example) are... tools for developers. They're NOT JS environment!
    • Something works in Dev Tool, doesn't mean JS compiler will understand it.

Many Faces

  • Paradigm-level code categories
    • Procedural: organizes codes in a top-down, linear progression. ← eg. C
    • Object-oriented (OO/classes): organizes codes into classes. ← eg. Java/C++
    • Functional (FP): organizes codes into functions. ← eg. Haskell
    • JS is a multi-paradigm language. => "meaning the syntax and capabilities allow a developer to mix and match (and bend and reshape!) concepts from various major paradigms"

Backwards & Forwards

  • Backwards compatibility:

    • Code from the past should still work today β€” "we don't break the web" (TC39)
    • Idea: JS developer can write code with confidence β†’ their code won't stop working in new released versions.
    • Once it’s in JS, it can’t be taken out because it might break programs, even if we’d
      really, really like to remove it!
  • Forward compatibility:

    • Code from future don't break the web today. ← tip to remember "forward"
    • CSS & HTML is forward, not backward!
    • Codes from the past may not work / work the same today.
    • Feature from 2019 in a browser 2010 => page isn't broken! Unrecognized things will be skipped!
  • JS is backwards compatibility + not forward compability

    • Codes written today, will work in future JS engines.
    • Codes written today may be broken in old JS engines.
  • Why?

    • "Markup" (HTML) / "Styling" (CSS) languages => easier to "skip over".
    • "Programming language" (JS) => cannot skip something it doesn't understand (the rest may be effected!)
  • Fill the gaps?

    • JS has "forward-compability problems" (FC) (not compatible with old engines)

    • How today codes can be used in an old engine? => use transpiling (using a tool to convert a source code of a program from one form to another)

    • FC problems related syntax => use a transpiler (eg. Babel) -- convert "new" JS syntax to "older" syntax.

      // New
      if (something) {
      let x = 3; // "let" was added in ES6 (2015)
      console.log(x);
      } else {
      let x = 4; // "let" => block scope
      console.log(x);
      }
      // Old
      var x$0, x$1; // different variables
      if (something) {
      x$0 = 3; // diferent variables
      console.log(x$0);
      } else {
      x$1 = 4;
      console.log(x$1);
      }
    • "It’s strongly recommended that developers use the latest version of JS so that their code is clean and communicates its ideas most effectively." <= Let the tools take care of converting.

    • FC problems related to missing API method => use polyfill (aka "shim"). <= Normally, a transpiler like Babel will detect and add it automatically.

      // NEW: .finally() <= ES2019
      // getSomeRecords() returns us a promise for some // data it will fetch
      var pr = getSomeRecords();
      // show the UI spinner while we get the data
      startSpinner();
      pr.then(renderRecords) // render if successful
      .catch(showError) // show an error if not
      .finally(hideSpinner) // always hide the spinner
      // OLD:
      if (!Promise.prototype.finally) { // prevents running on engine alrady has this API
      Promise.prototype.finally = function f(fn){ // define new for old engines
      return this.then(
      function t(v){
      return Promise.resolve( fn() )
      .then(function t(){
      return v; });
      }, function c(e){}
      );
      };
      }

What's in an Interpretation?

img
Source.

  • To clearify JS is interpreted or compiled => see how errors are handled.

  • Historically, scripted/interpreted languages were executed a top-down, line-by-line

    image-20211030214022778
    Interpreted./Scripted Execution. Lines 1-4 must be executed before finding an error in line 5.

  • Parsing whole process before any execution,

    image-20211030214228849
    Parsing + Compilation + Execution. An error in line 5 would be caught in parsing phase before any execution.

  • "Parsed" language 🀝 "compiled" language: All compiled are parsed.

  • JS code is parsed before it's executed. => "early errors" => JS is a parsed language

  • JS is closer to compiled than interpreted (but not clearly a compiled or clearly a interpreted) => "meaning the tools (including the JS engine) process and verify a program (reporting any errors!) before it executes."

  • Flow of a JS source program:

    image-20211030215050566
    Parsing, Compiling, and Executing JS.

    1. Program leaves IDE => transpiled by Babel => packed by Webpack => ... => form1 => delivered to a JS engine.
    2. JS engine parses the code to an AST (Abstract Syntax Tree) <= subsequent execution: form1 > AST > executable form.
    3. Engine convert that AST to a kind-of byte code => then to JIT (just in time) compiler.
    4. JS VM executes the program.
  • Web Assembly (WASM) => augments what the web (including JS) can accomplish.

    • 2013, "ASM.js" (a subset of JS lang, transpiled from C) was introduced (by Mozilla) to demonstrate the performance of JS engine where it can run an Unreal 3 game at full 60fps. => ASM.js is just a transpiled language (not for coding).
    • After ASM.js > another group (also Mozilla's) released Web Assembly (WASM) <= provide a path for non-JS program (like C) to be converted to a form that could run in the JS engine.
      • WASM's format is entirely unlike JS => skipping the parsing/compilation JS engine normally does
      • codes => WASM parsing/compilation => binary packed (easier for JS engine to understand) > JS engine execute them.
      • Ex: Go program has threaded programming => WASM convert it => JS engine can understand (JS no need to have something like threads feature)
      • πŸ’‘TC39 aren't stressed to add more features (from other "component" languages) => just keep their rules, WASM will make the bridge.
    • WASM isn't only for the web, also isn't JS.

Strictly Speaking

  • ES5 (2009) => "strict mode" => encourage better JS programs.

  • Why?

    • Not a restriction but rather a "guide" so that JS engine can optimize and effectciently run the code.
    • Prevent some "stupid" coding ways when working in group, for example.
  • In form of "early errors" => ex: disallows naming 2 function parameters the same.

  • Some examples

    // only whitespace and comments are allowed
    // before the use-strict pragma
    "use strict";
    // the rest of the file runs in strict mode
    // Per function scope
    // Used when you wanna convert non-strict to strict programs
    function someOperations() {
    // whitespace and comments are fine here "use strict";
    // all this code will run in strict mode
    }
  • Cannot be default => otherwise, it will break "backward compatibility" rule.

  • Virtually, all transpiled codes (codes in production) ends up in strict mode.

Chap 2 β€” Surveying JS

  • The best way to learn JS is to start writing JS.
  • Goal: get a better feel for it, so that we can move forward writing our own programs with more confidence.

Each File is a Program

  • In JS, each standalone file is its own separate program. <= for error handling.
  • How multiple files talk together? => Only way: sharing their state + use "global scope".
  • ES6 => module (also a file-based) <= files are imported to module and be considered as a single module.
    • JS does still treat each module separately
  • A JS file: either standardlone or module.

Value

  • Values come in 2 forms in JS: primitive and object

  • Primitive: string, number, boolean, undefined, null, symbol

    • literals: string, number, boolean

      • string literals, eg: const name = "Thi." <= Using "" or '' is optional but should pick one and to use it consistently throughout the program.

        // Also can use backtick ``
        console.log("My name is ${name}.") // My name is ${name}.
        console.log(`My name is ${name}.`) // My name is Thi.

        This is called interpolation

      • number, eg. 3.14 or Math.PI

      • boolean: true, false.

    • The "emptiness": undefined, null (they're not the same) => it’s safest and best to use only undefined as the single empty value

    • symbol, eg. const a = Symbol("meaning of life") <= Symbols are mostly used in low-level code such as in libraries and frameworks.

  • Fact: JS array indices are 0-based (eg. a[0])

  • Arrays:

    names = ["France", 1, null]
    names.length // 3
    names[0] // France
    typeof names // "object" <= yep!

    // array can contains a function
    const func = () => true;
    arr = [func, 1]
    typeof func // "function"
  • Objects: an unordered, keyed collection of any various values

    name = {
    first: "Thi",
    last: "Dinh",
    age: 30,
    specialties: [ "JS", "Drawing" ]
    };
    console.log(`My name is ${ name.first }.`); // My name is Thi.
  • Value Type Determination:

    typeof 42;									// "number"
    typeof "abc"; // "string"
    typeof true; // "boolean"
    typeof undefined; // "undefined"
    typeof null; // "object" <= yep!
    typeof { "a": 1 }; // "object"
    typeof [1,2,3]; // "object" <= yep!
    typeof function hello(){}; // "function"

Declaring and Using Variables

  • var vs let

    var adult = true;
    if (adule) {
    var name = "Thi"; // <= "var" says "this variable will be seen by a wider scope"
    let age = 30; // <= "let" limit access to "block scope"
    }
    console.log(name) // Thi
    console.log(age) // Error!

    Note: var should be avoided in favor of let (or const) => prevent confusing in scoping behaviors.

  • let vs const <= must give const an initial value and cannot re-assign.

    const somethingToBeAssignedLater; // Error!
    const myBirthday = true;
    let age;
    age = 30;
    if (myBirthday) {
    age=age+1; //OK!
    myBirthday = false; // Error!
    }
  • However,

    const odds = [1, 3, 5];
    odds[1] = 7; // OK :(
    odds = []; // Error!
  • πŸ’‘ Use const when you need a meaningful variable like myBirthDay instead of just true . Also, with primitive values, const helps avoid confusion due to reassignment problems.

Functions

  • In JS, the word "functions" takes a broader meaning of "procedure" -- a collection of statements can be invoked many times.

  • Different types,

    // Function declaration <= appear as a statement by itself
    function functionName(coolThings) {
    // ...
    return returnedValue;
    }
    // Association between "functionName" and "returnedValue" happens during
    // the compile phase, before the code is executed.
    // Function as an expression
    // Could be "let", "var"
    const functionName = function(coolThings) {
    // ...
    return returnedValue;
    }
    // (Diff from func declaration) Function expression is not associated with
    // its identifier until that statement during runtime.
  • Function are values that can be assigned and passed as an argument. It's a special type of object.

  • Functions can be assigned as properties of objects

    var whatToSay = {
    greeting() { console.log("Hello!"); },
    question() { console.log("What's your name?"); },
    answer() { console.log("My name is Kyle."); }
    };
    whatToSay.greeting(); // Hello!
  • Appendix A -- So many function forms

    • Named function expression

      // Could be "let" or "var"
      const awesomeFunc = function someName(arg) {
      // ...
      return amzingStuff;
      }
      awesomeFunc.name; // "someName"
      // "awesomeFunc" and "someName" are only linked at the runtime
      // πŸ‘Œ They should have the same name!
    • Should a function have a name? => "In my opinion [Kyle's], if a function exists in your program, it has a purpose; otherwise, take it out! And if it has a purpose, it has a natural name that describes that purpose."

    • Some more forms (early 2020, maybe more)

      // generator function declaration
      function *two() { .. }

      // async function declaration
      async function three() { .. }

      // async generator function declaration
      async function *four() { .. }

      // named function export declaration (ES6 modules)
      export function five() { .. }
      // IIFE
      (function(){ .. })();
      (function namedIIFE(){ .. })();

      // asynchronous IIFE
      (async function(){ .. })();
      (async function namedAIIFE(){ .. })();
    • Arrow function expression

      var f;
      f = () => 42;
      f = x => x * 2;
      f = (x) => x * 2;
      f = (x,y) => x * y;
      f = x => ({ x: x * 2 });
      f = x => { return x * 2; };
      f = async x => {
      var y = await doSomethingAsync(x);
      return y * 2;
      };
      someOperation( x => x * 2 );
      • "Since I don’t think anonymous functions are a good idea to use frequently in your programs, I’m not a fan of using the => arrow function form."
    • As methods in classes

      class SomethingKindaGreat {
      // class methods
      coolMethod() { .. } // no commas!
      boringMethod() { .. }
      }
      var EntirelyDifferent = {
      // object methods
      coolMethod() { .. }, // commas!
      boringMethod() { .. },
      // (anonymous) function expression property
      oldSchool: function() { .. }
      };

Comparisons

Chap 3 β€” Digging to the roots of JS

Chap 4 β€” The bigger picture

Appendix A β€” Exploring further

Appendix B β€” Practice, practice, practice!