欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

初级前端面试总结-2

程序员文章站 2022-04-22 19:01:41
...

初级前端面试总结-2

文章目录

小白一枚,今天参加面试,这次面试感觉要比前几次面试好一些,而且这次问的问题有部分上一次面试问的题。嘻嘻!不过还是要自己实际技术过硬才行。

面试可以让人增加经历,但是记得要总结反思自我,才能有所收获哦!

面试问题汇总

hr一面:

  • 自我介绍
  • 对于不熟悉的技术,你是通过渠道学习的呢?
  • 你接受高强度工作吗?
  • 你接受短期出差吗?
  • 为何从上一家公司离职?
  • 说一说你在团队中的优缺点?
  • 你有男朋友吗?(心里活动中:嘻嘻(#.#))
  • 你会选择在成都定居,还是回重庆呢?(心里活动中:倒想在成都定居哦,可是没车没房没存款,好穷啊!o(╥﹏╥)o)

技术一面:

  • 请简单说一下你的项目经历

  • 那你作为项目负责人需求是自己确定还是项目经理确定后自己开发?一进入公司就是项目负责人还是?

  • 关于数据分析这块,主要使用的是什么技术?

  • 项目中使用了什么技术。

  • 项目版本管理用的是什么?git

  • 对于Git你了解多少,git init,git add, git commit, git pull, git push 各代表什么,对于代码冲突 你是怎么解决的呢?

  • 产品经理有提供设计稿吗?

  • 那项目开发中的代码领导会检查吗?

  • 自动化部署项目?

  • 代码审核

  • 你会使用springcloude吗?

  • 服务代理

  • 负载均衡

  • 最好有一个至多上线演示项目)——建议,而且一定要保证项目能够正常运行

  • 页面打开速度很慢,如何排查?

  • 你使用过WebSocket吗?(实时通信,消息通知等领域)

  • 浏览器的兼容性

  • http状态码

  • js的设计模式

  • js中的数据类型

  • 解释null,undefined的区别?

  • 闭包

  • 产生跨域问题,如何解决跨域?

  • js的数组常用方法

HR

hr

请简单的自我介绍

我是从 姓名,毕业院校,毕业专业,工作经历,工作中自己负责了什么,担任什么角色,如何去完成,项目使用了什么技术,你会什么,最后阐述一下自己的愿景。来进行简短的自我介绍,最好在面试前都已经准备好而且背的很熟练。

在上一家公司中请简单介绍项目的情况。

根据自身的情况讲,都参加过工作可以能简单的说明。如果没有工作经历的话,那你就说说你平时写项目。

对于不熟悉的技术,你是通过渠道学习的呢?

  • 官方的api文档
  • 通过视频+书籍学习
  • 通过去github、gitee等开源网站找对应技术的项目来练习

为何从上一家公司离职?

根据自身进行回答,最官方的也是 技术深造。

说一说你在团队中的优缺点?

根据自身实际开发回答。

辩证的答,优点也是缺点,显得谦虚,缺点用好了也是优点,不至于让你自爆自己的短板。比如说优点是执着,对一件事,工作也好,生活也好,不做出个结果不能罢手,做事一定要善始善终才能放手。但另一面就是有点固执,也就是缺点,对一件事太坚持,原则性太强,少了点变通,而且,做事太执着的话,无论是工作上还是生活上,人都会活的比较累。
其实人性本来如此,你最大最明显的缺点往往来源于你最金子般的优点,看你从什么角度去看,看你自己怎么理解。人无完人,所谓性格本质上也没有好坏之分,再坏的人也有人喜欢,再好的人也有人唾弃,掌握好“度”,优缺点是可以相互转化的。

技术方面

技术方面

请简单说一下你的项目经历

根据自身情况回答

我的上一家公司做的是在线教育培训,所以我做的项目都是与教育相关的。

在上一家公司,作为项目负责人在带领团队的同时也负责在线教育平台的后台管理系统,对该系统进行日常的维护和需求的开发。同时也参与需求的确定、功能的开发、产品模块的测试(主要是功能测试,没有使用专业的黑白盒测试)、上线运营等项目全过程。因为该项目比较古老,所以只使用了 jQuery,js,bootstrap、layUI等相关技术,后期我也使用了vue、element,但是使用不多。主要还是因为该项目太古老,可能会导致新的技术无法融合…………

同时我也私下学习vue,使用vue仿写了一个 “去哪儿网”移动端,里面主要使用的技术是 vue+vuex+vue-router+webpack+axios。目前实现了 首页、城市切换、旅游详情页。

我也使用hexo搭建了个人博客,我常用在博客中发布文章,以此来总结反思自己。目前该博客已经上线了,网址我简历上附有链接,可直接访问。

最近在使用uni框架写募校园的微信小程序。

那你作为项目负责人需求是自己确定还是项目经理确定后自己开发?一进入公司就是项目负责人还是?

根据自身情况回答

我最初是以实习生的身份进入上一家公司,后期通过在工作的表现以及各方面的情况,领导提升我为项目负责人(主要是以下几点:对项目需求的熟悉较高、团队之间的沟通交流能力较强、其实最主要的就是我肯做,领导让我做啥我就做啥,但是我还有一点点自我要求,能最到最好,我一定要完成到最好,不然我不放手 、有自我的想法)

关于需求这块,还是有领导负责与上级领导沟通,然后确认后在传达给我,在最终确认后完成需求开发,功能的实现。

前期是由项目经理负责于上级领导沟通需求,后期是有

关于数据分析这块,主要使用的是什么技术?

echarts进行的数据的分析

项目版本管理用的是什么?

使用的是git对项目版本进行管理

对于Git你了解多少,git init,git add, git commit, git pull, git push 各代表什么,对于代码冲突 你是怎么解决的呢?

关于git方面的介绍可以参考:

【Git 笔记 - 程序员都要掌握的 Git】https://juejin.im/post/5d157bf3f265da1bcc1954e6

【全面理解Git】https://juejin.im/post/582bd0b4da2f600063d4f89e#heading-9

参考文献:

【廖雪峰git教程】https://www.liaoxuefeng.com/wiki/896043488029600/900004111093344

Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 Git 是 [Linus Torvalds](https://baike.baidu.com/item/Linus Torvalds/9336769) 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

git init

新建一个git目录,将其初始化为Git代码库

git add

将工作区的代码提交到暂存区

git commit

将暂存区的代码提交到仓库区

git pull

是将远程仓库的代码拉取到本地仓库中

git push

将本地仓库中的代码提交到远程仓库中

代码冲突

注:在提交到远程仓库前一定要先pull,这样使用工具方式提交代码就不会强制合并代码,导致代码的误删或者改动。

先查看是那个文件导致冲突,冲突部分文件具体是什么,是需要选择合并,还是 保留你的程序,还是他的程序,或者创建分支。

查看冲突文件:

$ git ls-files -s

$ git ls-files -s来查看到底是哪些文件发生了合并冲突,该命令输出的第二列的值如果为0表示对应的文件没有冲突,合并成功,如果不为0,则表示产生了合并的冲突,其中具体的值对应的意义是:1表示两个用户之前一个共同版本的对应文件内容;2表示当前用户对应的文件版本;3表示合并后的文件对应的远程版本

查看对应文件的对应版本的内容

git show :n:filename

产品经理有提供设计稿吗?

根据自身回答

前期产品经理没有提供设计稿,一般都是 项目经理给我讲解一下需求,然后画个草图(有时候也没有草图)根据草图,或者自己根据需求,自己设计页面,然后在完善其功能。

后期因为涉及到整个系统的改版以及新运营功能加入,所以就由UI设计师提供设计稿,要求高精确的还原设计稿。因为我做为项目负责人除了完成自己功能开发的同时,也会对其他项目成员完成新功能上线前,我都会去第一版本审核,审核通过后才能上线。

审核主要是:查看该功能是否存在bug,是否还有开发人员未没注意到细节问题,以及严格按照设计稿的精确度去检查页面开发效果(因为审核要耗费大量的时间,所以前期我严格要求他们必须按照设计稿进来开发,后期我整理出一套较为详情的开发规范文档),然后直到基本满足后就提交到测试环境中,得到专业的测试人员与运营人员进行测试,最终无异常后上线。

后期项目需求,项目经理不管,我主动每周定时给他汇报当周开发情况,并且统计成excel在线文档分享给经理,实时更新文档,方便经理随时了解项目开发情况。

那项目开发中的代码领导会检查吗?

根据自身回答

没有,上一家公司中领导不会坚持代码的质量等等。但是我起初都会去查看他们的代码情况,如果里面有问题的地方,或者说没有按照我给的那个开发规范文档来编写的,我会进行提醒,要求他遵守规范,从而形成有质感的代码模块。后期大部分都会按照文档来编写,所以我就没有再去查看了,不过有空的时候,也会查看,毕竟我也要参与开发,参与第一版的测试审核,所以精力不够。

什么是项目自动化部署?简单阐述一下webpack和gulp的部署。

参考文档:

【使用webpack定制前端开发环境】:https://www.kancloud.cn/sllyli/webpack/1242347

项目自动化部署:简化项目部署的工作量,减少了因代码发布而引起的bug数量。

webpack:主要是模块化文件进行压缩、打包、预处理、按需加载等进行相关配置,减少项目的开发大小,从而提高项目的运行速度。

部署过程:

初级前端面试总结-2

gulp:

可以采用 jenkins+gitlab 对项目进行自动化部署

webpack与gulp的区别

gulp是基于流的构建工具:all in one的打包模式,输出一个 js文件和一个 css 文件,优点是减少http的请求,玩金油方案。

webpack是模块化管理工具,使用webpack可以对模块进行压缩、预处理、打包、按需加载等。

你会使用springcloude吗?

对于springcloude我不了解,但是我知道他是分布式微服务的。我虽然不会springcloude,但是我会springboot框架,可以使用springboot来写简单的一个项目,复杂就不太会了。

服务代理

参考文档:

【前端代理nproxy】https://www.cnblogs.com/jinguangguo/p/nproxy.html

负载均衡

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

参考文档:

【几种常见的负载均衡】https://blog.****.net/bpb_cx/article/details/82771168

页面打开速度很慢,是什么原因导致的,如何进行排查?

  • 检查网络带宽是否稳定
  • 检查浏览器的缓存是否正常
  • 是否引用了太多的外部资源
  • F12查看网络请求,是否请求数量过多,减少文件的请求数量
  • 通过network查看网络请求的响应时间较长的部分接口,查看是服务端的问题还是客户端问题
  • 查看是不是js阻塞的问题导致(请求方式是同步还是异步)

你使用过WebSocket吗?(实时通信,消息通知等领域)

  • Websocket是一种用于H5浏览器的实时通讯协议,可以做到数据的实时推送,可适用于广泛的工作环境,例如客服系统、物联网数据传输系统

浏览器的兼容性

参考文献

【Web前端面试题第三道—浏览器的兼容性】https://www.jianshu.com/p/f971aae86f4d

参考文档

【Web前端面试指导:谈谈浏览器的兼容性】https://blog.****.net/weixin_42367621/article/details/80548025

【前端面试巧妙回答浏览器兼容问题】https://baijiahao.baidu.com/s?id=1619653290292160339&wfr=spider&for=pc

浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况。在大多数情况下,我们的需求是,无论用户用什么浏览器来查看我们的网站或者登陆我们的系统,都应该是统一的显示效果。所以浏览器的兼容性问题是前端开发人员经常会碰到和必须要解决的问题。

总结经常遇到的浏览器的兼容性问题分为以下九种,其它不常见的关于JS、CSS的兼容性小问题太多,就不再一一罗列,有兴趣可以去网上找找,有很多,如果实在没法解决的情况下可以用CSS hack解决,如果有其他方法解决兼容性,尽可能减少对CSS Hack的使用。Hack有风险,使用需谨慎。

常见的兼容性问题及解决办法

1、不同浏览器的标签默认的外补丁和内补丁不同

问题表现:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。

解决方案:CSS里 *{margin:0;padding:0;}

备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。

2、块属性标签float后,又有横向的margin情况下,在IE6显示margin比设置的大

问题表现:IE6后面的一块被顶到下一行

解决方案:在float的标签样式控制中加入display:inline;转化为行内属性

备注:横向浮动的div布局,使用上margin进行边界设置时,必然会碰到此问题

3、设置较小高度标签(一般小于10px),在IE6、IE7,遨游中高度超出设置高度值

问题表现:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度

解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height小于你设置的高度

备注:一般出现在设置小圆角背景的标签里。出现该问题原因是IE8之前的浏览器都会给标签一个最小默认行高的高度,即使标签是空内容,标签的高度还是会有默认行高。

4、行内属性标签,设置display:block后采用float布局,又有横向的margin情况,IE6间距bug

问题表现:IE6的间距比超过设置的间距

解决方案:在display:block;后面加入display:inline;display:table;

备注:行内属性标签,为了设置宽度,需要设置为display:block;(表单元素除外)在用float布局且有横向margin后,在IE6下,就具有了块属性float后的横向margin的bug。由于设置为display:inline,高度失效,所有在后面补上display:table。

5、图片默认有间距

问题表现:几个img标签放在一块,有些浏览器会有默认的间距,有通配符也不起作用

解决方案:使用float属性为img布局

备注:img标签是行内属性标签,只要不超出容器高度,img会排在一行里,使用float是比较好的选择

6、标签最低高度设置min-height不兼容**

问题表现:min-height本身就是一个不兼容的css属性,所以设置min-height时不能兼容所有浏览器

解决方案:如果设置一个标签最小高度为200px,需要进行设置 {min-height:200px; height:auto !important;

height: 200px; overflow:visible;}

备注:b/s系统前端时,当内容小于一个值时,容器的高度保持该值,当内容大于该值时,高度自适应且不出现滚动条。

7、光标手形

问题表现:firefox不支持hand,但ie支持pointer

解决方案:统一使用cursor:pointer;

8、字体大小定义不同

问题表现:对字体大小small定义不同,Firefox为13px,而IE为16px,差别比较大

解决方法:使用指定的字体大小如14px或者使用em

九、IE6 3px bug

问题表现:左侧div浮动left,右边DIV可以接着横向排列,形成典型一列固定,第二列自适应,IE6出现之间3px间隙

解决方法:对左侧left的盒子补上_margin-right: -3px;

10、其它方面

如果要减少浏览器兼容性问题的出现,可以分两种情况:

第一种是企业内部系统:通常会采用一些现成的UI技术,如ext、flex或其它UI框架完成。这些技术自己已经有相当好的浏览器兼容了。

第二种是互联网的:通常也会采用一些JS框架作辅助,如jQuery等作对dom、事件、ajax的兼容,页面上使用hack技术,如IE的*开始的选择器和条件注释作兼容。

11、css hack

先举一个小例子,简要说明一下CSS hack是干啥的。

比如要分辨IE6和firefox两种浏览器,可以这样写:

div{

background:green;/*forfirefox*/

*background:red;/*forIE6*/(bothIE6&&IE7)

}

我在IE6中看到是红色的,在firefox中看到是绿色的。

解释一下:

上面的css在firefox中,它是认识不了后面的那个带星号的东西是什么的,于是将它过滤掉,不予理睬,解析得到的结果是:div{background:green},于是理所当然这个div的背景是绿色的。

在IE6中呢,它两个background都能识别出来,它解析得到的结果是:div{background:green;*background:red;},于是根据优先级别,处在后面的red的优先级高,于是当然这个div的背景颜色就是红色的了。

css hack就是通过这种方式来对浏览器进行兼容性处理。也就是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),以达到应用不同的CSS样式的目的。因此我们就可以根据不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果。

针对不同浏览器的网站设计代码总结如下

1、针对I E 系列浏览器的网站设计代码

针对 IE 6 的专属 CSS Hack 网站设计代码 #id{ _display: block; } 也就是在网站设计CSS属性前加一个小划线就好。

针对 IE 7 的专属 CSS Hack 网站设计代码 #id{ *display: block; } 即在网站设计CSS属性前加上一个星号。

针对 IE 8 的专属 CSS Hack 网站设计代码 #id{ margin-top: 10px /9; /IE8/} 如上所示,解决办法为在网站设计CSS属性后分号前加上空格与斜线并加入一个数字9即可 。

**2、针对火狐的CSS Hack 网站设计代码 **

想要解决火狐的兼容性只要将CSS代码写入到 @-moz-document url-prefix(){ } 里面就行了 , 例如 @-moz-document url-prefix() { #id{ display: block; } } 。

**3、针对 Safari 的CSS Hack 网站设计代码 **

Safari是苹果中新的浏览器,解决兼容性的做法是加上@media screen and (-webkit-min-device-pixel-ratio:0)前缀。例如@media screen and (-webkit-min-device-pixel-ratio:0) { #id { display: block; } } 兼容性做法和火狐相近。

4、针对 Opera 的CSS Hack 网站设计代码

Opera解决兼容性的做法也是加上选择器前缀,例如 @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { head~body #id { display: block; } } 这个世界上必然不会存在绝对完美的事物,因此运用以上方法让我们的网站设计更好的与各种浏览器兼容的时候其实已经违反了网站制作的W3C标准。

http状态码

参考文献:

【HTTP状态码对照表】http://tools.jb51.net/table/http_status_code

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型。

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

HTTP状态码表(版本1) 此表含状态码英文名称

状态码 状态码英文名称 中文描述
1开头的状态码
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
2开头的状态码
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
3开头的状态码
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
4开头的状态码
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
5开头的状态码
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

js的设计模式

参考文档

【JavaScript中常见的十五种设计模式】https://www.cnblogs.com/imwtr/p/9451129.html

js常见的数据类型

参考文档

【js基础数据类型】https://www.jianshu.com/p/56e189e9201e

  • boolean
  • null
  • undefined
  • number
  • string
  • symbol

解释null,undefined的区别?

参考文献

【undefined与null的区别】http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html

**null表示"没有对象",即该处不应该有值。**典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。

(2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype)
// null

**undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。**典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var  o = new Object();
o.p // undefined

var x = f();
x // undefined

闭包

参考文献

【面试官问我:什么是JavaScript闭包,我该如何回答?】https://www.jianshu.com/p/102e44f35b3b

闭包就是有权访问另一个函数作用域中的变量的函数。简单来说闭包就是 一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

我个人认为,理解闭包的关键在于:外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。

初级前端面试总结-2

产生一个闭包

创建闭包最常见方式,就是在一个函数内部创建另一个函数。下面例子中的 closure 就是一个闭包:

初级前端面试总结-2

闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。

闭包的注意事项

.通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。

初级前端面试总结-2

从上述代码可以看到add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。最后通过 null 释放了 add5 和 add10 对闭包的引用。

在javascript中,如果一个对象不再被引用,那么这个对象就会被垃圾回收机制回收;

如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

闭包只能取得包含函数中的任何变量的最后一个值

初级前端面试总结-2

大家看一下上面这个代码,arr数组中包含了10个匿名函数,每个匿名函数都能访问外部函数的变量i,那么i是多少呢?

当arrFunc执行完毕后,其作用域被销毁,但它的变量对象仍保存在内存中,得以被匿名访问,这时i的值为10。

要想保存在循环过程中每一个i的值,需要在匿名函数外部再套用一个匿名函数,在这个匿名函数中定义另一个变量并且立即执行来保存i的值。

初级前端面试总结-2 这时最内部的匿名函数访问的是num的值,所以数组中10个匿名函数的返回值就是1-10。

闭包中的this对象

初级前端面试总结-2

在上面这段代码中,obj.getName()实际上是在全局作用域中调用了匿名函数,this指向了window。

这里要理解函数名与函数功能是分割开的,不要认为函数在哪里,其内部的this就指向哪里。

window才是匿名函数功能执行的环境。

如果想使this指向外部函数的执行环境,可以这样改写:

初级前端面试总结-2

在闭包中,arguments与this也有相同的问题。下面的情况也要注意:

初级前端面试总结-2

obj.getName();这时getName()是在对象obj的环境中执行的,所以this指向obj。

(obj.getName = obj.getName)赋值语句返回的是等号右边的值,在全局作用域中返回,所以(obj.getName = obj.getName)();的this指向全局。要把函数名和函数功能分割开来。

内存泄漏

闭包会引用包含函数的整个变量对象,如果闭包的作用域链中保存着一个HTML元素,那么就意味着该元素无法被销毁。所以我们有必要在对这个元素操作完之后主动销毁。

初级前端面试总结-2

函数内部的定时器

当函数内部的定时器引用了外部函数的变量对象时,该变量对象不会被销毁。

初级前端面试总结-2

闭包的应用

应用闭包的主要场合是:设计私有的方法和变量。

任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。私有变量包括函数的参数、局部变量和函数内定义的其他函数。

把有权访问私有变量的公有方法称为特权方法(privileged method)

初级前端面试总结-2

在这里,我们需要理解两个概念

模块模式(The Module Pattern):为单例创建私有变量和方法。

**单例(singleton):**指的是只有一个实例的对象。JavaScript 一般以对象字面量的方式来创建一个单例对象。

初级前端面试总结-2

上面是普通模式创建的单例,下面使用模块模式创建单例:

初级前端面试总结-2

匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染。

初级前端面试总结-2

在这段代码中函数 addEvent 和 removeEvent 都是局部变量,但我们可以通过全局变量 objEvent 使用它,这就大大减少了全局变量的使用,增强了网页的安全性。

运用闭包的关键

闭包引用外部函数变量对象中的值;

在外部函数的外部调用闭包。

闭包的缺陷

闭包的缺点就是常驻内存会增大内存使用量,并且使用不当很容易造成内存泄露。

如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

最后 来一道有关闭包的面试题

问:下面代码中,标记 ? 的地方输出分别是什么?

初级前端面试总结-2

结果:

产生跨域问题,如何解决跨域?

浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

所谓的同源指的是 域名,协议,端口均相同

  • 非跨域:http://www.123.com/index.html 调用 http://www.123.com/server.php
  • 域名不同 跨域:http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
  • 子域名不同跨域:http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
  • 端口不同跨域:http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
  • 协议不同:http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。

2、解决跨域办法

1、jsonp:

使用方式就不赘述了,但是要注意JSONP只支持GET请求,不支持POST请求。

<script type="text/javascript" src="jquery.js"></script>  
<script type="text/javascript">  
    $.ajax({  
        url:"http://www.123.com/server.php",  
        dataType:'jsonp',  
        data:'',  
        jsonp:'callback',  
        success:function(res) {  
            
        },  
        timeout:3000  
    });  
</script>   

2、vue3 中vue.config.js 文件下 配置 proxyTbale

devServer: {
    open: true, //是否自动弹出浏览器页面
    host: "localhost", 
    port: '8081',
    https: false,
    hotOnly: false, 
    proxy: {
        '/api': {
            target: 'http://www.123.com/api', //API服务器的地址
            changeOrigin: true, //是否跨域
            pathRewrite: {
                '^/api': ''
            }
        }
    },
}

3、vue2项目 中config 文件下 index.js 配置跨域

初级前端面试总结-2

js的数组常用方法

参考文献

【Array-MDN】https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

初级前端面试总结-2

初级前端面试总结-2

初级前端面试总结-2