javascript中this指向

在简单函数中,this是指向当前对象,可用来获取当前对象某个属性,但随着函数变复杂,this很多情况不指向当前对象,而是指向window。

1、在独立调用函数中,具有全局执行环境,this指向window。

1  var name="evan";
2  function Name(){
3     this.name="evan2";
4     console.log(this.name) //evan2
5  }
6 Name();
7 console.log(this.name)  //evan2

2. 匿名函数中,this都指向window对象

1  function ftn(){
2        ( function(){
3             console.log(this);// window
4         })();
5     }
6   ftn();
1  function ftn0(){
2         var ftn1 = function(){
3             console.log(this);// window
4         };
5         ftn1();
6     }
7     ftn0();

3、被嵌套的独立函数,this指向window

 1  var a = 0;
 2  var obj = {
 3     a : 2,
 4     foo:function(){
 5             function test(){
 6                 console.log(this.a);
 7             }
 8             test();
 9     }
10  }
11  obj.foo();//0

 在闭包中,也很容易出现这样,函数时立即调用,this指向window

1 var a=0;
2 var obj={
3    a:2,
4    fn:function foo(){
5        return function(){
6           console.log(this.a)
7   }
8 } }
9 obj.fn()(); //0

 这经常是不想得到的结果,用that=this就可以解决

 1  var a=0;
 2  var obj={
 3    a:2,
 4    fn:function foo(){
 5       var that=this;
 6       return function(){
 7         console.log(that.a)
 8       }
 9    }
10  }
11  obj.fn()(); //2

 闭包可以访问所在父函数的变量,所以先在父函数保存this,传递给闭包函数。

 注意:函数的传递

 1   var a = 0;
 2   function foo(){
 3       console.log(this.a);
 4   };
 5   var obj = {
 6       a : 2,
 7       foo:foo
 8   }
 9   var bar = obj.foo; //这行表示把foo函数体传给bar
10   bar();//0

  这相当于

1 var a = 0;
2 var bar = function foo(){
3     console.log(this.a);
4 }
5 bar();//0

 内置函数

1  var a = 0;
2  function foo(){
3       console.log(this.a);
4  };
5  var obj = {
6       a : 2,
7       foo:foo
8  }
9  setTimeout(obj.foo,100);//0

这相当于

1  var a = 0;
2  setTimeout(function foo(){
3       console.log(this.a);
4  },100);//0

间接引用

1  function foo() {
2       console.log( this.a );
3  }
4  var a = 2;
5  var o = { a: 3, foo: foo };
6  var p = { a: 4 };
7    o.foo(); // 3
8  //将o.foo函数赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即执行
9  (p.foo = o.foo)(); // 2
 1  function foo() {
 2      console.log( this.a );
 3   }
 4  var a = 2;
 5  var o = { a: 3, foo: foo };
 6  var p = { a: 4 };
 7   o.foo(); // 3
 8  //将o.foo函数赋值给p.foo函数,之后p.foo函数再执行,是属于p对象的foo函数的执行
 9  p.foo = o.foo;
10  p.foo();//4

call()   把方法绑定到某个对象中

1  var a = 0;
2  function foo(){
3      console.log(this.a);
4  }
5  var obj = {
6      a:2
7  };
8  foo();//0
9  foo.call(obj);//2   把foo方法绑定到obj对象。
 1   function ftn(name){
 2         console.log(name);
 3         console.log(this);
 4     }
 5     ftn("101");
 6     var obj = {
 7       name:"xtq"
 8     };
 9     ftn.call(obj,"102");
10    输出:101
11         Window 
12         102
13         Object {name: "xtq"}
 1 var name = "I am window";
 2 var obj = {
 3     name:"sharpxiajun",
 4     job:"Software",
 5     ftn01:function(obj){
 6         obj.show();
 7     },
 8     ftn02:function(ftn){
 9         ftn();
10     },
11     ftn03:function(ftn){
12         ftn.call(this);
13     }
14 };
15 function Person(name){
16     this.name = name;
17     this.show = function(){
18         console.log("姓名:" + this.name);
19         console.log(this);
20     }
21 }
22 var p = new Person("Person");
23 obj.ftn01(p);
24 obj.ftn02(function(){
25    console.log(this.name);
26    console.log(this);
27 });
28 obj.ftn03(function(){
29     console.log(this.name);
30     console.log(this);
31 });
32 
33 输出:
34 姓名:Person
35 Person {name: "Person"}
36 I am window
37 Window
38 sharpxiajun
39 Object {name: "sharpxiajun", job: "Software"}

new出一个对象时,this指向新生成的对象。

 1  function foo(something) {
 2      this.a = something;
 3  }
 4  var obj1 = {foo: foo};
 5  var obj2 = {};
 6  obj1.foo( 2 );
 7  console.log( obj1.a ); // 2
 8  obj1.foo.call(obj2,3);
 9  console.log( obj2.a ); // 3
10   //在下列代码中,隐式绑定obj1.foo和new绑定同时出现。最终obj1.a结果是2,而bar.a结果是4,说明this被绑定在bar上
11  var bar = new obj1.foo( 4 );
12  console.log( obj1.a ); // 2
13  console.log( bar.a ); // 4

简单说就是:

  • 有对象就指向调用对象  (如对象的方法)
  • 没调用对象就指向全局对象 (如setTimeout、对象的方法中的方法)
  • 用new构造就指向新对象 
  • 通过 apply 或 call 或 bind 来改变 this 的所指。

这篇文章是用于笔记记录,如有错误,望指正

参考:http://www.cnblogs.com/xiaohuochai/p/5735901.html

原文地址:https://www.cnblogs.com/ooooevan/p/5745266.html