《JavaScript语言精粹》勘误表

小马在《JavaScript语言精粹》的译者序中写道:“吉尔伯特海特(美国教育家)曾经说过:写了一本很糟糕的书只是犯错而已,而把一本好书翻译得很糟糕则是犯罪。但这样的大师经典之作,即便是冒着犯罪的风险,也值得翻译出来并推荐给大家。”这里就是弥补过错的地方,热烈欢迎您来帮助我们改正。

  1. 前言的致谢小节第3行2009.09.02
    “Julien LeComte”应是“Julien Lecomte”
  2. 16页表2-1右边第3排2009.09.02
    “取模”应是“取余运算”
  3. 20页,3.1 对象字面量小节的第3行代码2009.12.08
    “Jerome”应是“Joe”
    贡献者:约翰
  4. 28页,方法调用模式小节的第1段代码2009.09.03
    value:0;”应是“value:0,
  5. 29页,第一段代码的最后一句2009.11.15

    document.writeln(myObject.getValue(  ));    // 6
    //应该修改为
    document.writeln(myObject.value);    // 6
    

    贡献者:约翰

  6. 30页,第1段代码的最后1行2009.09.11
    // 令人困惑”应是“// confused
    贡献者:糖伴西红柿
  7. 32页,4.6 异常小节第2段代码的最后1行2009.09.03
    Try_It();”应是“try_it();
  8. 33页,第2段代码及其前1行2009.09.03
    Math.ceiling”应是“Math.ceil”,“return Math[this < 0 ? 'ceiling' : 'floor'](this);”中“ceiling”应是“ceil
  9. 34页,4.8 递归的第1段代码2009.09.03
    最后1个“}”后面应该加上分号变成“};
  10. 37页,第1段代码的倒数第2行2009.09.03
    }”后面应该加上分号变成“};
  11. 39页,第1段代码的倒数第3行2009.09.03
    紧接着“alert(i);”的“}”后面应该加上分号变成“};
  12. 39页,第2段代码块第6行2009.06.08
    alert(e);”应为“alert(i);
    贡献者:李穆
  13. 39页中间2009.09.03
    “add_the_handlers函数目的是给每个时间处理器一个唯一值(i)”中“时间”应是“事件”
  14. 42页,第1段代码的最后1行2009.09.11
    // unique is "Q1000"”应是“// unique 的值是 "Q1000"
  15. 44页,“译​​注​5”​应​​改为“​​译​​注​6”​,“​​译​​注​6”​应改​​为“​​译​​注​7”​。2009.12.08
    贡献者:约翰
  16. 47页,5.1 伪类的第2段代码2009.09.03
    var that = Object.beget(this.prototype)”后面应该加上分号变成“var that = Object.beget(this.prototype);
  17. 50页,5.2 对象说明符的第2段代码2009.09.03
    first: f,”后应增加1行“middle: m,
    贡献者:sofish
  18. 51页,第1段代码2009.09.03
    return this.says + ' ' + this.name + ' ' + this.says;”应为“return this.says() + ' ' + this.name + ' ' + this.says();
  19. 52页,第1段代码的最后1行2009.09.03
    }”后面应该加上分号变成“};
  20. 54页,第2段代码2009.09.03
    return that;”前面应增加1行“};
  21. 60页,6.3节的倒数第2行2009.06.08
    “值为‘shi’的属性的键值从‘4’变到‘3’”中“‘4’变到‘3’”应是“‘3’变到‘2’”
    贡献者:李穆
  22. 63页,6.7 维度第1段代码
    return a;”的下1行“}”后面应该加上分号变成“};
  23. 64页,第2段代码2009.09.03
    两处“return mat;”的下1行“}”后面应该加上分号变成“};
  24. 64页,第2段代码2009.09.03
    a[j] = 0;”应为“a[j] = initial;
  25. 69页,注释2009.09.03
    +)?(?::”应为“+)(?::
  26. 71页,第2段代码2009.09.03
    "\"(?:\\.”应为“"\"(?:\\\\.
  27. 74页,第2段代码2009.09.03
    /[A-Za-z\u00C0-\u1FFF\u2800-\uFFFD'\-]+\s+\1/gi”应为“/([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD'\-]+)\s+\1/gi
  28. 88页,string.charAt(pos )小节2009.09.03

    String.method('charAt', function () {
      return this.slice(0, 1);
    });
    //应为
    String.method('charAt', function (pos) {
      return this.slice(pos, pos + 1);
    });
    
  29. 90页,第3段代码最后1行注释2009.09.03
    p is '555-555-1212'”应为“p is '555-666-1212'
  30. 91页,string.split(separator, limit )小节第1段代码最后1行注释2009.09.04
    ['0', '1', '2', '3', '456789']”应为“['0', '1', '2', '3', '4']
  31. 105页,A.10. NaN小节的最后1段代码2009.09.04

    function isNumber(value) { return typeof value === 'number' &&
                isFinite(value);
    }
    //应为
    var isNumber = function isNumber(value) { return typeof value === 'number' &&
                isFinite(value);
    };
    
  32. 117页,表C-1,JSLint的选项2009.09.04
    删掉glovar,见http://www.jslint.com/lint.html
  33. 140页,E.3 一个JSON解析器2009.09.04

    escapee = {
        '"':  '"'
        '\\': '\\',
        '/':  '/',
        b:    'b',
        f:    '\f',
        n:    '\n',
        r:    '\r'
        t:    '\t'
    },
    //应为
    escapee = {
        '"':  '"',
        '\\': '\\',
        '/':  '/',
        b:    'b',
        f:    '\f',
        n:    '\n',
        r:    '\r',
        t:    '\t'
    },
    

有评论 34 条,发表一条新评论 »

《JavaScript语言精粹》 @ 随网之舞说:2009-09-09 23:41 #1

[...] 勘误表 [...]

糖伴西红柿说:2009-09-10 11:20 #2

你好,提供个 javascript 精粹的错误。40页。

// 构造一个 Quo 实例

其中 document.writeln(myQuo.get_status()); // 令人困惑

后面的注释,应该是 返回 confused 这个字符串。感觉这个地方不应该翻译吧,容易引起误解。

Sutra说:2009-09-10 21:29 #3

“取模”和“取余运算”?这个在数学正确性上没区别呀。

秦歌说:2009-09-11 15:18 #4

@糖伴西红柿:多谢。这的确是一个翻译错误,位于在30页,我已经增加到勘误表中。
@Sutra:取模(modulo)和取余(remainder)大部分情况下是等同的,但是还是有些不同,取模结果的符号和除数相同,取余结果符号和被除数相同,而JavaScript中的%和取余相同:
3 modulo 2 = 1
3 modulo -2 = -1
-3 modulo 2 = 1
-3 modulo -2 = -1
3 remainder 2 = 1
3 remainder -2 = 1
-3 remainder 2 = -1
-3 remainder -2 = -1

sofish说:2009-09-11 16:05 #5

15. 50页,5.2 对象说明符的第2段代码 “middle:m,”后应增加1行“last:l,”

似乎是: “first:f,”后应增加1行“middle: m,”…

秦歌说:2009-09-11 16:23 #6

@sofish:你是对的,我本意想写的是“​​last​:​l​,​​”​​后​​应​​增​​加​1​行​​“middle​:​m​,​​”,结果写反了。不过你的建议更能表达这个例子的含义,所以我采用了你的建议。非常感谢。

xthsky说:2009-09-14 18:25 #7

首页那个《JavaScript语言精粹》勘误表的图片里少了个“粹”字。

秦歌说:2009-09-14 18:52 #8

@xthsky:这真是一个很讽刺的事情哈,做图那天被出了问题的PS给整郁闷了,也没有仔细检查,所以就出了这出戏了。多谢,多谢。

watertree说:2009-09-23 15:59 #9

有一个问题请教,在书本35页,定义的getElementsByAttribute函数里有这么一行代码:var actual=node.nodeType===1&&node.getAttribute(att);不是很明白,还有,node是不是要先声明呢?
有好心人给我讲解下这个函数,更好。
谢谢了!

watertree说:2009-09-24 11:58 #10

整个函数如下:

var walk_the_DOM=function walk(node,func){
  func(node);
  node=node.firstChild;
  while(node){
    walk(node,func);
    node=node.nextSlibling;
  }
};

var getElementsByAttribute=function(att,value){
  var results=[];
  walk_the_DOM(document.body,function(node){
    var​ ​actual​=​node​.​nodeType​ =​​=​​=​ 1​&​​& ​node​.​getAttribute​(​att​)​​;
    if(typeof actual === "String" &&
           (actual === value||typeof value !== "String")){
      results.push(node);
    }
  });
  return results;
};
秦歌说:2009-09-24 22:24 #11

​walk_the_DOM是一个遍历整个DOM树函数,它有2个参数node是根节点,func是一个要对遍历到的节点进行操作的函数。这是一个典型的递归函数。
关于函数的细节可以看27页的4.2节。
getElementsBy​​Attribute函数有两个参数,att表示属性,value是可选的属性值,这个函数调用了wal_the_DOM函数,改写后或许可以看得更明白点:

var​ ​getElementsBy​​Attribute​=​function​(​att​,​value​)​​{​​
​​ ​​ ​var​ ​results​=​​[​​]​​,
      get_nodes = function​(​node​)​​{​​
​​ ​​ ​​ ​​ ​    var​​​​ ​​​​actual​​​​=​​​​node​​​​.​​​​nodeType​​​​ ​​=​​​​​​​​=​​​​​​​​=​​​​​ ​1​​​​&​​​​​​​​&​​ ​​​​node​​​​.​​​​getAttribute​​​​(​​​​att​​​​)​​​​​​​​;​​
​​ ​​ ​​ ​​ ​    if​(​typeof​ ​actual​ ​​=​​=​​=​​ ​​"​String​"​​ ​​&​​&​​
​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​(​actual​ ​​=​​=​​=​​ ​value​|​​|​typeof​ ​value​ ​​!​​=​​=​​ ​​"​String​"​​)​​)​​{​​
           //node是walk_the_DOM在执行的时候传递给get_nodes函数的
​​ ​​ ​​ ​​ ​​ ​​ ​    results​.​push​(​node​)​​;​​
​​ ​​ ​​ ​​ ​  ​  }​ ​
​​ ​​ ​​    };
​​ ​​ ​walk​_​the​_​DOM​(​document​.​body​,get_nodes)​​;​​
​​ ​​ ​return​ ​results​;​​
​​}​​;

另外如果对这种长表达式的运算顺序感到迷惑可以看看16页表2-1的运算符优先级。

觅JS高手者说:2009-11-01 19:06 #12

秦歌,你好!

我公司正在寻觅JS开发高手,薪水绝对有吸引力。有兴趣请联系:zqrain@yeah.net 或 MSN: qingrui_zeng(at)hotmail.com

公司简介:

开拓天际是一家专注于无线技术领域的IT公司。我们公司一贯比较低调,有别于国内大多数公司在技术和管理上比较浮躁的,我们一直眼光高远,非常注重在技术上深入积累,形成核心竞争力。在管理上,公司在文化上非常重视一线员工的创造力和贡献,公司CEO到各阶层管理人员,都十分“亲民”,十分尊重一线员工。所以这里相比国内其他公司(包括相比一些知名外企),离职率是非常低的。我们的工程师队伍中,有大量来自国内外一流公司的员工和国内著名大学的毕业生(包括Oracle,Motorola,Nokia,AOL,网易,易查等等)。在公司发展上,我们属于国内中型偏大的IT公司,技术实力,资金实力和市场营销能力都是十分不错的。同时,公司处于战略转型的关键期,公司的发展潜力和员工的发展空间都是非常巨大。

秦歌说:2009-11-01 19:14 #13

呵呵,感谢您的关注,不过目前没有这方面的计划,欢迎就前端相关的任何问题进行交流。

匿名说:2009-11-06 12:48 #14

Hi,我想问问,P39页的第一段代码的第四行”…function(e){ “第五行”alert(i);” 这个e在这里做什么?好像没有用?

tiramisu说:2009-11-06 12:51 #15

接上一问题,是不是应该像第11条勘误一样,把第五行的i改成e呢?

tiramisu说:2009-11-06 12:53 #16

貌似是去掉第四行的e?

秦歌说:2009-11-06 13:38 #17

呵呵,不是,那个e是传入事件参数,比如你在非IE浏览器中运行一下,注意我新增加了alert(e):

var add_the_handlers = function (nodes) {
    var i;
    for (i = 0; i < nodes.length; i += 1) {
        nodes[i].onclick = function (e) {
            alert(e);
            alert(i);
        }
    }
};

在IE下会弹出undefined,因为IE的事件保存在window.event上。
第2短段return function(e)这个e的意义是一样的。

约翰说:2009-11-15 6:57 #18

29页,第一段代码的最后一行是不是错了?
getValue应该是value吧?

约翰说:2009-11-15 12:55 #19

113页,
var foo = function foo() {};
应该是:
var foo = function () {};
吧?

秦歌说:2009-11-15 17:29 #20

@约翰:29页那个的确是个错误,您的修正也是对的,已添加到勘误表中,非常感谢。113页那个没错,两种写法都是对的,第一种写法中的那个foo可以省略,它主要用于递归。具体细节可以看看27页的4.2节。

DemoJameson说:2009-11-24 15:51 #21

11 页底部 “下面列出的值被当做假(falsy)”,falsy 应该改为 false 。

秦歌说:2009-11-24 23:46 #22

@DemoJameson :falsy即假值就是相对于truthy即真值来说。这个地方没有错,它是说下面列出的false、null、undefined、’ ‘、0和NaN都是假值falsy。多谢。

约翰说:2009-11-29 11:03 #23

更正中的第3条,21页,3.2 检索小节的第1行代码
“Joe”应是“Jerome”
不如把20页中的Jerome改为Joe,否则22页的3.3更新很难理解,因为其中的第一行代码也是Jerome,没有任何“更新”。而把20页的Jerome改为Joe后,22的代码意思就是:把Joe更新为Jerome,而21页无须更正。

约翰说:2009-11-29 11:13 #24

一个疑问,向你们请教。
第48页第二行中saying 看不懂,前面(包括前一页)似乎没有定义,到了11行似乎才出现定义,这一页下面的代码也读不太懂,望译者能够做些说明。

第四届D2嘉宾介绍:鄢学鵾 _ D2 前端技术论坛说:2009-12-03 15:31 #25

[...] 鄢学鵾曾与淘宝的小马一起翻译了 Douglas Crockford 的大作《JavaScript语言精粹》。 [...]

Supersha说:2009-12-07 21:51 #26

这本书非常不错,是我床头必备书籍之一……

约翰说:2009-12-08 8:09 #27

再提交一个印刷错误:
第44页,译注5应为译注6,译注6应为译注7.
我愿意向译者提供翻译或印刷错误,可惜没人对我前面的疑问回答,失望啊。

秦歌说:2009-12-08 22:12 #28

@约翰:
1、您在#23提出的修改方案的确是非常恰当的方式。
2、#27提出的印刷错误的确存在非常感谢。
3、48页的saying和前面一页定义是一样,都是对构造函数Mammal原型的扩充,并且当this.saying不存在时返回空。对原型进行扩充是为了实现基于原型的继承,所使用的属性并不需要构造函数一定定义了,如果理解还是比较费劲建议多看看上一章函数以及找一些prototype相关的资料。
4、49页是一个典型函数链式调用,这种方式在jQuery和YUI3.0中大量使用,看起来比较方便,这段代码本身是对48页倒数第二段那整段代码的重构,这段函数其实可以等同于:

var Cat = function (name) {
    this.name = name;
    this.saying = 'meow';
}
Cat.inherits(Mammal);
Cat.method('purr', function (n) {
        var i, s = '';
        for (i = 0; i < n; i += 1) {
            if (s) {
                s += '-';
            }
            s += 'r';
        }
        return s;
    });
Cat.method('get_name', function (  ) {
        return this.says(  ) + ' ' + this.name +
                ' ' + this.says(  );
    });

最后,非常感谢你对本书的关注和建议。另外,最近一直在生病,加上乱七八糟的事情集中在一起,如果不及时的回复让你失望,实在抱歉。

KUN10说:2009-12-30 11:17 #29

第7页的name的铁路图,name最下面的那一条走线圆圈里面到底是 _ 还是 – 让人分不清

KUN10说:2009-12-30 12:28 #30

想和秦歌讨论个问题,我在实际的使用中标识符常常以下划线开头,这样的使用从书上看是不规范的,额,书中的第七页的name铁路图指示必须以letter开头,但是使用的时候用下划线开头也没有引发什么错误,你怎么看这个规范

秦歌说:2010-01-01 12:47 #31

@KUN10 : 第7页的铁路图还好吧,可能是周围没有字母作为参照物所致。至于6页2.2小节中,作者对标识符的定义是比ECMA262中定义的窄的问题,也有朋友问过我,我准备在下一版的时候,增加一个注释来说明这个问题。原因是作者认为很多人以_作为私有变量的开头,但是JavaScript中没有私有变量,容易让人误解,私有变量应该采用私有成员的组成形式。这些想法作者在《JavaScript程序编码规范》中有说明。
译言翻译了这篇文章,由于译言出了意外,所以我就做了一个人工快照。但我发现有些地方漏掉翻译,或者不准。我准备找个时间重新整理一下。

tmac说:2010-01-04 13:17 #32

您好,秦歌,请问能否对第49页部件一小节做一个解释,兴许是我的理解力问题,这一节感觉比较费力…thx

tmac说:2010-01-04 13:18 #33

错了,是第55页~

yje2010说:2010-03-01 18:20 #34

大哥,俺昨天真的就被P30的“// 令人困惑”困惑了好久,今天发到CSDN求达人解惑,又困惑了一群人。

发表一条评论

您可以在下面评论内容中使用下列XHTML标签:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


回到页眉