前端面试题
1. JS 作用域和作用域链
作用域
作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是公有作用域,它们都是栈内存。
执行环境定义了变量或函数有权拜访的其余数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保留在这个对象中。尽管咱们编写的代码无法访问这个对象,但解析器在解决数据时会在后盾应用它。
全局执行环境是最外围的一个执行环境。依据 ECMAScript 实现所在的宿主环境不同,示意的执行环境的对象也不一样。
- 在 Web 浏览器中,全局执行环境被认为是 window 对象,因而所有全局变量和函数都是作为 window 对象的属性和办法创立的。
- 在 Node 环境中,全局执行环境是 global 对象。
某个执行环境中所有的代码执行结束后,该环境被销毁,保留在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出时,如敞开浏览器或网页,才会被销毁)。
每个函数都有本人的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将被环境弹出,把控制权返回给之前的执行环境。ECMAScript 程序中的执行流正是由这个不便的机制管制着。
作用域就是代码执行开拓栈内存。
作用域链
当代码在一个环境中执行时,会创立变量对象的一个作用域链(作用域造成的链条)。
- 作用域链的前端,始终都是以后执行的代码所在环境的变量对象。
- 作用域链中的下一个对象来自于外部环境,而在下一个变量对象则来自下一个外部环境,始终到全局执行环境。
- 全局执行环境的变量对象始终都是作用域链上的最初一个对象。
外部环境能够通过作用域链拜访所有外部环境,但外部环境不能拜访外部环境的任何变量和函数。
如函数的执行,造成一个公有作用域,形参和以后公有作用域中申明的变量都是公有变量,保留在外部的一个变量对象中,其下一个外部环境可能是函数,也就蕴含了函数的外部变量对象,直到全局作用域。
当在外部函数中,须要拜访一个变量的时候,首先会拜访函数自身的变量对象,是否有这个变量,如果没有,那么会持续沿作用域链往上查找,直到全局作用域。如果在某个变量对象中找到则应用该变量对象中的变量值。
因为变量的查找是沿着作用域链来实现的,所以也称作用域链为变量查找的机制。
这个机制也阐明了拜访局部变量要比拜访全局变量更快,因为两头的查找过程更短。然而 JavaScript 引擎在优化标识符查问方面做得很好,因而这个差异能够忽略不计。
2. 首屏优化
首屏优化分为两大方向:资源加载优化 和 页面渲染优化。
压缩资源,应用 CDN ,http 缓存等。
路由懒加载
把不同路由对应的组件宰割为不同的代码块,当路由被拜访的时候,再加载对应的组件。
如果是SPA(单页面利用),优先保障首页加载。
SPA 是一种非凡的 Web 利用,是加载单个 HTML 页面并在用户与应用程序交互时动静更新该页面的。它将所有的流动局限于一个 Web 页面中,仅在该 Web 页面初始化时加载相应的 HTML 、 JavaScript 、 CSS 。一旦页面加载实现, SPA 不会因为用户的操作而进行页面的从新加载或跳转,而是利用 JavaScript 动静的变换 HTML(采纳的是 div 切换显示和暗藏),从而实现UI与用户的交互。在 SPA 利用中,利用加载之后就不会再有整页刷新。相同,展现逻辑事后加载,并有赖于内容Region(区域)中的视图切换来展现内容。
服务端渲染SSR
服务端渲染(SSR)后,简略了解是将组件或页面通过服务器生成html字符串,再发送到浏览器,最初将动态标记"混合"为客户端上齐全交互的应用程序。渲染时申请页面,返回的body里曾经存在服务器生成的html构造,之后只须要联合css显示进去。这就节俭了拜访工夫和优化了资源的申请。
传统的 SPA 形式过程繁多:
- 下载 html ,解析,渲染
- 下载 js ,执行
- ajax 异步加载数据
- 从新渲染页面
而 SSR 则只有一步:
- 下载 html ,解析,渲染
分页
依据显示设施的高度,设计尽量少的页面内容。即,首评内容尽量少,其余内容上滑时加载。
图片lazyLoad
先加载内容,再加载图片。
3. JS事件循环
一、在理解js的事件循环之前,咱们先理解一下浏览器的工作线程
在浏览器执行各种过程,浏览器是多过程,每一个浏览器的标签都能够都能够了解为一个多过程的工作过程,浏览器渲染过程属于过程中的一种,次要负责,页面渲染,脚本执行,工作解决,那么线程大略有:(html的构造解析,css解析成dom树,),js脚本的主线程,事件触发线程,定时器线程,http线程。
二、对于事件循环
尽管说js是一个单线程执行,然而还是分为同步和异步,也能够说为主线程,和异步线程,那么如果在异步线程中,工作队列相对起到相对重要的作用,同步工作个别都会在主线程去执行,执行完之后,再去执行异步工作,也就是在异步线程,那么这时候异步工作就能够进入工作队列去执行异步工作,上诉一直地过程,让咱们叫做循环事件(Event loop)。
三、对于宏工作和微工作
在事件循环中,每进行一次循环操作称为tick,通过浏览标准可知,每一次 tick 的工作解决模型是比较复杂的,其要害的步骤能够总结如下:
1.在此次 tick 中抉择最先进入队列的工作( oldest task ),如果有则执行(一次)
2.查看是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
3.更新 render
4.主线程反复执行上述步骤
标准中规定,task分为两大类, 别离是 Macro Task (宏工作)和 Micro Task(微工作), 并且每个宏工作完结后, 都要清空所有的微工作,这里的 Macro Task也是咱们常说的 task
宏工作:script( 整体代码),setTimeout,setInterval,UI交互事件
微工作:promise,nextTick
4. 线程和过程是什么?
过程:cpu分配资源的最小单位(是能领有资源和独立运行的最小单位)。
线程:是cpu最小的调度单位(线程是建设在过程的根底上的一次程序运行单位,一个过程中能够有多个线程)。
栗子:比方过程=火车,线程就是车厢。
一个过程内有多个线程,执行过程是多条线程共同完成的,线程是过程的局部。
一个火车能够有多个车厢。
每个过程都有独立的代码和数据空间,程序之间切换会产生较大的开销;线程能够看作轻量级的过程,同一类线程共享代码和数据空间,每个线程都有本人独立的运行栈和程序计数器,线程之间切换的开销小。同一过程的线程共享本过程的地址空间和资源,而过程之间的地址空间和资源是互相独立的。
为什么js是单线程
JS是单线程的起因次要和JS的用处无关,JS次要实现浏览器与用户的交互,以及操作DOM。
如果JS被设计为多线程,如果一个线程要批改一个DOM元素,另一个线程要删除这个DOM元素,这时浏览器就不晓得该怎么办,为了防止简单的状况产生,所以JS是单线程的。
为了利用多核CPU的计算能力,HTML5提出Web Worker规范,容许JavaScript脚本创立多个线程,然而子线程齐全受主线程管制,且不得操作DOM。所以,这个新规范并没有扭转JavaScript单线程的实质。
5. js中的根底数据类型有哪几种? 理解包装对象吗?
六种,string, number, boolean, undefiend, null, symbol
根底数据类型长期创立的长期对象,称为包装对象。其中 number、boolean 和 string 有包装对象,代码运行的过程中会找到对应的包装对象,而后包装对象把属性和办法给了根本类型,而后包装对象被零碎进行销毁。
6. 对内存透露的理解
一、了解
- 定义:程序中已在堆中调配的内存,因为某种原因未开释或者无奈开释的问题
- 简略了解: 无用的内存还在占用,得不到开释和偿还,比较严重的时候,无用的内存还会减少,从而导致整个零碎卡顿,甚至解体。
二、生命周期
- 调配期
调配所须要的内存,在js中,是主动调配的。 - 使用期
应用调配的内存,就是读写变量或者对象的属性值。 - 开释期
不须要时将该内存开释,js会主动开释(除了闭包和一些bug以外)。内存透露就是呈现在这个期间,内存没有被开释导致的。
三、可能呈现内存透露的起因
- 意外的全局变量
- DOM元素清空时,还存在援用
- 闭包
- 忘记的定时器
如何优化内存透露?
- 全局变量先申明在应用。
- 防止过多应用闭包。
- 留神革除定时器和事件监听器。
7. HTTP与HTTPS的区别
HTTP(HyperText Transfer Protocol:超文本传输协定)是一种用于分布式、合作式和超媒体信息系统的应用层协定。 简略来说就是一种公布和接管 HTML 页面的办法,被用于在 Web 浏览器和网站服务器之间传递信息。HTTP 默认工作在 TCP 协定 80 端口,用户拜访网站 http:// 打头的都是规范 HTTP 服务。HTTP 协定以明文形式发送内容,不提供任何形式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就能够间接读懂其中的信息,因而,HTTP协定不适宜传输一些敏感信息,比方:信用卡号、明码等领取信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输平安协定)是一种透过计算机网络进行平安通信的传输协定。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的次要目标,是提供对网站服务器的身份认证,爱护替换数据的隐衷与完整性。
HTTPS 默认工作在 TCP 协定443端口,它的工作流程个别如以下形式:
1、TCP 三次同步握手
2、客户端验证服务器数字证书
3、DH 算法协商对称加密算法的密钥、hash 算法的密钥
4、SSL 平安加密隧道协商实现
5、网页以加密的形式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性爱护,保证数据不被篡改。
区别
- HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
- 应用 HTTPS 协定须要到 CA(Certificate Authority,数字证书认证机构) 申请证书,个别收费证书较少,因此须要肯定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
- HTTP 页面响应速度比 HTTPS 快,次要是因为 HTTP 应用 TCP 三次握手建设连贯,客户端和服务器须要替换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手须要的 9 个包,所以一共是 12 个包。
- http 和 https 应用的是齐全不同的连贯形式,用的端口也不一样,前者是 80,后者是 443。
- HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协定,所以,要比拟 HTTPS 比 HTTP 要更消耗服务器资源。
8. 数组排序及去重
一、简略的sort排序:
var arr = [1,5,3,87,23];arr.sort(function(a,b) { return a-b;})console.log(arr); // 输入:[1,23,3,5,87]
注:若返回b-a可取得从大到小的排序;
数组的sort办法只能实现简略的按位排序,并不准确。
二、冒泡排序
var arr = [1,5,2,6,3,3,4,56,7,5,5,5,6,7,8];function fn(arr) { //冒泡排序(以从小到大为例) for(var i=0;i<arr.length-1;i++) { //管制比拟的轮数 for(var j=0; j<arr.length-1-i; j++){ //内层每轮比拟的次数 if(arr[j] > arr[j+1]) { var temp = arr[j]; //替换这两个值的地位 arr[j] = arr[j+1]; arr[j+1] = temp; } } } return arr;}
三、抉择排序
function fn(arr) { //抉择排序 //用这个数别离和别的数相比拟,扭转的是索引的地位,每轮完结后才替换为地位 for(var i=0; i<arr.length-1; i++) { //管制外层比拟的轮数 var minIndex = i; //先假设一个最小值,定义变量minIndex指向该值的索引 for(var j=i+1; j<arr.length; j++) { if(arr[minIndex]>arr[j]) { minIndex = j; //扭转最小索引的指向 } } var temp = arr[i]; //每轮比拟完结,将最后假设的最小值和理论最小值替换 arr[i] = arr[minIndex]; arr[minIndex] = temp; } return arr; //将排序后的数组返回}
9. 一个页面从输出 URL 到页面加载显示实现,这个过程中都产生了什么?
当发送一个URL申请时,不论这个URL是web页面URl还是Web页面上每个资源的URL,浏览器都会开启一个线程来解决这个申请,同时在近程DNS服务器上启动一个DNS查问。这能使得浏览器失去申请对应的IP地址。
浏览器与近程web服务器通过TCP三次握手协商来建设一个TCP/IP连贯,该握手包含一个同步报文,一个同步-应答报文和一个应答报文。这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建设起通信,而后服务器相应并承受客户端的申请,最初由客户端收回该申请已被承受的报文。
一旦TCP/IP连贯建设,浏览器会通过该连贯向近程服务器发送HTTP的GET申请。近程服务器找到资源并应用HTTP相应返回该资源。
10. http缓存
http缓存指的是: 当客户端向服务器申请资源时,会先到达浏览器缓存,如果浏览器有“要申请资源”的正本,就能够间接从浏览器缓存中提取而不是从原始服务器中提取这个资源。常见的http缓存只能缓存get申请响应的资源,对于其余类型的响应则无能为力。
强缓存
在 Chrome 中,强缓存又分为 Disk Cache (寄存在硬盘中)和 Memory Cache (寄存在内存中),寄存的地位是由浏览器管制的。是否强缓存由 Expires、Cache-Control 和 Pragma 3 个 Header 属性独特来管制。
- Expires
Expires 的值是一个 HTTP 日期,在浏览器发动申请时,会依据零碎工夫和 Expires 的值进行比拟,如果零碎工夫超过了 Expires 的值,缓存生效。因为和零碎工夫进行比拟,所以当零碎工夫和服务器工夫不统一的时候,会有缓存有效期不准的问题。Expires 的优先级在三个 Header 属性中是最低的。 Cache-Control
Cache-Control 是 HTTP/1.1 中新增的属性,在申请头和响应头中都能够应用,罕用的属性值如有:- max-age:单位是秒,缓存工夫计算的形式是间隔发动的工夫的秒数,超过距离的秒数缓存生效
- no-cache:不应用强缓存,须要与服务器验证缓存是否陈腐,进入协商缓存
- no-store:禁止应用缓存(包含协商缓存),每次都向服务器申请最新的资源
- private:专用于集体的缓存,两头代理、CDN 等不能缓存此响应
- public:响应能够被两头代理、CDN 等缓存
- must-revalidate:在缓存过期前能够应用,过期后必须向服务器验证
- Pragma(优先级高)
Pragma 只有一个属性值,就是 no-cache ,成果和 Cache-Control 中的 no-cache 统一,不应用强缓存,须要与服务器验证缓存是否陈腐,在 3 个头部属性中的优先级最高。
协商缓存
- ETag/If-None-Match(优先级高)
首次申请的时候响应头会返回一个,ETAG,内容是一串hash值,此时刷新之后,发现状态码变成304,此时的申请头上会有一个If-None-Match属性,内容与上次申请的ETAG值一样。即通过比照两个属性的值。 - Last-Modified/If-Modified-Since(有工夫精度问题,或者文件批改,但内容没改,就不会走缓存)
Last-Modified/If-Modified-Since 的值代表的是文件的最初批改工夫,第一次申请服务端会把资源的最初批改工夫放到 Last-Modified 响应头中,第二次发动申请的时候,申请头会带上上一次响应头中的 Last-Modified 的工夫,并放到 If-Modified-Since 申请头属性中,服务端依据文件最初一次批改工夫和 If-Modified-Since 的值进行比拟,如果相等,返回 304 ,并加载浏览器缓存。
缓存地位(优先级从高到低)
- Service Worker
借鉴了Web work的思路 让JS 运行在主线程之外 - Memory Cache
内存缓存 效率快 存活短 渲染过程隐没就完结。比拟大的js css文件放进这里。 - Disk Cache
磁盘缓存 比内存缓存慢 然而贮存容量大和贮存时长长。小的js css放这里。内存使用率偏高的时候文件优先进入这里。 - Push Cache
http2的内容
本地存储
- Cookie
cookie的诞生是为了补救http治理状态上的有余。缺点:容量小。紧跟域名,同域状况下,无论以后地址是否须要,申请都会带上,当申请变多很影响性能。平安问题cookie能被获取到,而后批改发给服务器。 - LocalStorage
同样紧跟域名;容量大(5M);不接触服务器;永恒会话,除非手动删除;通过setItem、getItem手动获取、设置。 - sessionStorage
根本同local,然而针对服务器,会话级别,敞开页面就没了。个别用于form表单,刷新页面后缓存表单的值。