this 关键字
在 javascript
语言中,一切皆对象,运行环境也是对象,所以函数都是在某个对象中运行,this
就是函数运行时所在的对象(函数)。而且,js
支持运行环境的动态切换,也就是说,this
的指向是动态的。
【简单实例】
javascript
允许在函数体内引用当前环境的其他变量
上述代码中,函数体里面的 this.x
就是指当前运行环境的 x
上面代码中,函数f
在全局环境执行,this.x
指向全局环境的x
;在obj
环境执行,this.x
指向obj.x
。
【使用场合】
(1)全局环境
全局环境使用 this,它指的就是顶层对象 window
上面代码说明,不管是不是在函数内部,只要是在全局环境下运行,this
就是指顶层对象window
。
(2)构造函数
构造函数中,this 指的是实例对象
上面代码定义了一个构造函数Obj
。由于this
指向实例对象,所以在构造函数内部定义this.p
,就相当于定义实例对象有一个p
属性。
(3)对象的方法
如果对象的方法里面包含this
,this
的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this
的指向。
但是,这条规则很不容易把握。请看下面的代码。
上面代码中,obj.foo
方法执行时,它内部的this
指向obj
。
但是,下面这几种用法,都会改变this
的指向。
上面代码中,obj.foo
就是一个值。这个值真正调用的时候,运行环境已经不是obj
了,而是全局环境,所以this
不再指向obj
。
可以这样理解,JavaScript 引擎内部,obj
和obj.foo
储存在两个内存地址,称为地址一和地址二。obj.foo()
这样调用时,是从地址一调用地址二,因此地址二的运行环境是地址一,this
指向obj
。但是,上面三种情况,都是直接取出地址二进行调用,这样的话,运行环境就是全局环境,因此this
指向全局环境。上面三种情况等同于下面的代码。
如果this
所在的方法不在对象的第一层,这时this
只是指向当前一层的对象,而不会继承更上面的层。
上面代码中,a.b.m
方法在a
对象的第二层,该方法内部的this
不是指向a
,而是指向a.b
,因为实际执行的是下面的代码。
如果要达到预期效果,只有写成下面这样。
如果这时将嵌套对象内部的方法赋值给一个变量,this
依然会指向全局对象。
上面代码中,m
是多层对象内部的一个方法。为求简便,将其赋值给hello
变量,结果调用时,this
指向了顶层对象。为了避免这个问题,可以只将m
所在的对象赋值给hello
,这样调用时,this
的指向就不会变。
Last updated