cvte面经模拟
对网上面经进行整理
目录
[题目1] 盒模型
分为标准盒模型及怪异盒模型,分别对应box-sizing:content-box,box-sizing: border-box
标准盒模型width = content 怪异盒模型width = content + padding + border
[题目2] es6新特性有哪些
- let const 关键字
- 箭头函数
- promise
- async await
- 模板字符串
[题目3] 箭头函数与普通函数区别
- 箭头函数更加简洁
- 箭头函数没有prototype,所以没有自己的this
- 箭头函数不会创建this,箭头函数里的this在创建时已经被确定,继承自上一层普通函数的this
let obj = {
a: 10,
b: () => {
console.log(this.a); // undefined
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
},
c: function() {
console.log(this.a); // 10
console.log(this); // {a: 10, b: ƒ, c: ƒ}
}
}
obj.b();
obj.c();
- call bind apply改变不了箭头函数的this
- 箭头函数不能作为构造函数
- 箭头函数没有arguments 需要使用rest
// 普通函数
function A(a){
console.log(arguments);
}
A(1,2,3,4,5,8); // [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 箭头函数
let B = (b)=>{
console.log(arguments);
}
B(2,92,32,32); // Uncaught ReferenceError: arguments is not defined
// rest参数...
let C = (...c) => {
console.log(c);
}
C(3,82,32,11323); // [3, 82, 32, 11323]
- 箭头函数不能用作Generator函数,不能使用yield关键字
[题目4] 两栏布局的方法有哪些
两栏布局是左侧定宽,右侧宽度自适应
-
float
父级定高,左盒子定宽高,左浮动,右盒子定高,宽度auto
-
flex
将左边元素的放大和缩小比例设置为0,基础大小设置为200px。将右边的元素的放大比例设置为1,缩小比例设置为1,基础大小设置为auto。
-
定位
利用绝对定位布局的方式,将父级元素设置相对定位。左边元素设置为absolute定位,并且宽度设置为200px。将右边元素的margin-left的值设置为200px。
[题目5] 垂直居中方法
-
flex
display: flex align-item: center
-
absolute + margin: autp
.parent { height: 400px; position: relative; } .child { width: 300px; height: 200px; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; }
[题目6] padding: 50%设置为百分比是根据谁来的
padding-top 百分比定义基于父元素宽度的百分比上内边距
[题目7] 事件循环 event loop
执行栈 任务队列 宏任务 微任务
[题目8] 如何判断是引用数据类型还是基础数据类型
使用typeof
如果是引用数据类型会是object
typeof null 也是object 但null是基础数据类型
此时可以使用null instanceof Object
发现其为false 不是Object是实例,是基本数据类型
typeof Symbol 是function 但symbol是基础数据类型
Symbol instanceof Object
Symbol instanceof Function
均为true
想证明Symbol为基础数据类型,可能只能从定义下手
[题目9]cookie session localStorage sessionStorage区别
HTTP请求是无状态的,每一次都是新的请求,为了解决这个情况,使用cookie,session来保存信息。
cookie分为会话cookie及非会话cookie。如果未设置过期时间,则cookie被存储在浏览器中,关闭浏览器cookie生命周期结束。如果设置了过期时间,则cookie会存储在硬盘上,关闭浏览器不会使cookie消失
客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是 Session 对象
,存储结构为 ConcurrentHashMap。Session 弥补了 HTTP 无状态特***器可以利用 Session 存储客户端在同一个会话期间的一些操作记录
session需要借助cookie才能工作,禁止了cookie,session失效
webStorage仅为了本地存储数据而生
sessionStorage引入了浏览器窗口
的概念,只要sessionStorage所在的浏览器窗口不关闭,即使刷新页面或进入同源另一个页面,数据仍然存在,关闭窗口后,sessionStorage就会被销毁,同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的
- 减少了网络请求,数据保存在本地,可以及时获得
localStorage的生命周期是永久,除非手动删除,否则一直存在
不同浏览器无法共享localStorage或sessionStorage中的信息。相同浏览器的不同页面间可以共享相同的 localStorage。但是不同页面或标签页间无法共享sessionStorage的信息。,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的
localStorage适用于长期登录,存储用户登录信息 sessionStorage用于敏感用户一次性登录登录
localStorage通过window.localStorage
获取;sessionStorage通过window.sessionStorage
获取
[题目10] cookie字段有哪些
name:名称
value:cookie值
domain: 域名 如abc.com
path: cookie的页面路径 如/test
http字段: cookie的httponly属性。若为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie
expires/Max-Age字段:设置cookie的过期时间。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。
secure: Secure为Cookie的安全属性,若设置为true,则浏览器只会在HTTPS和SSL等安全协议中传输此Cookie,不会在不安全的HTTP协议中传输此Cookie。
[题目11] 强缓存和协商缓存
浏览器缓存分为强缓存和协商缓存
强缓存:浏览器不会向服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK
访问的地方有两个
200 form memory cache : 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
200 from disk cache: 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
浏览器会先访问memory cache 再访问 disk cache最后网络请求资源
强缓存的header参数
- Expires:过期时间。
浏览器进行第一次请求时,服务器会在返回头部加上Expires,下次请求,如果在这个时间之前则命中缓存.如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求
- Cache-Control:
该值是利用max-age判断缓存的生命周期
,当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。 - no-cache: 强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。
cache-control是http1.1的头字段,expires是http1.0的头字段,如果expires和cache-control同时存在,cache-control会覆盖expires,建议两个都写。
协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源
协商缓存的header参数
- last-modified: 浏览器向服务器发送资源最后的修改时间
- Etag: 通过比对资源内容来判断是否修改 如果响应头里有Etag则代表资源内容已被修改
为什么有了强缓存还要有协商缓存
因为强缓存有缺点,比如设置了expires,GMT格式,但是浏览器的时间可以改变,因此就通过cache-control返回一个相对时间来。但是假如说资源并没有更新,但是强缓存时间过期了,那就需要重新拉去资源,因此就有了last-modified,但是last-modified的时间单位是s,当1s内有资源修改,那浏览器返回的最后修改时间和上次的修改时间相同,那就不会重新拉取资源,因此推出了etag,通过比对资源内容来判断是否修改
[问题12] 输出最大回文字符串
给你一个字符串 s,找到 s 中最长的回文子串。
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
奇偶回文串的处理方法不一样,奇数回文串left与right可以相同,从而一起增减,偶数回文串left与right要传入不同的
function returnStr(str, left, right) {
while (left >= 0 && right < str.length) {
if (str[left] === str[right]) {
left--;
right++;
} else {
break;
}
}
return str.substring(left + 1, right);
}
function findStr(str) {
// 非法性检查
if (str.length < 2) {
return str;
}
// 定义最大长度
let maxLength = 1;
// 存储最大回文字符串
let maxStr = "";
// 遍历字符串
for (let i = 0; i < str.length - 1; i++) {
// 奇数回文串
let oddStr = returnStr(str, i, i);
// 偶数回文串
let eventStr = returnStr(str, i, i + 1);
let strStore = oddStr.length > eventStr.length ? oddStr : eventStr;
if (strStore.length > maxLength) {
maxStr = strStore;
maxLength = strStore.length;
}
}
return maxStr;
}
const str = "cababad";
console.log(findStr(str));
[问题13] 冒泡排序
function bubble(arr) {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
[问题14] HTML5语义化标签
语义元素指标签名称能向开发者描述其意义。
语义化标签有 <article>
<details>
<footer>
<time>
[问题15] 如何提高首屏加载速度
在代码被打包后,App.js 文件过大,加载时间过长,导致首屏加载速度变慢
我们可以
- 使用路由懒加载,让项目按需加载,使用webpack的code splitting,当使用路由加载的写法,webpack就会对app.js进行代码分割,减小app.js的体积,从而提高首屏加载数点
- 使用第三方库
vendor
,本质上还是code splitting - 代码层做懒加载,网络层面把CDN、本地缓存用好,视觉层使用骨架屏
[问题16] 如何提高页面的加载速度
-
如果有图片,使用雪碧图
雪碧图中使用background-position修改位置
-
使用cdn加速
缺点:响应时间可能会受到其他网站流量的影响。CDN服务提供商在其所有客户之间共享Web服务器组
-
使用expires
页面的初次访问者会进行很多HTTP请求,但是通过使用一个长久的Expires头,可以使这些组件被缓存,下次访问的时候,就可以减少不必要的HTPP请求,从而提高加载速度
Web服务器通过Expires头告诉客户端可以使用一个组件的当前副本,直到指定的时间为止
HTTP1.1中引入Cache-Control来克服Expires头的限制,使用max-age指定组件被缓存多久。
Cache-Control: max-age=12345600
若同时制定Cache-Control和Expires,则max-age将覆盖Expires头
-
将脚本放在底部
js的下载和执行会阻塞Dom树的构建(严谨地说是中断了Dom树的更新),所以script标签放在首屏范围内的HTML代码段里会截断首屏的内容。
-
使用外部的JavaScript和CSS
内联脚本或者样式可以减少HTTP请求,按理来说可以提高页面加载的速度。然而在实际情况中,当脚本或者样式是从外部引入的文件,浏览器就有可能缓存它们,从而在以后加载的时候能够直接使用缓存,而HTML文档的大小减小,从而提高加载速度。
-
Ajax 缓存
post请求不能被默认缓存,但get请求可以被缓存在本地,除非指定了不同的地址,否则同一个地址的AJAX请求,不会重复在服务器执行,而是返回304(
304代表本地资源
)。
[问题17] 如何进行图片的懒加载及预加载
图片预加载
图片预加载即图片需要显示前先加载
css处理方式
设置按钮,点击加载图片。随后可以先在预加载css文件中,对几个节点的background设置url,在加载css时会首先进行网络请求,随后缓存到本地。按下按钮,重新设置那几个节点,设置该节点的内联样式url为上文的图片地址。此时网络请求为304,是在本地得到的
js处理方式
最外层整体设置一个遮罩层。内部是img src是图片路径。下面是一个预加载js文件,将所有的url放到数组里,用count记录加载成功的图片数量。new Image
并使用img.onload
监听是否加载完成,加载完成count++,全部加载完成后,将遮罩层设置为display: none
- 此时可以分为
无序预加载
及有序预加载
无序加载适用于大量图片等,等待统一加载后去除遮罩层 遍历url数组即可
有序加载适用于漫画等场景,第一张图片显示出时,第二张图片正在加载,而此时第三张图片不需要加载,要等第二张图片加载完成后才会开始。执行第一次的预加载函数,在函数里面onload监听,只有加载成功后,才在函数里面再次调用预加载函数。
图片懒加载
与预加载相反,懒加载就是 先显示再加载
如电商网站,大量的图片,如果进行预加载,可能出现白屏现象。
使用懒加载同样有缺点:
- 需要监听图片是否显示,比较耗游览器性能。
- 图片是显示时才去加载。如果网络不太好可能会有一段时间是空白
如何进行懒加载
利用自定义属性将图片的 URL 存放到图片标签身上 , 图片的 src 为空或者用其他较小的图片资源代替(提示加载中)
图片的懒加载主要是监听 body 或者其他存放图片且滚动的元素的 scroll 事件.
在每一次事件触发时,通过相关的 API 和属性,检查图片是否显示 。
如果显示就将 URL 填到 src 属性中 ,加载图片 。如果没有显示则不进行操作。
如何检测图片是否显示
当scrollTop + clientHeight > img的offsetTop 时 , 图片便是显示出来或者在可视区之上了
但懒加载对服务器友好,对浏览器不友好。
因为一直监听滚动事件,一直触发是非常消耗性能的
对此我们可以进行防抖和节流来减少性能的消耗 。提高流畅度。
[问题19] caller callee
caller
返回调用当前函数的函数对象,如果是window则返回NUll
function fun(){
console.log(fun.caller)//这里必须写在fun里面,因为caller只有函数执行过程中才有效
}
fun(); // null
function a(){
fun();
function fun(){
console.log(fun.caller)//这里必须写在fun里面,因为caller只有函数执行过程中才有效
}
}
a(); //打印a函数
callee
该属性在arguments上,是该函数对象自身,使用callee是为了防止函数递归调用时,函数名被修改导致内部报错
function sum (num){
if(num <= 1){
return 1;
}else{
return num * (arguments.callee(num - 1))
}
}
console.log(sum(5))
[问题18] 如何统计页面上dom节点的数量
几个重要属性
nodeType
如果是元素属性 则dom.nodeType == 1
childNodes
dom.childNodes 返回该元素的所有儿子元素
function getElement(dom){
if (dom.nodeType == 1){
console.log(dom.nodeName);
}
let son = dom.childNodes;
for(let i = 0; i < son.length; i++) {
arguments.callee(son[i])
}
}
window.onload = getElement(document)