The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
Printed |
Page xiv,722-1016
entire page |
Confirming Alan Stearns report of Sep 21, 2011: All the placeholder text in the Core JavaScript Reference and Client-Side JavaScript Reference sections in my printed book are printed with all the same graphic character.
|
Joseph Michaud |
Nov 07, 2011 |
PDF |
Page Page 486
2nd paragraph,2nd line of comments |
The text
*To make use of a Keymap, call its install() method, passing an HTML element,
* such as the document object. install() adds an onkeydown event handler to
* the specified object.
change to
*To make use of a Keymap, call its install() method, passing an HTML element,
* such as the document object. Install() adds an onkeydown event handler to
* the specified object.
The dot behind object should be a stop rather than expression.3Q((。(^_^)。))
|
zhang shaofeng |
Jan 28, 2015 |
PDF |
Page n/a
In chapter 7, section "Iterating Arrays" |
This is regarding the following code example:
for(var i = 0; i < a.length; i++ {
if(!a[i]) continue; // Skip null, undefined and nonexistent elements
}
I think it's fair to say the code sample is somewhat misleading, because it will not work as intended if an array element contains a boolean value of false. The comment in the example says "Skip null, undefined, and nonexistent elements." That statement is correct, but it doesn't mention that if a[i] evaluates to false it will also be skipped via the continue statement.
|
WMullen |
Apr 16, 2016 |
|
https://www.safaribooksonline.com/library/view/javascript-the-definitive/9781449393854/rn01re15.html
array.pop() |
Reported by Safari customer.
Name
Array.pop() — remove and return the last element of an array
Synopsis
array.pop()
RETURNS
The last element of array.
Description
pop() deletes the last element of array, decrements the array length, and returns the value of the element that it deleted. If the array is already empty, pop() does not change the array and returns the undefined value.
Example
pop(), and its companion method push(), provide the functionality of a first-in, last-out stack. For example:
var stack = []; // stack: []
stack.push(1, 2); // stack: [1,2] Returns 2
stack.pop(); // stack: [1] Returns 2
stack.push([4,5]); // stack: [1,[4,5]] Returns 2
stack.pop() // stack: [1] Returns [4,5]
stack.pop(); // stack: [] Returns 1
|
Shaowei Wu |
Dec 12, 2016 |
Printed |
Page section 20.2.3
code sample |
in function getcookie, the variable of cookie is used in wrong way, my print is chinese edition.
|
Anonymous |
Jun 22, 2017 |
|
Chapter 5
5.5 Jumps |
> The throw statement is a kind of interim return from a generator function.
I'd guess that is likely supposed to be "yield" and not "return".
|
Matt Whipple |
Jan 25, 2021 |
|
Chapte 5
5.5 Jumps |
Meta-errata:
> The throw statement is a kind of interim return from a generator function.
s/throw/yield/ (my previous submission had the wrong target)
|
Matt Whipple |
Jan 25, 2021 |
PDF |
Page §8.5, on p.204
Last paragraph of the section |
Typo: "within that namesapce"
|
Charles |
Dec 04, 2022 |
PDF |
Page p.213, end of section 8.7
Code snippet in the middle of the page, constructFunction() |
The code has an error. It doesn't return any value for "scope" (expected value was "global", according to the book):
let scope = "global";
function constructFunction() {
let scope = "local";
return new Function("return scope");
}
constructFunction()();
Javascript output:
ReferenceError: scope is not defined
|
Anonymous |
Jan 09, 2023 |
Other Digital Version |
4
United States |
In the ePub version, the style sheet uses a fixed font size for code samples (the HTML <pre> tag). This prevents the code samples from scaling with the rest of the text as the user changes the font size settings on an eReader such as the Nook. The 10pt font size used is too large, resulting in almost every line of code wrapping and becoming unreadable. The code font should be scaled to the main document font so they resize together, as is done for some other O'Reilly books.
|
Bill Hensley |
May 29, 2012 |
PDF |
Page 4.12.1
1st paragraph of the section |
"that exception propogates from the call to eval()."
should read "propagates" instead of "propogates"
|
Charles |
Oct 17, 2022 |
Printed |
Page 7
United States |
refers to the object on which the method is defined
should read
refers to the object in which the method is defined
about line 13
|
Anonymous |
Mar 17, 2015 |
Printed |
Page 8
Last comment in code example |
In the comment ?Now the Point object p?? I wouldn?t risk the use of the word ?inherits?. Perhaps ?accommodates? or ?has? would be safer.
|
Angelos Sphyris |
Aug 05, 2013 |
PDF |
Page 12
1.2.1 |
The example code fails on Chrome 28 when loaded info a browser with the file:// scheme. The access to localStorage in line 117 fails with a SecurityError: DOM Exception 18. The script works fine if you have a local webserver and can serve the page via http://
|
huntdesign |
Aug 03, 2013 |
Printed, ePub, Mobi |
Page 15
Line 12 |
at the end of the line is missing semicolon
total.innerHTML = "" should be total.innerHTML = "";
|
Fernando Laso |
Dec 23, 2014 |
Printed |
Page 16
Page first segment |
The <canvas> page in the first paragraph into the wrong <vanvas>
|
Anonymous |
Sep 24, 2016 |
Printed |
Page 22
First paragraph |
In the Brazilian version of the book, the word "indent" has been translated as "edentar" instead "indentar". In brazilian portuguese, "edentar" have a totally different meaning and may cause confusion.
|
Mariana de Paula |
Oct 18, 2021 |
Printed |
Page 24
Last paragraph on this page |
The section 2.4.1 on reserved words is misleading as far as the reserved words class, const, enum, export, extends, import and super are concerned.
The second paragraph in this section says these were reserved in ECMAScript 5. In the last paragraph it says the reserved words policy has been relaxed in ECMAScript 5 and lists the above again as part of a big list of Java language keywords. Since they were said to be reserved in ECMAScript 5, they should be excluded from here.
|
Prasad Kukkamalla |
Dec 30, 2011 |
Printed |
Page 24
var 'pi' = 3.142 : near top of page |
The text clearly shows that the greek letter 'pi' is the first
and only letter in the identifier.
This contradicts the text in the preceding paragraph.
The greek letter 'pi' may be the second or later letter of
an identifier, but not the first.
|
Anonymous |
May 14, 2015 |
Printed |
Page 31
fourth line |
The line starts with
default, the are in base 10, ...
It should be
default, they are in base 10, ...
That is, 'the' should be replaced with 'they'.
|
Hugo Gabriel Eyherabide |
Jan 10, 2021 |
PDF |
Page 40
"All other values, including all objects..." |
6th edition, 3.3 boolean values, the sentence "All other values, including all objects..."
My comment may seem very pedantic, but I will post it here anyway.
You said this:
--begin of quote--
The following values convert to, and therefore work like, false:
undefined
null
0
-0
NaN
"" // the empty string
All other values, including all objects (and arrays) convert to, and work like, true
--end of quote--
You didn't mention "false" in the list, so, formally, "false" is in "all other values" and so false convert to true. So, literal meaning of this sentence implies false convert to true. Yes, probably, nobody will interpret it such way, but I think this is still good idea to fix somehow the sentence. Add "false" to the list or say "All other values (excluding "false")".
|
Askar Safin |
Aug 06, 2017 |
Printed |
Page 41
2nd paragraph; second sentence |
In the second sentence of the second paragraph on page 41 it is stated:
"The second case is less strict: ..."
Actually it is the opposite. The first case:
if (o !== null) ...
is less strict than the second case:
if (o) ...
The first case will execute the body of the if-statement only if any value other than null has been assigned to o. That is, it will execute the body of the if-statement even for undefined, 0, -0, NaN and "". Whereas the second case will execute the body of the if-statement only if o has been assigned a truthy value, that is, any value just not null, undefined, 0, -0, NaN and "".
|
Roman Jasmann |
Feb 28, 2017 |
PDF |
Page 44
4th paragraph |
CURRENT STATE:
If two distinct string values are compared, JavaScript treats them as equal if,
and only if, they have the same length and if the character at each index is the same.
SUGGESTION:
If two distinct string values are compared, JavaScript treats them as equal if,
and only if, they have the same length and if the 16-bit value at each index is the same.
|
kadzme |
Apr 24, 2019 |
PDF |
Page 46
Table, "['a'] (any other array)" |
The table implies that any array except for [] and single-numeric-element array such as [9] converts to non-NaN number. But this is not true. ["2"] converts to 2.
|
Askar Safin |
Aug 07, 2017 |
Printed |
Page 51
4th paragraph, last sentence |
The punctuation surrounding the word "however" is incorrect. There should not be a comma followed by a colon:
"The conversion is not exactly the same as those explained above, however: the primitive value..."
Instead, there should be a semicolon followed by a comma:
"The conversion is not exactly the same as those explained above; however, the primitive value..."
|
Rob Johansen |
Nov 17, 2014 |
PDF |
Page 51
"+ , == , != and the relational operators are the only ones..." |
"+, ==, != and the relational operators are the only ones that perform this special kind of
string-to-primitive conversions."
Are you sure you meant string-to-primitive here? Maybe object-to-primitive?
|
Askar Safin |
Aug 07, 2017 |
PDF |
Page 54
1st example |
Written:
console.log(j); // j is defined, but may not be initialized
j may be not defined if typeof o != "object"
|
Tigran |
Dec 18, 2013 |
PDF |
Page 69
2nd pararagraph |
The last sentence of the 2nd paragraph:
If you do so, JavaScript will treat the operand as a complete statement by itself and insert a semicolon before it.
I think 'before' should be 'after' so the sentence should be
If you do so, JavaScript will treat the operand as a complete statement by itself and insert a semicolon after it.
|
Anonymous |
Aug 21, 2014 |
PDF |
Page 69
2nd paragraph |
The details of this object-to-number conversion explain why an empty array converts to the number 0
// I tested in chrome, empty array converts to empty string, not 0
|
Yan Ji |
Apr 01, 2016 |
Printed |
Page 77
4th paragraph |
A wrong piece of code submitted by a reader ended up in the confirmed errata page. I wrote a test page with the wrong code to prove it:
----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
<html>
<head>
<script>
// Copy the enumerable properties of p to o, and return o.
function copy(p, o) {
o = p || {}; // If o is falsy, use a newly created object.
for(prop in p) { // For all props in p.
o[prop] = p[prop]; // Add the property to o.
}
return o;
}
function test_copy(){
var full = {name: "joe", surname: "doe", job: "worker"};
var empty = {};
var a_copy = copy(full,empty);
console.log(a_copy);
var a_copy2 = copy(full);
console.log(a_copy2);
console.log(full===a_copy2); // -> true ... THIS IS A MISTAKE
}
</script>
</head>
<body>
<button onclick=test_copy();> RUN </button>
</body>
</html>
----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
The function copy() as printed in the book is correct.
|
Massimiliano De Simone |
Jul 18, 2015 |
Printed |
Page 84
delete code examples in 4.13.3 |
...
delete o; // Can't delete a declared variable; returns false.
This statement return true on Firefox 6 & Chrome 13 outside of strict mode. And the text above the example need corrections as well.
Thanks for writing the book.
|
April |
Sep 06, 2011 |
PDF |
Page 103
Middle of 2nd last paragraph |
Author writes:
"A newline is not allowed between the break keyword and the label name."
This to me is quite misleading as it implies that doing so will result in some sort of error., which is not the case.
Maybe the above sentence should be rephrased to say:
A newline between the break keyword and the label name will cause the label to be ignored.
|
Daniel David |
Nov 18, 2015 |
Printed |
Page 113
2nd paragraph |
I don't know if the English Edition is wrong too, since I bought the Chinese Edition.
At 5.7 "其他语句类型“ in page 113 of Chinese Edition, it wrote that "本节讨论剩余的三种JavaScript语句——width, debugger和use strict".
"width" should be wrong, it should be "with"
|
Lisa |
Dec 13, 2017 |
Printed |
Page 113
1st paragraph |
The sentence "The throw statement is a kind of interim return from a generator function." appears to be describing the yield statement, not the throw statement.
|
Brian Chhun |
Apr 26, 2021 |
PDF |
Page 123
3rd code example |
The code reads as follows:
// A verbose and explicit technique
var len = undefined;
if (book) {
if (book.subtitle) len = book.subtitle.length;
}
// A concise and idiomatic alternative to get subtitle length or undefined
var len = book && book.subtitle && book.subtitle.length;
What good does if(book) and book do in these conditions knowing that they'll throw a ReferenceError if book variable is not defined? This is what I get when I run the code samples: Uncaught ReferenceError: book is not defined.
|
Samir Saeedi |
Apr 22, 2017 |
PDF |
Page 128
function union |
/*
* Return a new object that holds the properties of both o and p.
* If o and p have properties by the same name, the values from o are used. */
function union(o,p) { return extend(extend({},o), p); }
The second sentence of the comment says that where properties use the same name, the values from o are used. I believe this should be in reverse - properties using the same name use the values from p, not o.
For example:
var stock = {name: "AT&T", shares: 100};
var quote = {name: "ATT", shares: 50, price: 32.5};
extend(stock,quote);
returns:
({name:"ATT", shares:50, price:32.5})
Notice that the properties from quote overwrite the properties in stock with the same name.
|
Kory |
Oct 04, 2014 |
|
128
2nd sample code |
set r(newvalue) {
var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y);
var ratio = newvalue/oldvalue;
this.x *= ratio;
this.y *= ratio;
},
in the above block shouldn't "newvalue" be defined first like x and y in the new object created?
|
Prashanth Devadas |
Aug 23, 2016 |
Printed |
Page 140
2nd of 6.8.3 |
Printing error
not Object.isExtensible( ) but Object.isExtensible( )
|
alan fan |
Feb 25, 2019 |
Printed |
Page 142
var undefs = [ , , ] ; // length 2 : near top of page |
When testing ....
var undefs = [ , , ] ;
The length of the array was 3 .
|
Anonymous |
May 14, 2015 |
Printed |
Page 143
2 |
The original:
“What is special about arrays is that when you use property names that are non-negative integers less than 2^32, the array automatically maintains the value of the length property for you.”
Should be modified as:
Less than 2^32 – 1
|
Lucio Lu |
Feb 04, 2020 |
PDF |
Page 144
3rd paragraph of 7.3 |
It reads as follows:
"Arrays that are sufficiently sparse are typically implemented in a slower, more memory-efficient way than dense arrays are, and looking up elements in such an array will take about as much time as regular object property lookup."
How is it both "slow" and "memory-efficient"? I think it should be memory-intensive.
|
Samir Saeedi |
Apr 23, 2017 |
Printed |
Page 145
2nd paragraph |
The original:
“What is special about arrays is that when you use property names that are non-negative integers less than 2^32, the array automatically maintains the value of the length property for you.”
Should be modified as:
Less than 2^32 – 1
|
Tye Lokka |
Feb 04, 2020 |
Other Digital Version |
151
First example of splice in the paragraph 7.8.6 |
var a = [1,2,3,4,5,6,7,8];
If we call the method splice() on this array, the array itself we'll be [1, 4, 5, 6, 7, 8], not [1,4].
|
Sergej Osokin |
Apr 05, 2016 |
PDF |
Page 152
Last paragraph |
In the last paragraph of section 6.10.6, the snippet comment reads :
"The expression "random.octet", for example, yields a random number between 0 and 255 each time it is evaluated."
However, the range is 0-256 if Math.random() evaluates to 1: Math.floor(Math.random()*256);
Here's the full snippet of the book:
// This object has accessor properties that return random numbers.
// The expression "random.octet", for example, yields a random number
// between 0 and 255 each time it is evaluated.
const random = {
get octet() { return Math.floor(Math.random()*256); },
get uint16() { return Math.floor(Math.random()*65536); },
get int16() { return Math.floor(Math.random()*65536)-32768; }
};
|
Charles |
Nov 13, 2022 |
Printed |
Page 156
2nd Code example , undeneath 6th paragraph |
This concerns the inherit function in Javascript - The Definitive
Guide 6th edition:
var obj = { p1: 0, p2: new Array(10)}
var tab = [inherit(obj), inherit(obj)];
tab[0].p1 = 1;
tab[0].p2[0] = 'F';
tab[1].p1 = 2;
tab[1].p2[0] = 'S';
Note that for for both entries in tab, p2[0] is set to 'S'!
|
Anonymous |
Oct 17, 2011 |
Printed |
Page 165
1st paragraph |
The book states "A function declaration statement actually declares a variable and assigns a function object to it. A function definition expression, on the other hand, does not declare a variable."
I believe these are reversed. A function declaration does not declare a variable, while a function definition expression does.
The following is an example of a function definition expression where the function object IS assigned to a variable:
var tensquared = function(x) { return x*x; };
And the following is an example of a function declaration statement where the function object is assigned to an identifier, not to a variable:
function distance( x1, x2 ) { return x2 - x1; };
|
Anonymous |
Mar 12, 2013 |
Printed |
Page 165
1st paragraph |
i found the following phrase in the book:
"A function definition expression, on the other hand, does not declare a variable."
I would like to know whether it is a mishap or not.
Thanks
|
Anonymous |
Apr 29, 2014 |
Printed |
Page 168
10th line (including the example) |
The line starts with
<code>true</code>
It was most likely intended to be the value 'true' formatted as <code> (same as the value 'false') but it was not rendered as such.
|
Hugo Gabriel Eyherabide |
Jan 10, 2021 |
Printed |
Page 169
bottom |
What is at the bottom of page 169 is not a bug. Rather, it is a good example. There, one can read:
"Example 8-5, in ? 8.7.4, includes" ...
Unfortunately, the paragraph number is very often missing at other places in the book, when referring to an example. This makes it more difficult to find the example.
|
Saašha Metsärantala |
Dec 29, 2011 |
PDF |
Page 178
factorial function |
The factorial function always returns NaN !
Here is the function:
function factorial(n) {
if (isFinite(n) && n>0 && n==Math.round(n)) { // Finite, positive ints only
if (!(n in factorial)) // If no cached result
factorial[n] = n * factorial(n-1); // Compute and cache it
return factorial[n]; // Return the cached result
}
else return NaN; // If input was bad
}
So if I invoke factorial(1) - I get 1 * facttorial(0) = 1 * NaN = NaN
|
Daniel David |
Dec 15, 2015 |
Printed |
Page 178
Section 8.4.1 |
This looks like a big change for ES6.
Properties cannot be added to a function, they are undefined as per the following sources:
https://www.tutorialspoint.com/add-a-property-to-a-javascript-object-constructor
https://www.w3schools.com/js/js_object_prototypes.asp
The above has been validated in the following environments supporting ES6:
node.js
v12.11.1
MacOS v10.12.6
Safari
v12.1.2
The following sections of text are impacted:
p178 8.4.1 Defining Your Own Function Properties
p200 Example 9-1
p205 9.3 Java-Style Classes in JavaScript
p206 Example 9-3
|
Andrew Gallant |
Oct 15, 2019 |
Printed |
Page 179
Example 8-3 |
In some ways, the extend() function in example 8-3 is a step backwards. It produces the behavior of the simpler version of extend() on pg. 127 rather than building on the improved version on pg. 134. Namely it does not handle property attributes properly and overwrites existing properties of the object o.
|
David Sletten |
Dec 30, 2012 |
Printed |
Page 186
First sentence section 8.7.2 |
The book says: "Every function has a prototype property that refers to an object known as the prototype object." The standard requires this of (most) functions defined by the user, but it does not appear to be true of most built-in functions.
According to Chrome (23.0.1271.101) and Safari (5.1.7) none of the following function objects have a 'prototype' property: the function prototype (i.e., Function.prototype), Object.create, String.prototype.charAt, Date.prototype.getMilliseconds, Date.now
In fact, it may be the case that no built-in function other than the obvious constructors (Object(), Date(), Array(), ...) has a prototype associated with it.
Section 13.2 of ECMA-262 discusses the process of creating functions. In particular, steps 16 and 18 refer to the creation of a corresponding prototype object and its association with the new function through its 'prototype' property. The section ends with the following note: "A prototype property is automatically created for every function, to allow for the possibility that the function will be used as a constructor." This note may shed some light on why built-in functions don't have 'prototype' properties since they will never be used as constructors. It is more efficient to avoid creating the unnecessary prototype objects in this case.
Furthermore, section 15.3.5.2 discusses the special case of functions creted by means of bind(): "Function objects created using Function.prototype.bind do not have a prototype property." So it's not even true that all user-defined functions have a 'prototype' property.
|
David Sletten |
Dec 22, 2012 |
PDF |
Page 187
bottom of page 187 / top of page 188 |
This code appears at the bottom of page 187..
function trace(o, m) {
var original = o[m];
o[m] = function() {
console.log(new Date(), "Entering:", m);
var result = original.apply(this, arguments);
console.log(new Date(), "Exiting:", m);
return result;
};
}
Should the code be modified with the two changes noted below?..
function trace(o, m) {
var original = m; // change o[m] to m
o[m] = function() {
console.log(new Date(), "Entering:", m);
var result = original.apply(this, arguments);
console.log(new Date(), "Exiting:", m); Log message.
return result;
};
return o[m]; // add this line
}
// by making the above edits, the trace function could then be used as follows..
var myObj = {
myMethod : function(x,y) {return x + y}
};
var test = trace(myObj, myObj.myMethod);
test(1,2); // output => logging messages and result (3)
|
Gerald LeRoy |
Aug 16, 2014 |
PDF |
Page 191
Last paragraph |
"JavaScript is not a functional programming language like Lisp or Haskell". I disagree. Moreover, JavaScript is inspired by Scheme (Lisp dialect). Original JS is essentially Scheme with Java syntax
|
Askar Safin |
Aug 26, 2017 |
PDF |
Page 192
Function defining map method if it doesn't exist |
Why are the extra i and a included in the call parameters/arguments, positions 3 and 4?
Replace this current line
if (i in a) results[i] = f.call(null, a[i], i, a);
with this
if (i in a) results[i] = f.call(null, a[i]);
or this
if (i in a) results[i] = f.call(o || null, a[i]); //this is from the errata version page, excluding the i and a
seems to work to work to produce a new array. I am just trying to understand if there is an occasion where the extra i and a are needed?
|
Anonymous |
Mar 29, 2016 |
Printed |
Page 192
Third code block |
The ECMAScript 3 reduce() behaves differently to ECMAScript 5 Array.prototype.reduce() if an initial value is not supplied and:
* a.length=1 and a contains no elements (Returns undefined, but ES5 throws)
* a.length>1 and only a[a.length-1] exists (Throws, but ES5 returns a[a.length-1])
Fix listed below.
------------------------------------------------------------------------------------------------
TEST SCRIPT
------------------------------------------------------------------------------------------------
//**************************************************************************
// reduce() as listed in book, but split into ES3/ES5 versions for testing
//**************************************************************************
var reduceES5 =
function(a, f, initial) { // If the reduce() method exists
if(arguments.length > 2)
return a.reduce(f,initial);
else
return a.reduce(f);
};
var reduceES3 =
function(a, f, initial) {
var i=0, len=a.length, accumulator;
// Start with the specified initial value, or the first value in a
if(arguments.length > 2)
accumulator = initial;
else { // Find the first defined index in the array
if(len==0)
throw TypeError();
while(i<len) {
if(i in a) {
accumulator = a[i++];
break;
} else i++;
}
if(i==len && len>1)
throw TypeError();
}
// Now call f for each remaining element in the array
while(i < len) {
if(i in a)
accumulator = f.call(undefined, accumulator, a[i], i, a);
i++;
}
return accumulator;
};
//**************************************************************************
// Modified Array.prototype.toString()
// Shows non-existent elements as 'x'
//**************************************************************************
Array.prototype.toString = function() {
var str = "";
for (var i=0; i<this.length; ++i) {
if(i in this)
str += this[i];
else
str += 'x';
if(i<this.length-1)
str += ',';
}
return str;
};
//**************************************************************************
// Test code
//**************************************************************************
var testArrays = [ [,], [,1], [,,2] ];
var add = function(x,y){return x+y;};
var resES3 = [];
var resES5 = [];
var resES30 = [];
var resES50 = [];
var res, i;
// Call reduce() for each test case
for(i=0; i<testArrays.length; ++i) {
try { res = reduceES3(testArrays[i], add); }
catch(err) { res = "Throws" }
resES3.push(res);
try { res = reduceES5(testArrays[i], add); }
catch(err) { res = "Throws" }
resES5.push(res);
try { res = reduceES3(testArrays[i], add, 0); }
catch(err) { res = "Throws" }
resES30.push(res);
try { res = reduceES5(testArrays[i], add, 0); }
catch(err) { res = "Throws" }
resES50.push(res);
}
// Output results
for(i=0; i<testArrays.length; ++i) {
if( resES3[i]!==resES5[i] && !(resES3[i]!==resES3[i] && resES5[i]!==resES5[i]) )
bold = true;
else
bold = false;
if( resES30[i]!==resES50[i] && !(resES30[i]!==resES30[i] && resES50[i]!==resES50[i]) )
bold0 = true;
else
bold0 = false;
document.write( (bold?"<b>":"") + "reduceES3([" + testArrays[i].toString() + "], add) = " + resES3[i] + (bold?"</b>":"") + "<br/>" );
document.write( (bold?"<b>":"") + "reduceES5([" + testArrays[i].toString() + "], add) = " + resES5[i] + (bold?"</b>":"") + "<br/>");
document.write( (bold0?"<b>":"") + "reduceES3([" + testArrays[i].toString() + "], add, 0) = " + resES30[i] + (bold0?"</b>":"") + "<br/>");
document.write( (bold0?"<b>":"") + "reduceES5([" + testArrays[i].toString() + "], add, 0) = " + resES50[i] + (bold0?"</b>":"") + "<br/><br/>");
}
------------------------------------------------------------------------------------------------
FIXED reduceES3()
------------------------------------------------------------------------------------------------
var reduceES3 =
function(a, f, initial) {
var len=a.length, i, accumulator;
// Start with the specified initial value, or the first value in a
if(arguments.length > 2) {
i=0;
accumulator = initial;
} else { // Find the first defined index in the array
for(i=0; i<len && !(i in a); ++i);
if(i<len)
accumulator = a[i++];
else
throw TypeError();
}
// Now call f for each remaining element in the array
for(;i<len; ++i) {
if(i in a)
accumulator = f.call(undefined, accumulator, a[i], i, a);
}
return accumulator;
};
|
Jonathan Dodd |
Jan 23, 2017 |
Printed |
Page 192
3rd section |
I believe that this line... if (i in a) results[i] = f.call(o || null, a[i], i, a);
should either be this: if (i in a) results[i] = f.call(o || null, a[i]);
or this: if (i in a) results[i] = f.apply(o || null, [a[i], i, a]);
|
Gerald LeRoy |
May 17, 2018 |
Printed |
Page 193
16th line of code from top of page |
From the Confirmed Erata page:
Description:
The "if (i == len)" statement causes reduce to throw a TypeError when it is called with an array containing a single element and no initial value.
Note from the Author or Editor:
Change if (i == len) to if (i == len && len > 1)
Comment/Question:
Even with the above change, an error is still thrown for sparse arrays, for example [ , , 1].
Is the line (i == len && len >1) even needed? When that line is commented out, the code appears to work for all cases.
|
Gerald LeRoy |
Aug 31, 2014 |
PDF |
Page 193
Last paragraph |
The paragraph provides a way to easily test for an existing array, and to assign it to a variable, or, if no array exists, create a new one: a = a || [];
The problem is the explanation uses the word "object" instead of "array":
"In this case, if any object is passed as the second argument, the function will use that object"
|
Charles |
Dec 02, 2022 |
Printed |
Page 194
Middle of page |
The compose() function only works for 2 functions. Here is a version that works with an arbitrary number of functions. It is derived from Paul Graham's book "On Lisp" (pg. 66):
function compose() {
if ( arguments.length === 0 ) {
return function(x) { return x; }; // Identity
} else {
var fns = Array.prototype.concat.apply([], arguments);
var fn1 = fns.pop();
return function() {
return fns.reduceRight(function(x, f) { return f.call(this, x); }, fn1.apply(this, arguments));
};
}
}
|
David Sletten |
Jan 12, 2013 |
Printed |
Page 194
Middle of page |
Oops. The compose() function I submitted will work as expected since all of the arguments are functions, but the conversion of arguments to an Array will not work in general:
var fns = Array.prototype.concat.apply([], arguments);
The problem is that concat() flattens nested Array elements.
Here is a more general solution:
var fns = Array.prototype.slice.call(arguments, 0);
|
David Sletten |
Jan 13, 2013 |
Printed |
Page 194
Middle of page |
Oops again. I misidentified the problem above. In fact, concat() does not flatten nested elements. It's the use of apply() that is the problem. It causes the elements of arguments to be passed directly to concat(), which then flattens them as top-level args:
Array.prototype.concat.apply([], [[1, 2], [3, 4]]) => [1, 2, 3, 4]
|
David Sletten |
Jan 13, 2013 |
PDF |
Page 194
general example |
There is this comment:
// The returned function h passes all of its arguments to g, and then passes
There is no function h, so which function does h refer to?
|
Anonymous |
Mar 30, 2016 |
Printed |
Page 195
Top of page |
The partialRight() function is of limited use in JavaScript. In its most basic usage it does return a function whose rightmost argument(s) is fixed:
var square = partialRight(Math.pow, 2);
square(8) => 64
However, this partial function does not play nice with the new higher-order array functions such as map(), reduce(),... The problem is that JavaScript defines these functions in an idiosyncratic way.
Consider map(). In most languages, such a function traverses a sequence of values and yields a new sequence produced by applying a given function to each element of the sequence in turn. The key is that the function used to perform the mapping takes a single value, namely each element one at a time.
However, JavaScript's map() function passes three arguments to the mapped function: the element, its index, and the Array object itself. When a function created by partialRight() receives these three arguments it appends the fixed argument to the end and invokes the underlying function.
Suppose that we evaluate the following expression:
var a = [2, 3, 4];
a.map(square)
Rather than calling Math.pow(2, 2) with the first element and the fixed value 2, we actually get Math.pow(2, 0, a, 2). Math.pow() ignores the last 2 arguments and simply returns:
Math.pow(2, 0) => 1
Likewise, the 2nd element results in Math.pow(3, 1, a, 2), which evaluates:
Math.pow(3, 1) => 3
Only the 3rd element coincidentally produces the expected value: Math.pow(4, 2, a, 2) => 16
This problem can perhaps be mitigated by examining the 'length' property of the function being fixed:
function partialRight(f) {
var args = Array.prototype.slice.call(arguments, 1);
var length = f.length - args.length;
return function() {
return f.apply(this, Array.prototype.slice.call(arguments, 0, length).concat(args));
};
}
This modified partialRight() works with map() and square() as in the above example, but I haven't tested it exhaustively.
One obvious issue with relying on the function's 'length' property is that this only reflects the number of 'required' arguments. A varargs function would accept its arbitrary number of args via the 'arguments' object regardless of the value of 'length'. However, it doesn't make sense to apply partialRight() to a varargs function anyway.
|
David Sletten |
Jan 15, 2013 |
PDF |
Page 213
top of page |
The book reads:
If we define a constructor using an unnamed function definition expression, the getName() method will return an empty string.
That's just not true. In Chrome I wrote this:
var c = function(x){this.x=x}
var o = new c(1);
Querying o.constructor.name, the result is: "c".
Defining and using the getName() function of yours, the result is still the same, o.constructor.getName() returns "c".
|
Samir Saeedi |
Apr 25, 2017 |
PDF |
Page 215
Example 9-6 |
Please send me an example of how to test this script. I have tried to follow it and have no idea of how to use it. For example, do I input an object or an array and how to trigger the script? With a new edition it would be helpful if all examples include items that demonstrate how the script works, like with example 9-1. I realize most examples include examples uses and output, but this one has me lost. Thanks.
|
Anonymous |
Mar 31, 2016 |
Other Digital Version |
225
generic equals function |
An additional constraint on the classes for which the equals function works is that they have a fixed set of properties. If the properties of objects of the class are not predetermined, "that" could have properties that "this" does not have. In this case, the equals function would be more akin to a subset predicate.
Even for classes with such a constraint, users of such a class can make the function non-reflexive by adding a property to one object.
function Obj(val) { this.val = val; }
Obj.prototype.equals = generic.equals;
var obj1 = new Obj(3);
var obj2 = new Obj(3);
obj1.equals(obj2) // => true
obj2.equals(obj1) // => true
obj2.extra = 7;
obj1.equals(obj2) // => true
obj2.equals(obj1) // => false
|
Evan |
Sep 28, 2011 |
Printed |
Page 225 Chapter 9.6.5
Example 9-9. |
The code for the equals function does not consider the case that object "that" has an own property, that "this" does not have.
If "that" has an own property "b" that "this" does not have, both objects can still be equal, because only the set of own properties from the "this" object is checked for existence and equality with respect to the "that" object but not vice versa.
// Tests for equality by comparing the constructors and instance properties
// of this and that. Only works for classes whose instance properties are
// primitive values that can be compared with ===.
// As a special case, ignore the special property added by the Set class.
equals: function(that) {
if (that == null) return false;
if (this.constructor !== that.constructor) return false;
for(var name in this) {
if (name === "|**objectid**|") continue; // skip special prop.
if (!this.hasOwnProperty(name)) continue; // skip inherited
if (this[name] !== that[name]) return false; // compare values
}
return true; // If all properties matched, objects are equal.
|
Michael Aakolk |
Nov 25, 2013 |
Printed |
Page 228
United States |
The book uses two different and incompatible definitions for the term "method chaining":
1. The practice of writing methods to return the value of the receiver (this) so that subsequent method calls involving the same object can be chained onto the current method call. (pg. 169)
2. The act of a method on a subclass prototype invoking the corresponding overridden method on the superclass prototype in order to perform some of its work. (pg. 228, 230 and following).
The first definition is in widespread use, but the second seems to be idiosyncratic. In fact, page 169 warns not to confuse method chaining with the topics discussed in section 9.7.2 (pg. 230).
Some other JavaScript authors use the terms "constructor stealing" or "constructor borrowing", and to be fair, apparently the Java and C++ communities do use the term "constructor chaining". But the book's overloading of the term "method chaining" is confusing.
Incidentally, the footnote on page 169 refers to Martin Fowler's website to point out the origin of the term. This link is dead. The following link simply provides a short blurb: http://martinfowler.com/dslCatalog/methodChaining.html
It appears that Martin Fowler wants the reader to refer to ch. 35 of his DSL book.
|
David Sletten |
Feb 24, 2013 |
Printed |
Page 229
1st paragraph of section 9.7.1 |
The text says, "If an object O is an instance of a class B and B is a subclass of A, then O must also inherit properties from A. We arrange this by ensuring that the prototype of B inherits from the prototype of A."
An example is then given:
B.prototype = inherit(A.prototype);
B.prototype.constructor = B;
I disagree with this text. If B is a subclass of A, then I would think that A is the prototype of B rather than A.prototype. If B's prototype equals A's prototype as instructed in the text, then B will only have access to the members of A's prototype. B will not have access to the additional members of A. Consequently, B will not be a true subclass of A. In fact, A and B will be subclasses of some other object (namely the prototype of A). I think the example should be:
B.prototype = inherit(A);
B.prototype.constructor = B;
Furthermore, I am not convinced that the second line is really needed. B.prototype can only be assigned if B exists. If B exists, it will already have a constructor set to B. Assigning a new prototype to B should not change the constructor of B.
Would appreciate any thoughts on this.
Thank you.
|
David Cox |
Jan 31, 2012 |
Printed |
Page 233
example first line after opening comment |
the paragraph before the example talks about the advantage of composition over inheritance. Next the example starts with:
var FilteredSet = Set.extend(...
in my opinion this makes the example very hard to understand as it uses subclassing AND composition of Set. If you want to give an example about composition then it should be only about composition. In my opinion it should be:
var FilteredSet = Function.extend(...
I tested this and it works for me. thnx, Arnoud
PS I can understand it from a perspective that you want a FilteredSet to be an instance of Set but it that case it needs to be clarified why you extend Set instead of Function.
|
Anonymous |
Jan 06, 2014 |
Printed |
Page 234
Top of page |
The NonNullSet 's' created by means of FilteredSet is not identical to the earlier definition since the filter tests x !== null. This only weeds out null values and not undefined values. The earlier implementation effectively filters using the less strict x != null, which applies to undefined values as well.
|
David Sletten |
Feb 27, 2013 |
Printed |
Page 238
Example 9-17 |
Example 9-17 would be less cluttered if the 'enumerable', 'configurable', and 'writable' property attributes were simply omitted. The preceding text could remind the reader that for a new property defineProperty() assigns the value false to unspecified attributes (pg. 132).
|
David Sletten |
Mar 09, 2013 |
Printed |
Page 239
first line |
Current:
...you can create a SUPERCLASS simply by adding an extends clause...
Correction:
...you can create a SUBCLASS simply by adding an extends clause...
|
Adam C |
Oct 22, 2020 |
Printed |
Page 244
2nd paragraph |
Was it was meant to say "The returned object defines four useful methods:
toString(), descriptors(), hide(), and freeze().", not show() as the last method.
Also, was object should be plural in the 2nd comment below this?
Thank you. Great book!
|
Jim Olson |
Sep 19, 2016 |
Printed |
Page 245
the 13th line from the bottom, in the function 'toString()' of Example 9-23 |
to Author:
calling the function toString() of such an object below leads to an error:
var testa = {
A:1,
get a(){return this.A},
set a(x){this.A = x}
};
the output of the code " testa.properties().toString() " is:
"{
A: 1,
readonly accessor a
}"
But obviously, "a" is not readonly. Thats's because the 'writable' property of 'a' is ''undefined' which gets a Boolean false. And the code "!desc.writable" of 13th line from bottom makes output of function totSring() have an extra "readonly".
Both Chrome 39 and Firefox 43 tested.
|
Can Zheng |
Dec 06, 2016 |
PDF, ePub, Mobi, |
Page 251
4th paragraph |
"var pattern = /s$/ ;
This line creates a new RegExp object and assigns it to the variable pattern . This particular RegExp object matches any string that ends with the letter “s.” This regular expression could have equivalently been defined with the RegExp() constructor like this:"
The period isn't part of the match so it should be moved after the closing quotes to end the sentence as follows:
"This line creates a new RegExp object and assigns it to the variable pattern . This particular RegExp object matches any string that ends with the letter “s”. This regular expression could have equivalently been defined with the RegExp() constructor like this:"
|
Alfred Myers |
Jul 01, 2019 |
Printed |
Page 270
last two lines on page |
Due to changes in 2015 that made let compliant with the final ES6 standard (https://blog.mozilla.org/addons/2015/10/14/breaking-changes-let-const-firefox-nightly-44/) the code below no longer behaves as described in the book
let x = 1;
for (let x = x + 1; x < 5; x++) {
console.log(x); // prints 2, 3, 4
}
The above code no longer prints 2, 3, 4. Depending on the browser being used, the page error varies ("ReferenceError: x is not defined", "can't access lexical declaration `x' before initialization", etc.)
|
Gerald LeRoy |
Feb 12, 2019 |
Printed |
Page 308
7th paragraph |
The erroneous term 'CSS class' crops up in the book in several places.
It's not a 'CSS class', it's an HTML element 'class' attribute. 'HTML class' would perhaps be a better shorthand way to refer to it.
Given that the book is so excellent in its terminological accuracy throughout, this term should be replaced with something better.
A quick search through the PDF version of the book finds many other occurrences, of which the following are a sample:
page 309: 2nd paragraph 'CSS classes'
page 364: section 15.2, 4th bullet point 'CSS class'
page 437: section 16.5 heading contains 'CSS Classes'
page 525: 1st paragraph 'CSS Class
page 532: section 19.2.3 heading contains 'CSS Classes'
The term also appears in comments in sample code.
|
Alan Rew |
Mar 29, 2012 |
Other Digital Version |
309
Example 13-1 |
Example 13-1 is somewhat misleading. The loop through each element whose class is "reveal" suggests that clicking on the first "handle" child of each such element will reveal the element containing the handle. However, since each onclick handler shares the same elt variable, the only elements that will be revealed are those in the final element with class "reveal".
Since the example contains only a single element whose class attribute is "reveal", the behavior is fairly intuitive. Adding a second or third "reveal" element might cause some surprises.
|
Evan |
Oct 06, 2011 |
Printed |
Page 323
5th paragraph |
Chinese printed version.
Just one small typo.
addEventListaner()
This should be:
addEventListener()
|
zhiguang |
Oct 19, 2014 |
Printed |
Page 324
Last paragraph |
In the last paragraph you wrote:
"This timeline does not specify ... when the web browser must start responding to user input events...user input events might be fired before the event-driven phase..."
However step 8 of the timeline states:
"From this point on event handlers are invoked .. in response to user input events..."
|
Patrick Fischer |
Sep 07, 2012 |
Printed |
Page 359
1st paragraph, last sentence |
AS IS: "than the return value"
TO BE: "then the return value"
|
Thierry Tung |
Dec 04, 2020 |
Printed |
Page 362
HTML code example |
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<h1>An HTML Document</h1>
<p>This is a <i>simple</i> document.
</html>
As has already been noted the closing </body> tag is missing from the code example above.
Also missing is the closing </p> tag, which should appear as so:
<p>This is a <i>simple</i> document.</p>
|
winst |
Mar 12, 2015 |
Printed |
Page 375
6yh paragraph |
HTMLElement defines properties for the universal HTTP attributes
should be:
HTMLElement defines properties for the global HTML attributes
as stated here:
http://www.w3.org/TR/html-markup/global-attributes.html
|
Anonymous |
Mar 11, 2015 |
PDF |
Page 381
Last code example |
if (n.nodeType == 3 || n.nodeTyep == 4)
instead of
if (n.nodeType == 3 || n.nodeType == 4)
|
Askar Safin |
Oct 19, 2017 |
PDF |
Page 385
Example 15-5 |
"Setter__" was used in the comments instead of "__defineSetter__"
|
Anonymous |
Apr 16, 2015 |
Printed |
Page 391
Bottom |
Function getViewportSize treats window.innerWidth/Height and document.documentElement/body.clientWidth/Height as equivalent but in fact they are different: innerWidth/Height includes space covered by scrollbars while clientWidth/Height does not.
I confirmed this on my system, and you can also find it here:
http://www.quirksmode.org/mobile/viewports.html
(search for heading "Two property pairs")
|
Christoph Nahr |
Mar 03, 2013 |
Printed |
Page 399
4rd |
With this form, you might refer to the array of radio button elements like this:
var methods = document.forms.shipping.elements.method;
Note that <form> elements have an HTML attribute and corresponding JavaScript
property named ?method?, so in this case, we must use the elements property of the
form instead of directly accessing the method property.
why must use the elements property of the form instead of directly accessing the method property.
because of "Remember that when you index an HTMLCollection
with a name and more than one element shares that name, the returned value is an
array-like object that contains all matching elements"
when i do it
var methods = document.forms.shipping.method;
have same result?
|
Anonymous |
Jun 01, 2012 |
Printed, PDF |
Page 439
CSSClassList.prototype.contains function (24th line) |
classes.search( "\\b" + c +"\\b" ) != -1 is not a reliable solution, e.g.:
"x-list-header-inner".search("\\bx-list-header\\b") == 0 while
"x-list-header-inner" != "x-list-header"
|
Anonymous |
May 10, 2012 |
Printed |
Page 460
Section 17.3.1 |
The method for getting to the event object in an event handler which is defined inline as a property of the target element does not work in Firefox.
You should pass arguments[0] to the handler which seems to work across all browsers
See this demo:
<!DOCTYPE html>
<html>
<body>
<script>
function handler(event){
event = event || window.event;
alert("Type of event:" + event.type);
}
</script>
<button onclick="handler(arguments[0]);">Click on me for event in all browsers!</button>
<button onclick="handler();">Click on me for error in Firefox!</button>
</body>
</html>
|
Semmel |
Nov 16, 2012 |
Printed |
Page 468
2nd paragraph |
Text says: "It is important to note that mousemove and mouseup handlers are registered as capturing event handlers."
Both events are registered with document as target of the event. The event handlers moveHandler and upHandler both stop propagation. To me it seems that (because document is at the top of the DOM tree) it is NOT important whether error handling is bubbling (bottom up) or capturing (top down). Motion in either direction begins and ends at document.
So the questions is: why is capturing important?
PS. I tried the example with bubbling on and off and I don't see any difference in handling the drag.
|
Paul E.S. Wormer |
Dec 28, 2011 |
Printed |
Page 494
Example code in "XMLHttprequest in IE6" box |
The ActiveXObject "Msxml2.XMLHTTP.3.0" could usefully be replaced by "Microsoft.XMLHTTP". As the former always points to the latter, nothing would be lost by this and even older versions of the IE browser would be supported.
If this change was made then the title of the box would need to be updated to "XMLHttprequest in IE5 and IE6".
|
Martin Leese |
Jan 22, 2013 |
Printed, PDF |
Page 505
Example 18-9. |
The example does not upload a file via POST. XHR doesn't append the file to the request body.
Browsers Tested (on Ubuntu 12.10):
Google Chrome 26.0.1410.63
Mozilla Firefox 20.0
|
John Wesley |
Jul 08, 2013 |
Printed, |
Page 673
4th paragraph, just before screenshot |
Not so much a mistake as an alternative.
"Second, Firefox 4 no longer fires a popstate event for newly loaded pages that do not have any saved state. This second change means that the example below does not work quite right in Firefox 4."
Firefox 4 does fire the pageshow event, so it works right if you bind popState to that. I added this on line 6 of the listing:
window.onpageshow = popState;
|
Rob Crowther |
Aug 10, 2011 |
PDF |
Page 685
Examples 22-6 and 22-7 |
I get the following error when I try to run Examples 22-6 and 22-7 on Chrome browser:
"Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data."
|
Samir Saeedi |
May 10, 2017 |
Printed |
Page 719
Arguments entry |
The reference section entry for Arguments neglects any mention of the 'caller' property introduced on pg. 173.
|
David Sletten |
Apr 06, 2013 |
PDF |
Page 790
Toward the bottom |
The author asserts that - quote:
Math.max()
Returns the larger of two numbers.
Math.min()
Returns the smaller of two numbers
The above is quite misleading, as it implies that these functions will only inspect the first 2 arguments - which is of course incorrect.
Instead, see the definition on MDN:
"The Math.min() function returns the smallest of zero or more numbers." and
The Math.max() function returns the largest of zero or more numbers.
|
Daniel David |
Nov 10, 2015 |
PDF |
Page 849
top of the page |
An assertion is made that String.substr() is deprecated.
I believe that this is a mistake because I could not find any written evidence in the spec or elsewhere that is it deprecated.
|
Daniel David |
Nov 10, 2015 |
Printed, Mobi, |
Page 857
1st paragraph |
The second sentence in the paragraph says:
"It includes entries for important client-side JavaScript object such as Window, Document, [...]"
"object" should be "objects".
Terrific book by the way, one of the best.
|
Mark Giffin |
Jan 10, 2015 |
Printed |
Page 951
Third entry from the bottom of the page |
offsetParent() is listed in the section on jQuery Element methods, but it's also listed in the previous section on jQuery Selection methods (which is where it properly belongs).
|
Joshua Davies |
Mar 18, 2014 |
Printed |
Page 983
7th paragraph (double value) |
Second sentence reads, "This property mirrors the value attribute."
This entire paragraph is *about* the value attribute, so how can it mirror itself? Was there supposed to be something else that it mirrored, or was it supposed to be mirrored by something else? Position possibly? It makes determination of which attribute to remove to change determinate/indeterminate confusing.
|
Charles Hernandez |
Aug 15, 2015 |
Printed |
Page 1020
omition of !! operator |
there is no mention of the cast to boolean operator !!
I noticed this when attempting to use this book to determine what the !! operator was in reading the source code for the com.google.gwt.dom.client.Node class
|
Anonymous |
May 13, 2013 |