.jpeg

Modern JavaScript for the Impatient

Bug Report Page

Section 1.13
In the Caution note, change {} - 1 and 1 - {} to {{} - 1} and {1 - {}}. (Newer versions of Node.js changed the parsing rules, so that {} is not a block unless there is evidence for a block context, such as the added braces or a semicolon.)
Exercise 1.3
Change “if n is a negative integer” to “if n is a negative odd integer”
Section 2.10.3
Change “The order in which the keys are traversed depends on the implementation, so you should not rely on it.” to “In modern JavaScript, the order of iteration is well-defined. First come non-negative integer keys '0', '1', '2', and so on in increasing order. They are followed by the remaining keys, in the order of insertion.”
Section 2.10.3
In the last Caution, change for (const i of greeting) to for (const i in greeting)
Exercise 2.7
Change
for (i in arr) { if (i + 1 === 10) console.log(a[i]) } 
to
for (const i in arr) { if (i + 1 === 10) console.log(arr[i]) } 
Exercise 2.15
Change
for (let i = 0; i < a.length - b.length; i++)
to
for (let i = 0; i <= a.length - b.length; i++)
Section 3.9
Add ; n++ after the second sum += value
Section 4.2
Change “You can read and write the [[Property]] internal slot” to You can read and write the [[Prototype]] internal slot
Section 4.3
Change “Do not return any result from a constructor function. Otherwise the value of the new expression is that returned value, not the newly created object.” to “Do not return any object from a constructor function. Otherwise the value of the new expression is that returned object, not the newly created object.”
Section 4.4
In the first note, change “However, if it does, it is ignored, and the new expression still returns the newly created object.” to “If the constructor returns an object, it becomes the value of the new expression. Otherwise, the return value is ignored and the new expression yields the constructed object.”
Exercise 4.12
Change
button.addEventListener('click', function () {
  this.classList.toggle('clicked')
})
to
button.addEventListener('click', event =>  {
  this.classList.toggle('clicked')
})

You may wonder (as some eagle-eyed readers did) why the original code worked. Shouldn't this be undefined in a nested function? Yes, but the addEventListener method goes through a heroic effort to set this when it is passed a function.

Section 5.2
Change
x.toExponential(4) // '1.667e-3'
to
x.toExponential(4) // '1.6667e-3'
Section 5.4 Table 5-1
Change 0.001666 to 0.00166666, '1.667e-3' to '1.6667e-3', and “The range of all floating-point numbers” to The range of all positive floating-point numbers
Section 5.5 Table 5-2
Remove the . . . after the first values
Section 5.9
Change “Note that the time zone (but not the weekday or month name) appears in the user’s locale.” to “Note that the user's time zone (but not the weekday or month name) appears in the user’s locale. For some time zones, the date is July 21.” Change
moonlanding.toLocaleDateString() // '20.7.1969' if the locale is German
moonlanding.toLocaleDateString('en-US') // '7/20/1969'
to
moonlanding.toLocaleDateString() // '20.7.1969' with German locale and time zone
moonlanding.toLocaleDateString('en-US') // '7/20/1969' or '7/21/1969', depending on the time zone
Section 6.1 Caution
Add a ! to the string, i.e. 'Hi 🌐!'.codePointAt(i)
Section 6.3
Change
const phrase = 'à coté de'
const prefix = 'https://www.linguee.fr/anglais-francais/traduction'
const suffix = '.html'
const url = prefix + encodeURIComponent(phrase) + suffix
to
const phrase = 'à côté de'
const prefix = 'https://www.linguee.fr/anglais-francais/search?query='
const url = prefix + encodeURIComponent(phrase)
and '%C3%A0%20cot%C3%A9%20de' to '%C3%A0%20c%C3%B4t%C3%A9%20de'
Section 6.5
Remove the following three lines:

\${\nu\upsilon{
including three backslashes. The second string has two characters:
}}

Section 6.14
Change
let hours = '10:30 - 12:00'.match(/[0-9]+(?=:)/g) // ['10, 12']
to
let hours = '10:30 - 12:00'.match(/[0-9]+(?=:)/g) // ['10', '12'] 
and
let minutes = '10:30 - 12:00'.match(/[0-9][0-9](?!:)/g) // ['10, 12']
to
let minutes = '10:30 - 12:00'.match(/[0-9][0-9](?!:)/g) // ['30', '00']
Section 7.2
Change // someNumbers.length is 4 to // someNames.length is 4
Section 7.4 Table 7.1
In the entry for pop(), shift(), change “Removes and returns the last element” to Removes and returns the last or first element
Section 7.4 Table 7-1
Change firstIndex/lastIndex to indexOf/lastIndexOf
Section 7.10
Change map.forEach((key, value) => { to map.forEach((value, key) => {
Section 7.13
Change
const iarr = new Int32Array(1024)
to
const iarr = new Int16Array(1024)
and “Since 40000 is too large to fit in the range of 32-bit integers, the last 32 bits are taken” to “Since 40000 is too large to fit in the range of 16-bit integers, the last 16 bits are taken”
Section 7.13
Change
const farr = Float32Array.of(1, 0.5, 0.25, 0.125, 0.0625, 0.03215, 0.015625) 
to
const farr = Float32Array.of(1, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625)
Section 8.2
Change “// Yields the string '31.12.1999 23:59:00'” to “// Yields the string '31.12.1999, 23:59:00'
Section 8.3
Change 123,456.78 to 123.456,78 (2x) and switch value: '.' and value: ','
Section 8.8
Change the last Note to:

The Intl.Locale class provides a way for denoting a locale with certain options:

const usMilitaryTime = new Intl.Locale('en-US', { hourCycle: 'h23' })

Supported options are: language, script, region, calendar, collation, hourCycle, caseFirst, numeric, numberingSystem.

Section 9.1
Change “You never have to worry about mut or deadlocks” to “You never have to worry about race conditions or deadlocks”
Section 9.6
Change “The finally method invokes a handler whether or not a promise has settled.” to “The finally method invokes a handler whether or not a promise has been fulfilled. ”
Section 9.9
Change for (url of urls) to for (const url of urls) (2x)
Section 9.11
In the third code sample, remove Promise.all:
const [img1, img2] = [await loadImage(url), await loadCatImage()]
Section 10.6
In the exported anonymous class, change encrypt(key) and decrypt(key) to encrypt(str) and decrypt(str)
Section 11.10
Change “Every function that is an instance of the class Function” to “Every function that is defined with the function keyword”
Section 12.1
Change Symbol.iterable to Symbol.iterator
Section 12.3
Change
  for (line of lines(filename)) {
    if (line.contains(target)) { 
to
  for (const line of lines(filename)) {
    if (line.includes(target)) { 
Section 12.6
In the last code snippet, change
accum.throw() // Returns { value: 0, done; false }
to
accum.throw() // Returns { value: 0, done: false }
Section 13.6
Change
const more = (values: number[] | string[]) => {
  if (array.length > 0 && typeof x[0] === 'number') // Error—not a valid type guard
    return values.map(x => x + 1) 
  else
    return values.map(x => x + x)
}
to
const more = (values: number[] | string[]) => {
  if (values.length > 0 && typeof values[0] === 'number') // Error—not a valid type guard
    return values.map(x => x + 1) 
  else
    return values.map(x => x + x)
}
Section 13.12.2
In the last two code snippets, move the => to the preceding line:
                    . . .: string }) =>
    leftDelimiter + . . .
Section 13.12.3
Change “This assignment is sound because pf can surely accept” to “This assignment is sound because pc can surely accept”
Section 13.12.4
Change replace to replaceAll (11×)
Section 13.13.1
Change constructor(key: K, second: V) to constructor(key: K, value: V)
Section 13.13.3
Change
let greeting = 'Hello'
to
let greeting: String = 'Hello'
Exercise 13.13
Change arr to more (2×)

Credits

Thanks to Iskandar Agung, Sundararajan Athijegannathan, Jisu Chung, Massimiliano De Simone, Tessio Fechine, Dominik Gruntz, Katsutaka Ishibashi, Mark Meyer, Amiel Nava, Dumitru Postoronca, Jonas Rathert, Tekin Sal, Christiaan Smith, Koray Tugay, Eran Yarkon, Kunio Yoshikawa and (your name might go here) for their bug reports!

Bug Report Form

If you have found another bug in the book or in our code that is not mentioned in this bug list, then please send a report. Unfortunately, I cannot reply personally to each report, but I do read all your comments.

Your name:

Your email address:

Edition:
Page or section number:

Problem description:

To protect against spam robots, please answer this simple math problem:
* =