this 关键字

javascript 语言中,一切皆对象,运行环境也是对象,所以函数都是在某个对象中运行,this 就是函数运行时所在的对象(函数)。而且,js 支持运行环境的动态切换,也就是说,this 的指向是动态的。

【简单实例】

javascript 允许在函数体内引用当前环境的其他变量

var f = function () {
    console.log(this.x);
}

上述代码中,函数体里面的 this.x 就是指当前运行环境的 x

var f = function () {
    console.log(this.x)
}

var x = 1
var obj = {
    f: f,
    x: 2
}

// window 环境
f() // 1

// obj 环境
obj.f() //2

上面代码中,函数f在全局环境执行,this.x指向全局环境的x;在obj环境执行,this.x指向obj.x

【使用场合】

(1)全局环境

全局环境使用 this,它指的就是顶层对象 window

上面代码说明,不管是不是在函数内部,只要是在全局环境下运行,this就是指顶层对象window

(2)构造函数

构造函数中,this 指的是实例对象

上面代码定义了一个构造函数Obj。由于this指向实例对象,所以在构造函数内部定义this.p,就相当于定义实例对象有一个p属性。

(3)对象的方法

如果对象的方法里面包含thisthis的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。

但是,这条规则很不容易把握。请看下面的代码。

上面代码中,obj.foo方法执行时,它内部的this指向obj

但是,下面这几种用法,都会改变this的指向。

上面代码中,obj.foo就是一个值。这个值真正调用的时候,运行环境已经不是obj了,而是全局环境,所以this不再指向obj

可以这样理解,JavaScript 引擎内部,objobj.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