一、前言
这套题目是某位群友亲身经历过的,感谢小伙伴share~
这套题目,考得比较实用也还挺全面,下面我们来看看具体的内容。
二、原题
讲讲事件循环
JavaScript 是一门单线程语言,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程。
一、同步和异步
所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就是同步任务,比如简单的逻辑操作及函数,而异步任务不会立马立马执行,会挪步放到到异步队列中,比如ajax、promise、事件、计时器等等。
也就是先执行同步,主线程结束后再按照异步的顺序再次执行。
二、事件循环(Event Loop)
事件循环意思就是:等待主线程中任务全部完成后,再回来把异步队列中任务放到主程序中运行,这样反复的循环
三、宏观任务和微观任务(先执行微观任务,再执行宏观任务):
在事件循环中,每进行一次循环操作称为tick,tick 的任务处理模型是比较复杂的,里边有两个词:分别是 Macro Task (宏任务)和 Micro Task(微任务)。
简单来说:宏观任务主要包含:setTimeout、setInterval、script(整体代码)、I/O、UI 交互事件、setImmediate(Node.js 环境)微观任务主要包括:Promise、MutaionObserver、process.nextTick(Node.js 环境)规范:先执行微观任务,再执行宏观任务(microtask 优先于 task 执行,所以如果有需要优先执行的逻辑,放入microtask 队列会比 task 更早的被执行。)
事件委托
事件冒泡:
JS中当出发某些具有冒泡性质的事件是,首先在触发元素寻找是否有相应的注册事件,如果没有再继续向上级父元素寻找是否有相应的注册事件作出相应,这就是事件冒泡。
事件委托:
利用事件冒泡的特性,将本应该注册在子元素上的处理事件注册在父元素上,这样点击子元素时发现其本身没有相应事件就到父元素上寻找作出相应。
这样做的优势有:
1.减少DOM操作,提高性能。
2.随时可以添加子元素,添加的子元素会自动有相应的处理事件。适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
Tips:
mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
sass和less的区别
共同点:
sass和less都是css的预编译处理语言,他们引入了mixins,参数,嵌套规则,运算,颜色,名字空间,作用域,JavaScript赋值等 加快了css开发效率,
当然这两者都可以配合gulp和grunt等前端构建工具使用
主要区别:
1.编译环境不一样:
sass的安装需要Ruby环境的,是在服务端上处理的,而Less是需要引入less.js来处理Less代码输出css到浏览器,也可以在开发环节使用Less,然后编译成css文件,直接放到项目中。
2.变量符不一样:
Less是@,而Scss是$
3.输出设置
Sass提供4中输出选项:nested, compact, compressed 和 expanded.
4.Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持。
5. 引用外部CSS文件
scss引用的外部文件命名必须以开头, 文件名如果以下划线开头的话,Sass会认为该文件是一个引用文件,不会将其编译为css文件.
6.Sass和Less的工具库不同
Sass有工具库Compass
Less有UI组件库Bootstrap
http的状态码、http缓存
状态码分为5类:
状态码分为5类:
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
301:
(永久移动)请求的网页已被永久移动到新位置。服务器返回此响应(作为对GET或HEAD请求的响应)时,会自动将请求者转到新位置。
302:
(临时移动)服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。此代码与响应GET和HEAD请求的301代码类似,会自动将请求者转到不同的位置。
304:
响应禁止包含消息体,如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。
305:被请求的资源必须通过指定的代理才能被访问。
400:
语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求,或者请求参数有误。
403:服务器已经理解请求,但是拒绝执行它。
404:请求失败,请求所希望得到的资源未被在服务器上发现。
500:
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
http缓存请求相应头:
1.Cache-Control请求/响应头,缓存控制字段,可以说是控制http缓存的最高指令,要不要缓存也是它说了算。它有以下常用值
1.1 no-store:所有内容都不缓存
1.2 no-cache:缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新,它是个比较高贵的存在,因为它只用不过期的缓存。
1.3 max-age=x(单位秒) 请求缓存后的X秒不再发起请求,属于http1.1属性,与下方Expires(http1.0属性)类似,但优先级要比Expires高。
1.4 s-maxage=x(单位秒) 代理服务器请求源站缓存后的X秒不再发起请求,只对CDN缓存有效(这个在后面会细说)
1.5 public 客户端和代理服务器(CDN)都可缓存
1.6 private 只有客户端可以缓存
2.Expires 响应头,代表资源过期时间,由服务器返回提供,GMT格式日期,是http1.0的属性,在与max-age(http1.1)共存的情况下,优先级要低。
3.Last-Modified 响应头,资源最新修改时间,由服务器告诉浏览器。
4.if-Modified-Since 请求头,资源最新修改时间,由浏览器告诉服务器(其实就是上次服务器给的Last-Modified,请求又还给服务器对比),和Last-Modified是一对,它两会进行对比。
5.Etag 响应头,资源标识,由服务器告诉浏览器。
6.if-None-Match 请求头,缓存资源标识,由浏览器告诉服务器(其实就是上次服务器给的Etag),和Etag是一对,它两会进行对比。
http缓存方案
1.md5/hash缓存
不推荐缓存html文件,这样每次html加载渲染都可以感知文件变化,反正文件没变还是使用本地缓存,文件名都变了说明修改过,重新请求缓存就好了。
2.CDN缓存(作为了解)
1.CDN通过分流的形式,大大减轻源站的访问压力。
2.CDN也解决了跨地区访问问题,根本上为访问提供了加速。
强缓存与协商性缓存(弱缓存)
了解了上面不同浏览器行为对http缓存的不同影响,理解强缓存与协商性缓存就很容易了。
强缓存:
不发起http请求,直接使用本地缓存,比如浏览器地址栏回车,使用浏览器的刷新按钮,在Expires或max-age生效的情况下,触发的都是强缓存。
协商性缓存(弱缓存):
在使用本地缓存前,先与服务器协商,核对缓存文件是否为最新。比如设置了cache-control=no-cache,不管你做任何操作,都会发起请求,这一类就是协商性缓存了。
css盒模型
1. 基本概念:
标准模型和IE模型
/* 标准模型 */ box-sizing:content-box; /*IE模型*/ box-sizing:border-box;
根据盒模型解释边距重叠:父元素没有设置margin-top,而子元素设置了margin-top:20px;可以看出,父元素也一起有了边距。
BFC(边距重叠解决方案)
BFC(block formatting context)块级格式化上下文
BFC原理:
(1). 内部的box会在垂直方向上,一个接一个地放
(2). 每个元素的margin box的左边,与包含块border box的左边相接触(对于从做往右的格式化,否则相反)
(3). box垂直方向的距离由margin决定,属于同一个bfc的两个相邻box的margin会发生重叠
(4). bfc的区域不会与浮动区域的box重叠
(5). bfc是一个页面上的独立的容器,外面的元素不会影响bfc里的元素,反过来,里面的也不会影响外面的
(6). 计算bfc高度的时候,浮动元素也会参与计算
创建方式:
1. 脱离文档流(float不为none时)
2.position为absolute或fixed
3. display 为inline-block、table-cell、table-caption、flex、inline-flex。
4. overflow不为visible
5. 根元素。
应用场景:
1. 自适应两栏布局
2. 清除内部浮动
3. 防止垂直margin重叠
小程序分包机制
离线包机制
微信小程序采用的是类似离线包加载方案,用户第一次打开时会先下载好所有代码,然后再加载页面;当用户再次进入时,会直接使用已下载的代码,省去了代码下载的过程,打开速度更快。
存在问题:
第一次打开小程序时白屏时间很长,因为要先下载好所有的代码,代码越多,白屏时间越长
代码有部分更新时,没办法进行增量更新,每次发版用户都需要重新下载全部代码
分包加载
离线包和M页的一种结合机制,即把代码划分成主包+N个分包
打开小程序,默认先加载主包进入分包页面时,再加载对应分包好处:进入主包页面时,需要下载的代码量小了很多,白屏时间更短,体验更佳
目录
├── app.js ├── app.json ├── app.wxss ├── packageA │ └── pages │ ├── cat │ └── dog ├── packageB │ └── pages │ ├── apple │ └── banana ├── pages │ ├── index │ └── logs └── utils
app.json
subpackages 字段声明项目分包结构:
{ "pages":[ "pages/index", "pages/logs" ], "subpackages": [ { "root": "packageA", "pages": [ "pages/cat", "pages/dog" ] }, { "root": "packageB", "name": "pack2", "pages": [ "pages/apple", "pages/banana" ] } ] }
subpackages 中,每个分包的配置有以下几项:
字段类型说明rootString分包根目录nameString分包别名,分包预下载时可以使用pagesStringArray分包页面路径,相对与分包根目录independentBoolean分包是否是独立分包
打包原则
声明 subpackages 后,将按 subpackages 配置路径进行打包,subpackages 配置路径外的目录将被打包到 app(主包) 中
app(主包)也可以有自己的 pages(即最外层的 pages 字段)
subpackage 的根目录不能是另外一个 subpackage 内的子目录
tabBar 页面必须在 app(主包)内
引用原则
packageA 无法 require packageB JS 文件,但可以 require app、自己 package 内的 JS 文件
packageA 无法 import packageB 的 template,但可以 require app、自己 package 内的 template
packageA 无法使用 packageB 的资源,但可以使用 app、自己 package 内的资源
js的基本数据类型和引用类型
值类型(基本类型):
字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:
对象(Object)、数组(Array)、函数(Function)。
说说js缓存
缓存的好处:
(1).当页面渲染的数据过多时,为了减轻对内存的占用,对初次接收且会用到的数据进行本地缓存,是有着大好处的.
(2).受网速等各种因素的影响,当渲染数据过多时,若存在频繁的切换页面,用户体验效果不佳。
本地存储
storage来对数据进行存储(sessionStorage、localStorage)
sessionStorage
临时的会话存储,只要当前的会话窗口未关闭,存储的信息就不会丢失,即便刷新了页面或者在编辑器中更改了代码,存储的会话信息也不会丢失。
localStorage
不主动去清除,会一直将数据存储在客户端的储存方式,即使关闭了浏览器,下次打开的时候仍然可以看到之前存储的未主动清除的数据(即便是杀毒软件或者浏览器自带的清除功能,也不能将localStorage存储的数据清除掉)storage存储的数据只能是字符串类型,其他类型的数据需做类型转换storage直接属于顶层对象window.
cookie
cookie属于较老且最常见用的最多的技术了,cookie的优点很多,用起来也比较方便cookie缺陷:4kb,cookie本地存储的数据会被发送到服务器
cookie和storage的区别
1.cookie兼容所有的浏览器(本地cookie谷歌不支持),storage不支持IE6~8;
2.二者对存储的内容均有大小限制,前者同源情况写一般不能存储4kb的内容,后者同源一般能存储只能存储5MB的数据
3.cookie有过期时间,localStorage是永久存储(如果你不手动去删除的话)
4.一些浏览器处于安全的角度可能会禁用cookie,但无法禁用localStorage
jquery的ajax实现原理
1.jQuery底层在实现ajax功能时,调用了浏览器中的XMLHttpRequest对象,在最新的2.0版本后,由于不考虑IE浏览器的支持,直接使用该对象获取用户请求的数据,包括地址和参数等。
2.它将对象打开请求地址时的相关参数封装在相关函数如ajax()的配置项中,一旦传入了必需选项,则直接调用相应的send()方法进行数据的请求。
3.jQuery底层将对象请求后返回的数据结果,直接封装到相关函数的success方法中,所以,一旦异步请求成功,返回的数据对象直接注入到方法中,因此,可以调用success方法获取服务端返回的数据。
拓展:
1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
2、ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是通过HTTP来动态添加标签来调用服务器提供的js脚本。</span><span class="lake-fontsize-1515"> 3、其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。</span><span class="lake-fontsize-1515"> </span></div><div><span class="lake-fontsize-1515">4、jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。</span><span class="lake-fontsize-1515"> </span></div><div><span class="lake-fontsize-1515">5、jsonp整个过程中,本地站点一直处于主动的地位,主动的发送请求,主动的加载远程js.而第三方站点则处于被动的响应。</span></div>