前言
近期參加面試的伙伴比較多一些原因最近也參加了幾家公司的面試,發(fā)現(xiàn)有很多基礎(chǔ)性的東西掌握程度還是不夠,故此想總結(jié)一下最近面試遇到的問(wèn)題,希望能為在準(zhǔn)備面試的的小伙伴盡一些綿薄之力,主要說(shuō)的是一些我面試當(dāng)中問(wèn)到的一些問(wèn)題,說(shuō)的不對(duì)的地方請(qǐng)小伙伴們即使指正出來(lái),或者有其他的看法也可以一起探討。
一、HTML/CSS1.html5新增標(biāo)簽新增了一些語(yǔ)義化的標(biāo)簽例如:header,fotter,nav,main
新增圖像:canvas svg
新增媒體標(biāo)簽: audio video
2.什么是盒模型W3C標(biāo)準(zhǔn)盒模型,屬性width,height包含content,不包含border和padding
IE盒模型,屬性width,height包含content,border,padding
3.css居中元素說(shuō)一下我比較常用的的幾種
使用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.移動(dòng)端1px邊框問(wèn)題主要是不同手機(jī)的dpi不同會(huì)導(dǎo)致這個(gè)問(wèn)題。解決辦法:
看手機(jī)是否支持0.5px的邊框,并且dpi大于等于2,會(huì)用到j(luò)s判斷比較復(fù)雜,這里不做實(shí)現(xiàn)。使用背景圖,修改顏色麻煩,需要換圖。圓角需要特殊處理。偽類(lèi)元素加transform實(shí)現(xiàn),個(gè)人經(jīng)常使用。
.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-shadowbackground新增background-image,background-size background-repeat媒體查詢(xún)
6.rem em px區(qū)別px相對(duì)長(zhǎng)度單位,相對(duì)于顯示器屏幕分辨率來(lái)的em相對(duì)長(zhǎng)度單位,相對(duì)于當(dāng)前對(duì)象內(nèi)文本的字體尺寸來(lái)的,值不固定,會(huì)繼承父級(jí)元素字體的大小,未經(jīng)調(diào)整瀏覽器:16px = 1em。假如父元素為2em,子元素為2em字體實(shí)際大小為4emrem是css3新增的相對(duì)單位,使用rem為元素設(shè)置大小時(shí),是相對(duì)大小,相對(duì)的是html根元素,修改根元素就可以調(diào)整所有字體大小,還可以避免字體大小逐層復(fù)合的連鎖反應(yīng),未經(jīng)調(diào)整瀏覽器:16px = 1rem。
7.詳細(xì)說(shuō)下BFCBFC塊級(jí)格式上下文,是頁(yè)面上一個(gè)獨(dú)立的容器,容器內(nèi)的子元素不會(huì)影響到外邊的元素,垂直方向邊距重疊,計(jì)算高度是浮動(dòng)元素也會(huì)計(jì)算BFC觸發(fā):根元素(html),浮動(dòng)元素(float不為none),絕對(duì)定位元素(position為absolute和fixed),行內(nèi)塊元素(display為inline-block),overflow值不為visible,彈性元素(display為flex)應(yīng)用場(chǎng)景:設(shè)置元素為BFC防止浮動(dòng)高度塌陷,避免外邊距重疊8.重繪和回流
簡(jiǎn)單的一句話(huà)就是:回流必引起重繪,重繪不會(huì)引起回流,回流比重繪更耗性能?;亓鳎寒?dāng)元素的尺寸結(jié)構(gòu)和某個(gè)屬性發(fā)生改變時(shí),瀏覽器重新渲染部分或全部文檔的過(guò)程。會(huì)發(fā)生回流的操作:瀏覽器窗口發(fā)生改變,元素位置和大小發(fā)生改變,元素內(nèi)容發(fā)生改變,對(duì)可見(jiàn)的dom進(jìn)行添加或者刪除,查詢(xún)某些屬性或調(diào)用某些方法(clientWidth,offsetWidth, scrollWidth,scrollTo等等)重繪:改變?cè)氐臉邮讲挥绊懺谖臋n流的位置(color,background-color)瀏覽器把新的樣式重新賦給元素并繪制css避免:避免設(shè)置多層內(nèi)聯(lián)樣式,避免使用css表達(dá)式(ealc),將動(dòng)畫(huà)放在position的屬性上(absolute, fixed),避免使用table布局。js避免:避免重復(fù)操作樣式(定義一個(gè)class并一次修改class屬性),避免頻繁操作dom(創(chuàng)建一個(gè)documentFragment,在它上邊操作dom,最后添加的文檔中),避免頻繁讀取引起重繪/回流的值(可以使用變量緩存)。
二、JS1.js基本類(lèi)型和引用類(lèi)型基本類(lèi)型:Boolean Null Number String Undefined Symbol BigInt引用類(lèi)型:Object
2.作用域分為:全局作用域(定義在函數(shù)外部的變量)和局部作用域(定義在函數(shù)內(nèi)部的變量),每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)創(chuàng)建一個(gè)新的域。ECMAScript 6引入了let和const關(guān)鍵字,利用let和const可以形成塊級(jí)作用域。塊語(yǔ)句(if, switch, for, while)不會(huì)創(chuàng)建新的作用域,定義的變量保存在已經(jīng)存在的作用域中,let和const支持在局部作用域塊語(yǔ)句中聲明
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
作用域鏈:作用域鏈?zhǔn)窃谧兞繉?duì)象之后創(chuàng)建的,作用域鏈用于解析變量,當(dāng)變量被解析時(shí),javascript先從代碼嵌套的最內(nèi)層開(kāi)始找,如果內(nèi)層沒(méi)有找到,會(huì)轉(zhuǎn)到上一層父級(jí)作用域查找,直到找到該變量
3.閉包它允許函數(shù)訪(fǎng)問(wèn)局部作用域之外的數(shù)據(jù),閉包有自己的作用域鏈,父級(jí)作用域鏈和全局作用域鏈。
function a() {
var b = 3;
return function() {
console.log(b)
}
}
a()() // 3
4.前端存儲(chǔ)cookie,localStorage,sessionStoragelocalStorage有效期為永久,sessionStorage有效期為窗口關(guān)閉同源文檔可以修改并讀取localStorage的值,sessionStorage只允許同一個(gè)窗口下的文檔訪(fǎng)問(wèn)用法:
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是瀏覽器儲(chǔ)存少量數(shù)據(jù),cookie會(huì)自動(dòng)在瀏覽器和服務(wù)器之間傳輸,可以通過(guò)path和domain配置,頁(yè)面同目錄和子目錄都可以訪(fǎng)問(wèn)
document.cookie = 'a=1; path=/'; // 創(chuàng)建當(dāng)前頁(yè)面的cookie
var a = document.cookie; // 讀取cookie 返回格式key=value; key1=value1;
document.cookie = 'a=2; path=/'; // 修改值,會(huì)把以前的值覆蓋
document.cookie = "a=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; //刪除cookie
5.promise實(shí)現(xiàn)原理9k字 | Promise/async/Generator實(shí)現(xiàn)原理解析
6.宏任務(wù)和微任務(wù)首先你要知道Javascript是單線(xiàn)程語(yǔ)言,Event Loop是JavaScript的執(zhí)行機(jī)制微任務(wù)和宏任務(wù)都屬于異步任務(wù),屬于同一個(gè)隊(duì)列,主要區(qū)別是他們執(zhí)行的順序,開(kāi)始執(zhí)行宏任務(wù)的時(shí)候,宏任務(wù)執(zhí)行完畢之后會(huì)看有沒(méi)有微任務(wù),如果有的話(huà)執(zhí)行微任務(wù),沒(méi)有接著下一個(gè)執(zhí)行宏任務(wù)。在當(dāng)前微任務(wù)沒(méi)有執(zhí)行完畢,是不會(huì)執(zhí)行下一個(gè)宏任務(wù)的,而微任務(wù)又在宏任務(wù)之前執(zhí)行
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
宏任務(wù):setTimeout, setInterval, requestAnimationFrame微任務(wù) Promise.then catch finally
7.節(jié)流和防抖節(jié)流:高頻事件觸發(fā)n秒內(nèi)執(zhí)行一次,如果這個(gè)時(shí)間點(diǎn)內(nèi)觸發(fā)多次函數(shù),只有一次生效。
function throttle(fn) {
var flag = true
return function() {
if (!flag) return;
flag = false;
setTimeout(function () {
fn()
flag = true
}, 1000)
}
}
防抖:高頻事件觸發(fā)n秒之后執(zhí)行,如果n秒之內(nèi)再次被觸發(fā),重新記時(shí)。
function debounce(fn) {
var timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(function (){
fn()
}, 1000)
}
}
8.get和post區(qū)別最直觀(guān)的區(qū)別get把參數(shù)包含在URL中,post通過(guò)request body傳遞參數(shù),相對(duì)于get比較安全get請(qǐng)求URL傳參有長(zhǎng)度限制,post沒(méi)有g(shù)et在瀏覽器回退是無(wú)害的,post會(huì)再次提交請(qǐng)求get請(qǐng)求會(huì)被瀏覽器主動(dòng)緩存,post不會(huì)get和post報(bào)文格式不同get請(qǐng)求是冪等性的,而post請(qǐng)求不是(新增和刪除數(shù)據(jù)一般不用post請(qǐng)求就是這個(gè)原因)
9.Js的事件委托是什么,原理是什么通俗點(diǎn)說(shuō)將元素事件委托給他的父級(jí)或者更外級(jí)來(lái)處理事件委托是利用冒泡機(jī)制來(lái)實(shí)現(xiàn)的(事件冒泡:事件由具體的元素接受,然后逐漸向上傳播到不具體的節(jié)點(diǎn))
// 每個(gè)列表點(diǎn)擊彈出內(nèi)容
// 不使用事件委托需要給每個(gè)列表添加點(diǎn)擊事件(消耗內(nèi)存,不靈活,添加動(dòng)態(tài)元素時(shí)需要重新綁定事件)這里不做介紹
<ul id="myLink">
<li id="1">aaa</li>
<li id="2">bbb</li>
<li id="3">ccc</li>
</ul>
// 使用事件委托(減少內(nèi)存占用,提升性能,動(dòng)態(tài)添加元素?zé)o需重新綁定事件)
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);
}
};