內容較多,建議查看目錄,方便食用

高頻
React和Vue的區別
通常解法:vue是采用指令結合vue-loader實現構件用戶界面的漸進式框架,React是采用JSX構件用戶界面的組件化開發
詳細解法:在渲染界面的時候DOM操作是昂貴的,我們能做的最后就是減少DOM操作。Vue和React都使用虛擬DOM來實現,并且二者工作一樣好
相同點:
- 都支持服務端渲染
- 都使用虛擬DOM實現
- 都有組件化開發,通過props參數進行父子組件之間的數據傳遞
- 只有框架的骨架,路由、狀態管理等是分離的
- 都是JS的UI框架,都是數據驅動視圖的
- 都支持native的方案,React的React native,Vue的weex
- 都有狀態管理,React的redux,Vue的vuex
不同點:
- React嚴格上只針對MVC的view層,Vue則是MVVM模式
- 虛擬DOM不一樣,Vue會跟蹤每個組件的依賴關系,不需要重新渲染整個組件樹
- 對于React而言,每當應用狀態被改變時,全部組件都會重新渲染,所以需要shouldComponentUpdate生命周期方法來控制
- Vue實現了雙向數據綁定,而React的數據流是單向的
- state對象在React中是不可變的,需要用setState方法更新狀態。
- Vue中數據由data屬性在Vue對象中管理
什么時候用Vue什么時候用React?
Vue語法簡單,開發速度快,靈活,v指令極大地簡化了開發;React最大的特色就是強大的社區支持,是由facebook出品的。對移動端的構建很友好,React的版本遷移比Vue更好一些
React的優點
- 1、聲明式的設計可以輕松構建應用
- 2、采用虛擬DOM減少與真實DOM的交互,極大的提高了性能
- 3、使用JS的擴展語言JSX代碼可讀性很好
- 4、可以與已有的庫和框架進行很好的配合
- 5、單向數據流的設計減少了重復代碼
- 6、組件化的設計可以很好的實現代碼復用
- 7、faceBook出品,龐大的社區支持
React怎么獲取真實DOM
- 通過在標簽中添加ref屬性
class Index extends Component {onClick(event){const inputDom = this.refs.submit;console.log(inputDom);}render(){return (<div><input ref='submit' type='button' value='getDom' onClick={this.onClick.bind(this)}/></div>)}
- 在標簽中寫入一個匿名函數
class Input extends Component {componentDidMount() {console.log(this.textInput);}render() {return (<inputtype="text"ref={input => this.textInput = input}/>);}
- 在標簽中加入一個回調函數
class CustomTextInput extends Component {constructor(props) {super(props);this.textInput = React.createRef();}render() {return (<inputtype="text"ref={this.textInput}/>);}
new操作符
調用new會發生四件事
- 創建一個新對象
- 連接原型
- 改變this指向
- 返回新對象
function Person(name){this.name = name,this.age = 23
}
function myNew(Con, ...arg){//創建一個新對象 let obj = Object.creat(Con.prototype)//改變this的指向let res = Con.apply(obj, arg)return res instanceof Object ? res : obj
}
var per = myNew(Person, "miruo")
實現一個Instanceof
instanceof的機制:A instanceof B,在A的原型鏈上尋找B.prototype,找得到返回true,找不到返回false。但是instanceof不能準確判斷基礎數據類型,只能判斷引用數據類型
function myInstanceof(left, right){let pro = right.prototypeleft = left.__proto__while(left !== null){if(left == pro){return true}else{left = left.__proto__}}return false
}
TS/JS
TS比JS更可靠,TS引入類型定義和編譯器,可以避免JS大多數runtime錯誤,更可靠,易維護,更清晰。TS中顯式類型聲明可以提升代碼的可讀性,代碼校驗全部交給編譯器負責。TS其實是JS的超集,可以在TS代碼中混合使用任何JS庫和代碼。TS泛型其實就是讓一個組件支持多種類型,在定義函數、接口或者類時,不預先指定具體類型,而是在使用的時候再指定類型限制的一種特性。
Less
Less時CSS的預處理語言,增加了變量、混合、函數等功能,讓CSS更容易維護,方便制作主題,擴充。
怎么理解restful
REST就是表現層狀態轉移的縮寫。把資源具體呈現出來的形式就是“表現層”。URI只代表資源的實體,不代表形式。換句話說URI只代表資源的位置。具體的表現形式,是.html也好還是.txt也好應該在http的請求頭中指定的字段表示。對于http來說其實是一個無狀態的協議,也就是說狀態其實是保存在服務器的,那么客戶端要操作服務器就要想辦法讓服務器發生狀態轉移。而這種轉移是建立在表現層的。而客戶端用到的手段其實就是http協議,GET、POST、PUT、DELETE分別對應四種操作。那么其實restful架構就是每個URI代表一個資源,客戶端和服務端之間傳遞這種資源的表現層,客戶端通過四個http動詞,對服務端的資源進行操作,實現“表現層狀態轉移”
rem和em有什么區別
二者都是相對大小,區別就在于em是相對于父級元素的大小。rem則是相對于html根元素的大小。
es6有哪些特性
let/const、promise、async/await、generator、箭頭函數、解構、模板字符串等
箭頭函數和普通函數有哪些區別
箭頭函數使用起來更加的方便,箭頭函數的this指針指向外部函數的指針。
animation(動畫)、transition(過渡)、transform(變形)、translate(移動)
-
transition需要觸發條件,不能自動執行。
-
transition觸發一次只能執行一次,對此執行需要多次觸發條件。
-
transition只能設置開始和結束兩個狀態,不能設置中間狀態。
-
animation像flash動畫一樣,可以設置動畫關鍵幀
-
animation不需要觸發條件,頁面加載完成后自動執行
介紹一下React
React是用JS構建快速響應大型web應用的首選方案,是一個JS庫,主要用于構建ui。虛擬DOM最大限度減少與真實DOM的交互,使用JSX代碼可讀性很好。可以與已有的庫和框架很好的配合。使用React構建組件使代碼更容易得到復用可以很好的應用在大項目的開發過程中。單向數據流減少了重復的代碼。輕松實現數據綁定。
React生命周期
React聲明周期其實就是React組件從掛載到卸載的過程。組件掛載就是組件渲染到頁面呈現。組件卸載就是從DOM中移除。對于類組件來說我們可以在組件掛載到卸載的不同階段執行特殊的函數,就是生命周期函數。
- componentWillMount 組件將要掛載時觸發,主要進行一些初始化工作,這時是可以修改state的
- componentDidMount 組件掛載完成時觸發,這個階段可以發起請求
- componentWillReceiveProps 組件將要接受props時觸發
- shouldComponentUpdate 是否更新數據時觸發,返回一個布爾值
- componentWillUpdate 組件將要更新時觸發,做更新前的一些準備
- componentDidUpdate 組件更新完成時觸發,可以訪問或者修改DOM,也可以發請求
- componentWillUnmount 組件將要卸載時觸發,清除一些監聽和計時器啥的,做收尾工作
Vue生命周期
Vue實例從創建到銷毀的過程就是Vue的生命周期,創建-初始化-模板編譯-掛載DOM-渲染 更新-渲染 卸載等一系列操作。稱之為Vue生命周期。
- new Vue() 實例化一個Vue實例
- beforeCreate
- beforeCreate完成后就進行數據的初始化,會定義data,方法以及事件,完成數據劫持,給組件配置觀察者實例。
- created 這時已經拿到data以及方法,可以開始調用方法進行數據請求。
- beforeMount 相關的render函數首次被調用
- mounted 有初始值的DOM渲染完成
- beforeUpdate
- updated
- beforeDestroy
- destroyed
React函數組件和類組件的區別
函數組件沒有生命周期,沒有this,沒有state,通過hooks改變state,但是性能比較好,不用實例化
類組件有生命周期,有this,有state,通過setState方法改變state,,需要實例化,性能沒有函數組件好
‘’ == 0/‘0’ == 0/‘’ == {}
對于相等表達式來說,兩邊類型相同就直接比較,兩邊類型不同則兩邊都Number()再比較。如果是對象就先toString再Number(),對于表達式{}==true:實際上等價于ToPrimitive({}) == ToNumber(true),即Number({}.toString()) == Number(true)。所以上面三個分別返回true,true,false
==運算符規則
x == y
- x和y類型相同時,都為number時比較特殊。其中一個為NaN就返回false,-0==+0
- null == undefined 返回true
- 二者若一個number一個string就ToNumber(string)再進行比較
- 若其中一個時boolean就ToNumber(boolean)再進行比較
- 若其中一個是String/Number,另一個是Object。那么久ToPrimitive(Object)再進行比較
- 當兩邊都是Object時,比較的是引用,不是值。[] == []和{} == {}都返回false,就是因為引用不同。
ToPrimitive()就是先toString()再ToNumber()。[].toString()是空,再ToNumber就是0,{}.toString()返回[object Object],再ToNumber就是NaN。
構造器中沒用super會怎么樣
子類必須在構造方法中調用super函數,否則新建實例的時候會報錯,因為子類自己的this對象也需要父類構造函數構造,才能得到父類同樣的屬性和方法。不調用super子類就得不到this
Http緩存詳解
http緩存主要針對一些實時性要求不高的靜態文件進行的緩存,往往存在瀏覽器端,防止一些請求重復訪問服務器。
MVC和MVVM
MVC思想就是,控制器負責將Model的數據用View顯示出來。換句話說是控制器里面把Model的數據賦值給View。Model負責對數據的獲取和存放,也就是數據的管理者。而調用數據的就是控制器。而View簡單來說就是我們看到的界面上的一切,View就是負責界面的繪制。MVVM相比于MVC多了個VM少了控制器。Model負責對數據的存取,然而我們除了存取還要進行解析,所謂解析,就是把原始數據轉換成View可以用的數據。現在一些App越來越復雜,數據解析的工作完全交給控制器,控制器就會變得非常臃腫。而實際上控制器被設計出來也不是用于數據解析的。基于面向對象的思想,就創造出一個對象用于數據解析,VM就誕生了。VM相當于是C的秘書,VM進行數據解析,而C只需要知道解析后的結果就可以了。
控制器內把M的數據賦值給V,但是由于需要數據解析,就用VM當作C的秘書進行數據解析,C只需要知道解析結果,存在感低了
Vue雙向綁定的原理
利用Object.defineProperty()這個方法重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現。采用數據劫持結合發布者-訂閱者模式的方式,通過劫持各個屬性的setter和getter,在數據變動時發布消息給訂閱者,觸發相應的監聽回調.
Object.defineProperty與Proxy理解
Object.defineProperty與Proxy常常被用來做數據劫持,數據劫持就是在訪問和修改某個屬性時,通過一段代碼對操作進行攔截,進行額外的操作或者修改返回結果。最典型的應用是雙向數據綁定。數據劫持有時也應用在保持數據的不可變性而攔截對數據的修改操作。區別:
- Object.defineProperty是對對象的屬性進行遍歷然后修改,Proxy是監聽整個對象
- Object.defineProperty不能監聽數組,Proxy可以
- Object.defineProperty直接在原對象上進行修改,Proxy則是返回一個新對象,對新對象進行操作
mouseenter和mouseover的區別
- mouseenter無論鼠標指針穿過被選元素或其子元素都觸發mouseenter。對應mouseout
- mouseover只有在鼠標穿過被選元素時,才觸發mouseenter事件。對應mouseleave
CSS盒子模型
盒子模型就是用來裝頁面上元素的矩形區域,主要有兩種
- 標準盒子模型
- IE盒子模型
標準盒子模型和IE盒子模型的區別在于對widtd的計算,標準盒子模型的寬度就是content的寬度;IE盒子模型的寬度是content+padding+border
- 那么怎么設置這兩種盒子模型 ?
通過CSS提供的box-sizing,box-sizing:content-box表示標準盒子模型 ;box-sizing:border-box表示IE盒子模型 - 為什么會有兩種盒子模型?
在微軟的市場份額達到百分之80的時候,他們想自己制定一套瀏覽器標準,其中就包括IE盒子模型。但是其他的瀏覽器廠商并不同意微軟的做法,就采用了W3C的標準。這就導致IE瀏覽器和其他瀏覽器盒子模型不同,但是一些老網站仍然是IE盒子模型,所以就把IE盒子模型保留了下來。 - 應用場景:如果我們想設置兩個子容器,使其都左浮動,然后寬度都設置為50%,然后給一點padding,運行就會發現兩個子容器換行了,這時就可以用標準盒子模型了。
link和import的區別/src與href的區別
link和import的區別:
- link是屬于html標簽,而@import是css提供的,只能加載CSS
- 頁面加載時link就加載,而@import引入的是在頁面加載結束后加載
- link權重高于import
- link支持使用JS控制DOM改變樣式,@import不允許
src與href的區別:
- href是超文本引用,引用和頁面關聯,表示在當前元素和引用資源之間建立聯系
- src表示引用資源替換當前元素,會將指向資源下載并應用到當前文檔中
Flex布局
常見的布局方案對于一些特殊的布局很不方便,比如垂直居中。Flex非常靈活,Flex布局的屬性大致分為容器屬性和元素屬性
容器屬性:
- flex-direction: row | row-reverse | column | column-reverse決定主軸方向
- flex-wrap: nowarp | wrap | wrap-reverse 決定換行規則
- justify-content: 水平主軸對其方式
- align-items: 垂直軸線對齊方式
元素屬性:
- order: 定義元素排列順序,序號小的靠前
- flex-grow: 定義項目放大比例,取值為1是自適應,取值為0則沒大小
- flex-shrink: 定義項目縮小比例,空間不足時縮小,取值0則不縮小
- flex-basis: 定義了在分配多余空間時項目占據的空間,設置為auto則根據內容判斷大小,可以設置為一個具體的值,如100px
- flex: 是上面三種屬性的縮寫,默認值0 1 auto
- align-self: 允許單個項目與其他項目不一樣的對其方式,可以覆蓋align-item默認值是auto表示繼承父元素的align-items
BFC(塊級格式化上下文)
可形成獨立渲染區域,通常用于清除浮動,防止margin重疊。BFC是一個獨立的容器,容器內元素不會影響外面,計算高度時,浮動元素也計算在內。
BFC形成條件:
- 根元素
- 浮動元素
- 絕對定位元素absolute、fixed
- display為inline-block、table-cell、table-caption、flex、inline-flex
- overflow 不為visible的元素
BFC應用場景:
- 防止margin重疊
- 自適應兩欄布局,left浮動,right設置overflow: hidden,這樣不會重疊
- 清除浮動
塊級元素和行級元素
**塊元素:**獨占一行,并且自動填滿父元素,可以設置盒子模型的屬性;主要有:div、p、h1-6、ol、ul、table、form
**行元素:**不會獨占一行,width和height會失效,垂直方向上的padding和margin會失效,只能容納文本和其他行元素;主要有:a、em、strong、span、i、label、br
**行內塊:**綜合塊級元素與行內元素的特性,可設寬高(默認是內容寬高),也可以設置內外邊距;主要有img和input、textarea等,其實屬于行元素
p是塊級元素,但是不能包含除了p之外的其他塊級元素;a是行內元素,但是可以包含它本身外的任意塊元素
HTML5新標簽
visibility = hidden, opacity=0, display: none
opacity=0:元素被隱藏,不改變布局,可以觸發綁定事件
visibility = hidden:元素被隱藏,不改變布局,不可以出發綁定事件
display: none:元素被隱藏,會改變布局,不可觸發點擊事件,可以理解成該元素被刪除了
雙邊距重疊(外邊距重疊)
多個相鄰普通流的塊元素垂直方向上的margin會重疊
- 兩個正數取較大的
- 兩個負數取絕對值大的
- 一正一負取二者的和
清除浮動
- 在浮動元素后使用一個帶clear屬性的空元素
- 使用CSS的overflow屬性,給浮動元素的容器添加overflow:hidden或者overflow:auto清除浮動,添加overflow屬性后浮動元素回到容器層,把容器高度撐開
- 給浮動元素后面的元素添加clear屬性
- 給浮動的元素的容器添加浮動
- 使用CSS的:after屬性,相當于在現元素的末尾添加一個看不見的塊清除浮動
CSS選擇器,樣式優先級
- 樣式優先級:!important > 內聯樣式 > 內部樣式 > 外部樣式 > 瀏覽器用戶自定義樣式 > 瀏覽器默認樣式
- 內聯樣式>ID選擇器>類選擇器=屬性選擇器=偽類選擇器>標簽選擇器=偽元素選擇器
- 同一元素引用多個樣式,排在后面的樣式屬性優先級高
- 樣式選擇器類型不同時:id選擇器 > 類選擇器 > 標簽選擇器
- 標簽選擇器存在層級關系,后代屬性會覆蓋祖先屬性,繼承的樣式優先級比較低
- 屬性選擇器和偽類選擇器優先級相同
grid網狀布局
給div設置display: grid;那么這個div就是一個網狀布局容器,此div的直接下一級元素稱為項目。布局屬性分為容器屬性和項目屬性。
容器屬性:
- grid-template-columns 此屬性設置每一列的列寬
- grid-template-rows 定義每一行的行高
- repeat grid-template-rows: 30px 30px 30px 等價于grid-template-rows: repeat(3, 30px)
- auto-fill關鍵字 grid-template-rows: repeat(auto-fill, 30px)表示自動填充30px的塊直到容器裝滿
三欄布局
- 1、浮動加margin
- 2、定位
- 3、table
- 4、flex
- 5、grid
display屬性詳解
display也就是展示,通常用于定義元素生成顯示框的類型:
- inline 默認值,元素會被顯示為內聯元素,無法設置width,height,不獨占一行
- block 塊級元素,前后有換行符,可以設置width,height,元素獨占一行
- inline-block 行內塊元素,可以設置width和height,不獨占一行
- table 此元素會作為塊級表格來顯示(類似 ),表格前后帶有換行符
- table-cell 此元素會作為一個表格單元格顯示(類似 和 )
垂直居中的方法
三種方法:
- 1、首先想到的是對子元素設置left和top都是50%,這時子元素顯示在父元素中心點的右下角。然后利用margin top和left負值為子元素大小的一半使其向左上方偏移至水平垂直居中。
- 2、利用calc可以直接設置top和left為(50%-子元素高或寬的一半)
但是上面兩種方式都必須知道子元素的大小,下面的方法比較好
- 3、transform的translate屬性也可以設置百分比,其是相對于自身的寬和高,所以可以講translate設置為-50%,就可以做到居中了。
- 4、第三種就是將子元素四個位置都設置為零,margin設置為auto實現垂直居中。如果不把四個位置設置為0那么margin:auto將被視為margin: 0,如果不設置margin: auto,由于left和top的優先級高,子元素將顯示在左上角。
- 5、還有一種是利用table的屬性,將父元素設置為display: table-cell然后使用text-align: center;vertical-align: middle;使單元格里的內容水平垂直居中,當然子元素也要設置為display: inline-block
- 6、flex布局,父元素display: flex; justify-content: center; align-items: center
- 7、父元素grid布局,父元素display: grid; 子元素justify-self: center; align-item: center。但由于兼容性不好沒有廣泛使用
標簽語義化
header、footer、nav、article、aside、section主要作用就是提升用戶體驗、使代碼更具有可讀性,使代碼結構更清晰
Promise和async/await的區別
async/await是寄生于Promise和generator的語法糖。
- Promise是ES6的,async/await是ES7的
- async/await相對于Promise寫法上更加優雅
- promise錯誤可以通過catch來捕捉,建議尾部捕獲錯誤,async/await既可以用.then又可以用try-catch捕捉
HTTP簡介
HTTP(超文本傳輸協議),是從萬維網服務器傳輸超文本到本地瀏覽器的傳送協議。瀏覽器作為HTTP客戶端通過URL向HTTP服務器即web服務器發送請求。HTTP三要點:
- 無連接 每次連接只處理一個請求,結束就斷開
- 媒體獨立 只要客戶端和服務器知道如何處理內容,任何數據類型都可以發送
- 無狀態 無狀態,不會記憶傳輸過的數據。下次要重新請求
HTTP請求報文
一個HTTP請求由:請求行、請求頭、請求體組成
- 請求行由請求方法、URL、協議版本組成
- 請求頭,由若干屬性組成,屬性名:屬性值 的形式。服務端通過請求頭獲取客戶端的信息
- 請求體,就是請求的數據,請求體可以傳遞請求參數
常見請求頭字段
- Accept 告訴服務端可以接受的數據類型,可以為一個或多個MIME類型
- Cookie Cookie就是通過HTTP請求頭攜帶過去的
- Referer 表示請求是從哪個URL過來的
- Cache-Control 要求服務端返回的內容可以存的時間,設置為no-cache則希望響應內容不被客戶端緩存,max-age=10則是10秒
- Connection 控制兩端的連接狀態,Connection: keep-alive連接不會關閉,繼續訪問還用這條連接
- Host通常在URL中提取出來,指定被請求資源的主機和端口號
- User-Agent 告訴服務器客戶端使用的操作系統和瀏覽器版本
- Accept-Language 瀏覽器申明自己接受的語言
HTTP響應報文
一個HTTP響應由:響應行、響應頭、響應體組成
- 響應行由協議版本、狀態碼及狀態描述組成
- 響應頭,由若干屬性組成,屬性名:屬性值 的形式。
- 響應體,就是得到的數據
常見響應頭字段
- Cache-Control 服務器告訴客戶端如何控制響應內容的緩存
- expires 響應過期的時間
- Last-Modified 請求資源的最后修改時間
- ETag 一個代表資源版本的屬性,資源改變這個屬性也會改變
- Location 是一個URL地址,讓頁面重定向到另一個頁面,就是讓其向另一個頁面發請求
- Set-Cookie 服務端可以設置客戶端的Cookie 比如:Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
- Accept-Ranges 表示服務器是否支持指定范圍的請求
- Access-Control-Allow-Origin 設置允許訪問該資源的域
- Access-Control-Allow-Methods 允許哪些方法來訪問
- Age 從原始服務器到代理緩存形成的預估時間
- Connection 同上
- Content-Length 響應體的長度
- Content-Type 返回內容的MIME類型
- Date 原始服務器消息發出的時間
- Server web服務器軟件名稱
Cache-Control常見取值
- public 這個請求返回的內容所經過的路徑無論是代理服務器還是客戶端都可以緩存內容
- private 發起請求的瀏覽器才能使用返回數據的緩存
- no-cache 每次發起請求都要去服務器驗證,服務器返回可以使用緩存才可以真正使用本地緩存
- max-age 資源時限
- no-store 響應不被緩存,與no-cache不同,no-cache會緩存,只是每次都要驗證
Cache-Control與expires優先級
expires返回的到期時間是服務器端的時間,這樣存在一個問題,如果客戶端的時間與服務器的時間相差很大,那么誤差就很大
HTTP1.0
同一時間同一域名的請求數量有限制,超過限制數目請求會被阻塞。只保持短暫連接,每次請求都需要建立TCP連接,完成請求立即斷開并且不記錄過去請求
HTTP1.1
默認使用持久連接,不聲明Connection: keep-alive也可以使TCP不關閉,可以被多個請求復用。同一TCP連接可同時發送多個請求,但是一個TCP中所有數據按次序進行。一個一個的處理。如果前面的處理的慢,后面的就會阻塞,就是隊頭阻塞。
HTTP2
HTTP2性能增強的核心在于二進制分幀層,它定義了如何封裝HTTP消息并在客戶端和服務端之間進行傳輸。HTTP1.x以換行符作為純文本的分隔符,而HTTP2將所有傳輸信息分割成更小的消息和幀,并對他們采用二進制編碼。
JS
1、解決異步回調地獄
- Promise
- generator
- async/await
2、事件流
事件流描述的是從頁面中接收事件的順序,DOM2級事件流包括下面幾個階段
- 事件捕獲階段
- 處于目標階段
- 事件冒泡階段
- addEventListener是DOM2級事件新增的指定事件處理程序的操作,接收三個參數
- 要處理的事件名、作為事件處理程序的函數、一個布爾值
- 最后的布爾值如果是true表示在捕獲階段調用事件處理程序;如果是false表示在冒泡階段調用事件處理程序
- IE只支持事件冒泡
3、事件委托
事件委托指的是不直接在DOM上設置監聽函數,而是在其父元素上設置監聽函數,通過事件冒泡,父元素可以監聽到子元素上事件的觸發
4、圖片懶加載和預加載
- 預加載:提前加載圖片,當用戶需要查看時直接從緩存渲染
- 懶加載:懶加載的主要目的是作為服務器前端的優化,減少請求數或延遲請求數
- 懶加載對服務器前端有一定緩解壓力的作用,預加載會增加服務器前端的壓力
5、JS的new操作符做了哪些事情
- 創建一個空對象
- 將對象的原型設置為構造函數的原型
- 將構造函數的this指向這個新對象
6、JS的各種位置
- clientHeight:表示可視區域的高度,不包含border和滾動條
- offsetHeight:表示可視區域的高度,包括border和滾動條
- scrollHeight:表示所有區域高度,包含了因為滾動被隱藏的部分
- clientTop:表示邊框border的厚度,在未指定的情況下一般為零
- scrollTop:滾動后被隱藏的高度獲取對象相對于由offsetParent屬性指定的父坐標距離頂端的高度
7、異步加載JS的方法
- defer:defer是在瀏覽器加載完之后執行JS代碼,并按照加載順序執行代碼
- async:async是在加載完之后立即執行,特點是亂序執行,因為每個JS代碼加載時間不同
8、如何理解前端模塊化
就是把復雜的文件編程一個一個獨立的模塊,比如JS文件分成獨立的模塊有利于重用和維護,這就會有模塊間的依賴問題
所以有了commonJS規范,AMD,CMD規范等等,以及用于JS打包的工具webpack
- CommonJS:開始于服務器端模塊化,同步定義模塊化,每個模塊都是一個獨立作用域,模塊輸出modules.exports模塊加載require()引入模塊
- AMD:異步模塊定義主要用于解決兩個問題:被依賴的文件要早加載,加載時瀏覽器停止渲染,文件越多,頁面失去響應的時間越長
9、JS監聽對象屬性的改變
- 在ES5中可以通過Object.defineProperty來實現已有屬性的監聽
- 在ES6中可以通過Proxy來實現
Object.defineProperty(obj, prop, descriptor)
- obj需要定義屬性的對象
- prop需要定義的屬性
- descriptor屬性描述符
10、事件模型,DOM0級和DOM2級有什么區別,DOM分級
- JS DOM事件流存在三個階段:事件捕獲階段、處于目標階段、事件冒泡階段
- DOM節點添加事件監聽函數addEventListener(事件名,觸發函數,布爾值)
- 布爾值為true監聽添加在捕獲階段,布爾值為false監聽添加在冒泡階段
事件模型常用方法:
- event.stopPropagation:阻止捕獲和冒泡階段中,當前事件的進一步傳播
- event.preventDefault:取消該事件而不停止事件的進一步傳播
11、跨域
跨域問題是由瀏覽器的安全限制-同源策略引起的。兩個地址協議域名和端口都相同則是同域,有一個不同就是不同域。瀏覽器想要執行不同域的瀏覽器的腳本就要進行跨域操作。注意跨域并不是指請求發不出去而是發出去了,并且服務器接收到了并返回數據,只不過結果被瀏覽器攔截了。
以下三種方式解決跨域問題:
12、CORS(跨來源資源共享)
**原理:**簡單來說就是瀏覽器和服務器利用自定義的http頭部進行溝通,從而決定請求或者響應是否成功。服務器端對于CORS的支持,主要就是通過設置Access-Control-Allow-Origin來進行的,如果瀏覽器檢測到相應的控制就允許跨域。只需在后臺中加上響應頭來允許跨域。瀏覽器將CORS跨域請求分為簡單請求(get,post,head)和非簡單請求(其他方法)。
- 簡單請求的話瀏覽器直接發送CORS請求,在頭信息增加一個Origin字段說明本次請求的來源。服務器根據這個值判斷是否同意請求。響應頭中的Access-Control-Allow-Origin取值決定是否同意請求。
- 對于非簡單請求需要先發送預檢請求,詢問服務器支持的HTTP方法,請求中包含Origin
13、反向代理解決跨域
服務器與服務器之間不存在跨域問題,所以通過設置本地服務器去訪問目標服務器,然后本地服務器返回數據不存在跨域
14、JSONP解決跨域
原理就是src屬性是不存在跨域問題的,可以自定義一個script標簽,然后手動設置src屬性,實現跨域。但是缺點是只能發送get請求
15、XSS(跨站腳本攻擊)
簡單來說就是在用戶的瀏覽器中執行了攻擊者制定的腳本。用戶執行攻擊者的腳本,將自己的cookie發送到了攻擊者的網站。攻擊者獲得用戶信息,發送到了攻擊者自己的網站
XSS防御機制:對輸入進行過濾,對輸出進行編碼。對提交的所有內容進行過濾,過濾掉會導致腳本執行的相關內容;在輸出數據之前對潛在威脅的字符進行編碼、轉義;對cookie設置HttpOnly屬性,在瀏覽器的document對象中就看不到cookie了,JS腳本就不能讀取到cookie,但瀏覽器還是能正常使用cookie
16、CSRF(跨站請求偽造)
簡單來說就是攻擊者盜用受害者的身份,以受害者的名義發送惡意請求
原理:用戶登錄可信任網站A,登錄狀態下訪問了攻擊者網站B,網站B強制用戶給網站A發送請求,執行網站B的惡意代碼
CSRF防御機制:
- 1.驗證Http Referer字段:簡單來說這個字段就是請求頭中記錄請求來源地址的,服務器可以通過對Referer字段進行驗證來判斷發送請求的網站是否合法
- 2.在請求地址添加token: 用戶發送請求的驗證信息都存在于cookie,攻擊者利用用戶的cookie來通過安全驗證。所以只要在cookie之外,http請求中加入一個隨機的token,并在服務器端設置攔截器驗證token。token不正確就可能是CSRF攻擊
- 3.在http頭中自定義屬性并驗證:并不是把token以參數的形式置于http請求中,而是放到http頭中自定義的屬性中。通過XMLHttpRequest這個類,可以一次性給所有該類請求加上csrftoken這個Http頭屬性,并把token值放入其中。同時通過XMLHttpRequest請求的地址不會被記錄到瀏覽器的地址欄
**token:**token可以在用戶登錄后產生并存放在session中,然后每次請求時把token從session中拿出,與請求中的token進行比對。難點在于如何把token以參數的形式加入請求。對于get請求,token將附在請求地址之后。對于post請求來說,要在form最后加上token相關的。但是有一個缺點就是難以保證token本身的安全,比如一些支持用戶自己發表內容的網站。黑客可以在上面發送個人網站的網址就可以獲得token
17、Web worker
Web worker為JS創造了多線程的環境,允許主線程創建worker線程,并分配一些任務給后者,主線程運行的同時,worker線程在后臺運行。worker存在于一個不同的線程,它和主線程互不干擾,可以把處理大量數據的邏輯計算放在worker里,主線程就會很流暢。worker線程一旦新建成功,就會始終運行,不會被主線程上的活動打斷。有利于隨時響應主線程的通信。但是這也造成worker比較消耗資源,所以一旦使用完就要關閉。
18、防抖和節流
- 防抖:問題在于快速點擊按鍵時,無論點擊多快,只要點了一次,日志就打印一次,想要在快速點擊的過程中只讓最后一次產生效果,就要防抖
- 節流:在多次點擊的情況下保證每隔一段固定時間執行一次點擊事件觸發的函數
19、var let const區別
var一般用于聲明變量,是函數作用域的,但是因為var存在變量提升機制,所以在ES6新增了let和const;let和const都是塊級作用域的,不存在變量提升機制,因為暫時性死區的特性,let在使用前必須進行聲明。而const必須 初始化,一般用來聲明常量。另外const定義的是一個對象,存的僅僅是對象的引用。
20、判斷是否同域
- http://www.a.com/a.js http://www.a.com/b.js 同域
- http://www.a.com/lab/a.js http://www.a.com/script/b.js 同域,文件夾不同
- http://www.a.com:8000/a.js http://www.a.com/b.js 不同域,端口不同
- http://www.a.com/a.js https://www.a.com/b.js 不同域,協議不同
- http://www.a.com/a.js http://script.a.com/b.js 不同域,主域相同,子域不同
- http://www.a.com/a.js http://a.com/b.js 不同域,不同二級域名
parseInt()使用方法
parseInt(string, radix) 接受兩個參數,第一個參數時要解析的字符串,第二個參數是要轉化的進制,要點如下:
- 只返回字符串中第一個數字
- 允許前導和尾隨空格
- 如果第一個字符不能轉換為數字就輸出NaN
Math.toFixed/Math.round/toPrecision
- Math.toFixed(n) n是幾就保留幾位小數
- Math.round(1.2)//1 四舍五入到最近的整數
- 13.45toPrecision(3)//13.4 返回指定長度的數值字符串
||和&&的判定規則
|| 前面的值為true,返回true
|| 前面的值為false,返回后面的
&& 前面的值為true,返回后面的
&& 前面的值為false,返回false
scrollWidth、offsetWidth、clientWidth
- scrollWidth 內容+內邊距+溢出尺寸
- offsetWidth 內容+內邊距+邊框+滾動條
- clientWidth 內容+內邊距
- scrollWidth 網頁正文全文寬
- scrollHeight 網頁正文全文高
- scrollTop 網頁被卷去的高
- scrollLeft 網頁被卷去的左
document對象和window對象的區別
- 指代不同:document對象代表給定瀏覽器窗口中的HTML文檔。window表示瀏覽器中打開的窗口
- 作用不同:使用document可以對html文檔進行檢查修改或添加內容并處理該文檔內部的事件;瀏覽器會為 HTML 文檔創建一個 window 對象,并為每個框架創建一個額外的 window 對象。
- 使用方式不同:document對象可以通過window對象的document屬性引用或直接引用。而window對象沒有應用于window對象的公開標準。
前端性能優化方案
1、減少http請求數
一個完整的http請求需要進行DNS解析、tcp三次握手建立連接、發送請求、服務端響應處理、客戶端解析等一系列步驟。如果HTTP請求過多肯定會影響性能,可以將多個小文件合并成一個大文件減少請求數量
2、使用HTTP2
HTTP2有二進制分幀、首部壓縮、服務端推送、多路復用、請求優先級等優點
3、靜態資源使用CDN
CDN可以根據網絡流量、各節點連接數、負載情況、用戶距離、響應時間等將用戶請求重新導向至離用戶最近的服務節點上。可以使用戶就近得到內容,解決網絡擁擠的情況,提高響應速度
4、CSS放在文件頭部,JS放在文件底部
JS的加載會阻塞頁面的渲染,JS放在前面會使頁面空白。而CSS放在頭部是為了防止出現沒有CSS的頁面狀態。會很丑陋
5、善用緩存,不重復加載資源
強緩存、協商緩存
6、減少重繪和重排
- 改變樣式屬性時盡量使用class減少與DOM的交互
- 頻繁的修改可以現讓元素脫離文檔流,操作完之后再改回去,這樣只會觸發一次回流。絕對定位或者display:none
- 將原始元素拷貝到一個獨立的節點,操作完之后覆蓋之前的