JS中的this
用法很灵活,使用场景不同,this
的指向也会不同。
本文我先给出this
在使用过程中指向的注意点,配合下文示例服用更佳:
this
的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this
到底指向谁,实际上this
的最终指向的是那个调用它的对象this
,但是它没有被上一级的对象所调用,那么this
指向的就是window
,这里需要说明的是在js的严格模式中this
指向的不是window
this
,这个函数有被上一级的对象所调用,那么this
指向的就是上一级的对象this
,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this
指向的也只是它上一级的对象this
永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn
是被对象b所引用,但是在将fn
赋值给变量j的时候并没有执行所以最终指向的是window
,这和例子3是不一样的,例子3是直接执行了fn
例子一:
1function a(){
2 var userName = 'Nitx';
3 console.log(this.userName); //undefined
4 console.log(this); //window
5}
6
7a(); //
解释:等同于window.a(),而this指向的是在函数执行时最终调用它的那个对象,在本例中就是window调用的,而window对象中又没有userName属性
例子二:
1var o = {
2 a : 10,
3 fn : function(){
4 console.log(this.a)
5 }
6}
7o.fn(); //10
解释:fn函数执行时调用this的对象是o,所以this就指向了o,this.uer就是指的o.user的值,这里需求强调下,this的指向在函数创建时是决定不了的,只有当函数被调用时才能决定,谁调用就指向谁
例子三:
1var o = {
2 a : 10,
3 b : {
4 a : 12,
5 fn : function(){
6 console.log(this.a);
7 }
8 }
9}
10o.b.fn(); //12
解释:尽管fn函数被多层对象中的最外层对象o调用,但其中的this仍然指向该函数的上一级对象
//例子四:
1var o = {
2 a : 10,
3 b : {
4 a : 12,
5 fn : function(){
6 console.log(this.a)
7 }
8 }
9}
10
11var j = o.b.fn;
12j(); //undefined
解释:这边怎么又指向window了呢?其实还需要记住一个关于this的关键用法,this永远指向最后调用它的那个对象,这个例子虽然函数fn被对象b所引用,但是在将fn函数赋值给变量j的时候,却没有执行,而最终是变量j()来执行的,那么这个问题又回到j变量是谁调用上来了,此时变量j是window对象下面的属性,所以就是window是最后调用的对象,所以this指向window
例子五 构造函数中的this指向:
1function Foo(){
2 this.userName = 'Nitx';
3}
4
5var foo = new Foo();
6console.log(foo.userName); //'Nitx'
7
8console.log(typeof null) //Object 表示null是一个对象
9console.log(typeof undefined) //undefined 表示undefined是一个undefined类型
解释:new关键字会改变this的指向,把this指向对象foo,为什么说foo是对象,因为用了new关键字就是创建一个对象实例,所以此处从Foo构造函数中new出来的对象实例foo其实就相当于复制了复制了一份Foo到对象实例foo里面,但此时仅只是创建,还没有执行,当调用这个函数Foo时(其实就是代码Foo()表示调用),并且当调用函数Foo的是对象a时,this的指向就变更为指向foo对象实例上面,由于foo对象实例是从Foo构造函数中new出来的,所以Foo具有的各种属性和方法,foo对象实例也会具有。此时 foo.userName === this.userName === 'Nitx'
情况1:
1function fn(){
2 this.user = 'Nitx';
3 return {}; //返回一个空对象
4}
5var a = new fn();
6console.log(a.user) //undefined
情况2:
1function fn(){
2 this.user = 'Nitx';
3 return function(){}
4}
5var a = new fn();
6console.log(a.user); //undefined
情况3:
1function fn(){
2 this.user = 'Nitx';
3 return 1; //返回值不是对象
4}
5var a = new fn();
6console.log(a.user); //Nitx
情况4:
1function fn(){
2 this.user = 'Nitx';
3 return undefined;
4}
5var a = new fn();
6console.log(a.user); //Nitx
总结: 如果return返回值是一个对象,则this就指向那个返回的对象,如果return返回值不是一个对象,则this依旧指向new出来的对象实例。
但是有个例外特殊,就是null,虽然null也是一个对象,但是如果返回值是null的话,this依旧指向new出来的那个对象实例:
1function fn(){
2 this.user = 'Nitx';
3 return null;
4}
5var a = new fn();
6console.log(a.user) //Nitx
最后补充几个知识点: