蘋果手機(jī)做網(wǎng)站服務(wù)器深圳網(wǎng)站制作設(shè)計(jì)
有了這個八股文不僅對你基礎(chǔ)知識的鞏固,不管你是幾年老前端程序員,還是要去面試的,文章覆蓋了前端常用及不常用的方方面面,都是前端日后能用上的,對你的前端知識有總結(jié)意義,看完后,懂的不懂的都感覺茅塞頓開,會有前端知識有質(zhì)的提高。知識整理不易,請【收藏-點(diǎn)贊】
直接開始前端知識總結(jié),從淺到深,包括了HTML,css總結(jié),HTTP基礎(chǔ),javascript深入問題,Vue2 / Vue3,React知識點(diǎn),ES6新功能特性。
HTML前端基礎(chǔ)
1.1 html標(biāo)簽的類型(head, body,!Doctype) 他們的作用是什么
!DOCTYPE 標(biāo)簽
它是指示 web 瀏覽器關(guān)于頁面使用哪個 HTML 版本進(jìn)行編寫的指令
head:
- 是所有頭部元素的容器, 絕大多數(shù)頭部標(biāo)簽的內(nèi)容不會顯示給讀者
- 該標(biāo)簽下所包含的部分可加入的標(biāo)簽有 base, link, meta, script, style和title
body:
- 用于定義文檔的主體, 包含了文檔的所有內(nèi)容
- 該標(biāo)簽支持 html 的全局屬性和事件屬性
1.2 h5新特性
- 新增選擇器 document.querySelector、document.querySelectorAll
- 拖拽釋放(Drag and drop) API
- 媒體播放的 video 和 audio
- 本地存儲 localStorage 和 sessionStorage
- 離線應(yīng)用 manifest
- 桌面通知 Notififications
- 語意化標(biāo)簽 article、footer、header、nav、section
- 增強(qiáng)表單控件 calendar、date、time、email、url、search
- 地理位置 Geolocation
- 多任務(wù) webworker
- 全雙工通信協(xié)議 websocket
- 歷史管理 history
- 跨域資源共享(CORS) Access-Control-Allow-Origin
- 頁面可見性改變事件 visibilitychange
- 跨窗口通信 PostMessage
- Form Data 對象
- 繪畫 canvas
1.3 偽類和偽元素
偽類:用于已有元素處于某種狀態(tài)時為其添加對應(yīng)的樣式,這個狀態(tài)是根據(jù)用戶行為而動態(tài)變化的
例如:當(dāng)用戶懸停在指定元素時,可以通過:hover來描述這個元素的狀態(tài),雖然它和一般css相似,可以為 已有元素添加樣式,但是它只有處于DOM樹無法描述的狀態(tài)下才能為元素添加樣式,所以稱為偽類
偽元素:用于創(chuàng)建一些不在DOM樹中的元素,并為其添加樣式
1.4 html語義化132613673
標(biāo)簽名 | 頁面主體內(nèi)容 |
---|---|
h1~h6 | h1~h6,分級標(biāo)題,<h1> 和 <title> 協(xié)調(diào)有利于搜索引擎優(yōu)化 |
ul li | 無序列表 |
ol li | 有序列表 |
header | 頁眉通常包括網(wǎng)站標(biāo)志、主導(dǎo)航、全站鏈接以及搜索框 |
nav | 標(biāo)記導(dǎo)航,僅對文檔中重要的鏈接群使用 |
main | 頁面主要內(nèi)容,一個頁面只能使用一次。如果是web應(yīng)用,則包圍其主要功能 |
article | 定義外部的內(nèi)容,其中的內(nèi)容獨(dú)立于文檔的其余部分 |
section | 定義文檔中的節(jié)(section、區(qū)段)。比如章節(jié)、頁眉、頁腳或文檔中的其他部分 |
aside | 定義其所處內(nèi)容之外的內(nèi)容。如側(cè)欄、文章的一組鏈接、廣告、友情鏈接、相關(guān)產(chǎn)品列表等 |
footer | 頁腳,只有當(dāng)父級是body時,才是整個頁面的頁腳 |
small | 呈現(xiàn)小號字體效果,指定細(xì)則,輸入免責(zé)聲明、注解、署名、版權(quán) |
strong | 和 em 標(biāo)簽一樣,用于強(qiáng)調(diào)文本,但它強(qiáng)調(diào)的程度更強(qiáng)一些 |
em | 將其中的文本表示為強(qiáng)調(diào)的內(nèi)容,表現(xiàn)為斜體 |
mark | 使用黃色突出顯示部分文本 |
figure | 規(guī)定獨(dú)立的流內(nèi)容(圖像、圖表、照片、代碼等等)(默認(rèn)有40px左右margin) |
figcaption | 定義 figure 元素的標(biāo)題,應(yīng)該被置于 figure 元素的第一個或最后一個子元素的位置 |
cite | 表示所包含的文本對某個參考文獻(xiàn)的引用,比如書籍或者雜志的標(biāo)題 |
progress | 定義運(yùn)行中的進(jìn)度(進(jìn)程) |
address | 作者、相關(guān)人士或組織的聯(lián)系信息(電子郵件地址、指向聯(lián)系信息頁的鏈接) |
blockquoto | 定義塊引用,塊引用擁有它們自己的空間 |
del、ins、code | 移除的內(nèi)容、添加的內(nèi)容、標(biāo)記代碼 |
語義化優(yōu)點(diǎn)
- 易于用戶閱讀,樣式丟失的時候能讓頁面呈現(xiàn)清晰的結(jié)構(gòu)
- 有利于SEO,搜索引擎根據(jù)標(biāo)簽來確定上下文和各個關(guān)鍵字的權(quán)重
- 方便屏幕閱讀器解析,如盲人閱讀器根據(jù)語義渲染網(wǎng)頁
- 有利于開發(fā)和維護(hù),語義化更具可讀性,代碼更好維護(hù),與CSS3關(guān)系更和諧
1.5 引入樣式時,link和@import的區(qū)別?
- 鏈接樣式時,link只能在HTML頁面中引入外部樣式
- 導(dǎo)入樣式表時,@import 既可以在HTML頁面中導(dǎo)入外部樣式,也可以在css樣式文件中導(dǎo)入外部css樣式
1.6 介紹一下你對瀏覽器內(nèi)核的理解
主要分成兩部分:渲染引擎(Layout Engine或Rendering Engine)和js引擎
- 渲染引擎:負(fù)責(zé)取得網(wǎng)頁的內(nèi)容(HTML、XML、圖像等等)、整理訊息(例如加入CSS等),以及計(jì)算網(wǎng)頁的顯示方式,然后會輸出至顯示器或打印機(jī)。瀏覽器的內(nèi)核的不同對于網(wǎng)頁的語法解釋會有不同,所以渲染的效果也不相同。
- js引擎:解析和執(zhí)行JavaScript來實(shí)現(xiàn)網(wǎng)頁的動態(tài)效果
1.7 常見的瀏覽器內(nèi)核有哪些
- Trident( MSHTML ):IE MaxThon TT The World 360 搜狗瀏覽器
- Geckos:Netscape6及以上版本 FireFox Mozilla Suite/SeaMonkey
- Presto:Opera7及以上(Opera內(nèi)核原為:Presto,現(xiàn)為:Blink)
- Webkit:Safari Chrome
1.8 label標(biāo)簽的作用是什么? 是怎么用的?
- label標(biāo)簽用來定義表單控件間的關(guān)系
- 當(dāng)用戶選擇該標(biāo)簽時,瀏覽器會自動將焦點(diǎn)轉(zhuǎn)到和標(biāo)簽相關(guān)的表單控件上
- label 中有兩個屬性是非常有用的, FOR和ACCESSKEY
- FOR屬性功能:表示label標(biāo)簽要綁定的HTML元素,你點(diǎn)擊這個標(biāo)簽的時候,所綁定的元素將獲取焦點(diǎn)
1.9 title與h1的區(qū)別、b與strong的區(qū)別、i與em的區(qū)別?
- title屬性沒有明確意義,只表示標(biāo)題;h1表示層次明確的標(biāo)題,對頁面信息的抓取也有很大的影響
- strong標(biāo)明重點(diǎn)內(nèi)容,語氣加強(qiáng)含義;b是無意義的視覺表示
- em表示強(qiáng)調(diào)文本;i是斜體,是無意義的視覺表示
- 視覺樣式標(biāo)簽:bius
- 語義樣式標(biāo)簽:strong em ins del code
1.10 元素的alt和title有什么不同?
在alt和title同時設(shè)置的時候,alt作為圖片的替代文字出現(xiàn),title是圖片的解釋文字
1.11 瀏覽器頁面有哪三層構(gòu)成,分別是什么,作用是什么?
- 瀏覽器頁面構(gòu)成:結(jié)構(gòu)層、表示層、行為層
- 分別是:HTML、CSS、JavaScript
- 作用:HTML實(shí)現(xiàn)頁面結(jié)構(gòu),CSS完成頁面的表現(xiàn)與風(fēng)格,JavaScript實(shí)現(xiàn)一些客戶端的功能與業(yè)務(wù)。
1.12 網(wǎng)頁制作會用到的圖片格式有哪些?
- Webp:WebP格式,谷歌(google)開發(fā)的一種旨在加快圖片加載速度的圖片格式。并能節(jié)省大量的服務(wù)器帶寬資源和數(shù)據(jù)空間。Facebook Ebay等知名網(wǎng)站已經(jīng)開始測試并使用WebP格式。
- Apng:是PNG的位圖動畫擴(kuò)展,可以實(shí)現(xiàn)png格式的動態(tài)圖片效果,有望代替GIF成為下一代動態(tài)圖標(biāo)準(zhǔn)
1.13 viewport 所有屬性?
- width :設(shè)置layout viewport的寬度,為一個正整數(shù),或字符串’device-width’
- initial-scale:設(shè)置頁面的初始縮放值,為一個數(shù)字,可以帶小數(shù)
- minimum-scale:允許用戶的最小縮放值,為一個數(shù)字,可以帶小數(shù)
- maximum-scale:允許用戶的最大縮放值,為一個數(shù)字,可以帶小數(shù)
- height:設(shè)置layout viewport的高度,這個屬性對我們并不重要,很少使用
- user-scalable:是否允許用戶進(jìn)行縮放,值為‘no’或者‘yes’
- 安卓中還支持:target-densitydpi,表示目標(biāo)設(shè)備的密度等級,作用是決定css中的1px 代表多少物理像素
1.14 meta標(biāo)簽的name屬性值?
name 屬性主要用于描述網(wǎng)頁,與之對應(yīng)的屬性值為content,content中的內(nèi)容主要是便于搜索引擎機(jī)器人查找信息和分類信息用的
- Keywords(關(guān)鍵字)說明:keywords用來告訴搜索引擎你網(wǎng)頁的關(guān)鍵字是什么。
- description(網(wǎng)站內(nèi)容描述) 說明:description用來告訴搜索引擎你的網(wǎng)站主要內(nèi)容。
- robots(機(jī)器人向?qū)?說明:robots用來告訴搜索機(jī)器人哪些頁面需要索引,哪些頁面不需要索引。
1.15 a標(biāo)簽中 如何禁用href 跳轉(zhuǎn)頁面 或 定位鏈接?
- e.preventDefault();
- href="javascript:void(0);
1.16 video標(biāo)簽的幾個屬性方法
- src:視頻的URL
- poster:視頻封面,沒有播放時顯示的圖片
- preload:預(yù)加載
- autoplay:自動播放
- loop:循環(huán)播放
- controls:瀏覽器自帶的控制條
- width:視頻寬度
- height:視頻高度
1.17 塊級元素、行內(nèi)元素、行內(nèi)塊元素
塊級元素:
特點(diǎn):可設(shè)置寬高邊距,占滿整行,會自動換行
示例:div、 p、 h1 、h6、ol、ul、dl、table、address、blockquote、form
行內(nèi)元素:
特點(diǎn):無法設(shè)置寬高邊距,不會占滿整行,不會自動換行
示例:a、strong、b、em、i、del、s、ins、u、span
行內(nèi)塊元素:
特點(diǎn):可設(shè)置寬高,占滿整行,但不會自動換行
示例:img、input
1.18 web標(biāo)準(zhǔn)和w3c標(biāo)準(zhǔn)
web標(biāo)準(zhǔn):分為結(jié)構(gòu)、表現(xiàn)和行為
W3C標(biāo)準(zhǔn):提出了更規(guī)范的要求
1、結(jié)構(gòu)方面:標(biāo)簽字母要小寫,標(biāo)簽要閉合,標(biāo)簽要正確嵌套
2、css和js方面:盡量使用外鏈寫法,少用行內(nèi)樣式,屬性名要見名知意
1.19 前端需要注意哪些SEO
1、合理的title、description、keywords:搜素時對這三項(xiàng)的權(quán)重逐個減少,title強(qiáng)調(diào)重點(diǎn),重要關(guān)鍵詞不要超過兩次,而且要靠前,不同頁面title要有所不同,description高度概括頁面內(nèi)容,長度合適,不過分堆砌關(guān)鍵詞,不同頁面description有所不同,keywords列出重要關(guān)鍵詞即可
2、語義化的html代碼,符合W3C標(biāo)準(zhǔn)
3、提高網(wǎng)站速度
4、重要HTML代碼放前面
5、重要內(nèi)容不要用js輸出:爬蟲不會執(zhí)行js獲取內(nèi)容
6、少用 iframe:搜索引擎不會抓取 iframe 中的內(nèi)容
7、非裝飾性圖片必須加 alt
1.20 canvas和svg的區(qū)別
canvas | svg |
---|---|
通過js繪制2D圖形,按像素進(jìn)行渲染,當(dāng)位置發(fā)生改變會重新進(jìn)行繪制 | 使用XML繪制的2D圖形,可以為元素添加js處理器 |
依賴分辨率 | 不依賴分辨率 |
不支持事件處理器 | 支持事件處理器 |
弱的文本渲染能力 | 最適合帶有哦大型渲染區(qū)域的應(yīng)用程序(如谷歌地圖) |
能以.png或.jpg格式保存結(jié)果圖像 | 復(fù)雜度高會減慢渲染速度 |
最適合圖像密集型游戲,其中的許多對象會被頻繁重繪 | 不適合游戲應(yīng)用 |
+++++++++++++++++性感的分隔線++++++++++++++++++++++++++
CSS知識
1.1 標(biāo)準(zhǔn)盒模型和IE盒模型兩者的區(qū)別是什么?
概念
CSS盒模型本質(zhì)上是一個盒子,封裝周圍的HTML元素,它包括: 外邊距(margin) 、 邊框(border) 、 內(nèi)邊距(padding) 、實(shí)際內(nèi)容(content) 四個屬性
設(shè)置盒子模型
box-sizing:content-box;(標(biāo)準(zhǔn))
box-sizing:border-box;(IE)
區(qū)別
標(biāo)準(zhǔn)的(W3C)盒模型:元素的實(shí)際寬度等于設(shè)置的寬高 + border + padding (默認(rèn)方式)
IE盒模型: 元素的實(shí)際寬度就等于設(shè)置的寬高,即使定義有 border 和 padding 也不會改變元素的實(shí)際寬度,即 ( Element width = width )
1.2 盒子塌陷是什么?
盒子塌陷
本應(yīng)該在父盒子內(nèi)部的元素跑到了外部。為什么會出現(xiàn)盒子塌陷?
當(dāng)父元素沒設(shè)置足夠大小的時候,而子元素設(shè)置了浮動的屬性,子元素就會跳出父元素的邊界(脫離文檔流),尤其是當(dāng)父元素的高度為auto時,而父元素中又沒有其它非浮動的可見元素時,父盒子的高度就會直接塌陷為零, 我們稱這是CSS高度塌陷
解決塌陷的方法
- 設(shè)置寬高
- 設(shè)置BFC
- 清楚浮動
- 給父盒子添加border
- 給父盒子設(shè)置padding-top
1.3 繼承相關(guān)
css的繼承:就是給父級設(shè)置一些屬性,子級繼承了父級的該屬性,這就是我們的css中的繼承
常用無繼承性的屬性
display
:規(guī)定元素應(yīng)該生成的框的類型
常用無繼承性的文本屬性:
- vertical-align:垂直文本對齊
- text-decoration:規(guī)定添加到文本的裝飾
- text-shadow:文本陰影效果
- white-space:空白符的處理
- unicode-bidi:設(shè)置文本的方向
- 盒子模型的屬性:width、height、margin、padding、border
- 背景屬性:background
- 定位屬性:float、clear、position、top、right、bottom、left、min-width、min-height、max、width、max-height、overflow、clip、z-index
有繼承性的屬性
- font:字體系列屬性
有繼承性文本系列屬性:
-
text-indent:文本縮進(jìn)
-
text-align:文本水平對齊
-
line-height:行高
-
word-spacing:增加或減少單詞間的空白(即字間隔)
-
letter-spacing:增加或減少字符間的空白(字符間距)
-
text-transform:控制文本大小寫
-
direction:規(guī)定文本的書寫方向
-
color:文本顏色 a元素除外
-
元素可見性:visibility
表格布局屬性:caption-side、border-collapse、border-spacing、empty-cells、table-layout -
列表布局屬性:list-style-type、list-style-image、list-style-position、list-style
-
生成內(nèi)容屬性:quotes
-
光標(biāo)屬性:cursor
1.4 行內(nèi)元素可以設(shè)置padding,margin嗎?
行內(nèi)元素的margin左右有效,上下無效
行內(nèi)元素的padding左右有效 ,但是由于設(shè)置padding上下不占頁面空間,無法顯示效果,所以無效
1.5 什么是邊距重疊?什么情況下會發(fā)生邊距重疊?如何解決邊距重疊?
邊距重疊:兩個box如果都設(shè)置了邊距,那么在垂直方向上,兩個box的邊距會發(fā)生重疊,以絕對值大的那個為最終結(jié)果顯示在頁面上
邊距重疊分為兩種:
- 同級關(guān)系的重疊:同級元素在垂直方向上外邊距會出現(xiàn)重疊情況,最后外邊距的大小取兩者絕對值大的那個
- 父子關(guān)系的邊距重疊:嵌套崩塌
父子關(guān)系,如果子元素設(shè)置了外邊距,在沒有把父元素變成BFC的情況下,父元素也會產(chǎn)生外邊距。
給父元素添加overflow:hidden 這樣父元素就變?yōu)?BFC,不會隨子元素產(chǎn)生外邊距。
1.6 BFC是什么?
文檔有幾種流
-
定位流
- 絕對定位方案,盒從常規(guī)流中被移除,不影響常規(guī)流的布局;
- 它的定位相對于它的包含塊,相關(guān)CSS屬性:top、bottom、left、right;
- 如果元素的屬性position為absolute或fixed,它是絕對定位元素;
- 對于position: absolute,元素定位將相對于上級元素中最近的一個relative、fixed、
absolute,如果沒有則相對于body;
-
浮動流
- 左浮動元素盡量靠左、靠上,右浮動同理
- 這導(dǎo)致常規(guī)流環(huán)繞在它的周邊,除非設(shè)置 clear 屬性
- 浮動元素不會影響塊級元素的布局
- 但浮動元素會影響行內(nèi)元素的布局,讓其圍繞在自己周圍,撐大父級元素,從而間接影響塊級元素布局
- 最高點(diǎn)不會超過當(dāng)前行的最高點(diǎn)、它前面的浮動元素的最高點(diǎn)
- 不超過它的包含塊,除非元素本身已經(jīng)比包含塊更寬
- 行內(nèi)元素出現(xiàn)在左浮動元素的右邊和右浮動元素的左邊,左浮動元素的左邊和右浮動元素的
- 右邊是不會擺放浮動元素的
-
普通流
- 在常規(guī)流中,盒一個接著一個排列;
- 在塊級格式化上下文里面, 它們豎著排列;
- 在行內(nèi)格式化上下文里面, 它們橫著排列;
- 當(dāng)position為static或relative,并且float為none時會觸發(fā)常規(guī)流;
- 對于靜態(tài)定位(static positioning),position: static,盒的位置是常規(guī)流布局里的位置;
- 對于相對定位(relative positioning),position: relative,盒偏移位置由top、bottom、
left、right屬性定義。即使有偏移,仍然保留原有的位置,其它常規(guī)流不能占用這個位置。
定義
BFC的基本概念–BFC就是“塊級格式化上下文”的意思,也有譯作“塊級格式化范圍”。
通俗的講,就是一個特殊的塊,內(nèi)部有自己的布局方式,不受外邊元素的影響。
布局規(guī)則
- 內(nèi)部的 Box 會在垂直方向,一個接一個地放置
- 垂直方向上的距離由margin決定。(完整的說法是:屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊(塌陷),與方向無關(guān)。)
- 每個元素的左外邊距與包含塊的左邊界相接觸(從左向右),即使浮動元素也是如此。(這說明BFC中子元素不會超出他的包含塊,而position為absolute的元素可以超出他的包含塊邊界)
- BFC的區(qū)域不會與float的元素區(qū)域重疊
- 計(jì)算BFC的高度時,浮動子元素也參與計(jì)算
- BFC就是頁面上的一個隔離的獨(dú)立容器,容器里面的子元素不會影響到外面元素,反之亦然
哪些元素會創(chuàng)建 BFC
- 根元素
- float 屬性不為 none
- position 為 absolute 或 fixed
- display 為 inline-block, table-cell, table-caption, flex, inline-flex
- overflow 不為 visible
場景
-
清除元素內(nèi)部浮動:只要把父元素設(shè)為BFC就可以清理子元素的浮動了,最常見的用法就是在父元素上設(shè)置overflow: hidden樣式,對于IE6加上zoom:1就可以了。 計(jì)算BFC的高度時,自然也會檢測浮動或者定位的盒子高度。
-
解決外邊距合并問題(嵌套崩塌)
外邊距合并的問題。
盒子垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰盒子的margin會發(fā)生重疊
屬于同一個BFC的兩個相鄰盒子的margin會發(fā)生重疊,那么我們創(chuàng)建不屬于同一個BFC,就不會發(fā)生margin重疊了。 -
制作右側(cè)自適應(yīng)的盒子問題
普通流體元素BFC后,為了和浮動元素不產(chǎn)生任何交集,順著浮動邊緣形成自己的封閉上下文
1.7 塊元素居中
- 我們可以利用margin:0 auto來實(shí)現(xiàn)元素的水平居中。
- 利用絕對定位,設(shè)置四個方向的值都為0,并將margin設(shè)置為auto,由于寬高固定,因此對應(yīng)方向?qū)崿F(xiàn)平分,可以實(shí)現(xiàn)水平和垂直方向上的居中。
- 利用絕對定位,先將元素的左上角通過top:50%和left:50%定位到頁面的中心,然后再通過margin負(fù)值來調(diào)整元素的中心點(diǎn)到頁面的中心。
- 利用絕對定位,先將元素的左上角通過top:50%和left:50%定位到頁面的中心,然后再通過translate來調(diào)整元素的中心點(diǎn)到頁面的中心。
- 使用flex布局,通過align-items:center和justify-content:center設(shè)置容器的垂直和水平方向上為居中對齊,然后它的子元素也可以實(shí)現(xiàn)垂直和水平的居中。
- 對于寬高不定的元素,后面兩種方法,可以實(shí)現(xiàn)元素的垂直和水平的居中。
##1.8 CSS 優(yōu)化、提高性能的方法有哪些?
加載性能:
- css壓縮:將寫好的css進(jìn)行打包壓縮,可以減小文件體積
- css單一樣式:當(dāng)需要下邊距和左邊距的時候,很多時候會選擇使用margin-left:20px;margin-bottom:30px
- 減少使用@import,建議使用link,因?yàn)楹笳咴陧撁婕虞d時一起加載,前者是等待頁面加載完成之后再進(jìn)行加載
選擇器性能:
-
關(guān)鍵選擇器(key selector)。選擇器的最后面的部分為關(guān)鍵選擇器(即用來匹配目標(biāo)元素的部分)。CSS選擇符是從右到左進(jìn)行匹配的。
-
當(dāng)使用后代選擇器的時候,瀏覽器會遍歷所有子元素來確定是否是指定的元素等等
-
如果規(guī)則擁有ID選擇器作為其關(guān)鍵選擇器,則不要為規(guī)則增加標(biāo)簽。
-
過濾掉無關(guān)的規(guī)則(這樣樣式系統(tǒng)就不會浪費(fèi)時間去匹配它們了)。
-
盡量少的去對標(biāo)簽進(jìn)行選擇,而是用class。
-
盡量少的去使用后代選擇器,降低選擇器的權(quán)重值。后
-
代選擇器的開銷是最高的,盡量將選擇器的深度降到最低,最高不要超過三層,更多的使用類來關(guān)聯(lián)每一個標(biāo)簽元素。
-
了解哪些屬性是可以通過繼承而來的,然后避免對這些屬性重復(fù)指定規(guī)則。
渲染性能:
-
屬性值為0時,不加單位。
-
可以省略小數(shù)點(diǎn)之前的0。
-
標(biāo)準(zhǔn)化各種瀏覽器前綴:帶瀏覽器前綴的在前。標(biāo)準(zhǔn)屬性在后。
-
選擇器優(yōu)化嵌套,盡量避免層級過深。
-
css雪碧圖,同一頁面相近部分的小圖標(biāo),方便使用,減少頁面的請求次數(shù),但是同時圖片本身會變大,使用時,優(yōu)劣考慮清楚,再使用。
-
不濫用web字體。對于中文網(wǎng)站來說WebFonts可能很陌生,國外卻很流行。web fonts通常體積龐大,而且一些瀏覽器在下載web fonts時會阻塞頁面渲染損傷性能。
可維護(hù)性、健壯性:
-
將具有相同屬性的樣式抽離出來,整合并通過class在頁面中進(jìn)行使用,提高css的可維護(hù)性。
-
樣式與內(nèi)容分離:將css代碼定義到外部css中
1.9 行內(nèi)元素和塊級元素什么區(qū)別,然后怎么相互轉(zhuǎn)換
塊級元素
-
總是從新的一行開始,即各個塊級元素獨(dú)占一行,默認(rèn)垂直向下排列
-
高度、寬度、margin及padding都是可控的,設(shè)置有效,有邊距效果
-
寬度沒有設(shè)置時,默認(rèn)為100%
-
塊級元素中可以包含塊級元素和行內(nèi)元素
行內(nèi)元素
-
和其他元素都在一行,即行內(nèi)元素和其他行內(nèi)元素都會在一條水平線上排列
-
高度、寬度是不可控的,設(shè)置無效,由內(nèi)容決定
-
根據(jù)標(biāo)簽語義化的理念,行內(nèi)元素最好只包含行內(nèi)元素,不包含塊級元素
轉(zhuǎn)換
-
display:inline;轉(zhuǎn)換為行內(nèi)元素
-
display:block;轉(zhuǎn)換為塊狀元素
-
display:inline-block;轉(zhuǎn)換為行內(nèi)塊狀元素
1.10 min-width/max-width 和 min-height/max-height 屬性間的覆蓋規(guī)則?
-
max-width 會覆蓋 width,即使 width 是行內(nèi)樣式或者設(shè)置了 !important。
-
min-width 會覆蓋 max-width,此規(guī)則發(fā)生在 min-width 和 max-width 沖突的時候;
1.11 瀏覽器是怎樣解析CSS選擇器的?
CSS選擇器的解析是從右向左解析的
原因:
從右向左的匹配在第一步就篩選掉了大量的不符合條件的最右節(jié)點(diǎn)(葉子節(jié)點(diǎn)),而從左向右的匹配規(guī)則的性能都浪
費(fèi)在了失敗的查找上面
1.12 width:auto 和 width:100%的區(qū)別
-
width:100%會使元素box的寬度等于父元素的contentbox的寬度
-
width:auto會使元素?fù)螡M整個父元素,margin、border、padding、content區(qū)域會自動分配水平空間。
1.13 display、position和float的相互關(guān)系?
-
首先我們判斷display屬性是否為none,如果為none,則position和float屬性的值不影響元素最后的表現(xiàn)
-
然后判斷position的值是否為absolute或者fixed,如果是,則float屬性失效,并且display的值應(yīng)該被 設(shè)置為table或者block,具體轉(zhuǎn)換需要看初始轉(zhuǎn)換值
-
如果position的值不為absolute或者fixed,則判斷float屬性的值是否為none,如果不是,則display 的值則按上面的規(guī)則轉(zhuǎn)換。注意,如果position的值為relative并且float屬性的值存在,則relative相對 于浮動后的最終位置定位
-
如果float的值為none,則判斷元素是否為根元素,如果是根元素則display屬性按照上面的規(guī)則轉(zhuǎn)換,如果不是, 則保持指定的display屬性值不變
總的來說,可以把它看作是一個類似優(yōu)先級的機(jī)制,"position:absolute"和"position:fixed"優(yōu)先級最高,有它存在 的時候,浮動不起作用,'display’的值也需要調(diào)整;其次,元素的’float’特性的值不是"none"的時候或者它是根元素 的時候,調(diào)整’display’的值;最后,非根元素,并且非浮動元素,并且非絕對定位的元素,'display’特性值同設(shè)置值。
1.14 IFC 是什么?
IFC指的是行級格式化上下文,它有這樣的一些布局規(guī)則:
-
行級上下文內(nèi)部的盒子會在水平方向,一個接一個地放置。
-
當(dāng)一行不夠的時候會自動切換到下一行。
-
行級上下文的高度由內(nèi)部最高的內(nèi)聯(lián)盒子的高度決定
1.15 為什么不建議使用統(tǒng)配符初始化 css 樣式
采用*{pading:0;margin:0;}這樣的寫法好處是寫起來很簡單,但是是通配符,需要把所有的標(biāo)簽都遍歷一遍,當(dāng)網(wǎng)站較大時, 樣式比較多,這樣寫就大大的加強(qiáng)了網(wǎng)站運(yùn)行的負(fù)載,會使網(wǎng)站加載的時候需要很長一段時間,因此一般大型的網(wǎng)站都有分層次的一 套初始化樣式
出于性能的考慮,并不是所有標(biāo)簽都會有padding和margin,因此對常見的具有默認(rèn)padding和margin的元素初始化即 可,并不需使用通配符*來初始化
1.16 CSS3 新特新
-
新增各種 CSS 選擇器 :not§ 選擇每個非p的元素; p:empty 選擇每個沒有任何子級的p元素(包括文本節(jié)點(diǎn))
-
邊框(Borders)
-
背景 background-clip(規(guī)定背景圖的繪制區(qū)域),background-origin,background-size
-
線性漸變 (Linear Gradients) 向下/向上/向左/向右/對角方向
-
文本效果 陰影text-shadow,textwrap,word-break,word-wrap
-
2D 轉(zhuǎn)換 transform:scale(0.85,0.90) | translate(0px,-30px) | skew(-9deg,0deg) |rotate() - 3D轉(zhuǎn)換 perspective();transform是向元素應(yīng)用 2D 或者 3D 轉(zhuǎn)換
-
過渡 transition
-
動畫
-
多列布局 (multi-column layout)
-
盒模型
-
flex 布局
-
多媒體查詢 **定義兩套css,當(dāng)瀏覽器的尺寸變化時會采用不同的屬性
1.17 position 跟 display、float 這些特性相互疊加后會怎么樣?
-
display 屬性規(guī)定元素應(yīng)該生成的框的類型;position屬性規(guī)定元素的定位類型;float屬性是一種布局方式,定義元素在哪個方向浮動。
-
類似于優(yōu)先級機(jī)制:position:absolute/fixed優(yōu)先級最高,有他們在時,float不起作用,display值需要調(diào)整。float 或者absolute定位的元素,只能是塊元素或表格。
1.18 什么是CSS 預(yù)處理器?為什么使用?
Less、Sass、Stylus,用來預(yù)編譯Sass或less,增強(qiáng)了css代碼的復(fù)用性,還有層級、mixin、變量、循環(huán)、函數(shù)等,具有很方便的UI組件模塊化開發(fā)能力,極大的提高工作效率
為什么要使用?
-
可嵌套性
-
變量
-
Mixins(混合@mixin):可重用性高,可以注入任何東西
-
@extend:允許一個選擇器繼承另一個選擇器
@function:函數(shù)功能,用戶使用@function 可以去編寫自己的函數(shù)
-
引用父元素&:在編譯時,&將被替換成父選擇符
-
計(jì)算功能
-
組合連接: #{} :變量連接字符串
-
循環(huán)語句:(很少用到)
-
if 語句:(很少用到)
1.19 瀏覽器是怎樣解析的?
-
HTML 被 HTML 解析器解析成 DOM 樹;2. CSS 被 CSS 解析器解析成 CSSOM 樹;
-
結(jié)合 DOM 樹和 CSSOM 樹,生成一棵渲染樹(Render Tree),這一過程稱為 Attachment;
-
生成布局(flow),瀏覽器在屏幕上“畫”出渲染樹中的所有節(jié)點(diǎn);
-
將布局繪制(paint)在屏幕上,顯示出整個頁面。
1.20 在網(wǎng)頁中的應(yīng)該使用奇數(shù)還是偶數(shù)的字體?為什么呢?
-
使用偶數(shù)字體
-
Windows 自帶的點(diǎn)陣宋體(中易宋體)從 Vista 開始只提供 12、14、16 px 這三個大小的點(diǎn)陣,而 13、15、17 px時用的是小一號的點(diǎn)。(即每個字占的空間大了 1 px,但點(diǎn)陣沒變),于是略顯稀疏
1.21 元素豎向的百分比設(shè)定是相對于容器的高度嗎?
當(dāng)按百分比設(shè)定一個元素的寬度時,它是相對于父容器的寬度計(jì)算的,但是,對于一些表示豎向距離的屬性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,當(dāng)按百分比設(shè)定它們時,依據(jù)的也是父容器的寬度,而不是高度
1.22 怎么讓谷歌支持小于12px的文字?
使用 scale
1.23 li 與 li 之間有看不見的空白間隔是什么原因引起的?有什么解決辦法?
行框的排列會受到中間空白(回車空格)等的影響,因?yàn)榭崭褚矊儆谧址?這些空白也會被應(yīng)用樣式,占據(jù)空間,所以會有間隔,把字符大小設(shè)為0,就沒有空格了
解決方法:
-
可以將代碼全部寫在一排
-
浮動li中float:left
-
在ul中用font-size:0(谷歌不支持);
-
可以將 ul{letter-spacing: -4px;};li{letter-spacing: normal;}
1.24 display:inline-block 什么時候會顯示間隙?
-
有空格時候會有間隙 解決:除空格
-
margin正值的時候 解決:margin使用負(fù)值
-
使用font-size時候 解決:font-size:0、letter-spacing、word-spacing
1.25 png、jpg、gif 這些圖片格式解釋一下,分別什么時候用。有沒有了解過webp?
-
png是便攜式網(wǎng)絡(luò)圖片(Portable Network Graphics)是一種無損數(shù)據(jù)壓縮位圖文件格式.優(yōu)點(diǎn)是:壓縮比高,色彩好。 大多數(shù)地方都可以用。
-
jpg是一種針對相片使用的一種失真壓縮方法,是一種破壞性的壓縮,在色調(diào)及顏色平滑變化做的不錯。在www上,被用來儲存和傳輸照片的格式。
-
gif是一種位圖文件格式,以8位色重現(xiàn)真色彩的圖像??梢詫?shí)現(xiàn)動畫效果.
-
webp格式是谷歌在2010年推出的圖片格式,壓縮率只有jpg的2/3,大小比png小了45%。缺點(diǎn)是壓縮的時間更久了,兼容性不好,目前谷歌和opera支持。
1.26 style 標(biāo)簽寫在 body 后與 body前有什么區(qū)別?
頁面加載自上而下 當(dāng)然是先加載樣式。 寫在 body 標(biāo)簽后由于瀏覽器以逐行方式對HTML文檔進(jìn)行解析,當(dāng)解析到寫在尾部的樣式表(外聯(lián)或?qū)懺?style 標(biāo)簽)會導(dǎo)致瀏覽器停止之前的渲染,等待加載且解析樣式表完成之后重新渲染,在windows的IE下可能會出現(xiàn) FOUC 現(xiàn)象(即樣式失效導(dǎo)致的頁面閃爍問題)
1.27 ::before 和::after 中雙冒號和單冒號有什么區(qū)別、作用?
區(qū)別
在css中偽類一直用:表示,如 :hover,:active等
偽元素在CSS1中已存在,當(dāng)時語法使用 : 表示 ,如::before和:after
后來在CSS3中修訂,偽元素用 ::表示,如 ::before 和 ::after,以此區(qū)分偽元素和偽類
由于低版本 IE 對雙冒號不兼容,開發(fā)者為了兼容性各瀏覽器,繼續(xù)使使用 :after 這種老語法表示偽元素
單冒號: CSS3表示偽類;雙冒號::CSS3偽元素
作用:
::before 和::after 的主要作用是在元素內(nèi)容前后加上指定內(nèi)容
偽類與偽元素都是用于向選擇器加特殊效果
偽類與偽元素的本質(zhì)區(qū)別就是是否抽象創(chuàng)造了新元素
偽類只要不是互斥可以疊加使用
偽元素在一個選擇器中只能出現(xiàn)一次,并且只能出現(xiàn)在末尾
偽類與偽元素優(yōu)先級分別與類、標(biāo)簽優(yōu)先級相同
1.28 CSS3新增偽類,以及偽元素?
CSS3 新增偽類
p:first-of-type 選擇屬于其父元素的首個
元素的每個
元素
p:last-of-type 選擇屬于其父元素的最后
元素的每個
元素
p:nth-child(n) 選擇屬于其父元素的第 n 個子元素的每個
元素
p:nth-last-child(n) 選擇屬于其父元素的倒數(shù)第 n 個子元素的每個
元素
p:nth-of-type(n) 選擇屬于其父元素第 n 個
元素的每個
元素
p:nth-last-of-type(n)
選擇屬于其父元素倒數(shù)第 n 個
元素的每個
元素
p:last-child 選擇屬于其父元素最后一個子元素的每個
元素
p:target
選擇當(dāng)前活動的
元素
:not§ 選擇非
元素的每個元素
:enabled 控制表單控件的可用狀態(tài)
:disabled 控制表單控件的禁用狀態(tài)
:checked 單選框或復(fù)選框被選中
偽元素
-
::first-letter 將樣式添加到文本的首字母
-
::first-line 將樣式添加到文本的首行
:- :before 在某元素之前插入某些內(nèi)容
- ::after 在某元素之后插入某些內(nèi)容
1.29 未知高度元素垂直居中、垂直居中的實(shí)現(xiàn)方式有哪些?
- 絕對定位+css3 transform:translate(-50%,-50%)
.wrap{position:relative;
}
.child{position: absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);
}
css3 的flex布局.wrap{display:flex;justify-content:center;
}
.child{align-self:center;
}
- table布局
<div class="wrap">
<div class="child">
<div>sadgsdgasgd</div>
</div>
</div>
<style>
.wrap{display:table;text-align:center;
}
.child{background:#ccc;display:table-cell;vertical-align:middle;
}
.child div{width:300px;height:150px;background:red;margin:0 auto;
}
</style>
1.30 圖片垂直居中
- 使用flex實(shí)現(xiàn)圖片垂直居中
<div class="flexbox"><img src="1.jpg" alt="">
</div>
<style>
.flexbox{width: 300px;height: 250px;background:#fff;display: flex;align-items:center}
.flexbox img{width: 100px;height: 100px;align-items: center;}
</style>
- 利用Display: table;實(shí)現(xiàn)img圖片垂直居中
<div class="tablebox">
<div id="imgbox">
<img src="1.jpg" alt="">
</div></div>
<style>
.tablebox{width: 300px;height: 250px;background: #fff;display: table}
#imgbox{display: table-cell;vertical-align: middle;}
#imgbox img{width: 100px}
</style>
- 用絕對定位實(shí)現(xiàn)垂直居中
<div class="posdiv">
<img src="1.jpg" alt=""></div>
<style>
.posdiv{width: 300px;height: 250px;background: #fff;position: relative;
margin:0 auto}
.posdiv img{width: 100px;position: absolute;top: 50%;margin-top: -50px;}
</style>
1.31 文本元素居中
- 水平居中:text-align
- 垂直居中:line-height 和height設(shè)置一樣
- 多行文本垂直居中
- 父級元素高度不固定(padding-top和padding-bottom)
- 父級元素高度固定 (vertical-align:middle +display:table-cell )
1.32 CSS實(shí)現(xiàn)一個等腰三角形
主要是通過把寬高設(shè)置成0,邊框?qū)挾仍O(shè)置寬一些,設(shè)置其中三個邊透明,只留一個邊顯示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>測試</title>
<style type="text/css">div {width:0px;height:0px;margin:100px auto;border-left:80px solid transparent;border-right:80px solid transparent;border-bottom:138.56px solid #A962CE; /*--三角形的高--*/}
</style>
</head>
<body>
<div>
</div>
</body>
</html>
1.33 畫 0.5px 的直線
- 使用scale縮放
<style>
.hr.scale-half {height: 1px;transform: scaleY(0.5);
}
</style>
<p>1px + scaleY(0.5)</p>
<div class="hr scale-half"></div>
<!--
Chrome/Safari都變虛了,只有Firefox比較完美看起來是實(shí)的而且還很細(xì),效果和直接設(shè)置0.5px一
樣。所以通過transform: scale會導(dǎo)致Chrome變虛了,而粗細(xì)幾乎沒有變化。但是如果加上transformorigin: 50% 100%:
-->
.hr.scale-half {height: 1px;transform: scaleY(0.5);transform-origin: 50% 100%;
}
- 線性漸變linear-gradient
<style>
.hr.gradient {
height: 1px;
background: linear-gradient(0deg, #fff, #000);
}
</style>
<p>linear-gradient(0deg, #fff, #000)</p>
<div class="hr gradient"></div>
- boxshadow
<style>
.hr.boxshadow {height: 1px;background: none;box-shadow: 0 0.5px 0 #000;
}
</style>
<p>box-shadow: 0 0.5px 0 #000</p>
<div class="hr boxshadow"></div>
- viewport
<meta name="viewport" content="width=device-width,initial-sacle=0.5">
<!--
width=device-width表示將viewport視窗的寬度調(diào)整為設(shè)備的寬度,這個寬度通常是指物理上寬度
initial-sacle=0.5 縮放0.5
-->
1.34 移動端適配方案
- viewport 適配 :
缺點(diǎn):邊線問題,不同尺寸下,邊線的粗細(xì)是不一樣的(等比縮放后),全部元素都是等比縮放,實(shí)際顯示效果可能不太好
<meta name="viewport" content="width=750,initial-scale=0.5">
<!--
initial-scale = 屏幕的寬度 / 設(shè)計(jì)稿的寬度
為了適配其他屏幕,需要動態(tài)的設(shè)置 initial-scale 的值
-->
<head>
<script>
const WIDTH = 750
const mobileAdapter = () => {
let scale = screen.width / WIDTH
let content = `width=${WIDTH}, initial-scale=${scale}, maximumscale=${scale}, minimum-scale=${scale}`
let meta = document.querySelector('meta[name=viewport]')
if (!meta) {
meta = document.createElement('meta')
meta.setAttribute('name', 'viewport')
document.head.appendChild(meta)
}
meta.setAttribute('content',content)
}
mobileAdapter()
window.onorientationchange = mobileAdapter //屏幕翻轉(zhuǎn)時再次執(zhí)行
</script>
</head>
vw 適配(部分等比縮放)
- 開發(fā)者拿到設(shè)計(jì)稿(假設(shè)設(shè)計(jì)稿尺寸為750px,設(shè)計(jì)稿的元素標(biāo)注是基于此寬度標(biāo)注)
- 開始開發(fā),對設(shè)計(jì)稿的標(biāo)注進(jìn)行轉(zhuǎn)換,把px換成vw。比如頁面元素字體標(biāo)注的大小是32px,換成vw為 (100/750)*32 vw
- 對于需要等比縮放的元素,CSS使用轉(zhuǎn)換后的單位
- 對于不需要縮放的元素,比如邊框陰影,使用固定單位px
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximumscale=1, minimum-scale=1">
<script>const WIDTH = 750//:root { --width: 0.133333 } 1像素等于多少 vwdocument.documentElement.style.setProperty('--width', (100 / WIDTH))
</script>
</head>
rem適配
彈性盒適配(合理布局)
1.35 link 和 @import 的區(qū)別
-
引入的內(nèi)容不同
link 除了引用樣式文件,還可以引用圖片等資源文件,而 @import 只引用樣式文件 -
加載順序不同
link 引用 CSS 時,在頁面載入時同時加載;@import 需要頁面網(wǎng)頁完全載入以后加載 -
兼容性不同
link 是 XHTML 標(biāo)簽,無兼容問題;@import 是在 CSS2.1 提出的,低版本的瀏覽器不支持 -
對 JS 的支持不同
link 支持使用 Javascript 控制 DOM 去改變樣式;而 @import 不支持
1.36 iframe有什么優(yōu)點(diǎn)、缺點(diǎn)?
優(yōu)點(diǎn):
- iframe能夠原封不動的把嵌入的網(wǎng)頁展現(xiàn)出來。
- 如果有多個網(wǎng)頁引用iframe,那么你只需要修改iframe的內(nèi)容,就可以實(shí)現(xiàn)調(diào)用的每一個頁面內(nèi) 容的更改,方便快捷。
- 網(wǎng)頁如果為了統(tǒng)一風(fēng)格,頭部和版本都是一樣的,就可以寫成一個頁面,用iframe來嵌套,可以 增加代碼的可重用。
- 如果遇到加載緩慢的第三方內(nèi)容如圖標(biāo)和廣告,這些問題可以由iframe來解決。
缺點(diǎn):
- iframe會阻塞主頁面的onload事件;
- iframe和主頁面共享連接池,而瀏覽器對相同域的連接有限制,所以會影響頁面的并行加載。會 產(chǎn)生很多頁面,不容易管理。
- iframe框架結(jié)構(gòu)有時會讓人感到迷惑,如果框架個數(shù)多的話,可能會出現(xiàn)上下、左右滾動條,會 分散訪問者的注意力,用戶體驗(yàn)度差。
- 代碼復(fù)雜,無法被一些搜索引擎索引到,這一點(diǎn)很關(guān)鍵,現(xiàn)在的搜索引擎爬蟲還不能很好的處理 iframe中的內(nèi)容,所以使用iframe會不利于搜索引擎優(yōu)化(SEO)。
- 很多的移動設(shè)備無法完全顯示框架,設(shè)備兼容性差。
- iframe框架頁面會增加服務(wù)器的http請求,對于大型網(wǎng)站是不可取的。
+++++++++++++++++性感的分隔線++++++++++++++++++++++++++
JavaScript知識
1. Promise 的理解
Promise 是一種為了避免回調(diào)地獄的異步解決方案 2. Promise 是一種狀態(tài)機(jī): pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗) 只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。
回調(diào)函數(shù)中嵌套回調(diào)函數(shù)的情況就叫做回調(diào)。
回調(diào)地獄就是為是實(shí)現(xiàn)代碼順序執(zhí)行而出現(xiàn)的一種操作,它會造成我們的代碼可讀性非常差,后期不好維護(hù)。
Promise是什么?**
Promise是最早由社區(qū)提出和實(shí)現(xiàn)的一種解決異步編程的方案,比其他傳統(tǒng)的解決方案(回調(diào)函數(shù)和事件)更合理和更強(qiáng)大。
ES6 將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對象。
ES6 規(guī)定,Promise對象是一個構(gòu)造函數(shù),用來生成Promise實(shí)例。
Promise是為解決什么問題而產(chǎn)生的?**
promise是為解決異步處理回調(diào)金字塔問題而產(chǎn)生的
Promise的兩個特點(diǎn)**
1、Promise對象的狀態(tài)不受外界影響
1)pending 初始狀態(tài)
2)fulfilled 成功狀態(tài)
3)rejected 失敗狀態(tài)
Promise 有以上三種狀態(tài),只有異步操作的結(jié)果可以決定當(dāng)前是哪一種狀態(tài),其他任何操作都無法改變這個狀態(tài)
2、Promise的狀態(tài)一旦改變,就不會再變,任何時候都可以得到這個結(jié)果,狀態(tài)不可以逆,只能由 pending變成fulfilled或者由pending變成rejected
Promise的三個缺點(diǎn)
- 無法取消Promise,一旦新建它就會立即執(zhí)行,無法中途取消
- 如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反映到外部
- 當(dāng)處于pending狀態(tài)時,無法得知目前進(jìn)展到哪一個階段,是剛剛開始還是即將完成
Promise在哪存放成功回調(diào)序列和失敗回調(diào)序列?
- onResolvedCallbacks 成功后要執(zhí)行的回調(diào)序列 是一個數(shù)組
- onRejectedCallbacks 失敗后要執(zhí)行的回調(diào)序列 是一個數(shù)組
以上兩個數(shù)組存放在Promise 創(chuàng)建實(shí)例時給Promise這個類傳的函數(shù)中,默認(rèn)都是空數(shù)組。
每次實(shí)例then的時候 傳入 onFulfilled 成功回調(diào) onRejected 失敗回調(diào),如果此時的狀態(tài)是pending 則將onFulfilled和onRejected push到對應(yīng)的成功回調(diào)序列數(shù)組和失敗回調(diào)序列數(shù)組中,如果此時的狀態(tài)是fulfilled 則onFulfilled立即執(zhí)行,如果此時的狀態(tài)是rejected則onRejected立即執(zhí)行
上述序列中的回調(diào)函數(shù)執(zhí)行的時候 是有順序的,即按照順序依次執(zhí)行
2. 箭頭函數(shù)和普通函數(shù)的區(qū)別
箭頭函數(shù)與普通函數(shù)的區(qū)別在于: 1、箭頭函數(shù)沒有this,所以需要通過查找作用域鏈來確定this的值,這就意味著如果箭頭函數(shù)被非箭頭函數(shù)包含,this綁定的就是最近一層非箭頭函數(shù)的this, 2、箭頭函數(shù)沒有自己的arguments對象,但是可以訪問外圍函數(shù)的arguments對象 3、不能通過new關(guān)鍵字調(diào)用,同樣也沒有new.target值和原型
- 語法更加簡潔、清晰
- 箭頭函數(shù)不會創(chuàng)建自己的this,它只會從自己的作用域鏈的上一層繼承this。
- 箭頭函數(shù)繼承而來的this指向永遠(yuǎn)不變
- .call()/.apply()/.bind()無法改變箭頭函數(shù)中this的指向
- 箭頭函數(shù)不能作為構(gòu)造函數(shù)使用
- 箭頭函數(shù)沒有自己的arguments,可以在箭頭函數(shù)中使用rest參數(shù)代替arguments對象,來訪問箭頭函數(shù)的參數(shù)列表
- 箭頭函數(shù)沒有原型prototype
- 箭頭函數(shù)不能用作Generator函數(shù),不能使用yeild關(guān)鍵字
- 箭頭函數(shù)不具有super,不具有new.target
3. ES6新特性
1、let( let 允許創(chuàng)建塊級作用域(最靠近的一個花括號內(nèi)有效),不具備變量提升,不允許重復(fù)聲明: )、const( const 允許創(chuàng)建塊級作用域(最靠近的一個花括號內(nèi)有效)、變量聲明不提升、const 在聲明時必須被賦值、聲明時大寫變量(默認(rèn)規(guī)則): )、block作用域
2、箭頭函數(shù) ES6 中,箭頭函數(shù)就是函數(shù)的一種簡寫形式,使用括號包裹參數(shù),跟隨一個 =>,緊接著是函數(shù)體:
3、函數(shù)默認(rèn)參數(shù)值
ES6 中允許你對函數(shù)參數(shù)設(shè)置默認(rèn)值:
4、對象超類
ES6 允許在對象中使用 super 方法:
5、Map VS WeakMap
ES6 中兩種新的數(shù)據(jù)結(jié)構(gòu)集:Map 和 WeakMap。事實(shí)上每個對象都可以看作是一個 Map。
一個對象由多個 key-val 對構(gòu)成,在 Map 中,任何類型都可以作為對象的 key,如:
6、類
ES6 中有 class 語法。值得注意是,這里的 class 不是新的對象繼承模型,它只是原型鏈的語法糖表現(xiàn)形式。
函數(shù)中使用 static 關(guān)鍵詞定義構(gòu)造函數(shù)的的方法和屬性:
4. var let const 的區(qū)別
共同點(diǎn):都能聲明變量
不同點(diǎn):var 在ECMAScript 的所有版本中都可以使用,而const和let只能在ECMAScript6【ES2015】及更晚中使用
特點(diǎn) | var | let | const |
---|---|---|---|
作用域 | 函數(shù)作用域 | 塊作用域 | 塊作用域 |
聲明提升 | 能 | 不能 | 不能 |
重復(fù)聲明 | 能 | 不能 | 不能 |
全局聲明時為window對象的屬性 | 是 | 不是 | 不是 |
- ECMAScript6 增加了
let
和const
之后要盡可能少使用var
。因?yàn)?code>let 和const
申明的變量有了更加明確的作用域、聲明位置以及不變的值。 - 優(yōu)先使用const來聲明變量,只在提前知道未來會修改時,再使用let。
- 因?yàn)閘et作用域?yàn)閴K作用域!!!!【得要時刻記住這一點(diǎn)】
不能進(jìn)行條件式聲明 - 聲明時得直接初始化變量,且不能修改const聲明的變量的值
- 該限制只適用于它指向的變量的引用,如果它一個對象的,則可以修改這個對象的內(nèi)部的屬性。
Null 和 undefined 的區(qū)別
undefined和null的區(qū)別:.
undefined
表示一個變量沒有被聲明,或者被聲明了但沒有被賦值(未初始化),一個沒有傳入實(shí)參的形參變量的值為undefined
,如果一個函數(shù)什么都不返回,則該函數(shù)默認(rèn)返回undefined
。null
則表示"什么都沒有",即"空值"。.- Javascript將未賦值的變量默認(rèn)值設(shè)為
undefined
; - Javascript從來不會將變量設(shè)為
null
。它是用來讓程序員表明某個用var聲明的變量時沒有值的
Call、bind、apply方法的區(qū)別
-
apply方法- apply接受兩個參數(shù),第一個參數(shù)是this的指向,第二個參數(shù)是函數(shù)接受的參數(shù),以數(shù)組的形式傳入,且當(dāng)?shù)谝粋€參數(shù)為null、undefined的時候,默認(rèn)指向window(在瀏覽器中),使用apply方法改變this指向后原函數(shù)會立即執(zhí)行,且此方法只是臨時改變this指向一次。
-
call方法 - call方法的第一個參數(shù)也是this的指向,后面?zhèn)魅氲氖且粋€參數(shù)列表(注意和apply傳參的區(qū)別)。當(dāng)一個參數(shù)為null或undefined的時候,表示指向window(在瀏覽器中),和apply一樣,call也只是臨時改變一次this指向,并立即執(zhí)行。
-
bind方法 - bind方法和call很相似,第一參數(shù)也是this的指向,后面?zhèn)魅氲囊彩且粋€參數(shù)列表(但是這個參數(shù)列表可以分多次傳入,call則必須一次性傳入所有參數(shù)),但是它改變this指向后不會立即執(zhí)行,而是返回一個永久改變this指向的函數(shù)。
防抖和節(jié)流
防抖(debounce)
所謂防抖,就是指觸發(fā)事件后在 n 秒內(nèi)函數(shù)只能執(zhí)行一次,如果在 n 秒內(nèi)又觸發(fā)了事件,則會重新計(jì)算函數(shù)執(zhí)行時間。
非立即執(zhí)行版的意思是觸發(fā)事件后函數(shù)不會立即執(zhí)行,而是在 n 秒后執(zhí)行,如果在 n 秒內(nèi)又觸發(fā)了事件,則會重新計(jì)算函數(shù)執(zhí)行時間。
立即執(zhí)行版的意思是觸發(fā)事件后函數(shù)會立即執(zhí)行,然后 n 秒內(nèi)不觸發(fā)事件才能繼續(xù)執(zhí)行函數(shù)的效果。
節(jié)流(throttle)
**所謂節(jié)流,就是指連續(xù)觸發(fā)事件但是在 n 秒中只執(zhí)行一次函數(shù)。**節(jié)流會稀釋函數(shù)的執(zhí)行頻率。
對于節(jié)流,一般有兩種方式可以實(shí)現(xiàn),分別是時間戳版和定時器版
數(shù)組方法
數(shù)組原型方法主要有以下這些:
- join():用指定的分隔符將數(shù)組每一項(xiàng)拼接為字符串
- push():向數(shù)組的末尾添加新元素
- pop():刪除數(shù)組的最后一項(xiàng)
- unshift():向數(shù)組首位添加新元素
- shift():刪除數(shù)組的第一項(xiàng)
- slice():按照條件查找出其中的部分元素
- splice():對數(shù)組進(jìn)行增刪改
- filter():過濾功能
- concat():用于連接兩個或多個數(shù)組
- indexOf():檢測當(dāng)前值在數(shù)組中第一次出現(xiàn)的位置索引
- lastIndexOf():檢測當(dāng)前值在數(shù)組中最后一次出現(xiàn)的位置索引
- every():判斷數(shù)組中每一項(xiàng)都是否滿足條件
- some():判斷數(shù)組中是否存在滿足條件的項(xiàng)
- includes():判斷一個數(shù)組是否包含一個指定的值
- sort():對數(shù)組的元素進(jìn)行排序
- reverse():對數(shù)組進(jìn)行倒序
- forEach():es5及以下循環(huán)遍歷數(shù)組每一項(xiàng)
- map():es6循環(huán)遍歷數(shù)組每一項(xiàng)
- find():返回匹配的項(xiàng)
- findIndex():返回匹配位置的索引
- reduce():從數(shù)組的第一項(xiàng)開始遍歷到最后一項(xiàng),返回一個最終的值
- reduceRight():從數(shù)組的最后一項(xiàng)開始遍歷到第一項(xiàng),返回一個最終的值
- toLocaleString()、toString():將數(shù)組轉(zhuǎn)換為字符串
- entries()、keys()、values():遍歷數(shù)組
各個方法的基本功能詳解
1、join()
join()方法用于把數(shù)組中的所有元素轉(zhuǎn)換一個字符串,默認(rèn)使用逗號作為分隔符
var arr1 = [1,2,3];
console.log(arr1.join()); // 1,2,3
console.log(arr.join('-')); // 1-2-3
console.log(arr); // [1,2,3](原數(shù)組不變)
2、push()和pop()
push()方法從數(shù)組末尾向數(shù)組添加元素,可以添加一個或多個元素,并返回新的長度
pop()方法用于刪除數(shù)組的最后一個元素并返回刪除的元素
var arr1 = ['lily','lucy','Tom'];
var count = arr1.push('Jack','Sean');
console.log(count); // 5
console.log(arr1); // ['lily','lucy','Tom','Jack','Sean']var item = arr1.pop();
console.log(item); // Sean
console.log(arr1); // ['lily','lucy','Tom','Jack']
3、unshift()和shift()
unshift()方法可向數(shù)組的開頭添加一個或更多元素,并返回新的長度
shift()方法用于把數(shù)組的第一個元素從其中刪除,并返回第一個元素的值
var arr1 = ['lily','lucy','Tom'];
var count = arr1.unshift('Jack','Sean');
console.log(count); // 5
console.log(arr1); // ['Jack','Sean','lily','lucy','Tom']var item = arr1.shift();
console.log(item); // Jack
console.log(arr1); // [''Sean','lily','lucy','Tom']
4、sort()
用于對數(shù)組的元素進(jìn)行排序。
默認(rèn)情況下是將數(shù)組元素轉(zhuǎn)換成字符串,然后按照ASC碼進(jìn)行排序
排序順序可以是字母或數(shù)字,并按升序或降序,默認(rèn)排序順序?yàn)榘醋帜干?/p>
arrayObject.sort(sortby);參數(shù)sortby
可選。規(guī)定排序順序,必須是函數(shù)。
var arr1 = ['a','d','c','b'];
console.log(arr1.sort()); // ['a','b','c','d'] 排序了let arr = [23,12,1,34,116,8,18,37,56,50]
a.sort()
console.log(a) // [1, 116, 12, 18, 23, 34, 37, 50, 56, 8] 沒有排序function compare(value1,value2){if(value1 < value2){return -1;}else if(value1 > value2){return 1;}else{return 0;}
}var arr2 = [13,24,51,3];
console.log(arr2.sort(compare)); // [3,13,24,51]// 如果需要通過比較函數(shù)產(chǎn)生降序排序的結(jié)果,只要交后比較函數(shù)返回的值即可// arr2的可以簡化
var arr2 = [13,24,51,3];
console.log(arr2.sort((a, b) => (a - b))); // [3,13,24,51]
5、reverse()
用于顛倒數(shù)組中元素的順序,原數(shù)組改變
var arr1 = [13,24,51,3];
console.log(arr1.reverse()); // [3,51,24,13]
console.log(arr1); // [3,51,24,13](原數(shù)組改變)
6、concat()
用于連接兩個或多個數(shù)組,該方法不會改變現(xiàn)有的數(shù)組,而僅僅會返回被連接數(shù)組的一個副本
var arr1 = [1,3,5,7];
var arrCopy = arr1.concat(9,[11,13]);
console.log(arrCopy); // [1,3,5,7,9,11,13]
console.log(arr1); // [1,3,5,7](原數(shù)組未被修改)
7、slice()
返回從原數(shù)組中指定開始下標(biāo)到結(jié)束下標(biāo)之間的項(xiàng)組成的新數(shù)組,可以接受一或兩個參數(shù),即要返回項(xiàng)的起始和結(jié)束位置(不包括結(jié)束位置的項(xiàng))
用法:array.slice(start,end)
解釋:該方法是對數(shù)組進(jìn)行部分截取,并返回一個數(shù)組副本;參數(shù)start是截取的開始數(shù)組索引,end參數(shù)等于你要取的最后一個字符的位置值加上1(可選)
var arr1 = [1,3,5,7,9,11];
var arrCopy = arr1.slice(1);
var arrCopy2 = arr1.slice(1,4);
var arrCopy3 = arr1.slice(1,-2); // 相當(dāng)于arr1.slice(1,4);
var arrCopy4 = arr1.slice(-4,-1); // 相當(dāng)于arr1.slice(2,5);
console.log(arr1); // [1,3,5,7,9,11](原數(shù)組沒變)
console.log(arrCopy); // [3,5,7,9,11]
console.log(arrCopy2); // [3,5,7]
console.log(arrCopy3); // [3,5,7]
console.log(arrCopy4); // [5,7,9]//如果不傳入?yún)?shù)二,那么將從參數(shù)一的索引位置開始截取,一直到數(shù)組尾
var a=[1,2,3,4,5,6];
var b=a.slice(0,3); //[1,2,3]
var c=a.slice(3); //[4,5,6]//如果兩個參數(shù)中的任何一個是負(fù)數(shù),array.length會和它們相加,試圖讓它們成為非負(fù)數(shù),舉例說明:
//當(dāng)只傳入一個參數(shù),且是負(fù)數(shù)時,length會與參數(shù)相加,然后再截取
var a=[1,2,3,4,5,6];
var b=a.slice(-1); //[6]//當(dāng)只傳入一個參數(shù),是負(fù)數(shù)時,并且參數(shù)的絕對值大于數(shù)組length時,會截取整個數(shù)組
var a=[1,2,3,4,5,6];
var b=a.slice(-6); //[1,2,3,4,5,6]
var c=a.slice(-8); //[1,2,3,4,5,6]//當(dāng)傳入兩個參數(shù)一正一負(fù)時,length也會先于負(fù)數(shù)相加后,再截取
var a=[1,2,3,4,5,6];
var b=a.slice(2,-3); //[3]//當(dāng)傳入一個參數(shù),大于length時,將返回一個空數(shù)組
var a=[1,2,3,4,5,6];
var b=a.slice(6); //[]
8、splice()
可以實(shí)現(xiàn)刪除、插入和替換
用法:array.splice(start,deleteCount,item…)
解釋:splice方法從array中移除一個或多個數(shù)組,并用新的item替換它們。參數(shù)start是從數(shù)組array中移除元素的開始位置。參數(shù)deleteCount是要移除的元素的個數(shù)。
如果有額外的參數(shù),那么item會插入到被移除元素的位置上。它返回一個包含被移除元素的數(shù)組。
//替換
var a=['a','b','c'];
var b=a.splice(1,1,'e','f'); //a=['a','e','f','c'],b=['b']//刪除
var arr1 = [1,3,5,7,9,11];
var arrRemoved = arr1.splice(0,2);
console.log(arr1); // [5,7,9,11]
console.log(arrRemoved); // [1,3]// 添加元素
var arr1 = [22,3,31,12];
arr1.splice(1,0,12,35);
console.log(arr1); // [22,12,35,3,31,12]
9、forEach()
forEach方法中的function回調(diào)有三個參數(shù):第一個參數(shù)是遍歷的數(shù)組內(nèi)容,第二個參數(shù)是對應(yīng)的數(shù)組索引,第三個參數(shù)是數(shù)組本身
var arr = [1,2,3,4];
var sum =0;
arr.forEach(function(value,index,array){array[index] == value; //結(jié)果為truesum+=value; });
console.log(sum); //結(jié)果為 10
10、map()
返回一個新數(shù)組,會按照原始數(shù)組元素順序依次處理元素
let array = [1, 2, 3, 4, 5];
let newArray = array.map((item) => {return item * item;
})
console.log(newArray) // [1, 4, 9, 16, 25]
11、every()
判斷數(shù)組中每一項(xiàng)都是否滿足條件,只有所有項(xiàng)都滿足條件,才會返回true
var arr1 = [1,2,3,4,5];
var arr2 = arr1.every(x => {return x < 10;
});
console.log(arr2); // truevar arr3 = arr1.every(x => {return x < 3;
});
console.log(arr3); // false
12、some()
判斷數(shù)組中是否存在滿足條件的項(xiàng),只要有一項(xiàng)滿足條件,就會返回true
var arr1 = [1,2,3,4,5];
var arr2 = arr1.some(x => {return x < 3;
});
console.log(arr2); // true
var arr3 = arr1.some(x => {return x < 1;
});
console.log(arr3); // false
13、reduce()和reduceRight()
都會實(shí)現(xiàn)迭代數(shù)組的所有項(xiàng)(即累加器),然后構(gòu)建一個最終返回的值,reduce()方法從數(shù)組的第一項(xiàng)開始,逐個遍歷到最后,reduceRight()方法從數(shù)組的最后一項(xiàng)開始。向前遍歷到第一項(xiàng) 4個參數(shù):前一個值、當(dāng)前值、項(xiàng)的索引和數(shù)組對象
var arr1 = [1,2,3,4,5];
var sum = arr1.reduce((prev,cur,index,array) => {return prev + cur;
},10); // 數(shù)組一開始加了一個初始值10,可以不設(shè)默認(rèn)0
console.log(sum); // 25
14、toLocaleString()和toString()
都是將數(shù)組轉(zhuǎn)換為字符串
var arr1 = [22,3,31,12];
let str = arr1.toLocaleString();
var str2 = arr1.toString();console.log(str); // 22,3,31,12
console.log(str2); // 22,3,31,12
15、find()和findIndex()
都接受兩個參數(shù):一個回調(diào)函數(shù),一個可選值用于指定回調(diào)函數(shù)內(nèi)部的this
該回調(diào)函數(shù)可接受3個參數(shù):數(shù)組的某個元素、該元素對應(yīng)的索引位置、數(shù)組本身,在回調(diào)函數(shù)第一次返回true時停止查找。
二者的區(qū)別是:find()方法返回匹配的值,而findIndex()方法返回匹配位置的索引
let arr = [1,2,3,4,5];
let num = arr.find(item => item > 1);
console.log(num) // 2let arr = [1,2,3,4,5];
let num = arr.findIndex(item => item > 1);
console.log(num) // 1
16、entries()、keys()和values()
es6新增entries()、keys()和values()–用于遍歷數(shù)組。它們都返回一個遍歷器對象,可以用for…of循環(huán)進(jìn)行遍歷
區(qū)別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷、entries()是對鍵值對的遍歷
for(let index of [a,b].keys()){console.log(index);
}
// 0
// 1for(let elem of [a,b].values()){console.log(elem);
}
// a
// bfor(let [index,elem] of [a,b].entries()){console.log(index,elem);
}
// 0 'a'
// 1 'b'
17、indexOf()
indexof方法可以在字符串和數(shù)組上使用。
indexOf() 方法可返回某個指定的字符串值(基本數(shù)據(jù)類型)在字符串、數(shù)組中首次出現(xiàn)的位置。
arr = ['mfg', '2017', '2016'];console.log(arr.indexOf('mfg')); // 0console.log(arr.indexOf('m')); // -1console.log(arr.indexOf('2017'));// 1console.log(arr.indexOf(2017)); // -1,這里不會做隱式類型轉(zhuǎn)換const arr = ['111', '222', '333', 'NaN']console.log(arr.indexOf(NaN)) // -1
18、includes()
es7新增,用來判斷一個數(shù)組、字符串是否包含一個指定的值(基本數(shù)據(jù)類型),使用===運(yùn)算符來進(jìn)行值比較,如果是返回true,否則false,參數(shù)有兩個,第一個是(必填)需要查找的元素值,第二個是(可選)開始查找元素的位置
var arr1 = [22,3,31,12,58];
var includes = arr1.includes(31);
console.log(includes); // truevar includes2 = arr1.includes(31,3); // 從索引3開始查找31是否存在
console.log(includes2); // falsevar includes3 = arr1.includes(31,-1); // 從最后一個開始向后查找31是否存在
console.log(includes3); // falseconst arr = ['111', '222', '333', 'NaN']
console.log(arr.includes(NaN)) // true
console.log(arr.includes(111)) // false 不做隱式轉(zhuǎn)換
Vue知識總結(jié)
##1.1 怎樣理解 Vue 的單向數(shù)據(jù)流?
-
數(shù)據(jù)從父級組件傳遞給子組件,只能單向綁定
-
子組件內(nèi)部不能直接修改從父級傳遞過來的數(shù)據(jù)
-
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行,這樣會防止從子組件意外改變父級組件的狀態(tài), 從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
-
每次父級組件發(fā)生更新時,子組件中所有的 prop 都將會刷新為最新的值,這意味著你不應(yīng)該在一個子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發(fā)出警 告
-
子組件想修改時,只能通過 $emit 派發(fā)一個自定義事件,父組件接收到后,由父組件 修改
1.2 談?wù)勀銓?Vue 生命周期的理解?
(1)生命周期是什么?
Vue 實(shí)例有一個完整的生命周期,也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模版、掛載 Dom -> 渲染、更新 -> 渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期
(2)各個生命周期的作用
beforeCreate | 組件實(shí)例被創(chuàng)建之初,組件的屬性生效之前 |
---|---|
created | 組件實(shí)例已經(jīng)完全創(chuàng)建,屬性也綁定,但真實(shí) dom 還沒有生成,$el 還不可用 |
beforeMount | 在掛載開始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用 |
mounted | el 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子 |
beforeUpdate | 組件數(shù)據(jù)更新之前調(diào)用,發(fā)生在虛擬 DOM 打補(bǔ)丁之前 |
update | 組件數(shù)據(jù)更新之后 |
activited | keep-alive 專屬,組件被激活時調(diào)用 |
deadctivated | keep-alive 專屬,組件被銷毀時調(diào)用 |
beforeDestory | 組件銷毀前調(diào)用 |
destoryed | 組件銷毀后調(diào)用 |
1.3 談?wù)勀銓?keep-alive 的了解?
keep-alive
是 Vue 內(nèi)置的一個組件,可以使被包含的組件保留狀態(tài),避免重新渲染 ,其有以下特性:
一般結(jié)合路由和動態(tài)組件一起使用,用于緩存組件
提供 include
和 exclude
屬性,兩者都支持字符串或正則表達(dá)式, include
表示只有名稱匹配的組件會被緩存,exclude
表示任何名稱匹配的組件都不會被緩存 ,其中 exclude
的優(yōu)先級比 include
高
對應(yīng)兩個鉤子函數(shù) activated 和 deactivated ,當(dāng)組件被激活時,觸發(fā)鉤子函數(shù) activated,當(dāng)組件被移除時,觸發(fā)鉤子函數(shù) deactivated
1.4 組件中 data 為什么是一個函數(shù)?
因?yàn)榻M件是用來復(fù)用的,且 JS 里對象是引用關(guān)系,如果組件中 data 是一個對象,那么這樣作用域沒有隔離,子組件中的 data 屬性值會相互影響
如果組件中 data 選項(xiàng)是一個函數(shù),那么每個實(shí)例可以維護(hù)一份被返回對象的獨(dú)立的拷貝,組件實(shí)例之間的 data 屬性值不會互相影響;而 new Vue 的實(shí)例,是不會被復(fù)用的,因此不存在引用對象的問題
1.5 你對vue項(xiàng)目哪些優(yōu)化?
(1)代碼層面的優(yōu)化
-
v-if 和 v-show 區(qū)分使用場景
-
computed 和 watch 區(qū)分使用場景
-
v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if
-
長列表性能優(yōu)化
-
事件的銷毀
-
圖片資源懶加載
-
路由懶加載
-
第三方插件的按需引入
-
優(yōu)化無限列表性能
-
服務(wù)端渲染 SSR or 預(yù)渲染
(2)Webpack 層面的優(yōu)化
-
Webpack 對圖片進(jìn)行壓縮
-
減少 ES6 轉(zhuǎn)為 ES5 的冗余代碼
-
提取公共代碼
-
模板預(yù)編譯
-
提取組件的 CSS
-
優(yōu)化 SourceMap
-
構(gòu)建結(jié)果輸出分析
-
Vue 項(xiàng)目的編譯優(yōu)化
(3)基礎(chǔ)的 Web 技術(shù)的優(yōu)化
-
開啟 gzip 壓縮
-
瀏覽器緩存
-
CDN 的使用
-
使用 Chrome Performance 查找性能瓶頸
1.6 vue中的key有什么作用?
key 是為 Vue 中 vnode 的唯一標(biāo)記,通過這個 key,我們的 diff 操作可以更準(zhǔn)確、更快速
Vue 的 diff 過程可以概括為:oldCh 和 newCh 各有兩個頭尾的變量 oldStartIndex、oldEndIndex 和 newStartIndex、newEndIndex,它們會新節(jié)點(diǎn)和舊節(jié)點(diǎn)會進(jìn)行兩兩對比,即一共有4種比較方式:newStartIndex 和oldStartIndex 、newEndIndex 和 oldEndIndex 、newStartIndex 和 oldEndIndex 、newEndIndex 和 oldStartIndex,如果以上 4 種比較都沒匹配,如果設(shè)置了key,就會用 key 再進(jìn)行比較,在比較的過程中,遍歷會往中間靠,一旦 StartIdx > EndIdx 表明 oldCh 和 newCh 至少有一個已經(jīng)遍歷完了,就會結(jié)束比較
所以 Vue 中 key 的作用是:key 是為 Vue 中 vnode 的唯一標(biāo)記,通過這個 key,我們的 diff 操作可以更準(zhǔn)確、更快速
1.7 虛擬dom的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
-
保證性能下限: 框架的虛擬 DOM 需要適配任何上層 API 可能產(chǎn)生的操作,它的一些 DOM 操作的實(shí)現(xiàn)必須是普適的,所以它的性能并不是最優(yōu)的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虛擬 DOM 至少可以保證在你不需要手動優(yōu)化的情況下,依然可以提供還不錯的性能,即保證性能的下限;
-
無需手動操作 DOM: 我們不再需要手動去操作 DOM,只需要寫好 View-Model 的代碼邏輯,框架會根據(jù)虛擬 DOM 和 數(shù)據(jù)雙向綁定,幫我們以可預(yù)期的方式更新視圖,極大提高我們的開發(fā)效率;
-
跨平臺: 虛擬 DOM 本質(zhì)上是 JavaScript 對象,而 DOM 與平臺強(qiáng)相關(guān),相比之下虛擬 DOM 可以進(jìn)行更方便地跨平臺操作,例如服務(wù)器渲染、weex 開發(fā)等等
缺點(diǎn):
無法進(jìn)行極致優(yōu)化: 雖然虛擬 DOM + 合理的優(yōu)化,足以應(yīng)對絕大部分應(yīng)用的性能需求,但在一些性能要求極高的應(yīng)用中虛擬 DOM 無法進(jìn)行針對性的極致優(yōu)化:比如動畫等等
1.8 vue虛擬dom實(shí)現(xiàn)原理?
虛擬 DOM 的實(shí)現(xiàn)原理主要包括以下 3 部分:
-
用 JavaScript 對象模擬真實(shí) DOM 樹,對真實(shí) DOM 進(jìn)行抽象;
-
diff 算法 — 比較兩棵虛擬 DOM 樹的差異;
-
pach 算法 — 將兩個虛擬 DOM 對象的差異應(yīng)用到真正的 DOM 樹
1.9 Vue 是如何實(shí)現(xiàn)數(shù)據(jù)雙向綁定的?
Vue 數(shù)據(jù)雙向綁定主要是指:數(shù)據(jù)變化更新視圖
-
輸入框內(nèi)容變化時,Data 中的數(shù)據(jù)同步變化。即 View => Data 的變化。
-
Data 中的數(shù)據(jù)變化時,文本節(jié)點(diǎn)的內(nèi)容同步變化。即 Data => View 的變化
Vue 主要通過以下 4 個步驟來實(shí)現(xiàn)數(shù)據(jù)雙向綁定的:
-
實(shí)現(xiàn)一個監(jiān)聽器 Observer:對數(shù)據(jù)對象進(jìn)行遍歷,包括子屬性對象的屬性,利用 Object.defineProperty() 對屬性都加上 setter 和 getter。這樣的話,給這個對象的某個值賦值,就會觸發(fā) setter,那么就能監(jiān)聽到了數(shù)據(jù)變化
-
實(shí)現(xiàn)一個解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個指令對應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動,收到通知,調(diào)用更新函數(shù)進(jìn)行數(shù)據(jù)更新
-
實(shí)現(xiàn)一個訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁 ,主要的任務(wù)是訂閱 Observer 中的屬性值變化的消息,當(dāng)收到屬性值變化的消息時,觸發(fā)解析器 Compile 中對應(yīng)的更新函
-
實(shí)現(xiàn)一個訂閱器 Dep:訂閱器采用 發(fā)布-訂閱 設(shè)計(jì)模式,用來收集訂閱者 Watcher,對監(jiān)聽器 Observer 和 訂閱者 Watcher 進(jìn)行統(tǒng)一管理
1.20 Vue-router 有哪幾種路由守衛(wèi)?
-
全局守衛(wèi):beforeEach
-
后置守衛(wèi):afterEach
-
全局解析守衛(wèi):beforeResolve
-
路由獨(dú)享守衛(wèi):beforeEnter
1.21 Vue-router 的鉤子函數(shù)都有哪些?
關(guān)于 vue-router 中的鉤子函數(shù)主要分為 3 類
-
全局鉤子函數(shù)要beforeEach 函數(shù)有三個參數(shù),分別是
1.to:router 即將進(jìn)入的路由對象
2.from:當(dāng)前導(dǎo)航即將離開的路由
3.next:function,進(jìn)行管道中的一個鉤子,如果執(zhí)行完了,則導(dǎo)航的狀態(tài)就是 confirmed (確認(rèn)的)否則為 false,終止導(dǎo)航
-
單獨(dú)路由獨(dú)享組件 beforeEnter
-
組件內(nèi)鉤子
1.beforeRouterEnter
2.beforeRouterUpdate
3.beforeRouterLeave
1.22 vue-router 路由模式有幾種?
vue-router 有 3 種路由模式:hash
、history
、abstract
-
hash: 使用 URL hash 值來作路由。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器;
-
history : 依賴 HTML5 History API 和服務(wù)器配置。具體可以查看 HTML5 History 模式;
-
abstract : 支持所有 JavaScript 運(yùn)行環(huán)境,如 Node.js 服務(wù)器端。如果發(fā)現(xiàn)沒有瀏覽器的 API,路由會自動強(qiáng)制進(jìn)入這個模式.
1.23 說下 vue-router 中常用的 hash 和 history 路由模式實(shí)現(xiàn)原理嗎?
(1)hash 模式的實(shí)現(xiàn)原理 -
URL 中 hash 值只是客戶端的一種狀態(tài),也就是說當(dāng)向服務(wù)器端發(fā)出請求時,hash 部分不會被發(fā)送;
-
hash 值的改變,都會在瀏覽器的訪問歷史中增加一個記錄。因此我們能通過瀏覽器的回退、前進(jìn)按鈕控制hash 的切換;
-
可以通過 a 標(biāo)簽,并設(shè)置 href 屬性,當(dāng)用戶點(diǎn)擊這個標(biāo)簽后,URL 的 hash 值會發(fā)生改變;或者使用 JavaScript 來對 loaction.hash 進(jìn)行賦值,改變 URL 的 hash 值;
-
我們可以使用 hashchange 事件來監(jiān)聽 hash 值的變化,從而對頁面進(jìn)行跳轉(zhuǎn)(渲染)
(2)history 模式的實(shí)現(xiàn)原理
-
pushState 和 repalceState 兩個 API 來操作實(shí)現(xiàn) URL 的變化 ;
-
我們可以使用 popstate 事件來監(jiān)聽 url 的變化,從而對頁面進(jìn)行跳轉(zhuǎn)(渲染);
-
history.pushState() 或 history.replaceState() 不會觸發(fā) popstate 事件,這時我們需要手動觸發(fā)頁面跳轉(zhuǎn)(渲染)
1.27 vue 中如何重置 data?
要初始化 data 中的數(shù)據(jù),可以使用 Object.assign()方法,實(shí)現(xiàn)重置 data 中的數(shù)據(jù),以下就是對該方法的詳細(xì)介紹,以及如何使用該方法,重置 data 中的數(shù)據(jù)
-
**Object.assign()**方法基本定義
-
Object.assign() 方法用于將所有可枚舉屬性的值從一個或多個源對象復(fù)制到目 標(biāo)對象。它將返回目標(biāo)對象。
-
用法: Object.assign(target, …sources),第一個參數(shù)是目標(biāo)對象,第二個參數(shù) 是源對象,就是將源對象屬性復(fù)制到目標(biāo)對象,返回目標(biāo)對象
1.28 vue3 新特性有哪些?
1、性能提升
-
響應(yīng)式性能提升,由原來的 Object.defineProperty 改為基于ES6的 Proxy ,使其速度更快,消除警告。
-
重寫了 Vdom ,突破了 Vdom 的性能瓶頸。
-
進(jìn)行模板編譯優(yōu)化。
-
更加高效的組件初始化
2、更好的支持 typeScript
- 有更好的類型推斷,使得 Vue3 把 typeScript 支持得非常好
3、新增Composition API
Composition API 是 vue3 新增的功能,比 mixin 更強(qiáng)大。它可以把各個功能模塊獨(dú)立開來,提高代碼邏輯的可復(fù)用性,同時代碼壓縮性更強(qiáng)
4、新增組件
-
Fragment 不再限制 template 只有一個根幾點(diǎn)。
-
Teleport 傳送門,允許我們將控制的內(nèi)容傳送到任意的 DOM 中。
-
Supense 等待異步組件時渲染一些額外的內(nèi)容,讓應(yīng)用有更好的用戶體驗(yàn)。
5、Tree-shaking:支持搖樹優(yōu)化
搖樹優(yōu)化后會將不需要的模塊修剪掉,真正需要的模塊打到包內(nèi)。優(yōu)化后的項(xiàng)目體積只有原來的一半,加載速度更快
6、Custom Renderer API: 自定義渲染器
實(shí)現(xiàn) DOM 的方式進(jìn)行 WebGL 編程
1.29 vue3 組合式API生命周期鉤子函數(shù)有變化嗎?
setup 是圍繞 beforeCreate 和 created 生命周期鉤子運(yùn)行的,所以不需要顯示的定義它們。其他的鉤子都可以編寫到 setup 內(nèi)
1.30 watch 和 watchEffect 的區(qū)別?
watch 和 watchEffect 都是監(jiān)聽器,watchEffect 是一個副作用函數(shù)。它們之間的區(qū)別有:
-
watch 需要傳入監(jiān)聽的數(shù)據(jù)源,而 watchEffect 可以自動手機(jī)數(shù)據(jù)源作為依賴。
-
watch 可以訪問倒改變之前和之后的值,watchEffect 只能獲取改變后的值。
-
watch 運(yùn)行的時候不會立即執(zhí)行,值改變后才會執(zhí)行,而 watchEffect 運(yùn)行后可立即執(zhí)行。這一點(diǎn)可以通過 watch 的配置項(xiàng) immediate 改變。
1.31 vue中v-if和v-for優(yōu)先級在vue2和vue3中的區(qū)別
實(shí)踐中不管是vue2或者vue3都不應(yīng)該把v-if和v-for放在一起使用。
-
在 vue 2.x 中,在一個元素上同時使用 v-if 和 v-for 時, v-for 會優(yōu)先作用。
-
在 vue 3.x 中, v-if 總是優(yōu)先于 v-for 生效。
-
vue2中v-for的優(yōu)先級是高于v-if的,放在一起,會先執(zhí)行循環(huán)在判斷條件,并且如果值渲染列表中一小部分元素,也得再每次重渲染的時候遍歷整個列表,比較浪費(fèi)資源。
-
vue3中v-if的優(yōu)先級是高于v-for的,所以v-if執(zhí)行時,它調(diào)用相應(yīng)的變量如果不存在,就會導(dǎo)致異常
1.32 script setup 有什么用?
scrtpt setup
是 vue3 的語法糖,簡化了組合式 API 的寫法,并且運(yùn)行性能更好。使用 script setup
語法糖的特點(diǎn):
-
屬性和方法無需返回,可以直接使用。
-
引入組件的時候,會自動注冊,無需通過 components 手動注冊。
-
使用 defineProps 接收父組件傳遞的值。
-
useAttrs 獲取屬性,useSlots 獲取插槽,defineEmits 獲取自定義事件。
-
默認(rèn)不會對外暴露任何屬性,如果有需要可使用 defineExpose 。
1.33 vue常用的修飾符
.stop
:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;
.prevent
:等同于 JavaScript 中的 event.preventDefault() ,防止執(zhí)行預(yù)設(shè)的行為(如果事件可取消,則取消該事件,而不停止事件的進(jìn)一步傳播);作用是阻止默認(rèn)事件(例如a標(biāo)簽的跳轉(zhuǎn)
.capture
:與事件冒泡的方向相反,事件捕獲由外到內(nèi);
.self
:只會觸發(fā)自己范圍內(nèi)的事件,不包含子元素;
.once
:只會觸發(fā)一次。
.trim
修飾符的作用是把v-model綁定的值的首尾空格給去掉。在實(shí)際開發(fā)中我們一般用于搜索框的內(nèi)容修飾,過濾掉用戶多輸入前后空格導(dǎo)致內(nèi)容查不出來的情況。
.left
,.right
,.middle
這三個修飾符是鼠標(biāo)的左中右按鍵觸發(fā)的事件.
1.36 $route 和 $router 的區(qū)別?
$route
是“路由信息對象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息參數(shù)
$router
是“路由實(shí)例”想要導(dǎo)航到不同URL 對象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等。
1.37 vue路由跳轉(zhuǎn)傳參的方式有哪些?
params傳參(顯示參數(shù))
在url中會顯示出傳參的值,刷新頁面不會失去拿到的參數(shù),使用該方式傳值的時候,需要子路由提前配置好參數(shù)
params傳參(不顯示參數(shù))
在url中不會顯示出傳參的值,但刷新頁面會失去拿到的參數(shù),使用該方式 傳值 的時候,需要子路由提前配置好name參數(shù)
query 傳參
query 傳過去的參數(shù)會拼接在地址欄中(?name=xx),刷新頁面數(shù)據(jù)不會丟失,使用path和name都可以
VUE幾種路由跳轉(zhuǎn)幾種方式的區(qū)別
-
this.$router.push:跳轉(zhuǎn)到指定url路徑,并想history棧中添加一個記錄,點(diǎn)擊后退會返回到上一個頁面
-
this.$router.replace:跳轉(zhuǎn)到指定url路徑,但是history棧中不會有記錄,點(diǎn)擊返回會跳轉(zhuǎn)到上上個頁面 (就是直接替換了當(dāng)前頁面)
-
this.$router.go(n):向前或者向后跳轉(zhuǎn)n個頁面,n可為正整數(shù)或負(fù)整數(shù)
1.38 單頁面應(yīng)用和多頁面應(yīng)用區(qū)別及優(yōu)缺點(diǎn)?
單頁面:顧名思義,只有一個頁面。一般是一個主頁和多個路由頁面組成。
優(yōu)點(diǎn):
-
公共資源不重新加載,局部加載,服務(wù)器壓力小
-
切換速度快,用戶體驗(yàn)好
-
前后端分離
缺點(diǎn):
-
不利于SEO(可以優(yōu)化:比如路由懶加載等)
-
初次加載時耗時多
開發(fā)難度較大(相對多頁面)
多頁面(Multi Page Application——MPA):有多個HTML頁面,跳轉(zhuǎn)的時候是從一個html頁面跳到另一個頁面。
優(yōu)點(diǎn):
-
利于SEO。
-
更容易擴(kuò)展。
-
更易數(shù)據(jù)分析。
缺點(diǎn):
-
開發(fā)成本高。
-
服務(wù)器壓力大。
-
用戶體驗(yàn)相對較差。