根据函数的调用方式的不同,this会指向不同的对象
(1)普通函数以及定时器中 this 指向全局对象 window
在普通函数中,示例如下:
function fn(){
console.log('普通函数中的this ' + this);
}
fn() ; //调用过程中我们一般都省略了window,其实调用函数可以写成 window.fn(); 此时 this 被绑定为全局对象,在浏览器环境下为 window对象
打印结果如图所示:
在定时器中,示例如下:
setTimeout(function(){
console.log(this);
},1000); //定时器里的 this 也指向定时器的调用者window ,在定时器前面省略了window,原为
window.setTimeout(function(){
console.log(this);
},1000);
定时器里的 this 也指向定时器的调用者window ,在定时器前面省略了window,所以两种写法打印结果相同。
(2) 函数以对象的方法调用时,方法调用中谁调用this就指向谁
var o = {
sayHi: function(){
console.log('对象方法中的this ' + this); //O 调用 sayhi,所以 this 指向 o 这个对象
}
}
o.sayHi();
打印结果如下:
这里的this指向的对象是o,因为o 调用 sayhi,所以 this 指向 o 这个对象
(3)构造函数中this指向构造函数的实例对象
function Fun(){
console.log(this); //this 指向的是 fun实例对象
}
var fun = new Fun();
在构造函数中this指向这个构造函数的实例对象,在此例中,new关键字返回的是fun对象,因此this指向的就是返回的对象fun;
总结:this指向问题 一般情况下this的最终指向的是那个调用它的对象
了解了this的指向之后,我们再看一个知识点,如何去改变函数内部this的指向?JavaScript为我们专门提供了一些函数办法来处理this的指向问题,下面我将一一介绍。
1、call() 方法
call() 方法调用了一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。
语法:
fun.call(thisArg,arg1,arg2,...)
var o = {
name:'anni'
}
function fn(){
console.log(this);
}
fn(); //window
如这个实例,当我们单纯调用fn() ,this会指向普通函数中的window,当我们添加了call方法之后,就会得到o 对象中的结果,正是因为call()方法可以改变this 的指向。
var o = {
name:'anni'
}
function fn(){
console.log(this);
}
fn.call(o);
结果如图所示:
2、apply 方法
call() 方法调用了一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向,和call()方法一样。
语法:
fun.apply(thisArg,[argsArray])
thisArg:在fun 函数运行时指定的 this 值
argsArray :传递的值,必须包含在数组里面
返回值就是函数的返回值,因为它就是调用函数
var o = {
name:'anni'
}
function fn(arr){
console.log(this);
console.log(arr);
}
fn.apply(o,['hi']);
apply()方法也是调用函数,可以改变函数内部的this 指向
apply() 方法的注意点是调用的时候第二参数必须为数组(伪数组),如果不是数组的话是会报错的奥,注意结果返回的是对象。
3、bind 方法
bind() 方法不会调用函数,但是能改变函数内部的 this 指向
fun.bind(thisArg,arg1,arg2,...)
thisArg :在fun函数运行时指定的this值
arg1,arg2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数
var o = {
name:'anni'
}
function fn(){
console.log(this);
}
var f = fn.bind(o);
f();
bind() 方法不会调用原来的函数,但是可以改变原来函数内部的this指向,返回的是原函数改变this之后产生的新函数。
总结一下三个方法:
相同点:都可以改变函数内部的this指向
区别点:call 和 apply 会调用函数,并且改变函数内部的 this 指向
call 和 apply 传递的参数不一样,call 传递参数 aru1 ,aru2...形式,apply 必须数组形式[arg]
bind 不会调用函数,可以改变函数内部this 指向