警告
由于Js的this指向存在历史问题以及各种复杂情况,由于本人无法准确的描述this的全貌以及特性,所以本文仅简易的教导基础的this内容,如果出现与本文不符的情况以及知识,请以实际为准。
什么是this
this就是函数在执行的时候所在的作用域,一般默认的this指针指向window,(作用域一个盒子,我们一般声明的函数以及变量都在这个(window指针)里。并且js对象也存在作用域(相当于盒子里又有一个盒子))
为什么需要this
当js引入了this这个特性之后可以更好的控制了数据结构,使写代码的过程中更具有条理性,同时在某些情况下可以将代码反复利用,节省了造轮子的时间,可以用更多的时间用来喝茶摸鱼,相信大家在以后可以逐渐感受到this到底是什么。
函数中的this
如果是我们直接写function函数以及变量的时候,这个函数内的this作用域一般是Windows
对象中的this
当我们声明一个对象的时候,输出this就会发现this从Window变成了对象,也就是说函数的调用作用域不再是window,变成了对象。
举个例子
var testthis={showthis:function(){console.log('我的this是对象',this)}}
Call和Apply
假如两个对象具有几乎相同的函数功能,虽然我们可以使用复制粘贴大法来直接解决,但是有没有更方便的方法呢?这时候就出现了call和apply两个函数,他可以改变某个函数的this指向,来让一个对象调用其他对象的函数。
这里举一个简单的例子
var cat={name:'小猫',eat:function(){console.log(this.name+'在吃饭')}}
小猫对象拥有name变量代表名字以及eat的吃饭函数
如果我们调用cat.eat()会执行对应的函数,this作用域拿到cat对象,并获取了cat.name跟在吃饭拼接,变成了小猫在吃饭
但是如果这时候我们再创建一个小狗
var dog={name:'大黄'}
想让小狗也吃饭,其实并不需要再声明一次函数,直接使用cat.eat.call(dog)就可以了
cat.eat获取了cat对象里的eat函数
call可以改变函数内部的this作用域得指向,call的括号内部就是指向哪个对象,这里我们指向了dog,所以在执行这句代码的过程中cat.eat的this作用域 由于使用了call(dog)而变成了dog
call与apply的功能一致,唯一的区别就是apply是数组传入参数而已。
本质上的this
如果你了解了call和apply,那么我们再回过头来看看函数的调用。
function getthis(){console.log(this)}
getthis()
本质上其实就是
getthis.call()
当call内部没有对象的时候,会默认把传入的当成Windows,所以这时候getthis函数内部的this变成了Windows。
而
var testthis={showthis:function(){console.log('我的this是对象',this)}}
testthis.showthis()
本质上就是
showthis.call(testthis)
testthis.showthis()这条语句的.后边的函数会自动设置点的前方对象作为this的指向
总结
js中的this还存在许多其他奇奇怪怪的问题以及特性,这点大家以实际写代码的情况为准,并不推荐死记硬背,用到哪里记下来就可以了。