前段时间面试(包括阿里巴巴的电话面试),遇到过一些面试题,且面试中出现机率较高的提问/笔试,有些答的不是很好挂掉了,今天终于有时间整理出来分享给你们,但愿对你们面试有所帮助,都能轻松拿offer。javascript
主要分三部分:html
、css
、js
;react/vue等都归类于js,内容来源于面试过程当中遇到的
、在复习过程当中看到认为值得加深巩固
、群友交流分享
的;若有理解的错误或不足之处,欢迎留言纠错、斧正,这里是 @IT·平头哥联盟,我是首席填坑官
∙ 苏南(South·Su) ^_^~
有些面试官会问你对盒子模型的理解,在咱们平时看到的网页中,内部的每个标签元素它都是有几个部分构成的:内容(content)、外边距(margin)、内边距(padding)、边框(border),四个部分组成,当你说完这些面试官是不会满意这个答案的,由于还有一个重点(IE盒模型和标准盒模型的区别)———IE盒模型的content包括border、paddingcss
link
标签引入,也是当下用的最多的一种方式,它属于XHTML标签,除了能加载css外,还能定义rel、type、media等属性;@import
引入,@import是CSS提供的,只能用于加载CSS;style
嵌入方式引入,减小页面请求(优势),但只会对当前页面有效,没法复用、会致使代码冗余,不利于项目维护(缺点),此方式通常只会项目主站首页使用(腾讯、淘宝、网易、搜狐)等大型网站主页,以前有看到过都是这种方式,但后来有些也舍弃了 小结:link
页面被加载的时,link会同时被加载,而@import
引用的CSS会等到页面被加载完再加载,且link是XHTML
标签,无兼容问题; link支持动态js去控制DOM节点去改变样式,而@import不支持,
小结:块元素老是独占一行,margin对内联元素上下不起做用;
localStorage
存储持久数据,浏览器关闭后数据不丢失除非用户主动删除数据或清除浏览器/应用缓存;sessionStorage
数据在当前浏览器窗口关闭后自动删除。cookie
设置的cookie过时时间以前一直有效,即便窗口或浏览器关闭部分面试官可能还会再深刻一些:1)、如何让cookie浏览器关闭就失效?——不对cookie设置任何正、负或0时间的便可;
2)、sessionStorage在浏览器多窗口之间 (同域)数据是否互通共享? ——不会,都是独立的,localStorage会共享;
3)、能让localStorage也跟cookie同样设置过时时间?答案是能够的,在存储数据时,也存储一个时间戳,get数据以前,先拿当前时间跟你以前存储的时间戳作比较 详细可看我以前写的另外一篇分享( 小程序项目总结 )。
语义化是指根据内容的类型,选择合适的标签(代码语义化),即用正确的标签作正确的事情; html
语义化让页面的内容结构化,结构更清晰,有助于浏览器、搜索引擎解析对内容的抓取; 语义化的HTML在没有CSS
的状况下也能呈现较好的内容结构与代码结构; 搜索引擎的爬虫也依赖于HTML标记来肯定上下文和各个关键字的权重,利于SEO
;html
absolute
:绝对定位,元素会相对于值不为 static 的第一个父元素进行定位(会一直往父级节点查找),且它是脱离正常文档流、不占位的;fixed
:一样是绝对定位,但元素会相对于浏览器窗口进行定位,而不是父节点的position (IE9如下不支持);relative
:相对定位,元素相对于自身正常位置进行定位,属于正常文档流;static: position的默认值,也就是没有定位,当元素设置该属性后( top、bottom、left、right、z-index )等属性将失效; inherit
:貌似没用过,查了一下文档“规定从父元素继承 position 属性的值”;<div class="div-demo"></div> <style> .div-demo{ width:100px; height:100px; background-color:#06c; margin: auto; position:absolute; top: 0; left: 0; bottom: 0; right: 0; } </style>
<style> .div-demo{ width:100px; height:100px; background-color:#06c; margin: auto; position:absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); } </style>
<body class="container"> <div class="div-demo"></div> <style> html,body{ height:100%; } .container{ display: box; display: -webkit-box; display: flex; display: -webkit-flex; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; -webkit-box-align: center; -webkit-align-items: center; align-items: center; } .div-demo{ width:100px; height:100px; background-color:#06c; } </style> </body>
<body class="container"> <div class="div-angles"></div> <div class="div-angles right"></div> <div class="div-angles bottom"></div> <div class="div-angles left"></div> <style> html,body{ height:100%; } .container{ display: box; display: -webkit-box; display: flex; display: -webkit-flex; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; -webkit-box-align: center; -webkit-align-items: center; align-items: center; } .div-angles{ width: 0; height: 0; border-style: solid; border-width:30px; width:0px; height:0px; border-color: transparent transparent #06c transparent; } .right{ border-color: transparent transparent transparent #06c ; } .bottom{ border-color: #06c transparent transparent ; } .left{ border-color: transparent #06c transparent transparent; } </style> </body>
而新的在CSS3中引入的伪元素则不容许再支持旧的单冒号的写法;前端
::before
,以后则使用::after; 在代码顺序上,::after
生成的内容也比::before生成的内容靠后。若是按堆栈视角,::after生成的内容会在::before生成的内容之上; vue
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill { background-color: #fff;//设置成元素本来的颜色 background-image: none; color: rgb(0, 0, 0); } //方法2:由(licongwen )补充 input:-webkit-autofill { -webkit-box-shadow: 0px 0 3px 100px #ccc inset; //背景色 }
linear-gradient
,缺点就是:样式多,遇到圆角这个方案就杯剧了; box-shadow:网上看到说使用box-shadow模拟边框,box-shadow: inset 0px -1px 1px -1px #06c;没用过,不过多评论,建议本身百度;贴上三、5两方案代码,也是目前公司一直在用的( 预处理SCSS):
//三、css3的background-image 本文由@IT·平头哥联盟-首席填坑官∙苏南分享 @mixin border($top:1, $right:1, $bottom:1, $left:1, $color:#ebebf0) { background-image:linear-gradient(180deg, $color, $color 50%, transparent 50%), linear-gradient(90deg, $color, $color 50%, transparent 50%), linear-gradient(0deg, $color, $color 50%, transparent 50%), linear-gradient(90deg, $color, $color 50%, transparent 50%); background-size: 100% $top + px, $right + px 100%, 100% $bottom + px, $left + px 100%; background-repeat: no-repeat; background-position: top, right top, bottom, left top ; } @mixin borderTop($top:1, $color:#ebebf0) { @include border($top, 0, 0, 0, $color); } @mixin borderRight($right:1, $color:#ebebf0) { @include border(0, $right, 0, 0, $color); } @mixin borderBottom($bottom:1, $color:#ebebf0) { @include border(0, 0, $bottom, 0, $color); } @mixin borderLeft($left:1, $color:#ebebf0) { @include border(0, 0, 0, $left, $color); } @mixin borderColor($color:#ebebf0) { @include border(1, 1, 1, 1, $color); } //五、css3的transform:scale 本文由平头哥联盟-首席填坑官∙苏南分享 @mixin borderRadius($width:1,$style:solid,$color:#ebebf0,$radius:2px) { position:relative; &:after{ left:0px; top:0px; right:-100%; bottom:-100%; border-radius:$radius; border-style: $style; border-color: $color; border-width: $width+ px; position:absolute; display:block; transform:scale(0.5); -webkit-transform:scale(0.5); transform-origin:0 0; -webkit-transform-origin:0 0; content:''; } }
重绘/回流请看JS部分第七题
;//本文由@IT·平头哥联盟-首席填坑官∙苏南分享,若有错误,欢迎留言 function b(){ var a=1; }; function b(){ var a=1; return ()=>{ a++; return a; } }; let c = b(); c(); //2 c(); //3 c(); //4
ECMAScript 标准定义有7种数据类型: java
Boolean
Null
Undefined
Number
String
Symbol
:(ECMAScript 6 新定义 ,Symbol 生成一个全局惟1、表示独一无二的值) Object
:(Array、Function、Object)//方法1: var separator=(num)=>{ if(!num){ return '0.00'; }; let str = parseFloat(num).toFixed(2); return str && str .toString() .replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) { return $1 + ","; }); } separator(386485473.88) //"386,485,473.88" //方法2: (386485473.88).toLocaleString('en-US') // "386,485,473.88" 由 (sRect)补充
for
循环 数组下标的typeof类型:number
, for in 循环数组下标的typeof类型:string
;var southSu = ['苏南','深圳','18','男']; for(var i=0;i<southSu.length;i++){ console.log(typeof i); //number console.log(southSu[i]);// 苏南 , 深圳 , 18 , 男 } var arr = ['苏南','深圳','18','男','帅气',"@IT·平头哥联盟-首席填坑官"]; for(var k in arr){ console.log(typeof k);//string console.log(arr[k]);// 苏南 , 深圳 , 18 , 男 , 帅气,平头哥联盟-首席填坑官 }
for
循环 没法用于循环对象,获取不到obj.length; for in 循环遍历对象的属性时,原型链上的全部属性都将被访问,解决方案:使用hasOwnProperty
方法过滤或Object.keys会返回自身可枚举属性组成的数组Object.prototype.test = '原型链上的属性,本文由平头哥联盟-首席填坑官∙苏南分享'; var southSu = {name:'苏南',address:'深圳',age:18,sex:'男',height:176}; for(var i=0;i<southSu.length;i++){ console.log(typeof i); //空 console.log(southSu[i]);//空 } for(var k in southSu){ console.log(typeof k);//string console.log(southSu[k]);// 苏南 , 深圳 , 18 , 男 , 176 ,本文由平头哥联盟-首席填坑官∙苏南分享 }
<body class="container"> <table id="table"> <tr><td>咱们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr> <tr><td>咱们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr> <tr><td>咱们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr> ………… </table> <script> let table =document.querySelector("#table"); table.addEventListener("click",(e)=>{ let {nodeName} = e.target; if(nodeName.toUpperCase() === "TD"){ console.log(e.target);//<td>N</td> } },false); </script> </body>
<script> let str = "12qwe345671dsfa233dsf9876ds243dsaljhkjfzxcxzvdsf本文由平头哥联盟-首席填坑官∙苏南分享"; let array = str.split(""); //方案一: array = [...new Set(array)].join(""); array = ((a)=>[...new Set(a)])(array).join(""); console.log(array);//12qwe34567dsfa98ljhkzxcv本文由平头哥联盟-首席填坑官∙苏南分享 只能过滤,不会统计 //方案二: function unique (arr) { const seen = new Map() return (arr.filter((a) => !seen.has(a) && seen.set(a, 1))).join(""); } console.log(unique(array)) // 12qwe34567dsfa98ljhkzxcv本文由平头哥联盟-首席填坑官∙苏南分享 //方案三: function unique (arr) { let arrs=[]; var news_arr = arr.sort();//排序能减小一次循环 for(var i=0;i<news_arr.length;i++){ if(news_arr[i] == news_arr[i+1] && news_arr[i]!= news_arr[i-1] ){ arrs.push(arr[i]); }; }; return arrs.join(""); } console.log(unique(array)) // 12qwe34567dsfa98ljhkzxcv本文由平头哥联盟-首席填坑官∙苏南分享 //方案四: function unique (arr) { let obj={}; for(var i=0;i<arr.length;i++){ let key = arr[i]; if(!obj[key] ){ obj[key]=1; }else{ obj[key]+=1; } }; return obj; } console.log(unique(array)) // object 对应每一个key以及它重复的次数 </script>
promise
吗?请写出下列代码的执行结果,并写出你的理解思路:setTimeout(()=>{ console.log(1); }, 0); new Promise((resolve)=>{ console.log(2); for(var i = 1; i < 200; i++){ i = 198 && resolve(); } console.log(3); }).then(()=>{ console.log(4); }); console.log(5); // 结果:二、三、五、四、1;
宏任务
:js异步执行过程当中遇到宏任务,就先执行宏任务,将宏任务加入执行的队列(event queue),而后再去执行微任务; 微任务
:js异步执行过程当中遇到微任务,也会将任务加入执行的队列(event queue),可是注意这两个queue身份是不同的,不是你先进来,就你先出去的(就像宫里的皇上选妃侍寝同样,不是你先进宫(或先来排队)就先宠幸的 ),真执行的时候是先微任务里拿对应回调函数,而后才轮到宏任务的队列回调执行的; 说细步骤以下:
setTimeout 是异步,不会当即执行,加入执行队列;
new Promise 会当即执行 输出 二、3,而在二、3之间执行了resolve 也就是微任务;
再到console.log(5)了,输出5;
而后异步里的微任务先出,那就获得4;
最后执行宏任务 setTimeout 输出 1;
若有错误欢迎纠正!
node
function SouthSu(){ this.name = "苏南"; this.age = 18; this.address = "深圳"; this.address = "首席填坑官"; }; let South = new SouthSu(); console.log(South,South.__proto__ === SouthSu.prototype) //true 执行过程: 建立一个空的对象 let p1 = new Object(); 设置原型链 p1.__proto__ = SouthSu.prototype; 让 构造函数 的this 指向 p1 这个空对象 let funCall = SouthSu.call(p1); 处理 构造函数 的返回值:判断SouthSu的返回值类型,若是是值类型则返回obj,若是是引用类型,就返回这个引用类型的对象;
window.requestAnimationFrame()
方法告诉浏览器您但愿执行动画并请求浏览器在下一次重绘以前调用指定的函数来更新动画。该方法使用一个回调函数做为参数,这个回调函数会在浏览器重绘以前调用,回调的次数一般是每秒60次,是大多数浏览器一般匹配 W3C 所建议的刷新频率。在大多数浏览器里,当运行在后台标签页或者隐藏的<iframe>
里时,requestAnimationFrame() 会暂停调用以提高性能和电池寿命。小结:以往项目开发中大数人可能都是第一时间选择JS定时器
setInterval
或者setTimeout
来控制的动画每隔一段时间刷新元素的状态,来达到本身所想要的动画效果,可是这种方式并不能准确地控制动画帧率,由于这是开发者主动要求浏览器去绘制,它这可能会由于动画控制的时间、绘制的频率、浏览器的特性等而致使丢帧的问题;requestAnimationFrame
是浏览器何时要开始绘制了浏览器它本身知道,经过requestAnimationFrame
告诉咱们,这样就不会出现重复绘制丢失的问题。react
//一个持续旋转的正方形, <div class="angle-div"></div> <script> let timer = null; let Deg = 0; let distance = 360; var _requestAnimationFrame_ = window.requestAnimationFrame || window.webkitRequestAnimationFrame;//本文由平头哥联盟-首席填坑官∙苏南分享 let angleDiv = document.querySelector(".angle-div"); cancelAnimationFrame(timer); let fn = ()=>{ if(Deg < distance){ Deg++; }else{ Deg=0; }; angleDiv.style.transform = `rotateZ(${Deg}deg) translateZ(0)`; angleDiv.style.WebkitTransform = `rotateZ(${Deg}deg) translateZ(0)`; timer = _requestAnimationFrame_(fn); } timer = _requestAnimationFrame_(fn); </script>
1)、Expirescss3
Expires
的值为服务端返回的到期时间,响应时告诉浏览器能够直接从浏览器缓存中读取无需再次请求。缺点:返回的是服务端的时间,比较的时间是客户端的时间,若是时间不一致有可能出现错误。git
2)、Cache-Control
Cache-Control
可设置的字段有:private
:客户端能够缓存public
:客户端和代理服务器均可以缓存max-age=xxx
:缓存内容在xxx秒后失效no-cache
:须要用另外一种缓存策略来验证缓存(ETag
,Last-Modified
)no-store
:不进行缓存Last-Modified
:浏览器请求得到文件后,服务器返回该文件的最后修改时间Last-Modified
,下一次请求会带上If-Modified-Since
标识,若是If-Modified-Since
等于服务器的文件修改时间,则表示文件没有修改,返回304状态码,浏览器从浏览器缓存中读取文件。若是If-Modified-Since
小于服务端的文件修改时间,则浏览器会从新发送请求获取文件,返回状态码200。ETag
:服务器文件的一个惟一标识,例如对文件内容取md5值做为ETag
的字段返回给浏览器。当文件变化时ETag
的值也会发生变化。下次请求会带上If-None-Match
即浏览器保留的ETag
值,若是发送了变化,则文件被修改,须要从新请求,返回200状态码。反之浏览器就从缓存中读取文件,返回304状态码。总结:——几者之间的关系
- 当
Cache-Control
设置为max-age=xx
而且同事设置Expires
时,Cache-Control
的优先级更高- 当
ETag
和Last-Modified
同时存在时,服务器先会检查ETag
,而后再检查Last-Modified
,最终决定返回304仍是200- 该题由 本文由平头哥联盟-成员(
ZodiacSyndicate
)补充
//该题由 本文由平头哥联盟-成员(ZodiacSyndicate )补充 const shuffle = arr => { let end = arr.length - 1 while(end) { // 当end为0时不须要交换 const index = Math.floor(Math.random() * (end + 1)) [arr[index], arr[end]] = [arr[end], arr[index]] end -= 1 } return arr }
//该题由 本文由平头哥联盟-成员(ZodiacSyndicate )补充 const mousePosition = Component => class extends React.Component { state = { x: 0, y: 0, } handleMouseMove = e => { this.setState({ x: e.clientX, y: e.clientY }) } render() { const { x, y } = this.state return ( <> <div onMouseMove={this.handleMouseMove}> <Component {...this.props} /> </div> <span>x: {x}</span> <span>y: {y}</span> </> ) } }
文本将持续更新,整理收集本身/群友的面经分享给你们,如以为不错,记得关注咱们的公众号哦
!!
作完小程序项目、老板给我加了6k薪资~
你应该作的前端性能优化之总结大全!
如何给localStorage设置一个过时时间?
手把手教你如何绘制一辆会跑车
如何用CSS3画出懂你的3D魔方?
SVG Sprites Icon的使用技巧
immutability因React官方出镜之使用总结分享!
做者:苏南 - 首席填坑官
交流群:912594095,公众号:honeyBadger8
本文原创,著做权归做者全部。商业转载请联系@IT·平头哥联盟
得到受权,非商业转载请注明原连接及出处。