javascript 中的 this 关键字

what is this? 在 javascript 中,每个 function 都有一个 this 关键字的隐私绑定。当调用某个 function 时,这个 function 的 this 绑定将会被确定。

eg-1:

1
2
3
4
5
6
function test() {
console.log('this is ---', this);
}
test();
 
// this is ---Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}

eg-2:

1
2
3
4
5
6
7
8
var test2 = {
console: function () {
console.log('this is ---', this);
}
};
test2.console();
 
// this is ---Object {console: function}

  • 对于 eg-1 代码执行的结果可以看出,调用 test() 后, test函数 this 绑定的对象是 window 对象。因为在定义 test 函数的时候,这个函数会被加在 window 这个全局对象中,其实在执行 test() 的时候,相当于 window.test(),这样可以明显的看出,调用 test() 的对象是 window,也就是 this 绑定的对象是 window 。

  • eg-2 中,当执行 test2.console() 时,调用 console 方法(函数)的对象为 test2,也就是 console 方法(函数)的 this 的值,就绑定了 test2 对象。

  上面两个例子,描述的只是在函数体内的 this关键字。让我们来看一下,在全局中使用 this:

eg-3:

1
2
3
4
var name = 'aikin';
console.log(this.name);
 
// 'aikin'

  • eg-3这个例子看来,全局对象中的 this,表示的就是全局对象本身(window)。

  通过 eg-1eg-2eg-3 可以知道,在不同的执行上下文中,this 的值是不相同的。即,在全局的执行上文中,this 表示的是全局对象本身(window);在函数执行上文中,this 的值绑定的是调用函数的对象。

接下来做个练习:

1
2
3
4
5
6
function practice() {
console.log('this in practice', this);
}
this.practice();
  
// 打印的结果会是?

  在 javascript 中,随着函数的调用方式不同,将会导致函数的执行上下文不同,也就是将会导致函数内部 this 关键字绑定的对象不同。下面探索一下:构造函数调用方法调用函数调用

a. 构造函数调用

  构造函数和函数其实是一样,如果不使用关键字 new 调用,和其他的普通函数是一样的。

eg-4:

1
2
3
4
5
6
7
8
function  User(name) {
this.name = name;
}

var me = new User ('aikin');
console.log(me.name);
  
//=> 'aikin'

  • 使用 new 操作符来调用 User, 就会将User视为构造函数。 构造函数的调用会将一个全新的对象(也就是 new 出来的对象)作为 this 关键字的绑定对象。

b. 函数调用

  函数调用,也就是直接调用函数,正如上面 eg-1 例子所描述的, 这时 this 绑定的对象是全局对象(window)。

c. 方法调用

  当函数作为一个对象的属性时,这个函数就称为方法。

eg-5:

1
2
3
4
5
6
7
8
9
var obj = {
name : "aikin",
helllo : function () {
console.log('hello, ' + this.name)
}
};
obj.hello();
  
//=> "hello, aikin"

  • 在这个例子(eg-5)中,obj 是 hello 方法的调用者,也就是说,hello 方法中的 this 关键字将会绑定 obj 对象。

所以,

  • 函数调用时,将会将全局对象作为 this 的绑定对象。

  • 方法调用时,方法调用者将会成为 this 的绑定对象。

  • 构造函数,通过 new 关键字来调用后,将会产生一个新的对象作为其 this 的绑定对象。

参考