前端基礎(chǔ)篇
如何理解執(zhí)行上下文
JavaScript執(zhí)行上下文(context)主要指代碼執(zhí)行環(huán)境的抽象概念。執(zhí)行上下文分為三種:
全局執(zhí)行上下文
函數(shù)執(zhí)行上下文
eval執(zhí)行上下文
每一段js代碼執(zhí)行,都會先創(chuàng)建一個上下文環(huán)境。
如何理解作用域鏈
前沿知識:js代碼執(zhí)行前會創(chuàng)建上下文環(huán)境,這個上下文環(huán)境包含了變量、作用域鏈和this.
簡單理解就是從當前環(huán)境向父級一層一層查找變量的過程稱之為作用域鏈。
var name = '前端未來';
function hello(){
console.log(name);
}
解釋:當我們在函數(shù)hello里面打印name的時候,會先在hello作用域中查找,如果沒有找到就去hello的父級作用域中查找。
如何理解原型鏈
每個函數(shù)都擁有一個prototype屬性,每個函數(shù)實例對象都擁有一個proto屬性,而這個屬性指向了函數(shù)的prototype,當我們訪問實例對象的屬性或者方法時,會先從自身構(gòu)造函數(shù)中查找,如果沒有就通過proto去原型中查找,這個查找的過程我們稱之為原型鏈。(跟作用域鏈有點像)
// 定義動物 - 父類
function Animal(){
this.age = 10;
this.say = function(){
return 'hello tom';
}
}
// 定義貓 - 子類
function Cat(){
this.name = 'tom';
}
// 通過原型繼承動物類
Cat.prototype = new Animal()
// 實例化一個cat對象
var cat = new Cat();
// 打印返回true
cat.proto === Cat.prototype
// 打印age,會先查找cat,再查找Animal
console.log(cat.age)

通過截圖,我們可以看到cat實例對象proto指向了Animal,當cat沒有age的時候,會通過proto到原型上查找,如果原型上依然沒有,會繼續(xù)向Object上查找。
什么是閉包
簡單理解就是函數(shù)中嵌套函數(shù)。我們都知道局部變量我們是無法訪問的,但是通過閉包可以做到。
// 正常訪問
var lan = 'zh';
function hello(){
var name = '前端未來';
}
console.log(name)//很明顯'undefined'
// 換成閉包
function hello(){
var name = '前端未來';
function demo(){
console.log(name)//打印:前端未來
}
}
以上幾個基礎(chǔ)面試題都是密切關(guān)聯(lián)的,理解其中一個,基本就能理解剩下幾個
繼承有哪些方法
原型繼承
構(gòu)造繼承
實例繼承
call/apply繼承(組合繼承)
ES6 使用class extends繼承
什么是深/淺拷貝,有哪些實現(xiàn)方式
JS數(shù)據(jù)類型分別基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型保存的是值,引用類型保存的是引用地址(this指針)。淺拷貝共用一個引用地址,深拷貝會創(chuàng)建新的內(nèi)存地址。
淺拷貝方法
-直接對象復制
-Object.assign
深拷貝
-JSON.stringify轉(zhuǎn)為字符串再JSON.parse
-深度遞歸遍歷
如何準確判斷一個對象是數(shù)組
面試官希望的答案:Object.prototype.toString.call([]) 返回 "[object Array]"
擴展答案
-[].slice (能力判斷 )
-[] instanceof Array(類型判斷)
-[].proto === Array.prototype
-Array.isArray([]) 存在兼容問題
數(shù)組也是引用類型,通過typeof依然返回object
數(shù)組有哪些常用方法
這個非常多,說起來也很快,我主要考察你會多少,另外也為了引出下一個問題,slice和splice區(qū)別
-push 末尾添加
-pop 末尾刪除
-shift 首部刪除
-unshift 首部添加
-concat 數(shù)組合并
-join 數(shù)組元素 通過連接符 連接
-reverse 數(shù)組反轉(zhuǎn)
-sort 數(shù)組排序
-map/forEach/filter/indexOf/includes/slice/splice
slice表示截取,slice(start,end)不改變原數(shù)組,返回新數(shù)組。
splice表示刪除,splice(start,length,item),會改變原數(shù)組,從某個位置開始刪除多個元素,并可以插入新的元素。
DOM節(jié)點創(chuàng)建和修改有哪些常用API
創(chuàng)建節(jié)點
-createElement
-createTextNode
-createDocumentFragment(臨時節(jié)點)
修改節(jié)點
-appendChildparent.appendChild(child)
-insertBefore parentNode.insertBefore(newNode,refNode);
-removeChild parent.removeChild(node)
-replaceChild
CSS清除浮動有哪些方法
-父級元素設(shè)置高度,手動撐開
-浮動元素結(jié)尾增加空標簽,設(shè)置clear:both
-父元素設(shè)置overflow:hidden
-父元素添加偽類:after和zoom
CSS選擇器優(yōu)先級
!import > 內(nèi)聯(lián)樣式(style) > ID選擇器 > 類/屬性/偽類 > 元素/關(guān)系
CSS實現(xiàn)三列布局(左右固定寬度,中間自適應(yīng))
-CSS浮動
第一個float:left,第二個float:right,第三個設(shè)置margin-left和margin-right
-絕對定位法
第一個定位到left,第二個定位到right,第三個設(shè)置margin-left和margin-right
-flex布局
.left{
width:200px;
或者
flex:0 0 200px;
}
.right{
width:200px;
或者
flex:0 0 200px;
}
.center{
flex:1;
}
-阿里圣杯布局(忽略)
談一下flex布局
flex是一種彈性布局,包含flex-container和flex-item.
常用的屬性包括flex-direction、flex-wrap、justify-content、align-items
水平居中 justify-content:center 水平兩頭居中 justify-content:space-between 垂直居中 align-items:center
談一下盒模型
盒模型包括:content,padding,border,margin
盒模型分為:IE盒模型和標準w3c盒模型
IE盒模型寬度包含了padding和border,w3c盒模型寬度就是內(nèi)容寬度。
transition動畫和animation有什么區(qū)別
他們雖然都可以做出動畫效果,但是transition主要做簡單的過渡效果,而animation可以做復雜的動畫效果,在語法和用法上有非常大的區(qū)別。
H5自適應(yīng)方案
H5自適應(yīng)方案大家在網(wǎng)速能找到很多,我個人推薦一種我非常喜歡的方式,就是rem. rem是一種相對單位,它基于html的font-size值來進行調(diào)整。
通常我們以750為基準,我們會在header中嵌套一段js腳本,獲取手機網(wǎng)頁分辨率尺寸除以375,為了方便計算,我們假設(shè)750像素下1rem = 100px;所以 我們除以375后需要乘以50.
call/apply/bind作用和區(qū)別
他們都可以改變函數(shù)的作用域。
-call/apply可以直接執(zhí)行該函數(shù),而bind不會立刻執(zhí)行
-call/apply作用類似,都可以改變指針和執(zhí)行函數(shù),區(qū)別在于傳參不同,call需要單個傳參,apply通過數(shù)組傳參
GET和POST有什么區(qū)別
大小方面
-GET傳輸一般2K-8K,IE限制2K,,POST沒有大小限制
安全方面
-GET通過url明文傳輸,POST通過body傳輸,本身都不安全,因為HTTP就是明文傳輸。
瀏覽器記錄
-GET請求瀏覽器會記錄,POST不會
瀏覽器后退
-GET無害,POST會再次提交
瀏覽器收藏
-GET可以收藏,POST不可以
瀏覽器緩存
-GET可以緩存,POST不會
編碼方式
-GET通過url編碼,POST支持多種編碼
TCP數(shù)據(jù)包
-GET產(chǎn)生一個數(shù)據(jù)包,POST產(chǎn)生2個數(shù)據(jù)包
使用方式(習慣上講)
-GET主要拉取數(shù)據(jù),POST主要提交保存數(shù)據(jù)
談一下防抖和節(jié)流
防抖和節(jié)流都是希望在同一時間內(nèi),不要重復觸發(fā)請求。一般場景用在搜索和網(wǎng)頁滾動事件中。
區(qū)別:
防抖主要是在規(guī)定時間內(nèi)只觸發(fā)一次,如果再次調(diào)用,時間從新計算。
節(jié)流主要是在固定時間內(nèi)只觸發(fā)一次。比如每間隔1秒觸發(fā)一次。
數(shù)組如何去重
-ES6 Set去重
-利用Object key去重
-兩層循環(huán)逐一對比,生成新數(shù)組
-indexOf去重
-sort排序,再單層循環(huán)前后對比
數(shù)組如何排序
-數(shù)組sort排序
-冒泡排序(兩層循環(huán),兩兩互換)
//冒泡排序
function bubbleSort ( data ) {
var temp = 0;
for ( var i = data.length ; i > 0 ; i -- ){
for( var j = 0 ; j < i - 1 ; j++){
if( data[j] > data[j + 1] ){
temp = data[j];
data[j] = data [j+1];
data[j+1] = temp;
}
}
}
return data;
}
-選擇排序
//選擇排序
function selectionSort( data ) {
for( var i = 0; i< data.length ; i++){
var min = data[i];
var temp;
var index = i;
for( var j = i + 1; j< data.length; j++){
if( data[j] < min ){
min = data[j];
index = j;
}
}
temp = data[i];
data[i] = min;
data[index]= temp;
}
return data;
}
-插入排序
//插入排序
function insertionSort( data ) {
var len = data.length;
for (var i = 1; i < len; i++) {
var key = data[i];
var j = i - 1;
while ( j >= 0 && data[j] > key) {
data[j + 1] = data[j];
j--;
}
data[j + 1] = key;
}
return data;
}
談一下for...of
for...of 是ES2015版本引入的語法,它可以遍歷數(shù)組、類數(shù)組、以及Map/set/字符串等
-數(shù)組迭代
for (const number of [1,2,5]) { }
-類數(shù)組迭代
for (const number of arguments) { }
-字符串迭代
const message = 'hello';
for (const character of message) { }
-map迭代
const map = new Map();
map.set("name", '前端未來');
map.set("author", '河畔一角');
for(const item of map){ }
// 或者
for(const [key,val] of map){ }
-Set迭代
const names = new Set(['Tom', 'Jack', 'Lily']);
for (let name of names) { }
前端常見攻擊方式
-XSS攻擊
-CSRF攻擊
-Sql注入
-html腳本注入
前端有哪些跨域方案
-JSONP跨域(本質(zhì)是JS調(diào)用)
-CORS(后臺設(shè)置)
-Nginx反向代理(運維配置)
跨域是瀏覽器做出的安全限制,必須同協(xié)議、同域名、同端口否則會被瀏覽器block
前端網(wǎng)站常規(guī)優(yōu)化方案
優(yōu)化策略:減少請求次數(shù)、減小資源大小、提高響應(yīng)和加載速度、優(yōu)化資源加載時機、優(yōu)化加載方式
-合并、壓縮、混淆html/css/js文件(webpack實現(xiàn),減小資源大?。?br>
-Nginx開啟Gzip,進一步壓縮資源(減小資源大?。?br>
-圖片資源使用CDN加速(提高加載速度)
-符合條件的圖標做base64處理(減小資源大?。?br>
-樣式表放首部,JS放尾部(JS單線程,會阻塞頁面;資源加載方式)
-設(shè)置緩存(強緩存和協(xié)商緩存,提高加載速度)
-link或者src添加rel屬性,設(shè)置prefetch或preload可預(yù)加載資源。(加載時機)
-如果使用了UI組件庫,采用按需加載(減小資源大?。?br>
-SPA項目,通過import或者require做路由按需(減小資源大小)
-服務(wù)端渲染SSR,加快首屏渲染,利于SEO
-頁面使用骨架屏,提高首頁加載速度(提高加載速度)
-使用 JPEG 2000, JPEG XR, and WebP 的圖片格式來代替現(xiàn)有的jpeg和png,當頁面圖片較多時,這點作用非常明顯
-使用圖片懶加載-lazyload