说明:《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. hotels near hershey park | 09月 16th, 2011 at 01:29

    Would you be interested by exchanging links?

    Reply to this comment
  2. bathroom remodeling lancaster | 09月 16th, 2011 at 01:31

    Wow, I enjoyed your neat post.

    Reply to this comment
  3. furniture maker | 09月 16th, 2011 at 01:46

    There are actually quite a lot of details like that to take into consideration. That is a great point to deliver.

    Reply to this comment
  4. indianapolis mortgage companies | 09月 16th, 2011 at 02:00

    Aw, this was a very nice post. In thought I want to write like this – taking time and actual effort to make an excellent article is very rare…

    Reply to this comment
  5. computer repair fargo | 09月 16th, 2011 at 02:02

    you have a terrific weblog right here! would you prefer to make some invite posts on my weblog?

    Reply to this comment
  6. cloud computing providers | 09月 16th, 2011 at 02:14

    I was very pleased to find this website. I wanted to thank you for your time for this wonderful post!! I definitely enjoy reading it and I have you bookmarked to check out new stuff you blog post.

    Reply to this comment
  7. ford edge | 09月 16th, 2011 at 02:30

    Can I just say what a relief to find someone who actually knows what theyre talking about on the internet.

    Reply to this comment
  8. sectional garage | 09月 16th, 2011 at 02:36

    Rarely do I encounter a blog that’s both educated and entertaining, and let me let you know, you’ve hit the nail on the head. Your thought is excellent; the issue is something that not enough individuals are speaking intelligently about. I’m very happy that I stumbled across this in my search for info regarding this.

    Reply to this comment
  9. UGG Sheepskin Boots Australia | 09月 19th, 2011 at 09:11

    very nice post, i certainly love this website, keep on it.

    Reply to this comment
  10. Air Yeezy | 09月 27th, 2011 at 22:28

     One must mourn not the death of men but their birth. (Charles Scondat Montesquieu, French thinker and Philosopher)

    Reply to this comment
  11. Ed Hardy T Shirts | 10月 5th, 2011 at 15:39

    Who has deceiv'd thee so oft as thy self?

    Reply to this comment
  12. new era hats | 10月 11th, 2011 at 09:04

    This really answered my problem, thank you!

    Reply to this comment
  13. cheap nike shoes | 10月 13th, 2011 at 15:40

    Thanks for your sharing!

    Reply to this comment
  14. Moncler Quincy Black Grid Bubble Down Jacket | 10月 18th, 2011 at 14:40

    Excellent, I just passed this onto a colleague who was doing a little research on that.

    Reply to this comment
  15. 路远 | 10月 21st, 2011 at 09:50

    我觉得作者说的没有错,
    “this引用的是函数据以执行操作的对象–或者也可以说,
    this是函数在执行时所处的作用域.”
    前半句很好理解,默认定义一个函数,访问这个函数,其this是全局的,
    毫无疑问,如果你把这个函数的引用给了别人.那么这个函数的this
    也就也就给了别人了.”this引用的是函数,据以执行操作的,对象”.
    好好品味一下这句话你就会明白了.
    后半句”或者也可以说,this是函数在执行时所处的作用域.”跟前半句
    一个意思只是换了一个说法. 个人看法,劳驾!
    var greeting = ‘Hello from global scope!’;

    window.greeting = “Hello window”;

    function e(){
    alert(greeting);
    alert(this.greeting);
    }
    e();
    var tom = {
    greeting: ‘Hello from Tom!’
    };
    tom.f = e;
    tom.f();

    Reply to this comment
  16. fake oakley sunglasses | 10月 31st, 2011 at 15:14

    I’m still learning from you, but I’m improving myself. I definitely liked reading everything that is written on your blog.Keep the information coming. I liked it!

    Reply to this comment
  17. china wholesale | 11月 7th, 2011 at 14:44

    Hi, the article is so wonderful, I am interested in it. I will pay attention to your articles.

    Reply to this comment
  18. Ugg Boots | 11月 7th, 2011 at 14:45

    Thank you for your articles!

    Reply to this comment
  19. cheap jerseys from china | 11月 10th, 2011 at 12:02

    Welcome to visiting our jerseys .jerseys from china . jerseys sale products are won highly praise from our customers.
    our goal is to be popular and fashionable vane,offer the best products and service, the most preferential price.

    Reply to this comment
  20. Cheap Jordans | 11月 11th, 2011 at 15:52

    The decline of literature shows the decline of the nation; the two retain within their downwad tendency. (Johann Wolfgang von Goethe German poet)

    Reply to this comment
  21. kkjames | 11月 17th, 2011 at 10:21

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

    我觉得在这里,博主把作用域链与原型链给混淆了。。。具体请看下面的代码:

    var val = 'val from global scope';
    var Tester = (function(){
    var val = 'val from closure scope';
    var handler = {
    val: 'val from handler',
    getVal: function(){
    return val;
    },
    getThisVal: function(){
    return this.val;
    },
    getHandlerVal: function(){
    return handler.val;
    }
    };
    return handler;
    })();

    console.log(Tester.val); // val from handler
    console.log(Tester.getVal()); // val from closure scope
    console.log(Tester.getThisVal()); // val from handler
    console.log(Tester.getHandlerVal()); // val from handler

    Reply to this comment
    • luol17 | 01月 1st, 2012 at 23:30

      我也觉得博主你对你举得的例子的说明本身就有问题,有错误

      var greeting = ‘Hello from global scope!’;

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

      var tom = {
      greeting:’Hello from Tom!’
      };

      tom.f = e;
      tom.f();

      在这里执行tom.f()的时候,相当于就是执行tom的一个方法f。
      那么
      首先会执行 alert(greeting); 这里的greeting是一个变量。在函数e中并没有这个变量,那么会向上找到全局定义的var greeting = ‘Hello from global scope!’;这一句。
      这里没有说明问题呀,怎么会像作者说的会执行 greeting:’Hello from Tom!’这一句呢,这一句是tom的属性。跟alert(greeting);中的greeting完全是两码事。

      不知道你是不是这样理解的。先不说原著那句话是不是对的。但是你用这个例子来说明作者的那句话,我觉得你对这个例子的解释就有问题。
      个人之见,欢迎批评指正。谢谢

      Reply to this comment
  22. fake oakley sunglasses | 11月 25th, 2011 at 14:49

    This is a very informative article.I was looking for these things and here I found it. I am doing a project and this information is very useful me. If you are interested in, but this is my duty to inform you that virtual administrative assistant a very dedicated service and can be applied anywhere you want and get better results.

    Reply to this comment
  23. fake oakley sunglasses | 11月 28th, 2011 at 15:42

    Thanks for sharing,I really like it. I will be back to check some more information on this.

    Reply to this comment
  24. wl | 11月 29th, 2011 at 00:50

    在我看来原书作者的表述是正确的,原书作者明确提到this指向的是运行时的作用域,而博主所列举的第二个例子中的解释是有问题的,”这个例子中的this指向的是什么?显然是tom。那么f(即e)执行时所处的作用域是什么?”这一句里的括号中的“即e”描述是不准确的,在本例中,当函数e和函数f执行时,他们其实是处在不同的作用域中的。不管是e,还是f都只是一个指针,在他们各自的对象不同的时候是不能进行等价的。以上纯属个人见解哈,欢迎博主及各位同行批评指正

    Reply to this comment
  25. fake oakley sunglasses | 12月 9th, 2011 at 14:37

    I’m still waiting for some interesting thoughts from your side in your next post thanks.

    Reply to this comment
  26. casper | 01月 17th, 2012 at 08:36

    英文第三版出了,有沒有要翻成中文呢?

    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