当前位置: 首页 > Web前端 > JavaScript

JavaScript中的this指向

时间:2023-03-27 01:06:30 JavaScript

在javascript语言中,有一个奇怪的“关键字”,叫做this。为什么这么奇怪?就是因为你写100个这个,可能有100个解释,完全不相关。但是,在你的学习过程中,如果你弄清楚了这个东西,对你的发展事业会有很大的帮助。下面我们就来一点一点的了解一下。第一次看到的时候,先给他翻译一下。”这是什么意思?饭桌上,你妈跟你说,在这家店里多吃点东西,你儿媳妇跟你说,我宴会上会有这个包,这个包,这个包,你爸介绍给别人,这个傻孩子是我儿子。不是的,就像我们js中的this一样,每一个this的意思都是一样的,但是我们会发现在说话的过程中,“this”是和我们说话的手势有关的,在js中,this表示它有一些东西用代码的“手势”来做。例子:当你老婆指着一个LV包的时候,“这个”指的是LV包。当你妈妈指着鱼香肉丝时,她说“this”指的是鱼香肉丝,所以javascript中的this就是看“这句话的代码指向哪里”看下面这段codevarbox=document.querySelector('#box')box.onclick=function(){console.log(this)}当你点击box元素的时候,会触发下面的函数,然后一旦函数执行完毕,它会在控制台打印this,这里this是box元素,this是一个很简单的this指向的例子,接下来我们就开始详细研究this给大家一个概念,this,是一个指针变量,它是动态的指向当前函数的运行环境,“什么鬼,我不懂”,给出个人解释:“根据this所在函数的调用方式来判断this是什么。”比如看atfunctionfn(){console.log(this)}fn()//thisiswindow因为this在fn函数中,所以fn函数的调用方式决定this函数是什么a(){functionb(){console.log(this)}b()}a()//thisiswindow因为this在函数b内部,所以函数b的调用方法决定了this是什么,和它无关具有功能a.这就是它的意思。最后,根据这些年的经验,给出一个私人的概念。您必须记住,函数的this和定义函数的位置并不重要。函数是如何定义的并不重要。只依赖于这个函数的调用方式,箭头函数除外。对象调用objectcall,以对象为宿主调用函数,最简单的方法是把函数写在对象中,用对象调用//在对象中写函数constobj={fn:function(){console.log(this)}}//调用这个函数obj.fn()这个时候我们调用这个对象中的fn函数。调用函数的方法是使用对象调用的函数,所以这个函数中的this就是obj的对象。也就是说,只要在这个函数中,只要出现this,就是这个对象的全局调用。顾名思义,全局调用就是直接调用一个全局函数functionfn(){console.log(this)}fn()这时候这个函数里的this就是window,可能有朋友认为是疯了,但是如果我们仔细想想,你会发现因为fn是全局的,所以完整的调用方式可以写成window.在路上,这会让陌生电话变得顺畅。这时候可能有朋友会想到一个问题,如果这个函数不放在全局呢?constobj={fn:function(){functionfun(){console.log(this)}fun()}}obj.fn()此时的this应该是什么?按照之前的思路,○obj.fn()确实调用了函数,但是这个不在obj.fn函数中,是在fun函数中,○fun()确实调用了函数,但是我没办法写成window.fun(),○那么这个是window吗,还是应该在obj里?答案确实是窗口,那是为什么呢?稍微想一想,我们就会发现,这真的很奇怪o( ̄︶ ̄)o想不通。如果我按照这个方法,我来来回回你要记住多少种,谁来记住?接下来(划重点)我以30年写代码的经验为大家总结了一些内容。我希望你能记住这个个人经历。首先,这是在各种情况下使用的。下次就不一样了,以后我会把我总结的内容毫无保留的传给大家。经验一:适用于js的非严格模式适用于非箭头函数不管函数定义在什么地方,不管函数是怎么定义的,看函数的调用方法就可以了。只要想知道这是谁,就看this写在哪个函数里,这个函数是怎么调用的。观察this在functionfn()中是哪个函数{console.log(this)}//this是在函数fn中,看fn函数怎么调用就知道this是谁了constobj={fn:function(){console.log(this)}}//this在obj.fn函数里,看这个函数怎么调用就知道这是谁了constobj={fn:function(){functionfun(){console.log(this)}}}//thisthis在fun函数里面//如果你想知道这是谁//和obj.fn函数无关,只要你知道fun函数是怎么做的被调用时,一定要注意:想知道this在哪个函数中,只要观察调用了哪个函数即可。一些常用的函数调用方式普通调用方式:函数名()thisiswindow只要你写“函数名()”来调用一个函数,那么这个函数中的this就是windowfunctionfn(){console.log(this)}fn()//这里是fn()调用了一个函数,那么fn中的this就是windowconstobj={fn:function(){functionfun(){console.log(this)}fun()}}obj.fn()//这里的this在fun函数里面//fun()调用这个fun函数//所以不管fun函数写在哪里//这个thisinthisfunfunction是window2,调用对象的方法:object.functionname()object'functionname'this是thisobject,调用的对象是什么,调用的函数中this是什么constobj={fn:function(){console.log(this)}}obj.fn()//因为obj.fn()调用了这个函数,所以obj.fn函数中的this就是objconstxhl={fn:function(){console.log(this)}}xhl.fn()//因为obj.fn()调用了这个函数,所以xhl.fn函数中的this就是xhlfunctionfn(){constxhl={fn:function(){console.log(this)}}xhl.fn()}fn()//因为我们要观察的this在函数内部xhl.fn//所以我们只需要关注这个函数是怎么调用的//因为它是xhl.fn调用了这个函数,所以函数里的this是xhl3,定时器调用方法setTimeout(function(){},1000)setInterval(function(){},1000)this不管怎样都是window的函数定义了,只要是作为定时器处理函数使用的,thisiswidnowsetTimeout(function(){console.log(this)},1000)//这里this是windowssetInterval(function(){console.log(this)},1000)//这里是windowconstxhl={fn:function(){console.log(this)}}setTimeout(xhl.fn,1000)//这里的xhl.fn函数并没有直接写调用xhl.fn()//而是给了setTimeout定时器处理函数//所以这里是window4,事件处理函数调用方法eventsource.oneventtype=eventprocessingfunctioneventsource.addEventListener(eventtype,eventprocessingfunction)这个是事件源只要是作为事件处理函数使用的,那么函数中的this就是事件源,顺便说下事件是:在事件中,当前正在操作的元素是事件源)//这里的this是boxconstxhl={fn:function(){console.log(this)}}box.addEventListener('click',xhl.fn)//这里的xhl.fn函数并没有直接写成调用xhl.fn()//但是给了事件,它被用作事件处理程序//所以这里是事件Sourceboxconstxhl={fn:function(){console.log(this)}}box.onclick=xhl.fn//这里的xhl.fn函数并没有直接写调用xhl.fn()//而是给定Event,作为事件处理器使用//所以这里是事件源box5,调用构造函数.新函数名()this是构造函数的当前实例。只要用new关键字调用就是实例对象functionfn(){console.log(this)}constf=newfn()//这里是因为fn函数和new关键字在一起//所以这就是fn函数的实例对象//即fconstxhl={fn:function(){console.log(this)}}constx=newxhl.fn()//这里是xhl。fn也是因为和new关键字一起//所以这里的this是xhl.fn函数的实例对象//也就是记住清楚x的原则:不管函数是在哪里定义的,不管函数是怎么定义的function是定义好的,只依赖于函数的调用方式经验二:适用于严格模式。事实上,只有一个。全局函数没有this,这是undefined。其他的可以照搬经验1.非严格模式//非严格模式functionfn(){console.log(this)}fn()//因为是非严格模式,所以这里的this是window2。严格模式//严格模式'usestrict'functionfn(){console.log(this)}fn()//因为是在严格模式下,所以这里的this是undefined原理记住清楚:在严格模式下,全局的function没有this,也就是undefined经验3:具体说说箭头函数,其实只有一个把前面的内容都推翻了,箭头函数没有自己的this,就是箭头函数中的this箭头函数是外部作用域的this。换句话说,当你需要判断箭头函数中的this时,它与函数的调用方式无关,取决于函数的定义位置//非箭头函数constxhl={fn:function(){console.log(this)}}xhl.fn()//因为是非箭头函数,所以这里的this是xhl//==============================================================//箭头函数constxhl={fn:()=>{console.log(this)}}xhl.fn()//因为是箭头函数,前面的经验不适用//这个函数外面其实是全局的,所以这里的this是window//非箭头函数框。onclick=function(){console.log(this)}//因为是非箭头函数,所以这里的this是box//=================================================================//箭头函数框.onclick=()=>{控制台。log(this)}//因为是箭头函数//这个函数外面是全局的,所以这里的this是window//非箭头函数constobj={fn:function(){functionfun(){console.log(this)}fun()}}obj.fn()//因为是非箭头函数,所以fun函数中的this是window//==============================================================//箭头函数constobj={fn:function(){constfun=()=>{console.log(this)}fun()}}obj.fn()//因为是箭头函数//那么thisfun外面其实是一个obj.fn函数//所以只要知道obj.fn函数里的this是谁,然后fun函数里的this就出来了//因为obj.fn函数里的this是obj//所以this里的funfunctionisobj把原理记住清楚:只要是箭头函数,不管函数怎么调用,都要看函数定义在哪里。根据以上三个经验,记住原则,看到这个不要慌张