Chinaunix首页 | 论坛 | 博客
  • 博客访问: 817887
  • 博文数量: 62
  • 博客积分: 526
  • 博客等级: 二等列兵
  • 技术积分: 2078
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-04 20:41
个人简介

博客迁移至 freefe.cc

文章分类

全部博文(62)

分类: JavaScript

2013-04-30 22:05:46

简单的实例

e.g.1

  1. var name = "I am window";
  2. var obj_test={
  3.   name:"I am obj_test",
  4.   show_name:function(){
  5.    console.log(this.name);
  6.   },
  7.   wait_show:function(){
  8.       setTimeout(this.show_name,100);
  9.   }
  10. }
  11. obj_test.show_name();
  12. obj_test.wait_show();

其答案为:

很显然,我们可以清楚的理解第一个输出为 "I am obj_test",但是第二个 "I am window" 对于一些理解this不是很深的同学就有点迷惑了。先不急,再来看第二个例子。

e.g.2

  1. var name = "I am window";
  2. function show_name(){
  3.   console.log(this.name);
  4. }
  5. var obj_test={
  6.   name:"I am obj_test",
  7.   wait_show:function(){
  8.       setTimeout(show_name,100);
  9.   }
  10. }
  11. show_name();
  12. obj_test.wait_show();

答案:

上述可能能马上理解,也可能无法下手,那么来综合的讲一下关于 this。对于一般的我们可以作以下的理解。


4种函数调用方式的 this

先来说说4中基本的函数调用方式的this指向:

  1. 纯粹的函数调用 - Function Invocation Pattern

e.g.3

  1. function test(){
  2.   console.log(this);
  3. }
  4. test();

很简单的一个函数调用,对于纯粹的函数调用,内部的this均指向于window。实质上是纯粹的函数调用均是相当于在window对象下调用。

e.g.4

  1. function test(){
  2.   console.log(this);
  3. }
  4. console.log(window.test() === test());

答案当然为true。均为指向 window对象。

2. 作为方法调用 - Method Invocation Pattern

e.g.5


  1. var obj = {
  2.   name:"I am obj",
  3.   show_name:function(){
  4.     console.log(this.name);
  5.   }
  6. }
  7. obj.show_name();



很显然上述代码会输出 I am obj,从上述来看本质与 点1是一样的。当函数被作为方法被某一个对象调用的时候,方法内部的this会指向调用该方法的对象。

3. 构造函数式调用 - Constructor Pattern

对于构造函数的this值都知道会指向新构造的对象。

e.g.6


  1. function A(){
  2.   this.cons = "A";
  3. }
  4. var a = new A();
  5. console.log(a.cons );

但是对于构造函数来说一个很严重的弊端就是我们遗忘了new的时候,那么构造函数并非是被作为构造函数来new出一个新的对象,而是以纯粹函数的方式进行调用,不会有任何的报错,但是却会污染全局变量导致一些难以发现的BUG

4. apply 调用 - Apply Pattern

apply 与 call 除了参数形式不尽相同外,都是用来手动的可以切换this的指向。

e.g.7


  1. var name = "window";
  2. function show_name(){
  3.   console.log(this.name);
  4. }
  5. show_name.apply({name:"object"});



稍微复杂一点的 this


上半篇主要介绍了简单的基本 this 指向判定,接下来理清一些较为绕的 this 指向。

e.g.8


  1. var name = "window";
  2. function a(){
  3.   var name = "a";
  4.   function b (){
  5.     console.log(this.name);
  6.   }
  7.   b();
  8. }
  9. a();

即使ba内部调用,但是b的调用依旧是纯粹的函数调用,所以b内部的this依旧指向的是window对象。(该说法其实并不准确)

e.g.9


  1. var name = "I am window";
  2. var obj_test={
  3.   name:"I am obj_test",
  4.   show_name:function(){
  5.    console.log(this.name);
  6.   },
  7.   wait_show:function(fn){
  8.        fn();
  9.   }
  10. }

  11. obj_test.wait_show(obj_test.show_name)


首先要知道 参数传入的部分 obj_test.show_name 传入近函数的仅仅只是一个函数(更准确的说应该是一个执行函数的地址),然后执行中便成了纯粹的函数调用。在作为参数传入后就不在会有调用的从属关系。(可以这么简单的理解,但是这个不是很正确的。)

所以对于文章头部的2个实例也是这个道理,setTimeout 也是相当于e.g.9中的wait_show。

更奇怪的 this 指向


  1. var foo = {
  2.   bar: function () {
  3.     console.log(this);
  4.   }
  5. };
  6.  
  7. foo.bar();
  8. (foo.bar)();
  9. (foo.bar = foo.bar)();
  10. (false || foo.bar)();
  11. (foo.bar, foo.bar)();



那么,深入了解this的机制


简单的来说,说有的关于this的取值均为与函数的上下文有关,在进入上下文的时候就产生并且不在改变。对于方法中的 this 等价于在该方法引用类型在进入上下文过程中便记录的调用该方法的对象,并且在方法中的this指向于这个对象。

      在全局中调用函数相当于 全局 来调用的方式,所以 this 会指向全局,而全局就等价与 window 所以该 this 便等于 window。
      而在一般的函数中在纯粹的调用函数的时候,其实是当前的 活动对象 (AO) 对该函数进行调用,而该AO在之后是无法被我们访问的,出了这个上下文便不存在变为null,那么就相当于 null 对函数的调用,那么会被默认 this 指向全局,即window。(完全是个人简单的理解)

对于this 也并非那么简单,还是需要和执行环境等相挂钩,能力有限想要理解更深请参考重点推荐
    http://www.cnblogs.com/TomXu/archive/2012/01/17/2310479.html对于深入理解~

http://www.cnblogs.com/KevinYang/archive/2009/07/14/1522915.html

http://www.cnblogs.com/rush/archive/2012/07/31/2617429.html

http://www.cnblogs.com/TomXu/archive/2012/01/17/2310479.html

http://www.cnblogs.com/rubylouvre/archive/2009/11/13/1602122.html

http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html

阅读(1863) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~