在简单函数中,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