前言
近期参加面试的伙伴比较多一些原因最近也参加了几家公司的面试,发现有很多基础性的东西掌握程度还是不够,故此想总结一下最近面试遇到的问题,希望能为在准备面试的的小伙伴尽一些绵薄之力,主要说的是一些我面试当中问到的一些问题,说的不对的地方请小伙伴们即使指正出来,或者有其他的看法也可以一起探讨。
一、HTML/CSS
1.html5新增标签
新增了一些语义化的标签例如:header,fotter,nav,main
新增图像:canvas svg
新增媒体标签: audio video
2.什么是盒模型
W3C标准盒模型,属性width,height包含content,不包含border和padding
IE盒模型,属性width,height包含content,border,padding
3.css居中元素
说一下我比较常用的的几种
- 使用position布局
postion: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
- 使用flex布局
display: flex;
align-items: center;
justify-content: center;
- 知道宽高的情况下使用position布局
postion: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
4.移动端1px边框问题
主要是不同手机的dpi不同会导致这个问题。解决办法:
- 看手机是否支持0.5px的边框,并且dpi大于等于2,会用到js判断比较复杂,这里不做实现。
- 使用背景图,修改颜色麻烦,需要换图。圆角需要特殊处理。
- 伪类元素加transform实现,个人经常使用。
.border {
position: relative;
border:none;
}
.border:after {
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
transform: scaleY(0.5);
}
5.css3有哪些新特性
- border新增border-img, border-raius
- 新增盒阴影box-shadow,文字阴影 text-shadow
- background新增background-image,background-size background-repeat
- 媒体查询
6.rem em px区别
- px相对长度单位,相对于显示器屏幕分辨率来的
- em相对长度单位,相对于当前对象内文本的字体尺寸来的,值不固定,会继承父级元素字体的大小,未经调整浏览器:16px = 1em。假如父元素为2em,子元素为2em字体实际大小为4em
- rem是css3新增的相对单位,使用rem为元素设置大小时,是相对大小,相对的是html根元素,修改根元素就可以调整所有字体大小,还可以避免字体大小逐层复合的连锁反应,未经调整浏览器:16px = 1rem。
7.详细说下BFC
- BFC块级格式上下文,是页面上一个独立的容器,容器内的子元素不会影响到外边的元素,垂直方向边距重叠,计算高度是浮动元素也会计算
- BFC触发:根元素(html),浮动元素(float不为none),绝对定位元素(position为absolute和fixed),行内块元素(display为inline-block),overflow值不为visible,弹性元素(display为flex)
- 应用场景:设置元素为BFC防止浮动高度塌陷,避免外边距重叠
8.重绘和回流
- 简单的一句话就是:回流必引起重绘,重绘不会引起回流,回流比重绘更耗性能。
- 回流:当元素的尺寸结构和某个属性发生改变时,浏览器重新渲染部分或全部文档的过程。
- 会发生回流的操作:浏览器窗口发生改变,元素位置和大小发生改变,元素内容发生改变,对可见的dom进行添加或者删除,查询某些属性或调用某些方法(clientWidth,offsetWidth, scrollWidth,scrollTo等等)
- 重绘:改变元素的样式不影响在文档流的位置(color,background-color)浏览器把新的样式重新赋给元素并绘制
- css避免:避免设置多层内联样式,避免使用css表达式(ealc),将动画放在position的属性上(absolute, fixed),避免使用table布局。
- js避免:避免重复操作样式(定义一个class并一次修改class属性),避免频繁操作dom(创建一个documentFragment,在它上边操作dom,最后添加的文档中),避免频繁读取引起重绘/回流的值(可以使用变量缓存)。
二、JS
1.js基本类型和引用类型
基本类型:Boolean Null Number String Undefined Symbol BigInt引用类型:Object
2.作用域
- 分为:全局作用域(定义在函数外部的变量)和局部作用域(定义在函数内部的变量),每个函数在被调用时都会创建一个新的域。ECMAScript 6引入了let和const关键字,利用let和const可以形成块级作用域。
- 块语句(if, switch, for, while)不会创建新的作用域,定义的变量保存在已经存在的作用域中,let和const支持在局部作用域块语句中声明
if (true) {
var a = 1;
let b = 2;
const c =3;
}
console.log(a) // 1
console.log(b) // Uncaught ReferenceError: b is not defined
console.log(c) // Uncaught ReferenceError: c is not defined
- 作用域链:作用域链是在变量对象之后创建的,作用域链用于解析变量,当变量被解析时,javascript先从代码嵌套的最内层开始找,如果内层没有找到,会转到上一层父级作用域查找,直到找到该变量
3.闭包
- 它允许函数访问局部作用域之外的数据,闭包有自己的作用域链,父级作用域链和全局作用域链。
function a() {
var b = 3;
return function() {
console.log(b)
}
}
a()() // 3
4.前端存储cookie,localStorage,sessionStorage
- localStorage有效期为永久,sessionStorage有效期为窗口关闭
- 同源文档可以修改并读取localStorage的值,sessionStorage只允许同一个窗口下的文档访问
- 用法:
localStorage.setItem('a', 1); // storge a->1
localStorage.getItem('a'); // return value of a
localStorage.removeItem('a'); // remove a
localStorage.clear(); // remove all data
- cookie是浏览器储存少量数据,cookie会自动在浏览器和服务器之间传输,可以通过path和domain配置,页面同目录和子目录都可以访问
document.cookie = 'a=1; path=/'; // 创建当前页面的cookie
var a = document.cookie; // 读取cookie 返回格式key=value; key1=value1;
document.cookie = 'a=2; path=/'; // 修改值,会把以前的值覆盖
document.cookie = "a=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; //删除cookie
5.promise实现原理
9k字 | Promise/async/Generator实现原理解析
6.宏任务和微任务
- 首先你要知道Javascript是单线程语言,Event Loop是JavaScript的执行机制
- 微任务和宏任务都属于异步任务,属于同一个队列,主要区别是他们执行的顺序,开始执行宏任务的时候,宏任务执行完毕之后会看有没有微任务,如果有的话执行微任务,没有接着下一个执行宏任务。在当前微任务没有执行完毕,是不会执行下一个宏任务的,而微任务又在宏任务之前执行
console.log(1)
setTimeout(() => {
console.log(5)
},0)
new Promise(resolve => {
resolve()
console.log(2)
}).then(() => {
console.log(4)
})
console.log(3)
// 打印出1,2,3,4,5
- 宏任务:setTimeout, setInterval, requestAnimationFrame
- 微任务 Promise.then catch finally
7.节流和防抖
- 节流:高频事件触发n秒内执行一次,如果这个时间点内触发多次函数,只有一次生效。
function throttle(fn) {
var flag = true
return function() {
if (!flag) return;
flag = false;
setTimeout(function () {
fn()
flag = true
}, 1000)
}
}
- 防抖:高频事件触发n秒之后执行,如果n秒之内再次被触发,重新记时。
function debounce(fn) {
var timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(function (){
fn()
}, 1000)
}
}
8.get和post区别
- 最直观的区别get把参数包含在URL中,post通过request body传递参数,相对于get比较安全
- get请求URL传参有长度限制,post没有
- get在浏览器回退是无害的,post会再次提交请求
- get请求会被浏览器主动缓存,post不会
- get和post报文格式不同
- get请求是幂等性的,而post请求不是(新增和删除数据一般不用post请求就是这个原因)
9.Js的事件委托是什么,原理是什么
- 通俗点说将元素事件委托给他的父级或者更外级来处理
- 事件委托是利用冒泡机制来实现的(事件冒泡:事件由具体的元素接受,然后逐渐向上传播到不具体的节点)
// 每个列表点击弹出内容
// 不使用事件委托需要给每个列表添加点击事件(消耗内存,不灵活,添加动态元素时需要重新绑定事件)这里不做介绍
<ul id="myLink">
<li id="1">aaa</li>
<li id="2">bbb</li>
<li id="3">ccc</li>
</ul>
// 使用事件委托(减少内存占用,提升性能,动态添加元素无需重新绑定事件)
var myLink = document.getElementById('myLink');
myLink.onclick = function(e) {
var e = event || window.event;
var target = e.target || e.srcElement;
if(target.nodeName.toLowerCase() == 'li') {
alert(target.id + ':' + target.innerText);
}
};
下期接着给大家讲!