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

学习中文指指

时间:2023-03-27 10:15:07 JavaScript

学习中文指指要知道中文第一人称、第二人称、第三人称的区别,先看一则新闻“我体内的恶魔被锁住了这么多年了,现在链子松了。”“我很害怕,很孤独,我很迷茫,我会反击我痛苦的源头——社会,我想尽我所能去伤害这个社会,然后死去。”这段令人毛骨悚然的文字是发生在美国北达科他州的一系列凶杀案,作者是嫌疑人约瑟夫·邓肯,写于2005年5月11日。将近两个月后,当人们看到这篇文字时,他残忍地杀害了一个5口之家的3名成员,并绑架了另外2名儿童8岁和9岁。假设,你是一名警察,你抓到一个嫌疑人,你在他家里发现了这本日记,这一刻你有什么感觉?你一定在想,如果这是嫌疑人自己写的,这不就等于认罪了吗?当然,犯罪嫌疑人也可以辩称,这本日记根本不是我写的,只是我从网上抄来的一段话。其实,我们只需要对上面的这段话稍加改动,这个有力的杀人证据,瞬间就没那么强大了。他心中的恶魔被束缚了这么多年,现在束缚松了。他害怕、孤独、迷茫,他要反抗他的痛苦之源——社会,他想尽可能地伤害社会,然后死去。你找到了吗?只是把第一人称改成了第三人称。正因为如此,很难给嫌疑人定罪。因为它看起来很像小说,为什么会有这样的差异?带着对这个问题的思考,让我们开始今天所指的研究。1.this的英文含义先用英文解释一下:this:这样,我们接下来看一段代码:varobj={show:function(){console.log(this)}}obj.show();结果很容易预料,打印obj对象本身在JS中,这是一个关键字,即可以理解为系统内置的命令。通常,我们将其含义解释为:当前对象。那么问题来了:当前对象指的是谁?羊毛布?在上面的代码案例中,this代表对象obj接下来我们看一段代码functionshow(){console.log(this);}show();结果打印window对象如果你对打印结果感到奇怪,那么你可能忽略了一个常识性问题。window对象可以省略!所以,上面的代码实际上等价于:functionshow(){console.log(this);}window.show();让我们看一个关于事件绑定的常见例子btn.onclick=function(){console.log(this);}btn.onclick();//手动调用函数//鼠标点击按钮,也可以浏览器自动调用函数最后不管是手动调用还是鼠标点击时浏览器自动调用打印出来的结果都是btn对象2.我们似乎总结出了一个规律,就是这一点。对象本身就假设这个结论是真的,那么我们不妨验证一下我们的猜想吧!!功能显示(){console.log(this);}window.show();//打印窗口对象varobj1={};obj1.show1=show;obj1.show1();//打印obj1对象varobj2={};obj2.show2=obj.show1;obj2.show2();//打印obj2对象从上面的代码示例可以看出,window对象、obj1对象和obj2对象共享一个函数showwindow.show=obj1.show1;//truewindow.show=obj2.show2;//真正的三个对象,使用相同的函数但打印出来这是不同的window.show();打印出窗口对象obj1.show1();打印出obj1对象obj2.show2();打印出obj2对象似乎再次证明了这一点。我们刚才的猜想:函数是从哪个对象调用的,this指向哪个对象3.科学严谨。在下结论之前,我们还是要反复验证,再看一个例子:btn.onclick=duction(){setTimeout(function(){console.log(this);},0)}btn.onclick();其实我只是在原来的代码中加了一个延时器,如果时间设置为0,打印出来的这个会不会有变化??你可以先考虑一下。通常,根据直觉,我们认为延迟器只是延迟了执行时间,打印结果仍然是btn对象,没有变化。但是经过测试发现,实际的打印结果是window对象,这是我们刚才猜测的错误。然而?为了解释这个现象,我们不得不重新观察这段代码,注意到代码中有两个函数。我们分别将它们命名为函数A和函数B。根据我们刚才的猜测:函数被哪个对象调用,this就指向那个对象。那么,这个点将取决于它所在的功能以及这个功能,它是功能A还是功能B?其实从代码中不难看出,this明明是在函数B里面,所以结果没有打印btn,现在我们也不奇怪了,因为this已经不在函数A里面了,而是在函数里面B的,你可能还会问,为什么B函数中的this指向window?这其实是一个特例。我们不知道哪个对象调用了传入定时器的函数。这都指向窗口。暂时记住这条规则。当你学完作用域链,你就能明白它的精髓了4.回到最开始的新闻,假设日记是嫌疑人写的,但是日记全是第三人称。那么就很难说“他”是谁了。反之,如果日记是用第一人称写的。那么“我”肯定是指嫌疑人自己的JS函数中的this关键字,相当于我们说话中的第一人称代词I。比如这个例子中:A对B说:“我要杀了你!”这里我指A,你指BB,对A说:“我杀了你!”这里我指B,你指A所以你看,同一个词可以指任何人,关键看Fromwhomtosayfunction(){//这个,相当于中文里的我//不要askthiswillpointtowhointhefirstline//我们必须弄清楚最后谁会调用fn函数(完全取决于这句话是谁说的)//如果我们搞不清楚问题,就没有重点在讨论这一点console.log(this);}5.至此,我们差不多可以得出结论了,让我们用几个练习来最终验证一下varobj={show:function(){console.log(this);}}btn.onclick=function(){window.setTimeout(function(){obj.show();},100)}btn.onclick();上面的代码最终打印出obj对象。无论我们经历多少波折,最后只能看到一个结论,那就是哪个对象调用了this所在的函数?我进一步修改了代码,100)}上面的代码最终会打印出obj对象。当然,总会有一些例外,例如:functionm1(){functionm2(){console.log(this);}m2();}m1();我们不禁要问,函数m2调用的是哪个对象呢?我们竭尽所能,结果证明一切都是错误的。我们还不知道这个m2是被哪个对象调用的,好像就是这么执行的一样,但是实际的打印结果呢?毫不奇怪,它仍然是窗口对象的最终结论。所有的this关键字只有在函数运行时才能确定,它指向的函数被哪个对象调用,this会指向谁。函数执行时,没有明确的调用对象,则this指向window6。由此衍生出来的问题正好留下了一个没有解决的问题btn.onclick=function(){setTimeout(functioni(){console.log(this);},0)}btn.onclick();我们希望它指向btn,但现在它指向window。如何解决这个问题?方法有很多种如果你不知道call,apply,bind,那恐怕你只能理解methodA//methodabtn.onclick=function(){varself=this;//用变量保存this,self的值为setTimeout(function(){console.log(self);},0);}//methodbbtn.onclick=function(){varself=this;//使用变量保存这个函数fn(){console.log(this);}setTimeout(function(){fn.call(self);//使用call方法调用函数,强制this为self对象},0)}//methodcbtn.onclick=function(){varself=这个;//使用一个变量来保存这个函数fn(){//把代码写在一个函数中fnconsole.log(this);}setTimeout(function(){fn.apply(self);//使用apply方法调用函数,强制指定this为slef对象},0)}//methoddbtn.onclick=function(){setTimeout(function()){console.log(this);}.bind(this),0);//使用bind方法将定时器函数的this强制绑定到时间函数的this上}7.接下来的内容,学完ES6的箭头函数就来1.如何判断箭头函数的this?因为箭头函数没有自己的this,很简单,假装不存在,像这样:现在this的方向很明确了吧?2、箭头函数可以用call改变this的方向吗?不能!!试图改变箭头函数的this是徒劳的varfnn=()=>{console.log(this);}fnn.call(document);//仍然打印window8。最后一个特例构造函数1.什么是构造函数?假设有一个函数Fn,我们有两种调用方式。一般用new关键字调用Fn()调用newFn()第二种调用方式,函数变成构造函数注意在构造函数中,我们上面说的结论是不成立的!!2.构造函数中的this是谁?请期待下一篇文章《构造函数与class》