HTML
CSS
定位
flex布局
display
css3新屬性
- css3的邊框-border-radius–box-shadow–border-image
背景 background-size–background-origin :屬性規定背景圖片的定位區域。文字效果:text-shadow:在 CSS3 中,text-shadow 可向文本應用陰影。
javaScript
1.Javascript 的作用域和作用域鏈
- 作用域: 作用域是定義變量的區域,它有一套訪問變量的規則,這套規則來管理瀏覽器引擎如何在當前作用域以及嵌套的作用域中根據變量(標識符)進行變量查找。
- 作用域鏈: 作用域鏈的作用是保證對執行環境有權訪問的所有變量和函數的有序訪問,通過作用域鏈,我們可以訪問到外層環境的變量和 函數。
作用域鏈的本質上是一個指向變量對象的指針列表。變量對象是一個包含了執行環境中所有變量和函數的對象。作用域鏈的前 端始終都是當前執行上下文的變量對象。全局執行上下文的變量對象(也就是全局對象)始終是作用域鏈的最后一個對象。
當我們查找一個變量時,如果當前執行環境中沒有找到,我們可以沿著作用域鏈向后查找。
2.null 和 undefined 的區別?
- 首先 Undefined 和 Null 都是基本數據類型,這兩個基本數據類型分別都只有一個值,就是 undefined 和 null。
- undefined 代表的含義是未定義, null 代表的含義是空對象(其實不是真的對象,請看下面的注意!)。一般變量聲明了但還沒有定義的時候會返回 undefined,null 主要用于賦值給一些可能會返回對象的變量,作為初始化。
- undefined 在 js 中不是一個保留字,這意味著我們可以使用 undefined 來作為一個變量名,這樣的做法是非常危險的,它 會影響我們對 undefined 值的判斷。但是我們可以通過一些方法獲得安全的 undefined 值,比如說 void 0。
- 當我們對兩種類型使用 typeof 進行判斷的時候,Null 類型化會返回 “object”,這是一個歷史遺留的問題。當我們使用雙等 號對兩種類型的值進行比較時會返回 true,使用三個等號時會返回 false。
3.js的數據類型
- JavaScript一共有8種數據類型,其中有7種基本數據類型:Undefined、Null、Boolean、Number、String、Symbol(es6新增,表示獨一無二的值)和BigInt(es10新增);
- 1種引用數據類型——Object(Object本質上是由一組無序的名值對組成的)。里面包含 function、Array、Date等。JavaScript不支持任何創建自定義類型的機制,而所有值最終都將是上述 8 種數據類型之一。
- 原始數據類型:直接存儲在棧(stack)中,占據空間小、大小固定,屬于被頻繁使用數據,所以放入棧中存儲。
- 引用數據類型:同時存儲在棧(stack)和堆(heap)中,占據空間大、大小不固定。引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體。
4. js的數據類型的轉換
在 JS 中類型轉換只有三種情況,分別是:
- 轉換為布爾值(調用Boolean()方法)
- 轉換為數字(調用Number()、parseInt()和parseFloat()方法)
- 轉換為字符串(調用.toString()或者String()方法)
5.this的指向
- 全局作用域中 this指向windows
- 函數環境作用域 函數由誰調用,this就指向誰
- 對象中的方法函數調用 this指向該方法所屬的對象
- 在構造函數中this終究指向新對象
- 通過事件綁定的方法 this指向事件綁定的方法
- 定時器 因為是異步操作所以this指向的是windows
- 箭頭函數 a. 箭頭函數的this是在定義函數時綁定的, 不是在執行過程中綁定的
b. 箭頭函數中的this始終指向父級對象
c. 所有 call() / apply() / bind() 方法對于箭頭函數來說只是傳入參數, 對它的 this 毫無影響。 - 更改this指向
每個Function構造函數的原型prototype, 都有方法
call(), apply(), bind()
6.什么是高階函數?
- 高階函數只是將函數作為參數或返回值的函數。
7.什么是函數式編程? JavaScript的哪些特性使其成為函數式語言的候選語言?
- 函數式編程(通常縮寫為FP)是通過編寫純函數,避免共享狀態、可變數據、副作用 來構建軟件的過程。數式編程是聲明式 的而不是命令式 的,應用程序的狀態是通過純函數流動的。與面向對象編程形成對比,面向對象中應用程序的狀態通常與對象中的方法共享和共處。
- 函數式編程是一種編程范式 ,這意味著它是一種基于一些基本的定義原則(如上所列)思考軟件構建的方式。當然,編程范式的其他示例也包括面向對象編程和過程編程。
- 函數式的代碼往往比命令式或面向對象的代碼更簡潔,更可預測,更容易測試 - 但如果不熟悉它以及與之相關的常見模式,函數式的代碼也可能看起來更密集雜亂,并且 相關文獻對新人來說是不好理解的。
8.ES6 模塊與 CommonJS 模塊、AMD、CMD 的差異。
- 1.CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。CommonJS 模塊輸出的是值的,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。ES6 模塊的運行機制與 CommonJS 不一樣。JS 引擎對腳本靜態分析的時候,遇到模塊加載命令 import,就會生成一個只讀引用。等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。
- 2.CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。CommonJS 模塊就是對象,即在輸入時是先加載整個模塊,生成一個對象,然后再從這個對象上面讀取方法,這種加載稱為“運行時加載”。而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成
9.js創建對象的幾種方式
- (1)第一種是以原型鏈的方式來實現繼承,但是這種實現方式存在的缺點是,在包含有引用類型的數據時,會被所有的實例對象所共享,容易造成修改的混亂。還有就是在創建子類型的時候不能向超類型傳遞參數。
- (2)第二種方式是使用借用構造函數的方式,這種方式是通過在子類型的函數中調用超類型的構造函數來實現的,這一種方法解決了不能向超類型傳遞參數的缺點,但是它存在的一個問題就是無法實現函數方法的復用,并且超類型原型定義的方法子類型也沒有辦法訪問到。
- (3)第三種方式是組合繼承,組合繼承是將原型鏈和借用構造函數組合起來使用的一種方式。通過借用構造函數的方式來實現類型的屬性的繼承,通過將子類型的原型設置為超類型的實例來實現方法的繼承。這種方式解決了上面的兩種模式單獨使用時的問題,但是由于我們是以超類型的實例來作為子類型的原型,所以調用了兩次超類的構造函數,造成了子類型的原型中多了很多不必要的屬性。
- (4)第四種方式是原型式繼承,原型式繼承的主要思路就是基于已有的對象來創建新的對象,實現的原理是,向函數中傳入一個對象,然后返回一個以這個對象為原型的對象。這種繼承的思路主要不是為了實現創造一種新的類型,只是對某個對象實現一種簡單繼承,ES5 中定義的 Object.create() 方法就是原型式繼承的實現。缺點與原型鏈方式相同。
- (5)第五種方式是寄生式繼承,寄生式繼承的思路是創建一個用于封裝繼承過程的函數,通過傳入一個對象,然后復制一個對象的副本,然后對象進行擴展,最后返回這個對象。這個擴展的過程就可以理解是一種繼承。這種繼承的優點就是對一個簡單對象實現繼承,如果這個對象不是我們的自定義類型時。缺點是沒有辦法實現函數的復用。
- (6)第六種方式是寄生式組合繼承,組合繼承的缺點就是使用超類型的實例做為子類型的原型,導致添加了不必要的原型屬性。寄生式組合繼承的方式是使用超類型的原型的副本來作為子類型的原型,這樣就避免了創建不必要的屬性。
ES6新語法
Vue
Vue是什么
- 低耦合。視圖(View)可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。
- 可重用性。你可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯。
獨立開發。開發人員可以專注于業務邏輯和數據的開發(ViewModel),設計人員可以專注于頁面設計。 - 可測試。界面素來是比較難于測試的,而現在測試可以針對ViewModel來寫。
什么是MVVM
- MVVM是Model-View-ViewModel的縮寫。MVVM是一種設計思想。Model 層代表數據模型,也可以在Model中定義數據修改和操作的業務邏輯;View 代表UI 組件,它負責將數據模型轉化成UI 展現出來,ViewModel 是一個同步View 和 Model的對象。
- 在MVVM架構下,View 和 Model 之間并沒有直接的聯系,而是通過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 因此View 數據的變化會同步到Model中,而Model 數據的變化也會立即反應到View 上。
- ViewModel 通過雙向數據綁定把 View 層和 Model 層連接了起來,而View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發者只需關注業務邏輯,不需要手動操作DOM, 不需要關注數據狀態的同步問題,復雜的數據狀態維護完全由 MVVM 來統一管理。
Vue的生命周期
- 創建、掛載、更新、卸載
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
beforecreate : 可以在這加個loading事件,在加載實例時觸發
created : 初始化完成時的事件寫在這里,如在這結束loading事件,異步請求也適宜在這里調用
mounted : 掛載元素,獲取到DOM節點
updated : 如果對數據統一處理,在這里寫上相應函數
beforeDestroy : 可以做一個確認停止事件的確認框
nextTick : 更新數據后立即操作dom
Vue和jQuery的區別
- jQuery是通過選擇器操作dom對象,進行賦值、取值、事件綁定等操作;
- vue則是通過vue對象將數據和view分離,不需要引用dom對象,使用MVVM。
- mvc和mvvm其實區別并不大。都是一種設計思想。主要就是mvc中Controller演變成mvvm中的viewModel。mvvm主要解決了mvc中大量的DOM 操作使頁面渲染性能降低,加載速度變慢,影響用戶體驗。
Vue中的攔截器
- 對特定的http請求或響應消息或請求頭進行驗證,攔截不合法的http交互以保證web環境的安全。
- 分為兩種:路由攔截、請求攔截
Vue的雙向數據綁定原理
- 1.核心點: Object.defineProperty 2.默認 Vue 在初始化數據時,會給 data 中的屬性使用 Object.defineProperty 重新定義所有屬 性,當頁面取到對應屬性時。會進行依賴收集(收集當前組件的watcher) 如果屬性發生變化會通 知相關依賴進行更新操作。
Vue如何做的響應式
- “響應式”,是指當數據改變后,Vue 會通知到使用該數據的代碼。例如,視圖渲染中使用了數據,數據改變后,視圖也會自動更新。
- Vue 的響應式,核心機制是 觀察者模式。
數據是被觀察的一方,發生改變時,通知所有的觀察者,這樣觀察者可以做出響應 - 每個組件實例都對應一個 watcher 實例,它會在組件渲染的過程中把“接觸”過的數據屬性記錄為依賴。之后當依賴項的 setter 觸發時,會通知 watcher,從而使它關聯的組件重新渲染。
ajax請求放在哪個生命周期中
- 在created的時候,視圖中的 dom 并沒有渲染出來,所以此時如果直接去操 dom 節點,無法找到相 關的元素
- 在mounted中,由于此時 dom 已經渲染出來了,所以可以直接操作 dom 節點
- 一般情況下都放到 mounted 中,保證邏輯的統一性,因為生命周期是同步執行的, ajax 是異步執行的,服務端渲染不支持mounted方法,所以在服務端渲染的情況下統一放到created中
什么是webpack
- Webpack 是一個前端資源加載/打包工具。它將根據模塊的依賴關系進行靜態分析,然后將這些模塊按照指定的規則生成對應的靜態資源。
entry: 入口,定義整個編譯過程的起點
output: 輸出,定義整個編譯過程的終點
module: 定義模塊module的處理方式
plugins:插件,對編譯完成后的內容進行二度加工
resolve.alias 定義模塊的別名
Vue是如何解析模板的
- 首先模板最終必須轉換成js代碼,因為:
第一個模板有邏輯,有v-if,v-for。必須用js才能實現(圖靈完備的語言)
第二個模板要轉化為html渲染頁面,必須用js才能實現
因此,模板最終要轉換成一個js函數(render函數,也就是渲染函數)這個render函數返回vode對象,后面其他函數(update)將vnode渲染成html。
Vue的常用指令
- v-if:判斷是否隱藏;v-for:數據循環;v-bind:class:綁定一個屬性;v-model:實現雙向綁定
v-if和v-show的區別
- v-show指令是通過修改元素的display的CSS屬性讓其顯示或者隱藏
- v-if指令是直接銷毀和重建DOM達到讓元素顯示和隱藏的效果
v-for中key的作用
- 當有相同標簽名的元素切換時,需要通過 key 特性設置唯一的值來標記以讓 Vue 區分它們,否則 Vue 為了效率只會替換相同標簽內部的內容。
v-if和v-for能不能同時使用
- 當 Vue 處理指令時,v-for 比 v-if 具有更高的優先級,通過v-if 移動到容器元素,不會再重復遍歷列表中的每個值。取而代之的是,我們只檢查它一次,且不會在 v-if 為否的時候運算 v-for。
計算屬性跟偵聽器的區別用途
- 計算屬性用來聲明式的描述一個值依賴了其他的值。
- watch監聽自定義的變量,當變量的值發生變化時,調用對應的方法
Vue中的delete和vue.delete的區別
- delete只是把刪除的元素變成了empty / undefined其他的元素的鍵值還是不變。
- Vue.delete直接刪除了數據,改變了數組的鍵值。
VueX的作用
- (1)vuex是什么?怎么使用?哪種功能場景使用它?vue框架中狀態管理。在main.js引入store,注入。新建一個目錄store,…… export 。場景有:單頁應用中,組件之間的狀態。音樂播放、登錄狀態、加入購物車
- (2)vuex有哪幾種屬性?
有五種,分別是 State、 Getter、Mutation 、Action、 Module
vuex的State特性
A、Vuex就是一個倉庫,倉庫里面放了很多對象。其中state就是數據源存放地,對應于一般Vue對象里面的data
B、state里面存放的數據是響應式的,Vue組件從store中讀取數據,若是store中的數據發生改變,依賴這個數據的組件也會發生更新
C、它通過mapState把全局的 state 和 getters 映射到當前組件的 computed 計算屬性中 - vuex的Getter特性
A、getters 可以對State進行計算操作,它就是Store的計算屬性
B、 雖然在組件內也可以做計算屬性,但是getters 可以在多組件之間復用
C、 如果一個狀態只在一個組件內使用,是可以不用getters
vuex的Mutation特性
Action 類似于 mutation,不同在于:Action 提交的是 mutation,而不是直接變更狀態;Action 可以包含任意異步操作。 - (3)不用Vuex會帶來什么問題?
可維護性會下降,想修改數據要維護三個地方;
可讀性會下降,因為一個組件里的數據,根本就看不出來是從哪來的;
增加耦合,大量的上傳派發,會讓耦合性大大增加,本來Vue用Component就是為了減少耦合,現在這么用,和組件化的初衷相背。
Vue中組件通訊
- 父組件與子組件傳值
父組件通過標簽上面定義傳值
子組件通過props方法接受數據 - 子組件向父組件傳遞數據
子組件通過$emit方法傳遞參數
Vue中的組件緩存機制
- keep-alive 是 Vue 的內置組件,當它包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。和 transition 相似,keep-alive 是一個抽象組件:它自身不會渲染成一個 DOM 元素,也不會出現在父組件鏈中。
- Props
include - 字符串或正則表達式。只有名稱匹配的組件會被緩存。
exclude - 字符串或正則表達式。任何名稱匹配的組件都不會被緩存。
max - 數字。最多可以緩存多少組件實例。 - 生命周期函數
- activated
在 keep-alive 組件激活時調用
該鉤子函數在服務器端渲染期間不被調用 - deactivated
在 keep-alive 組件停用時調用
該鉤子在服務器端渲染期間不被調用
- activated
- 被包含在 keep-alive 中創建的組件,會多出兩個生命周期的鉤子: activated 與 deactivated
- 用 keep-alive 會將數據保留在內存中,如果要在每次進入頁面的時候獲取最新的數據,需要在 activated 階段獲取數據,承擔原來 created 鉤子函數中獲取數據的任務。
- 注意: 只有組件被 keep-alive 包裹時,這兩個生命周期函數才會被調用,如果作為正常組件使用,是不會被調用的,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,這兩個鉤子函數依然不會被調用!另外,在服務端渲染時,此鉤子函數也不會被調用。
route和router的區別
v-if 和 v-show 的區別
- v-show指令是通過修改元素的display的CSS屬性讓其顯示或者隱藏
- v-if指令是直接銷毀和重建DOM達到讓元素顯示和隱藏的效果
網絡請求
ajax是什么
- ajax 即 “Asynchronous Javascript And XML”(異步 JavaScript 和 XML),是指一種創建交互式、快速動態網頁應用的技術。早期只有同步的方式,多個請求,只能順序執行,只能等待執行。有了ajax異步技術,可以無需等待上一個請求執行完成,就可以直接發起請求。服務端返回后,ajax通過回調技術通知客戶端程序,把響應的結果傳遞給用戶事先寫好的回調函數。通過在后臺與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁進行局部更新,提升網頁的效率,用戶無需等待頁面的刷新,嗖的一下內容就變化了。改變原有整個頁面刷新,造成頁面晃眼的現象。所以這項技術一出現,就得到業界的推崇。
ajax請求時get和post的區別?
-
get:從服務器上獲取數據,傳送數據量小,安全性低,請求會被緩存,緩存是針對URL進行緩存的,get請求參數直接加在URL地址后面,一種參數組合就會產生一種URL的緩存,重復的請求結果是相同的;
-
post:向服務器發送數據;傳送數據量大,請求不會被緩存,參數封裝在二進制的數據體中,服務器也不會記錄參數,相對安全,所以涉及用戶隱私的數據都要用post傳送;
-
http狀態碼
-
什么叫跨域
跨域是指一個域下的文檔或腳本試圖去請求另一個域下的資源,這里跨域是廣義的
為什么會出現跨域(同源策略)
同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源
如何解決跨域問題
-
通過jsonp跨域
通常為了減輕web服務器的負載,我們把js、css,img等靜態資源分離到另一臺獨立域名的服務器上,在html頁面中再通過相應的標簽從不同域名下加載靜態資源,而被瀏覽器允許,基于此原理,我們可以通過動態創建script,再請求一個帶參網址實現跨域通信。
-
document.domain + iframe跨域
此方案僅限主域相同,子域不同的跨域應用場景。 實現原理:兩個頁面都通過js強制設置document.domain為基礎主域,就實現了同域。
-
location.hash + iframe
實現原理: a欲與b跨域相互通信,通過中間頁c來實現。三個頁面,不同域之間利用iframe的location.hash傳值,相同域之間直接 js訪問來通信。 具體實現:A域:a.html -B域:b.html -> A域:c.html,a與b不同域只能通過hash值單向通信,b與c也不同域也只能單向通信,但c與a同域,所以c可通過parent.parent訪問a頁面所有對象。
-
window.name + iframe跨域
window.name屬性的獨特之處:name值在不同的頁面(甚至不同域名)加載后依舊存在,并且可以支持非常長的 name 值(2MB)。
-
postMessage跨域
-
跨域資源共享(CORS)
-
nginx代理跨域
-
nodejs中間件代理跨域
-
WebSocket協議跨域
綜合開發問題
- 本地存儲的區別
你有哪些性能優化的方法?
- 減少http請求次數:CSS Sprites, JS、CSS源碼壓縮、圖片大小控制合適;網頁Gzip,CDN托管,data緩存 ,圖片服務器。
- 前端模板 JS+數據,減少由于HTML標簽導致的帶寬浪費,前端用變量保存AJAX請求結果,每次操作本地變量,不用請求,減少請求次數
- 用innerHTML代替DOM操作,減少DOM操作次數,優化javascript性能。
- 當需要設置的樣式很多時設置className而不是直接操作style。
- 少用全局變量、緩存DOM節點查找的結果。減少IO讀取操作。
- 避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性)。
- 圖片預加載,將樣式表放在頂部,將腳本放在底部 加上時間戳。