Javascript-You Dont Know JS: A book series on JavaScript. @YDKJS on twitter.

You Don't Know JS Yet (book series) - 2nd Edition

This is a series of books diving deep into the core mechanisms of the JavaScript language. This is the second edition of the book series:

     ...

To read more about the motivations and perspective behind this book series, check out the Preface.

If you're looking for the previous first edition books, they can be found here.

Premier Sponsor

This edition of the YDKJS book series is exclusively sponsored by Frontend Masters.

Frontend Masters is the gold standard for top-of-the-line expert training material in frontend-oriented software development. With over 150 courses on all things frontend, this should be your first and only stop for quality video training on HTML, CSS, JS, and related technologies.


I teach all my workshops exclusively through Frontend Masters. If you like this book content, please check out my video training courses.

I want to extend a warm and deep thanks to Marc Grabanski and the entire Frontend Masters team, not only for their excellent work with the video training platform, but for their unwavering support of me and of the "You Don't Know JS" books!


Titles

I recommend reading the second edition books in this order:

If you're looking for the previous first edition books, they can be found here.

Publishing

As always, you'll be able to read these books online here entirely for free.

This edition of the books is being self-published through GetiPub publishing. The published books will be made available for sale through normal book retail sources.

If you'd like to contribute financially towards the effort (or any of my other OSS efforts) aside from purchasing the published books, please consider these options:

Contributions

Please feel free to contribute to the quality of this content by submitting PRs for improvements to code snippets, explanations, etc. While typo fixes are welcomed, they will likely be caught through normal editing/publishing processes, so please don't worry about them right now.

Any contributions you make to this effort are of course greatly appreciated.

But PLEASE read the Contributions Guidelines carefully before submitting a PR.

License & Copyright

The materials herein are all © 2019-2020 Kyle Simpson.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 4.0 Unported License.

Comments

  • Update ch1.md
    Update ch1.md

    Jun 9, 2021

    修复一个错误, 该错误导致部分文字不显示

    Yes, I promise I've read the Contributions Guidelines (please feel free to remove this line).

    Specifically quoting these guidelines regarding typos:

    Typos?

    Please don't worry about minor text typos. These will almost certainly be caught during the editing process.

    If you're going to submit a PR for typo fixes, please be measured in doing so by collecting several small changes into a single PR (in separate commits). Or, just don't even worry about them for now, because we'll get to them later. I promise.


    Please type "I already searched for this issue":

    Edition: (pull requests not accepted for previous editions)

    Book Title:

    Chapter:

    Section Title:

    Topic:

    Reply
  • typo
    typo

    Jul 6, 2021

                                                                                                                                                                                                           
    Reply
  • Can I replace 填充 to prollyfill on ch5 of async & performance, branch 1ed-zh-CN?
    Can I replace 填充 to prollyfill on ch5 of async & performance, branch 1ed-zh-CN?

    Sep 29, 2021

    Hi, Kyle, thank you for you books! I already searched for this issue as nobody mentioned "prollyfill" in issues.

    Edition: 1st

    Book Title: async & performance

    Chapter: 5

    Section Title: SIMD

    Problem:

    I read the paperback version ISBN 9787115431165 and found a typo (or maybe not?), on the note they use prolyfill (shown as the picture below) instead of prollyfill. It might be a little bit off-the-topic but I wonder 1) future Chinese translators might take a glance at issues or 2) other Chinese readers may check and read the 1ed-zh-CN branch, so I made a patch, and here's my thought.

    The community-translated version uses 填补 (polyfill) with quotation marks, which means it's not a real polyfill. Many Chinese readers may have seen polyfill, but prollyfill is rarely used. I think it could be left alone to reduce misunderstandings, at least people may be able to google the word. I also deleted the duplicated adjective 许多.

    footnote-page-294

    Reply
  • The reason for JS being a prototype language?
    The reason for JS being a prototype language?

    Oct 20, 2021

    I already tried to search for this but did not find anything that matched my question. I am reading the second edition of the first book and when I was reading the chapter about polyfills, the following question popped in my head.

    Is JS a prototype based language partially or wholly for the reason to easily support polyfills?

    Looking forward to hearing from you guys what you think.

    Reply
  • let for objects?
    let for objects?

    Oct 21, 2021

    This question relates to chapter 2 of the 2nd edition of the first book.

    I feel like I need a better explanation on this, why should I use let for declaring an object? What makes sense for me is to use const on an object and if I want it to be immutable, I can freeze it.

    It’s ill-advised to use const with object values, because those values can still be changed even though the variable can’t be re-assigned.

    If you stick to using const only with primitive values, you avoid any confusion of re-assignment (not allowed) vs. mutation (allowed)! That’s the safest and best way to use const.

    Reply
  • website for this repo
    website for this repo

    Nov 11, 2021

    Hey @getify, First of all, thank you for doing open-source all the You Don't Know JS book series. I think now we should make a website for the same, It would be great if the markdown files under this repo get converted into HTML pages similar to this site https://btholt.github.io/intro-to-web-dev-v2/ Thank you.

    Reply
  • todo: fix images to support light mode/dark mode
    todo: fix images to support light mode/dark mode

    Nov 30, 2021

    See: https://twitter.com/stefanjudis/status/1465775940034781186?s=20

    Reply
  • Fix sentence
    Fix sentence

    Dec 6, 2021

    Sentence correction Line 678. but allowing -> by allowing.

    Yes, I promise I've read the Contributions Guidelines


    Please type "I already searched for this issue": - I already searched for this isssue.

    Edition: (pull requests not accepted for previous editions) - 2nd

    Book Title: - Get Started 2nd Edition

    Chapter: - 2 - Surveying JS

    Section Title: - How we organize in JS

    Topic: - class inheritance

    Reply
  • fix: closure example
    fix: closure example

    Dec 13, 2021

    Yes, I promise I've read the Contributions Guidelines (please feel free to remove this line).

    Specifically quoting these guidelines regarding typos:

    Typos?

    Please don't worry about minor text typos. These will almost certainly be caught during the editing process.

    If you're going to submit a PR for typo fixes, please be measured in doing so by collecting several small changes into a single PR (in separate commits). Or, just don't even worry about them for now, because we'll get to them later. I promise.


    Please type "I already searched for this issue": I already searched for this issue Edition: (pull requests not accepted for previous editions) 2nd Book Title: Scope & Closures Chapter: apA.md Section Title: var and let Topic: example code

    The example code will cause a SyntaxError: Unexpected token '.' by record.name.

    function getStudents(data) {
        var studentRecords = [];
    
        for (let record of data.records) {
            let id = `student-${ record.id }`;
            studentRecords.push({
                id,
                record.name  // <---- SyntaxError: Unexpected token '.', fixed this line to `name: record.name`
            });
        }
    
        return studentRecords;
    }
    
                 record.name
                      ^
    
    SyntaxError: Unexpected token '.'
        at wrapSafe (internal/modules/cjs/loader.js:1001:16)
        at Module._compile (internal/modules/cjs/loader.js:1049:27)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:12)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        at internal/main/run_main_module.js:17:47
    
    for second edition 
    Reply
  • fix: more complete statement for Map
    fix: more complete statement for Map

    Dec 28, 2021

    Please type "I already searched for this issue": I already searched for this issue Edition: (pull requests not accepted for previous editions) 2-nd edition Book Title: Get Started Chapter: Chapter 3: Digging to the Roots of JS Section Title: Iteration -> Iterables Topic: Fixed statement about Map keys.

    question for second edition 
    Reply
  • Up & going equality 3 simple rules
    Up & going equality 3 simple rules

    Sep 20, 2016

    Hi, I just finish the Up and Going book and now Javascript makes much more sense to me. Thank you.

    However when talking about Equality you give the example of "42" == 42 is true and "42" === 42 is false. So far no issues with it.Understood why how you got there. Few lines below (page 38) you mention the your few simple rules:

    • 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 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 read‐ ability.

    How is "42" == 42 would be safe? The third rule should have better explanation?

    Thank you

    for second edition 
    Reply
  • update zalgo link
    update zalgo link

    Dec 2, 2015

    The link is not anymore valid since that post was removed in new commits

    for second edition 
    Reply
  • Is the open parts of book welcome translate to other language like chinese?
    Is the open parts of book welcome translate to other language like chinese?

    Nov 19, 2013

                                                                                                                                                                                                            foreign language translations 
    Reply
  • "up & going": Ch1 Practice. Purchase is always unaffordable

    May 28, 2015

    Can you improve on the Ch 1 practice? Because despite any changes to the constants in the Ch 1 Practice solution, the purchase is always unaffordable. That is it always comes back with "You can't afford this purchase. :(" I tested this by copy/pasting the very text from the digital book into my console. I did it again and again using different values in the constants for the threshold, prices, bank balance, etc... Always You can't afford this purchase. :("

    for second edition 
    Reply
  • "types & grammar": review - jesseharlin

    Aug 20, 2014

    My review of types and grammar.

    Edit: I'm coming back for a second pass on these first three for proofing, etc.

    Reply
  • "this & object prototypes": cover shadowing properties

    Mar 20, 2014

    Cover:

    1. Setting a shadowed property:

      var o = { a: 2 };
      var f = Object.create( o );
      f.a; // 2 -- accessed via delegation from `f` to `o`
      f.a = 5;
      f.a; // 5 -- created a shadowed property on `f`!
      o.a; // 2 -- still intact
      
    2. Strangely, shadowing cannot be done in the case of a property having been marked as writable:false:

      var o = { };
      Object.defineProperty( o, "a", { value:2, writable:false } );
      var f = Object.create( o );
      f.a; // 2 -- accessed via delegation from `f` to `o`
      f.a = 5;
      f.a; // 2 -- wtf!? didn't let us create a shadowed property on `f`?
      o.a; // 2 -- still intact
      
    3. Also strangely, a getter/setter prevents shadowing too:

      var o = { };
      Object.defineProperty( o, "a", { set: function(){}, get: function(){ return 2; } } );
      var f = Object.create( o );
      f.a; // 2 -- accessed via delegation from `f` to `o`
      f.a = 5;
      f.a; // 2 -- wtf!? didn't let us create a shadowed property on `f`?
      o.a; // 2 -- still intact
      

    To be clear, in cases 2) and 3) above, the [[Set]] algorithm consults the descriptor of the o.a property and actually uses the o.a to attempt the = 5 assignment, which fails for 2) and has no effect for 3). In neither of those cases does shadowed f.a get created.

    But in case 1) above, the descriptor for o.a isn't special, so o.a isn't used at all, and f.a = 5 creates shadowed f.a.

    This WTF inconsistency between 1) and 2)/3) here is what's at issue to me.

    Reply
  • Tech Editors
    Tech Editors

    Jan 8, 2014

    I'm seeking out folks who want to be official tech reviewers for this book series (to work with the editors at O'Reilly). You will review the drafts as posted here and provide technical feedback, also here, which can be addressed as revisions during the editing/production phase.

    You should have a solid understanding of the core parts of JavaScript (not just frameworks). :)

    If you're interested, please leave your contact info in a comment below, and @bmacdonald-oreilly will get in touch with you!

    question help wanted editorial 
    Reply
  • `let` hoisting?
    `let` hoisting?

    Jun 19, 2016

    Hi, thanks for taking the time to write such a great book! I'm working my way through it - in Chapter 3, you talk about hoisting let variables. Specifically:

    However, declarations made with let will not hoist to the entire scope of the block they appear in. Such declarations will not observably "exist" in the block until the declaration statement.

    {
       console.log( bar ); // ReferenceError!
       let bar = 2;
    }
    

    Even though the variable bar isn't initialized as undefined, it seems that they are still created.

    Using the example from this article as an example,

    let x = 'outer scope';
    (function() {
        console.log(x); // Reference error
        let x = 'inner scope';
    }());
    

    Do you think it would be helpful to add a clarification regarding the meaning of "hoisting" (since x here is technically still being created at the top of the block - it's just not initialized and can't be accessed), or perhaps just include a similar example?

    EDIT: removed extra console.log in the example that may have caused confusion

    question 
    Reply
  • "es6 & beyond": ch 7, errors in example code

    Apr 29, 2015

    Symbol.hasInstance requires Object.defineProperty (b/c non-configurable property on Function.prototype):

    Foo[Symbol.hasInstance] = function(inst) {
        return inst.greeting == "hello";
    };
    

    Needs to be:

    Object.defineProperty(Foo, Symbol.hasInstance, {
      value: function (inst) {
        return inst.greeting == "hello";
      },
      configurable: true
    });
    

    The additive operator calls ToPrimitive without a hint, that means the hint argument for Symbol.toPrimitive is "default":

    arr[Symbol.toPrimitive] = function(hint) {
        if (hint == "number") {
            // sum all numbers
            return this.reduce( function(acc,curr){
                return acc + curr;
            }, 0 );
        }
    };
    

    Needs to be:

    arr[Symbol.toPrimitive] = function(hint) {
        if (hint == "number" || hint == "default") {
            // sum all numbers
            return this.reduce( function(acc,curr){
                return acc + curr;
            }, 0 );
        }
    };
    

    true and false need to be switched for the Symbol.unscopables example.

    o[Symbol.unscopables] = {
        a: true,
        b: false,
        c: true
    };
    

    =>

    o[Symbol.unscopables] = {
        a: false,
        b: true,
        c: false
    };
    
    Some of the functions will look familiar as functions of the same names on Object:
        ...
        Reflect.ownKeys(..) --> Object.getOwnPropertyNames(..)
    

    Not quite correct, Reflect.ownKeys(..) returns the union of Object.getOwnPropertyNames(..) and Object.getOwnPropertySymbols(..).

    Also, Reflect.has(..) corresponds to the Object.prototype.hasOwnProperty(..) method. Essentially, Reflect.has(o,"foo") performs o.hasOwnProperty("foo").
    

    Wrong, Reflect.has(object, key) performs key in object.

    You can enumerate an object's values, essentially identical to consuming its @@iterator with ... or for..of, with Reflect.enumerate(..). For example, Reflect.enumerate([1,2,3]) would consume the iterator of the array, and return the received values as another [1,2,3] array.
    

    Wrong, Reflect.enumerate(..) returns the enumerable properties (including prototype properties) like for..in, e.g. [...Reflect.enumerate([1,2,3])] returns [ "0", "1", "2" ].

    And in "Tail Call Optimization (TCO)" it should be noted that tail calls are only valid in strict mode code. Maybe also add "use strict"; to the examples?

    editorial 
    Reply
  • "types & grammar": review - vball525

    Aug 10, 2014

    For reference I am testing using JSFiddle with Chrome 36, Firefox 30, and IE 11.

    Chapter 1 - Looks real good and all examples worked. Chapter 2

    • Strings Section
      • In the first example "b !== d;" is returning True instead of False as stated. All 3 browsers. try { var a = "foo"; var b = ["f","o","o"]; document.write(a.length); document.write(' '); // 3 document.write(b.length); document.write(' '); // 3 document.write(a.indexOf( "o" )); document.write(' '); // 1 document.write(b.indexOf( "o" )); document.write(' '); // 1 var c = a.concat( "bar" ); // "foobar" var d = b.concat( ["b","a","r"] ); // ["f","o","o","b","a","r"] document.write(c); document.write(' '); document.write(d); document.write(' '); document.write(a === c); document.write(' '); // false document.write(b !== d); document.write(' '); // false document.write(a); document.write(' '); // "foo" document.write(b); document.write(' '); // ["f","o","o"] } catch(ex) { alert(ex); }
    Reply