前端面試題攻關(guān)

**如何理解原型鏈

每個函數(shù)都擁有一個prototype屬性,每個函數(shù)實例對象都擁有一個proto屬性,而這個屬性指向了函數(shù)的prototype,當(dāng)我們訪問實例對象的屬性或者方法時,會先從自身構(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)
微信圖片_20200514191843.jpg

通過截圖,我們可以看到cat實例對象proto指向了Animal,當(dāng)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)//打?。呵岸宋磥?    }
}
**什么是深/淺拷貝,有哪些實現(xiàn)方式

JS數(shù)據(jù)類型分別基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型保存的是值,引用類型保存的是引用地址(this指針)。淺拷貝共用一個引用地址,深拷貝會創(chuàng)建新的內(nèi)存地址。

  • 淺拷貝方法
    直接對象復(fù)制
    Object.assign
  • 深拷貝
    JSON.stringify轉(zhuǎn)為字符串再JSON.parse
    深度遞歸遍歷
**如何準(zhǔn)確判斷一個對象是數(shù)組

面試官希望的答案:

  • Object.prototype.toString.call([]) 返回 "[object Array]"
    擴(kuò)展答案
  • [].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ù)組,從某個位置開始刪除多個元素,并可以插入新的元素。
**CSS實現(xiàn)三列布局(左右固定寬度,中間自適應(yīng))
  • CSS浮動
    第一個float:left,第二個float:right,第三個設(shè)置margin-left和margin-right
  • 絕對定位法
    第一個定位到left,第二個定位到right,第三個設(shè)置margin-left和margin-right
  • flex布局
**H5自適應(yīng)方案

H5自適應(yīng)方案大家在網(wǎng)速能找到很多,我個人推薦一種我非常喜歡的方式,就是rem. rem是一種相對單位,它基于html的font-size值來進(jìn)行調(diào)整。
通常我們以750為基準(zhǔn),我們會在header中嵌套一段js腳本,獲取手機(jī)網(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ù)組傳參

瀏覽器解析渲染頁面過程

image
  • 解析HTML,生成DOM樹
  • 解析CSS,生成CSSOM樹
  • 將DOM樹和CSSOM樹關(guān)聯(lián),生成渲染樹(Render Tree)
  • 布局render樹(Layout/reflow),負(fù)責(zé)各元素尺寸、位置的計算
  • 繪制render樹(paint),繪制頁面像素信息
  • 將像素發(fā)送給GPU,展示在頁面上。(Display)
**談一下防抖和節(jié)流

防抖和節(jié)流都是希望在同一時間內(nèi),不要重復(fù)觸發(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)前后對比
**前端有哪些跨域方案
  • JSONP跨域(本質(zhì)是JS調(diào)用)
  • CORS(后臺設(shè)置)
  • Nginx反向代理(運(yùn)維配置)
  • 跨域是瀏覽器做出的安全限制,必須同協(xié)議、同域名、同端口否則會被瀏覽器block
    不常用跨域方案,我不進(jìn)行列出
**前端網(wǎng)站常規(guī)優(yōu)化方案
  • 優(yōu)化策略:減少請求次數(shù)、減小資源大小、提高響應(yīng)和加載速度、優(yōu)化資源加載時機(jī)、優(yōu)化加載方式
    合并、壓縮、混淆html/css/js文件(webpack實現(xiàn),減小資源大?。?/li>
  • Nginx開啟Gzip,進(jìn)一步壓縮資源(減小資源大?。?/li>
  • 圖片資源使用CDN加速(提高加載速度)
  • 符合條件的圖標(biāo)做base64處理(減小資源大小)
  • 樣式表放首部,JS放尾部(JS單線程,會阻塞頁面;資源加載方式)
  • 設(shè)置緩存(強(qiáng)緩存和協(xié)商緩存,提高加載速度)
    link或者src添加rel屬性,設(shè)置prefetch或preload可預(yù)加載資源。(加載時機(jī))
  • 如果使用了UI組件庫,采用按需加載(減小資源大小)
    SPA項目,通過import或者require做路由按需(減小資源大?。?/li>
  • 服務(wù)端渲染SSR,加快首屏渲染,利于SEO
  • 頁面使用骨架屏,提高首頁加載速度(提高加載速度)
  • 使用 JPEG 2000, JPEG XR, and WebP 的圖片格式來代替現(xiàn)有的jpeg和png,當(dāng)頁面圖片較多時,這點作用非常明顯
    使用圖片懶加載-lazyload
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容