关于this的指向问题
概要
在javascript当中每一个function都是一个对象,this是javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用
this出现的场景分为四类
1、有对象就指向调用对象
2、没调用对象就指向全局对象:window是js中的全局对象
3、用new构造就指向新对象
4、通过apply或者call或bind来改变this的指向
1、函数有所有对象时:指向所属对象
举个栗子
var a={value:20};
a.show=function(){
console.log(this.value)
console.log(this)
}
show()这个函数所属对象是a,并由a调用.因此this指向对象是a
函数没有所属对象:指向全局对象
window.name='阿姨请您别把你闺女介绍给我';
function foo(){
console.log(this.name)
}
foo()
构造器中的this:指向新对象
var a=function(){
this.value=100;
}
var p1=new a();
console.log(p1.value);//100
这里面的this指向新对象
apply和call调用以及bind绑定:指向绑定对象
apply()方法接受两个参数第一个是函数运行的作用于,另一个是一个参数数组(arguments)
call()方法第一个参数的意思与apply方法相同,只是其他的参数需要一个个列举出来
简单来说:call的方式更接*我们*时调用函数,而apply需要我们传递Array形式的数组给它。
var a={value:100};
var show=function(){
console.log(this)
}
foo();//全局变了 global
foo.apply(a);//{value:100}
foo.call(a);//{value:100}
var aA=foo.bind(a);
aA();//{value}
关于this的指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向是那个调用它的对象
栗子一:
function a(){
var user='阿姨请不要把您闺女介绍给我';
console.log(this.user);//undefined
console.log(this);//window
}
按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被window对象所点出来的,下面代码可以证明
function a(){
var user='阿姨请不要把您闺女介绍给我';
console.log(this.user);//undefined
console.log(this);//window
}
window.a();
栗子二:
var a={
user:'阿姨请不要把您闺女介绍给我',
fn:function(){
console.log(this.user)
}
}
a.fn()
这里面的this指的是a,因为你调用这个fn是通过a.fn()执行的,那自然指向就是对象a,this的指向在函数创建的时候是觉定不了的,在调用的时候才能决定
栗子三:推翻上面的理论
var a={
user:'阿姨请您不要把您闺女介绍给我'
foo:function(){
console.log(this.user)
}
}
window.a.foo();//输出来是a这个对象里面的user。
为什么不是window呢?按照道理来说this会指向调用它的对象,window是js中的全局对象,而我们创建变量其实是给window添加属性,所以我们可以用window.a
我们在来看一个栗子
var a={
b:10,
foo:{
b:20,
show:function(){
console.log(this)
}
}
}
a.foo.show()
这里面输出的是foo这个对象,为什么会是foo?而不是a!那么下面我们来说一下this的几种情况
1、如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们不讨论严格模式
2、如果一个函数中有this,这个函数有被上一级对象调用,那么this指向的就是上一级的对象
3、如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。上面的例子可以证明
栗子四:继续探讨第三种情况
var a={
b:10,
foo:{
show:function(){
console.log(this.b)
}
}
}
a.foo.show()//undefined
尽管对象foo中没有a这个属性,这个this指向的也是对象foo,因此this只会指向它的上一级对象,不管这个对象中有没有this要的东西
栗子五:特殊情况
var a={
b:10,
foo:{
b:20,
show:function(){
console.log(this.b);
console.log(this)
}
}
}
var j=a.foo.show;
j()
//第一次输出是undefined
//第二次输出的是window
这里的this指向是window,为什么会这样?我们要清楚一句话this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,上面的案例中show被foo引用,但是在将show赋值给变了j的时候并没有执行,所以最终指向是window