欢迎进入教育资讯网!
当前页面: 首页 > 电脑IT培训 > Web前端 > web培训中JavaScriptthis指的是什么?这篇说的真的太清楚了!

web培训中JavaScriptthis指的是什么?这篇说的真的太清楚了!

来源:教育资讯网 139 2021-08-20

  因为工作原因,经常关注有关互联网行业的***动态。说起到WEB的工作,如今这个市场行情,做WEB前端开发工作,没有经验不好找工作,但是基础的操作都不会,按时压根就找不到工作啊。所以,由于市场的引导,web培训机构也是层出不穷。web培训发展已十余年之久,服务与课程体系都已成熟。而且还是包就业哦!那么***小编先给大家说点实际的吧!我们***带来的是web培训课程中JavaScript

  this的应用。

  要说JavaScript这门语言**容易让人困惑的知识点,this关键词肯定算一个。JavaScript

  语言面世多年,一直在进化完善,现在在服务器上还可以通过node.js来跑JavaScript。显然,这门语言还会活很久。

  所以说,我一直相信,如果你是一个JavaScript开发者或者说web开发者,学好JavaScript

  的运作原理以及语言特点肯定对你以后大有好处。

  开始之前

  在开始正文之前,我强烈推荐你先掌握好下面的知识:

  变量作用域和作用域提升

  JavaScript的函数

  闭包

  如果没有对这些基础知识掌握踏实,直接讨论JavaScript的this关键词只会让你感到更加地困惑和挫败。

  什么是this?

  在我开始讲解前,如果你学过一门基于类的面向对象编程语言(比如C#,Java,C++),那请将你对this

  这个关键词应该是做什么用的先入为主的概念扔到垃圾桶里。JavaScript的this关键词是很不一样,因为JavaScript

  本来就不是一门基于类的面向对象编程语言。

  虽说ES6里面JavaScript提供了类这个特性给我们用,但它只是一个语法糖,一个基于原型继承的语法糖。

  this就是一个指针,指向我们调用函数的对象。

  我难以强调上一句话有多重要。请记住,在Class添加到ES6之前,JavaScript中没有Class这种东西。Class

  只不过是一个将对象串在一起表现得像类继承一样的语法糖,以一种我们已经习惯的写法。所有的魔法背后都是用原型链编织起来的。

  如果上面的话不好理解,那你可以这样想,this的上下文跟英语句子的表达很相似。比如下面的例子

  Bob.callPerson(John);

  就可以用英语写成“BobcalledapersonnamedJohn”。由于callPerson()是Bob发起的,那this

  就指向Bob。我们将在下面的章节深入更多的细节。到了这篇文章结束时,你会对this关键词有更好的理解(和信心)。

  执行上下文

  执行上下文是语言规范中的一个概念,用通俗的话讲,大致等同于函数的执行“环境”。具体的有:变量作用域(和

  作用域链条,闭包里面来自外部作用域的变量),函数参数,以及this对象的值。

  引自:Stackoverflow.com

  记住,现在起,我们专注于查明this关键词到底指向哪。因此,我们现在要思考的就一个问题:

  是什么调用函数?是哪个对象调用了函数?

  为了理解这个关键概念,我们来测一下下面的代码。

  varperson={

  name:""Jay"",

  greet:function(){

  console.log(""hello,""+this.name);

  }

  };

  person.greet();

  谁调用了greet函数?是person这个对象对吧?在greet()调用的左边是一个person对象,那么this关键词就指向

  person,this.name就等于""Jay""。现在,还是用上面的例子,我加点料:

  vargreet=person.greet;//将函数引用存起来;

  greet();//调用函数

  你觉得在这种情况下控制台会输出什么?“Jay”?undefined?还是别的?

  正确答案是undefined。如果你对这个结果感到惊讶,不必惭愧。你即将学习的东西将帮助你在JavaScript旅程中打开关键的大门。

  this的值并不是由函数定义放在哪个对象里面决定,而是函数执行时由谁来唤起决定。

  对于这个意外的结果我们暂且压下,继续看下去。(感觉前后衔接得不够流畅)

  带着这个困惑,我们接着测试下this三种不同的定义方式。

  我为什么要学this?

  如果上面的简单介绍没有说服你来深入探索this关键词,那我用这节来讲讲为什么要学。

  考虑这样一个重要问题,假设开发者,比如DouglasCrockford(译者注:JavaScript领域必知牛人),不再使用new和

  this,转而使用完完全全的函数式写法来做代码复用,会怎样?

  事实上,基于JavaScript内置的现成的原型继承功能,我们已经使用并且将继续***使用new和this关键词来实现代码复用。

  理由一,如果只能使用自己写过的代码,你是没法工作的。现有的代码以及你读到这句话时别人正在写的代码都很有可能包含this

  关键词。那么学习怎么用好它是不是很有用呢?

  因此,即使你不打算在你的代码库中使用它,深入掌握this的原理也能让你在接手别人的代码理解其逻辑时事半功倍。

  理由二,拓展你的编码视野和技能。使用不同的设计模式会加深你对代码的理解,怎么去看、怎么去读、怎么去写、怎么去理解。我们写代码不仅是给机器去解析,还是写给我们自己看的。这不仅适用于

  JavaScript,对其他编程语言亦是如此。

  随着对编程理念的逐步深入理解,它会逐渐塑造你的编码风格,不管你用的是什么语言什么框架。

  就像毕加索会为了获得灵感而涉足那些他并不是很赞同很感兴趣的领域,学习this会拓展你的知识,加深对代码的理解。

  找出this的指向

  上一节我们已经对this做了测试。但是这块知识实在重要,我们需要再好好琢磨一下。在此之前,我想用下面的代码给你出个题:

  varname=""JayGlobal"";

  varperson={

  name:'JayPerson',

  details:{

  name:'JayDetails',

  print:function(){

  returnthis.name;

  }

  },

  print:function(){

  returnthis.name;

  }

  };

  console.log(person.details.print());//?

  console.log(person.print());//?

  varname1=person.print;

  varname2=person.details;

  console.log(name1());//?

  console.log(name2.print())//?

  console.log()将会输出什么,把你的答案写下来。如果你还想不清楚,复习下上一节。

  准备好了吗?放松心情,我们来看下面的答案。

  答案和解析

  person.details.print()

  首先,谁调用了print函数?在JavaScript中我们都是从左读到右。于是this指向details而不是

  person。这是一个很重要的区别,如果你对这个感到陌生,那赶紧把它记下。

  print作为details对象的一个key,指向一个返回this.name的函数。既然我们已经找出this指向details

  ,那函数的输出就应该是'JayDetails'。

  person.print()

  再来一次,找出this的指向。print()是被person对象调用的,没错吧?

  在这种情况,person里的print函数返回this.name。this现在指向person了,那'JayPerson'

  就是返回值。

  console.log(name1)

  这一题就有点狡猾了。在上一行有这样一句代码:

  varname1=person.print;

  如果你是通过这句来思考的,我不会怪你。很遗憾,这样去想是错的。要记住,this关键词是在函数调用时才做绑定的。name1()

  前面是什么?什么都没有。因此this关键词就将指向全局的window对象去。

  因此,答案是'JayGlobal'。

  name2.print()

  看一下name2指向哪个对象,是details对象没错吧?

  所以下面这句会打印出什么呢?如果到目前为止的所有小点你都理解了,那这里稍微思考下你就自然有答案了。

  console.log(name2.print())//??

  答案是'JayDetails',因为print是name2调起的,而name2指向details。

  词法作用域

  你可能会问:“什么是词法作用域?”

  逗我呢,我们不是在探讨this关键词吗,这个又是哪里冒出来的?好吧,当我们用起ES6的箭头函数,这个就要考虑了。如果你已经写了不止一年的

  JavaScript,那你很可能已经碰到箭头函数。随着ES6逐渐成为现实标准,箭头函数也变得越来越常用。

  JavaScript的词法作用域并不好懂。如果你理解闭包,那要理解这个概念就容易多了。来看下下面的小段代码。

  //outerFn的词法作用域

  varouterFn=function(){

  varn=5;

  console.log(innerItem);

  //innerFn的词法作用域

  varinnerFn=function(){

  varinnerItem=""inner"";//错了。只能坐着电梯向上,不能向下。

  console.log(n);

  };

  returninnerFn;

  };

  outerFn()();

  想象一下一栋楼里面有一架只能向上走的诡异电梯。

#FormatImgID_0#

  建筑的顶层就是全局windows对象。如果你现在在一楼,你就可以看到并访问那些放在楼上的东西,比如放在二楼的outerFn和放在三楼的

  window对象。

  这就是为什么我们执行代码outerFn()(),它在控制台打出了5而不是undefined。

  然而,当我们试着在outerFn词法作用域下打出日志innerItem,我们遇到了下面的报错。请记住,JavaScript

  的词法作用域就好像建筑里面那个只能向上走的诡异电梯。由于outerFn的词法作用域在innerFn上面,所以它不能向下走到innerFn

  的词法作用域里面并拿到里面的值。这就是触发下面报错的原因:

  test.html:304UncaughtReferenceError:innerItemisnotdefined

  atouterFn(test.html:304)

  attest.html:313

  this和usestrict

  为了让JavaScript更加健壮及尽量减少人为出错,ES5引进了严格模式。一个典型的例子就是this

  在严格模式下的表现。你如果想按照严格模式来写代码,你只需要在你正在写的代码的作用域**顶端加上这么一行""usestrict;""。

  记住,传统的JavaScript只有函数作用域,没有块作用域。举个例子:

  functionstrict(){

  //函数级严格模式写法

  'usestrict';

  functionnested(){return'AndsoamI!';}

  return""Hi!I'mastrictmodefunction!""+nested();

  }

  functionnotStrict(){return""I'mnotstrict."";}

  代码片段来自MozillaDeveloperNetwork。

  不过呢,ES6里面通过let关键词提供了块作用域的特性。

  现在,来看一段简单代码,看下this在严格模式和非严格模式下会怎么表现。在继续之前,请将下面的代码运行一下。

  (function(){

  ""usestrict"";

  console.log(this);

  })();

  (function(){

  //不使用严格模式

  console.log(this);

  })();

  正如你看到的,this在严格模式下指向undefined。相对的,非严格模式下this指向全局变量window。大部分情况下,开发者使用

  this,并不希望它指向全局window对象。严格模式帮我们在使用this关键词时,尽量少做搬起石头砸自己脚的蠢事。

  举个例子,如果全局的window对象刚好有一个key的名字和你希望访问到的对象的key相同,会怎样?上代码吧:

  (function(){

  //""usestrict"";

  varitem={

  document:""Mydocument"",

  getDoc:function(){

  returnthis.document;

  }

  }

  vargetDoc=item.getDoc;

  console.log(getDoc());

  })();

  这段代码有两个问题。

  this将不会指向item。

  如果程序在非严格模式下运行,将不会有错误抛出,因为全局的window对象也有一个名为document的属性。

  在这个简单示例中,因为代码较短也就不会形成大问题。

  如果你是在生产环境像上面那样写,当用到getDoc

  返回的数据时,你将收获一堆难以定位的报错。如果你代码库比较大,对象间互动比较多,那问题就更严重了。

  值得庆幸的是,如果我们是在严格模式下跑这段代码,由于this是undefined,于是立刻就有一个报错抛给我们:

  test.html:312UncaughtTypeError:Cannotreadproperty'document'of

  undefinedatgetDoc(test.html:312)attest.html:316attest.html:317

  明确设置执行上下文

  先前假定大家都对执行上下文不熟,于是我们聊了很多关于执行上下文和this的知识。

  让人欢喜让人忧的是,在JavaScript中通过使用内置的特性开发者就可以直接操作执行上下文了。这些特性包括:

  bind():不需要执行函数就可以将this的值准确设置到你选择的一个对象上。还可以通过逗号隔开传递多个参数,如func.bind(this,

  param1,param2,...)。

  apply():将this的值准确设置到你选择的一个对象上。第二个参数是一个数组,数组的每一项是你希望传递给函数的参数。***,执行函数。

  call():将this的值准确设置到你选择的一个对象上,然后想bind

  一样通过逗号分隔传递多个参数给函数。如:print.call(this,param1,param2,...)。***,执行函数。

  上面提到的所有内置函数都有一个共同点,就是它们都是用来将this

  关键词指向到其他地方。这些特性可以让我们玩一些*操作。只是呢,这个话题太广了都够写好几篇文章了,所以简洁起见,这篇文章我不打算展开它的实际应用。

  重点:上面那三个函数,只有bind()在设置好this关键词后不立刻执行函数。

  this和箭头函数

  在ES6里面,不管你喜欢与否,箭头函数被引入了进来。对于那些还没用惯箭头函数或者新学JavaScript的人来说,当箭头函数和this

  关键词混合使用时会发生什么,这个点可能会给你带来小小的困惑和淡淡的忧伤。那这个小节就是为你们准备的!

  当涉及到this关键词,箭头函数和普通函数主要的不同是什么?

  答案:

  箭头函数按词法作用域来绑定它的上下文,所以this实际上会引用到原来的上下文。

  引自:hackernoon.com

  我实在没法给出比这个更好的总结。

  箭头函数保持它当前执行上下文的词法作用域不变,而普通函数则不会。换句话说,箭头函数从包含它的词法作用域中继承到了this的值。

  我们不妨来测试一些代码片段,确保你真的理解了。想清楚这块知识点未来会让你少点***,因为你会发现this关键词和箭头函数太经常一起用了。

  示例

  仔细阅读下面的代码片段。

  varobject={

  data:[1,2,3],

  dataDouble:[1,2,3],

  double:function(){

  console.log(""thisinsideofouterFndouble()"");

  console.log(this);

  returnthis.data.map(function(item){

  console.log(this);//这里的this是什么??

  returnitem*2;

  });

  },

  doubleArrow:function(){

  console.log(""thisinsideofouterFndoubleArrow()"");

  console.log(this);

  returnthis.dataDouble.map(item=>{

  console.log(this);//这里的this是什么??

  returnitem*2;

  });

  }

  };

  object.double();

  object.doubleArrow();

  如果我们看执行上下文,那这两个函数都是被object调用的。所以,就此断定这两个函数里面的this都指向object

  不为过吧?是的,但我建议你拷贝这段代码然后自己测一下。

  这里有个大问题:

  arrow()和doubleArrow()里面的map函数里面的this又指向哪里呢?

  上一张图已经给了一个**的提示。如果你还不确定,那请花5分钟将我们上一节讨论的内容再好好想想。然后,根据你的理解,在实际执行代码前把你认为的this

  应该指向哪里写下来。在下一节我们将会回答这个问题。

  回顾执行上下文

  这个标题已经把答案泄露出来了。在你看不到的地方,map函数对调用它的数组进行遍历,将数组的每一项传到回调函数里面并把执行结果返回。如果你对

  JavaScript的map函数不太了解或有所好奇,可以读读这个了解更多。

  总之,由于map()是被this.data调起的,于是this将指向那个存储在data这个key里面的数组,即

  [1,2,3]。同样的逻辑,this.dataDouble应该指向另一个数组,值为[1,2,3]。

  现在,如果函数是object调用的,我们已经确定this指向object对吧?好,那来看看下面的代码片段。

  double:function(){

  returnthis.data.map(function(item){

  console.log(this);//这里的this是什么??

  returnitem*2;

  });

  }

  这里有个很有迷惑性的问题:传给map()的那个匿名函数是谁调用的?答案是:这里没有一个对象是。为了看得更明白,这里给出一个map

  函数的基本实现。

  //Array.mappolyfill

  if(Array.prototype.map===undefined){

  Array.prototype.map=function(fn){

  varrv=[];

  for(vari=0,l=this.length;i

  rv.push(fn(this[i]));

  returnrv;

  };

  }

  fn(this[i]));前面有什么对象吗?没。因此,this关键词指向全局的windows对象。那,为什么

  this.dataDouble.map使用了箭头函数会使得this指向object呢?

  我想再说一遍这句话,因为它实在很重要:

  箭头函数按词法作用域将它的上下文绑定到原来的上下文

  现在,你可能会问:原来的上下文是什么?问得好!

  谁是doubleArrow()的初始调用者?就是object对吧?那它就是原来的上下文

  我们学习任何一门技术都得先从企业需求的角度来分析,到底这个市场需要怎样的前端开发人才,这样才有让我们这些开发从业者有机会去思考满足需求这个问题,进而才能正确地确立一个可行的职业发展方向,***达到自己想要的目标。web的前景无限啊!web培训大门为你敞开,欢迎你的加入。

免责声明

非本网作品均来自互联网,转载目的在于传递更多信息,并不**本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其他问题,请及时与本网联系,我们将及时删除内容。

猜你喜欢

热点排行榜

教育部即将调整中小学上课时间,学生真的高兴坏了!
教育,是任何一个国家和民族的未来。如果没有了教育,那么这个国家和民族未来也会以前黑暗。随着知识在社会中的作用越来越大,人们也越来越重视教育。尤其是家长,为了能让孩子学习好,对于教育的投资可以说是不计代价!在许多人都越来越注重学习成绩的同时,孩子的学习压力却是越来越大,有的时候甚至孩子的睡眠时间都会严重不足。 如此一来虽然看似是孩子的学习成绩进步了,但是却严重影响了孩子的正常健康发育。如此
来看看在双减政策后,到底公立学校和私立学校有什么差距?
大部分的中小学生,都会选择在公立学校接受义务教育,但是随着教育“内卷”的情况越来越严重,不少学生家长会选择将孩子送到私立学校去上学,在这样的情况之下,中小学生的学习压力也越来越大,因此中小学生在上学的过程中,也会觉得非常疲惫。这种状态不仅不利于学生们提高学习成绩,更不利于学生们成长,因此相关部门也是引起了高度重视。 随着“双减”政策的实行,学生们的学习压力也在逐渐减小,“双减”实行后,公
为了推行三胎,课本的封面也变成三胎了,来看看人社部怎么说的~
开学没几天,网络上就开始流传着热心家长们对语文课本的“新发现”:一年的时间,课本封面由二胎变成了三胎,妈妈也不打扮了,头发随便一扎,衣服还是去年那件,只是旧了。多了个娃,爸爸也不在家下棋了,估计为了养家加班挣钱去了。家长们口中的两个封面分别是统编语文教材五年级上册、六年级上册封面。这段“看图说话”因为贴近“三胎”的社会热点,迅速引发了众多网友的共鸣、转发。人民教育出版社在其公众号上进行了“辟谣”:
清华北大亚洲***排名来啦!泰晤士公布了2022世界大学排名结果!
综合报道,当地时间2日,泰晤士高等教育特刊(Times Higher Education,简称THE)更新了***2022年THE世界大学排名。中国高校排名再次上升,***有两所大学进入前20名,创下亚洲比较好纪录。根据新发布的排名,北大和清华并列第16名,这是***中国有两所大学进入前20名,也亚洲国家迄今为止的比较高排名。此外,中国内地共有10所大学进入前200名。根据排名,牛津大学连续6年位列***。美
怎么选择美国留学中介?选的时候一定要清醒!
此篇文章会把下面很多问题中的内容阐述的逻辑层次更简单分明一些,假使同学们如果没有太多时间,不妨粗略阅读下面的问题,大概了解下!我计划去美国留学入读硕士,想请教一下如何选择美国留学中介机构呢?美国留学中介选择策略:衡量自己的消费者心理选择美国留学中介机构请务必要依据你的需求进行相关选择。首先你需要询问自己,你申请是要干什么呢?这个问题就像是购买衣服和鞋,你买运动鞋,就不会去西装店。美国留学作为一个很
英语的单词怎么写才好看?学会这几个小习惯,你也能写的好看!
英语学习重视听说读写,其中的写作涉及标准的写作规范。以下是英语单词写法的介绍,供参考。1.倾斜。每个字母稍微向右倾斜,大约在5°~20°之间,但每个字母的倾斜必须一致,所以很漂亮。2.大写字母。大写字母都一样高,占上面的两个格子,顶部面向***条线。3.小写字母。中间一格小写字母a、c、e、m、n、o、r、s、u、v、w、x、z写在中间一格中,上下抵抗,但不及格。小写字母B、D、H、K、L上端顶**
乐读推出一年级20人在线小班:通过小班教学 建构积极有效的师生互动
随着全国各地中小学和幼儿园秋季开学时间的确定,幼小、初小衔接又成了热点话题,但究竟要如何“衔接”,并不是每位家长都有科学的认识。乐读20人在线小班面向一年级孩子,激发兴趣、培养习惯,希望科学有效地帮助孩子适应小学学习生活,实现从幼儿教育阶段到小学教育阶段的顺利过渡。从孩子喜闻乐见的事物入手,培养学习的兴趣小学生活泼好动,注意力持续时间短,不少孩子初入小学课堂可能会出现发呆、坐不住的情况。据此,家长
学而思网校的线下校区即将关闭,只因房租成本过高!
9月27日消息,据媒体报道,学而思老师群内告知家长,因运营成本过高,不足以支撑面授班运营,所有面授课转为在线班。并统一在10月9日中午12:00开启转线上功能。此外,多名学而思工作人员均表示线下校区将会关闭。业内人士指出,在高额的房租下,退租关店也许是**理智的做法。目前线下教培机构在节假日、休息日及寒暑假的营收能占到全年收入的一半以上,但是现在不让上课,商业模型该怎么搭,目前很多线下机构恐怕还没想
教育部又来消息了,以后这类竞赛要被管理了!速来看看!
9月23日,教育部举行新闻通气会,介绍规范校外培训机构管理制度建设有关情况。会上,教育部校外教育培训监管司负责人介绍,“双减”工作是一项长期性复杂性系统性的工程,必须注重当前和长远相统一,研究修订竞赛管理办法,将治理打着“国际”旗号的各类竞赛。教育部校外教育培训监管司负责人表示,加快预收费监管、加强培训机构党建等其他配套政策法规的制订进度。同时完善“营改非”流程,进一步明确过程中的公示期限、资产确
各大高校开学了,清华大学开学典礼的主题演讲走红了,这个主题真不错!
9月是开学季,很多人带着对大学的憧憬迈入校园。在清华大学开学典礼上,一段开学演讲走红。教师**梅赐琪没有讲成功,而是讲失败。在他看来,与成功相比,失败能带给人更多可能性。以下是演讲全文:首先请允许我**我的同事们向***(9月2日)入学的2021级同学们表示**热烈的祝贺!每一级的清华人都是特殊的,但是你们还是要更特殊一些。在人类和七种冠状病毒的遭遇之中,你们中的绝大多数见证了其中**危险的两次,一次懵