说明:《JavaScript高级程序设计(第2版)》(预计2010年7月份上市)的审校者谢廷晟针对书中一句关键的表述,给出了如下分析说明。虽然译者也同样意识到将this关键字函数执行时所处的作用域简单地等同起来不恰当,但在书中其他章节里,还有多处类似表述。本着不擅自修改原文的原则,谨以此说明帮助读者慎思明辨(书中也通过译者注形式给出了此文的链接)。感谢廷晟的认真审校。

第5章中有这样一句话:“this是函数在执行时所处的作用域”(《JavaScript高级程序设计(第2版)》第5章5.5.4节正文倒数第3段中)。我觉得作者的这种说法大有问题。对JavaScript不熟悉的读者会越看越糊涂。这里首先需要明确两个概念:函数执行时所处的作用域、在哪个作用域中调用函数函数调用发生的作用域,否则讨论就无法继续深入。把后一概念明确为“函数调用语句所处的那个作用域”应该没有问题。而前一个概念,实际上就是函数的定义所处的那个作用域。以下面的代码为例:


function a() {
 // ...
}

function b() {
 /// ...

 return function c() {
  // ...
 };
}

var d = b();
a();
d();

在这里,函数a、b和d(实际上就是c)都是在全局作用域中调用的。a和b执行时所处的作用域都是全局作用域。但是d执行时所处的作用域并不是全局作用域,而是函数b的局部作用域。说到这里,就可以看到“this是函数在执行时所处的作用域”这一说法的不妥了。假如函数c中引用到了this(在本例中,d是直接调用的,所以this指向的是全局对象),那么按作者的说法,c 岂不是直接运行在全局作用域中而不是b的局部作用域中了?再看下述例子:


var greeting = 'Hello from global scope!';

function e() {
 alert(greeting);
 alert(this.greeting);
}

var tom = {
 greeting:'Hello from Tom!'
};
tom.f = e;
tom.f();

这个例子中的this指向的是什么?显然是tom。那么f(即e)执行时所处的作用域是什么?显然是全局作用域。假如f执行时所处的作用域如作者所说为this所指对象的话,那就意味着在本例中f执行时所处的作用域为tom,也就是说在f执行过程中,与其作用域链相对应的那个变量对象链的最前端那个对象是tom,而这就意味着在此时函数体内对名称greeting进行解析时首先遇到的是tom中定义的greeting,于是两条输出语句的结果都应该是“Hello from Tom!”,这不符合事实,所以按作者的说法所做的那个假设是错误的。

对于this这个关键字,我认为不应该扯什么作用域的事儿,只要向读者说明以下几项这样一句话就够了:函数作为哪个对象的方法调用,函数体内的this(不包括嵌套定义在其中的函数中的this)指向的就是那个对象。直接调用一个函数,相当于把它当作全局对象的方法调用。JavaScript 中没有类作用域的概念,因此方法内部要访问据以调用此方法的那个对象的属性,必须使用this关键字,按‘this.属性名’的语法来访问

  1. 函数作为哪个对象的方法调用,函数体内的this(不包括嵌套定义在其中的函数中的this)指向的就是那个对象。
  2. 结合new运算符调用一个构造函数时,系统会先自动生成一个对象,然后在该对象上调用构造函数。此时在构造函数体内,this指向的就是这个对象。
  3. 直接调用一个函数,相当于把它当作全局对象的方法调用。
  4. JavaScript中没有类作用域的概念,因此方法内部要访问据以调用此方法的那个对象的属性,必须使用this关键字,按“this.属性名”的语法来访问。

与这个问题相关的还有一个函数体内的名称解析的问题。我看过的JavaScript教材上都说得不太全面。实际上,那种直接引用的名称,其名称解析是在作用域链上进行的;而那种按“obj.属性名”方式引用的名称,其名称解析是在obj的原型对象链上进行的(首先检查obj是否直接定义了同名属性,如果没有,则在其原型对象链上逐层查找)。理解了这一点,就更能搞清前面的this与作用域的瓜葛。

谢廷晟,《JavaScript设计模式》和《深入浅出HTML》的译者。

《JavaScript设计模式》    《深入浅出HTML》



朋友们的留言

  1. amio | 05月 9th, 2010 at 02:24

    “直接引用的名称,其名称解析是在作用域链上进行的;而那种按“obj.属性名”方式引用的名称,其名称解析是在obj的原型对象链上进行的(首先检查obj是否直接定义了同名属性,如果没有,则在其原型对象链上逐层查找)。”

    这个讲得精到

    Reply to this comment
  2. LC | 05月 9th, 2010 at 13:40

    问下 该书的发行时间定下来了么?

    Reply to this comment
  3. lenel | 05月 9th, 2010 at 14:45

    博主咋不把英文原文发出来
    我看到的版本,没有5.5.4这样的序号…
    一通好找,没找到…
    我的理解this怎么都应该指向一个对象.
    scope和对象生成时的context相关,
    像是对象的一个隐式的属性,记载一个scope链,
    所有scope加起来更像是一个树状结构.
    说不清楚,但对象和scope不是层面概念吧…

    期待这本书,第一版确实不错,非常应时,记得对this的解释也是蛮好的.
    想知道zakas第一二版之间,到了YAHOO之后的这几年里是怎么进化的.

    其实更期待写js解释引擎,通读v8源代码的人出的书,
    而不是用js的人边用边猜的输出,即便精通262,没解析器实战也不够.
    博主博闻强识,是否有这方面的推荐?
    老道的有点感觉,特别是那些语法图解,
    有些词法,语法,语义这类意思.不过那个太薄了.
    没有更底层的认识,我想是写不出JsLint,Node.js,
    Java-to-JavaScript Translator以及各种JSCompressor的.

    国内见到的比较少,上届D2上语法高亮有些这个意思,
    不过据amy介绍似乎是借助了flash的内部解析器.
    hax如果不借助外力,就算没有amy快,但却是更牛一些.

    Reply to this comment
  4. 为之漫笔 | 05月 9th, 2010 at 19:51

    @ LC

    发行时间差不多在7月份吧。

    Reply to this comment
  5. 为之漫笔 | 05月 9th, 2010 at 19:56

    @ lenel

    原文:
    The other special object is called this , which operates similar to the this object in Java and C#. It is a reference to the object that the function is operating on — or rather, it is the scope in which the function is being executed (when a function is called in the global scope of a web page, the this object points to window ).

    译文:
    函数内部的另一个特殊对象是this,其行为与Java和C#中的this大致类似。换句话说,this引用的是函数据以执行操作的对象——或者也可以说,this是函数在执行时所处的作用域(当在网页的全局作用域中调用函数时,this对象引用的就是window)。

    Reply to this comment
  6. nickli | 05月 9th, 2010 at 23:35

    顶,网上很多人都说this指向作用域,这其实真的是错误的,this关联函数的执行环境而和作用域没关系。this其实简单点就是说是谁调用了这个函数而已。

    Reply to this comment
  7. 为之漫笔 | 05月 10th, 2010 at 06:49

    @LC

    请给我发邮件,把真实姓名告诉我,以便在译者序中一并致谢(lsf.email[at]gmail.com)。

    Reply to this comment
  8. lenel | 05月 10th, 2010 at 08:46

    JavaScript设计模式–是非常好的一本.看重对OOP的实现全面完整..
    YAHOO系还有一本Stoyan Ftefanov的书,国内没有翻译,很可惜Packt.Publishing.Object.Oriented.JavaScript
    ——————————-

    it is the scope in which the function is being executed
    读到原文,感觉作者这里的scope,不像指语言中一般意义的scope.
    不知道怎么描述,有点context的意思,领地?范围?东西?影响的那片儿? 呵呵….

    ——————————-
    JavaScript精粹,老道有一段比较经典的伪代码,解释什么是new.
    前几天planabc.net上圆心引入的一张图片也很好.

    Reply to this comment
  9. win-google blogs | 05月 10th, 2010 at 22:03

    看不懂,路过的

    Reply to this comment
  10. argb | 05月 11th, 2010 at 16:33

    The other special object is called this , which operates similar to the this object in Java and C#. It is a reference to the object that the function is operating on — or rather, it is the scope in which the function is being executed (when a function is called in the global scope of a web page, the this object points to window ).

    译文:
    函数内部的另一个特殊对象是this,其行为与Java和C#中的this大致类似。换句话说,this引用的是函数据以执行操作的对象——或者也可以说,this是函数在执行时所处的作用域(当在网页的全局作用域中调用函数时,this对象引用的就是window)。

    建议:
    1、or rather 译为“更确切的说”是否更合适?
    2、It is a reference to the object that the function is operating on 这句能否译的更准确,更通俗些,“它是一个到函数执行时所在对象的引用”是否更合理?

    Reply to this comment
  11. soni | 05月 12th, 2010 at 09:29

    我感觉还是 《JavaScript: the good parts》中表述的清楚。

    Reply to this comment
  12. psing.org | 05月 13th, 2010 at 09:24

    一直在等呀,第一版的电子版也看得差不多了,想买第二版的,七月份才上市,有点迟了。

    Reply to this comment
  13. 本心 | 05月 17th, 2010 at 19:55

    都说好了上半年上市,7月份已经是下半年了吧,等这本书等的好辛苦~

    Reply to this comment
  14. 为之漫笔 | 05月 17th, 2010 at 20:48

    @psing.org @本心

    非常抱歉,让朋友们久等了。

    实际上,如果想早出,6月份也是有可能的。但是,我还是对自己的翻译不太放心。所以,上周我又通读了一遍前17章,结果真的又发现了一些错别字和错误。此外,谢廷晟帮忙审校时又发现了其他一些错误和问题。这些天就一直忙着在修改这些错误和问题,所以就耽搁了。

    不过,我相信只要错误更少,大家觉得看着更流畅,即使晚上市一个月(其实也就是6月底和7月初的关系),也是值得的;大家不会白等的。

    Reply to this comment
  15. duanhun87 | 05月 18th, 2010 at 12:09

    博主真是一个认真的翻译者!!相比起犀牛书第五版的译者。。。
    那个叫李强的人可以回家睡了,那种翻译态度真是。。。

    Reply to this comment
  16. duanhun87 | 05月 18th, 2010 at 12:21

    但貌似拿不出时间再看这种大部头书籍了

    Reply to this comment
  17. 本心 | 05月 18th, 2010 at 20:00

    嗯,支持支持~~

    Reply to this comment
  18. myhere | 05月 19th, 2010 at 21:01

    javascript 中函数调用是在定义的作用域执行的,而不是调用所处的作用域

    Reply to this comment
  19. littlebear | 05月 23rd, 2010 at 23:59

    牛人啊, 顶一下

    Reply to this comment
  20. dddkkk01 | 05月 30th, 2010 at 18:31

    说的不错,等书出来了,一定买一本。另外博主能对execute context做一下详细的解读吗?

    Reply to this comment
  21. 凌空一叶 | 06月 19th, 2010 at 09:01

    看到楼上有人提起李强,想起他的《权威指南第五版》,和博主的《jQuery基础教材第二版》里面的两个单词的翻译。

    《权威指南第五版》中文P247正数第13行 13.1.5
    “无干扰的JavaScript的第二个目标是它必须降低优雅性”

    当初一读到这句,就彻底对这人绝望了,以前以为他只是没有js的专业知识,按做英语六级科技文翻译的模式在乱翻译。一看原文:
    The second goal of unobtrusive JavaScript is that it must degrade gracefully.
    这人连副词都当名词来翻译,这种人不学无术也就罢了,偏偏不学有术,弄些机器翻译的来忽悠读者。

    degrade gracefully,这个虽然大概知道是“优雅地降级”但始终觉得这不是很贴切的中文翻译。后来看到博主翻译的《jQuery基础教材第二版》P11页最下面的注解:

    “负责任的jQuery开发者应该在编写自己的程序时,始终坚持循序渐进(progessive enhancemet)和平稳退化(gradual degeradation)”

    博主为了方便读者理解很贴心的将比较重要的单词给出的原文,翻译成“平稳退化”真的很不错。

    再次感谢博主,期待你的《JavaScript高级程序设计(第2版)》,一上市,我们肯定第一时间收藏。

    Reply to this comment
  22. 为之漫笔 | 06月 19th, 2010 at 13:49

    @凌空一叶

    书中把progressive enhancement翻译成“渐进增强”,可不是你说的“循序渐进”啊,呵呵

    Reply to this comment
  23. 凌空一叶 | 06月 20th, 2010 at 12:51

    打字打快了呵呵,谢谢你推荐的php网站。前天在china-pub搜JavaScript高级程序设计(第2版),看见你早前翻译的《Ajax构建工具箱指南》,网站有二手书四折,直接入手,今天拿到书,崭新的,窃喜。看完估计高级程序设计也上市了。

    Reply to this comment
  24. 游客 | 07月 21st, 2010 at 22:21

    请问本站有订阅吗? 没找到

    Reply to this comment
  25. 为之漫笔 | 07月 24th, 2010 at 10:48

    @游客

    http://www.cn-cuckoo.com/rss

    已经在侧栏上方添加,多谢提醒。

    Reply to this comment
  26. denisdeng | 08月 4th, 2010 at 10:23

    关于this,本人认为Dmitry A. Soshnikov在ECMA-262-3 in detail. Chapter 3. This.中讲解的比较透彻。

    Reply to this comment
  27. 为之漫笔 | 08月 4th, 2010 at 19:52

    @denisdeng 这个链接已经前没看到过,回头要仔细研究,多谢。

    Reply to this comment
  28. johnnychen | 09月 4th, 2010 at 15:36

    精彩

    Reply to this comment
  29. johnnychen | 09月 4th, 2010 at 15:44

    这样的话,普通对象,比如var tom = {
    greeting:’Hello from Tom!’
    };
    不能作为”作用域链”的一个环节或者一个”变量对象
    “了?我们自己的作用域链只是函数嵌套函数形成的一条链?

    Reply to this comment
  30. hiro | 10月 31st, 2010 at 13:02

    var t = “1″;
    function a() {

    02 // …

    03 }

    04

    05 function b() {
    var t = “2″;
    06 /// …

    07

    08 return function c() {
    alert(this.t); //输出1
    09 // …

    10 };

    11 }

    12

    13 var d = b();

    14 a();

    15 d();

    Reply to this comment
  31. MessyCS | 12月 18th, 2010 at 01:12

    非常有帮助,特别是结尾部分关于函数体内名称解析的解释。
    // 另:博主对译作的态度非常认真负责,值得学习。

    Reply to this comment
  32. ugg boots | 12月 20th, 2010 at 17:03

    多谢提醒。

    Reply to this comment
  33. lemoncolaz | 12月 30th, 2010 at 11:46

    我给作者写信了,作者回答:Scope” is the wrong word. The value of “this” is determined by the current execution context, and that is determined by how the function is being called. When the function is attached to an object, then “this” is always equal to the value of the object.
    同时感谢依着提醒!!

    Reply to this comment
  34. qxhy123 | 02月 21st, 2011 at 13:39

    正在看这本书,看到这里就在浏览器里输入地址进来瞧瞧了,本来没打算买中文版的,因为有英文版的电子版,嘎嘎,但是看了译者的文章之后决定还是买一本,看了之后是物超所值.

    Reply to this comment
  35. effulgent | 03月 26th, 2011 at 15:25

    最近拜读大作,有几点疑问:
    1、最常见的就是关于“变量声明”和“变量定义”这两个词的混淆和滥用,我是C++程序员,所以对此比较敏感,大作中多次穿插使用这两个词,如p19-3.3“定义变量时要使用var操作符…”、p67“在使用var关键字声明变量时”,具我对JAVASCRIPT的初步了解,貌似此语言中没有变量声明的概念,只有定义。
    2、第2个问题是关于4.2.1 延长作用域链 的问题,关于with和try-catch语句可以在作用域链前段临时增加一个变量对象的说法我存在一些疑问,经测试,with和catch中的变量标识符会优先在函数执行环境中搜寻,而不是在所谓的临时添加的那个变量对象中,所以我觉得是将变量添加到函数现在执行环境中比较可靠,或者说只是和VB一样的语法TRICK更贴切。

    Reply to this comment
  36. Hanzongze Website » 关于JavaScript中的this | 05月 16th, 2011 at 14:23

    [...] 1.《JavaScript高级程序设计》译者李松峰在翻译中指出的原作者关于this见解的错误:http://www.cn-cuckoo.com/2010/05/08/about-one-sentence-of-pro-js-2nd-1626.html [...]

    Reply to this comment
  37. chenky | 07月 4th, 2011 at 02:25

    我认为原著的说法是对的,你举得第二个例子说:“this指向tom,那么f(即e)执行时所处的作用域是什么?显然是全局作用域。” 显然不是全局作用域,是tom的作用域。因为f把e给复制到了tom对象下面。
    请作者参考http://www.quirksmode.org/js/this.html,我认为这里讲的很详细。

    Reply to this comment
  38. 消失的海洋 | 08月 5th, 2011 at 20:43

    支持前面童鞋讲得。
    博主给出的例子中alert(greeting)和this并无关系。
    输出’Hello from global scope!’倒有点困惑。

    Reply to this comment
  39. 仟葉qinyip | 08月 18th, 2011 at 21:26

    答chenky和 消失的海洋,你们错了,博主是对的,“f把e给复制到了tom对象下面”是你想当然地认为的,f里只存在着e函数的引用,也就是说f和e都是指向同一个函数,也就是全局函数,所以第一句alert(greeting)才会输出出’Hello from global scope!’,假设f是把e复制到tom对象下面了,alert(greeting)绝对会输出’Hello from Tom!’

    Reply to this comment
  40. Jeffery | 08月 29th, 2011 at 22:04

    @仟葉qinyip

    “假设 f 是把 e 复制到 tom 对象下面了,alert(greeting) 绝对会输出 ‘Hello from Tom!’” —- 怎么个复制法?请举出例子!不能举出例子你怎么可以断然说别人是错的?‘绝对’又从何而来?

    Reply to this comment
  41. public speaking skills | 09月 16th, 2011 at 00:10

    An interesting dialogue is worth a comment. I feel that you must write more on this matter, it may not be a taboo topic however generally individuals are not brave enough to talk on such topics. To the next. Cheers

    Reply to this comment
  42. zildjian zbt | 09月 16th, 2011 at 00:14

    After researching just a few of the weblog posts on your web site now, and I truly like your approach of blogging. I bookmarked it to my bookmark web site listing and will probably be checking back soon. Pls try my web site as effectively and let me know what you think.

    Reply to this comment
  43. lace table cloth | 09月 16th, 2011 at 00:39

    I am often blogging and i really appreciate your content. The article has really peaked my interest. I am going to bookmark your site and keep checking for new information.

    Reply to this comment
  44. vacation packages | 09月 16th, 2011 at 00:49

    Thank you so much for providing individuals with an extraordinarily wonderful chance to check tips from this website. It is always very enjoyable and full of a great time for me personally and my office peers to visit your blog at minimum thrice in a week to learn the fresh things you have. And of course, I’m so at all times contented considering the surprising pointers you serve. Certain 4 facts in this post are in reality the most effective we have ever had.

    Reply to this comment
  45. corn field maze | 09月 16th, 2011 at 00:54

    Good article , thanks and we want more! Added to FeedBurner as well

    Reply to this comment
  46. computer networking denver | 09月 16th, 2011 at 00:57

    I wish to express appreciation to the writer for this wonderful post.

    Reply to this comment
  47. log home kits | 09月 16th, 2011 at 01:05

    This really answered my problem, thank you!

    Reply to this comment
  48. lyophilization | 09月 16th, 2011 at 01:06

    I wish to express appreciation to the writer for this wonderful post.

    Reply to this comment
  49. amish country lancaster county | 09月 16th, 2011 at 01:20

    You definitely know how to bring an issue to light and make it important. I cant believe youre not more popular because you definitely have the gift.

    Reply to this comment
  50. vw lebanon | 09月 16th, 2011 at 01:23

    very good post, i certainly love this website, keep on it

    Reply to this comment

我来说两句儿

可以在留言中使用以下标签 :<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam Protection by WP-SpamFree