this究竟指向谁?

Author Avatar
Emily Chan 4月 29, 2017
  • 在其它设备中阅读本文章

this的指向是由它所在函数调用的上下文决定的;而不是由它所在函数定义的上下文决定的。也就是说,函数的调用场景不同,this指向也会相应地有所改变。

函数的不同调用场景

1. 独立的函数调用

在一个独立的函数调用中,非strict模式下,函数中this的指向为window;strict模式下,函数中this的指向undefined。

var x = 1;
function test(){
  alert(this.x);
}
test(); // 1

2. 作为对象的方法调用

在一个方法(绑定到对象上的函数称作方法)内部的this,始终指向当前对象。

function test(){
  alert(this.x);
}
var o = {};
o.x = 1;
o.m = test;
o.m(); // 1

3. 作为构造函数调用

所谓构造函数,即通过这个函数生成一个新对象。此时,this指向这个新对象。

function test(){
  this.x = 1;
}
var o = new test();
alert(o.x); // 1

4. apply调用

为了控制函数中的this指向,可以调用函数本身的apply方法,apply中传入两个参数,第一个是需要绑定的this变量,第二个参数是Array类型的,表示函数本身的参数。

function getAge(){
 var y = new Date().getFullYear();
 return y - this.birth;
}
var bowen = {
 name:'bowen',
 birth:1993,
 age:getAge
};
console.log(bowen.age());//24
console.log(getAge());//NaN
console.log(getAge.apply(bowen,[]));//24

call()方法和apply()类似,区别在于:
apply是将参数打包成array传递;call则是将参数逐个传递。
举个例子,调用Math.max(3,4,5),使用apply和call传参方式如下:

console.log(Math.max.apply(null,[3,4,5]));//5
console.log(Math.max.call(null,3,4,5));//5

var count = 0;
var oldparseInt = parseInt;
window.parseInt = function (){
 count += 1;
 return oldparseInt.apply(null,arguments);
};
console.log(parseInt('10'));
console.log(parseInt('20aaa'));
console.log(parseInt('30bbbe11'));
console.log('count='+count);//3

另,apply()参数为空时,默认调用全局对象。

参考/引用: