引言
- js中,this关键是令人头疼的问题,它的指代对象和this所处的上下文环境、函数调用者等多重因素有关;
- 我们要解决的问题是,this关键字代指哪个对象;
- 本文用丰富的实例让您清晰、明确的判断各种情况下,this关键字所指代的对象;
判断原则:
- 原则一:this指的是直接调用函数的那个对象,没有的话就值window;
- 原则二:this代指的对象就是它使用的时候(不是定义的时候)所处的环境的上下文;
- 原则三:当new关键字出现时,this指代new出来的那个对象;
- this是js关键字,某些程序中出现的that仅仅是普通的变量,不是关键字;
- 下面,我们用实例说话,一一验证上述原则;
无对象调用函数时this指代window的例子
- 例一:
1 | function test(){ |
- 例二:
1 | var x = 1; |
- 例三:
1 | var x = 1; |
- 例四:
1 | var x = 0; |
- 例五:
- 执行第一个this时,function调用者为obj,故this指代obj对象;
- 执行f函数和匿名函数时,函数没有直接的调用者,故this指代window;
1 | var context = "global"; |
有对象调用函数时this指代调用函数者的例子
- 例一:
- o调用了test函数,故this指代对象o
1 | function test(){ |
- 例二:
- getInfo()函数的调用者是ext1,this指代ext1;
- 例三:
- getInfo()函数的调用者是ext1,this指代ext1;
- this.id和this.name都是代指ext1对象的id和name,但是由于ext1对象本身没有name属性,所以需要到原型链上查找name属性;
- 例四:
- 内层的funcion中包含了this,但是,内层function没有直接调用者;
- 故这里的this指window;
- 例五:
- object对象调用了外层函数,所以var that = this中的this指代object对象,执行完此句后,that也指代object对象;
- that并不是js的关键字,仅仅是一个普通的变量,所以下面return that.name的时候,返回的是object.name;
- 例六:
- object对象直接调用了外层的function,故var that = this中的this指代object对象,执行完此句后,that也指代object对象;
- 内层function没有直接调用者,故内层函数中的this指代window;
- 例七:
- point对象调用moveTo方法,故this指代point对象;
1 | var point = { |
- 例八:
- moveX和moveY函数没有调用者,所以其中的this指代window,而不是point对象;
1 | var point = { |
this指代new出来的那个对象
- 例一:
- 由于存在new关键字,this指代的对象是new出来的对象,即对象o;
1 | function test(){ |
- 例二:
- this指代对象o,而不是window;
1 | var x = 2; |
- 例三:
- np对象是new出来的,所以this指代np对象;
- p对象不是new出来的,且Point函数无调用者,故this指代window;
1 | function Point(x,y){ |
- 例四:
- apply使得Point函数的调用者为p2,故this指代p2对象;
1 | function Point(x, y){ |
bind/call/apply重定向this关键字指向
- 例一:
- apply和call将函数的调用者转变了,所以this指代的对象随之转变;
- bind创建一个新的函数,这个函数中的this对象指代的内容也由bind函数指定;
1 | function add(numA, numB){ |
js事件中的this指代
- 例一:
- 前面的一个,console调用者是button对象,故this指代button对象;
- 中间的一个,匿名函数没有直接调用者,所以this指代window;
- 第三个,通过bind重定向函数中的this指向,所以this代表button对象;
1 | document.write('<button onclick="console.log(this)">Show this</button>'); |
- 其他的js事件中的this关键字指代请参考这里;
this关键字指代对象的暂存方法
- 说明:
- 有些时候希望在this指代正确的对象的时候将this指代的对象暂存起来,备用;
- 例一:
- 下面程序将this指代的bar对象暂存到self对象中;
1 | var bar = { |
- 上面的程序也可以用bind实现:
1 | var bar = { |