一、MVVM和MVC的區別?
(1)MVC中M表示Model模型,V表示view視圖, C表示controller控制器;MVVM中M表示model模型,V表示view視圖,VM表示viewmodel;
(2)MVC的見解是界面上的每一個變化都是一個事件,咱們只須要針對每一個事件來寫一堆代碼,來把用戶的輸入轉換成model裏的對象,而這段轉換的代碼就是controller。簡言之,MVC是單向通訊,view和model必須經過controller來承上啓下。
MVVM的見解是我給view裏面的各類控件也定義一個對應的數據對象,只須要修改這個數據對象,view裏面顯示的內容就會自動更新,而view裏作了任何操做,這個數據對象也會跟着更新。這就是所謂的雙向數據綁定。viewmodel就是與界面view對應的model,由於數據庫結構每每是不能直接和界面控件一一對應,因此咱們須要再定義一個數據對象專門對應view上的控件,而viewmodel的職責就是把model對象封裝成能夠顯示和接受輸入的界面數據對象。簡單來講,viewmodel就是view和model的鏈接器,view和model經過viewmodel實現雙向綁定。
(3)MVC各部分通訊以下:
view傳送指令到controller,controller完成業務邏輯後,要求model改變狀態,model將新的數據發送到view,用戶獲得反饋。
MVVM各部分通訊以下:
各部分之間的通訊都是雙向的,view與model不發生聯繫,而經過viewmodel傳遞,view很是薄,不部署任何業務邏輯,稱爲‘被動視圖’,即沒有任何主動性,而viewmodel很是厚,全部的邏輯都部署在那裏。
MVVM和MVP的主要區別在於,MVVM採用的是雙向綁定,view的變更自動反映在viewmodel上,反之亦然。angular、ember、vue都採用這種模式。
二、Mobx和Redux的區別?
(1)Mobx的優點來源於可變數據和可觀察數據;Redux的優點來源於不可變數據。
(2)redux和mobx都沒有使用傳統的mvc/mvvm形式,而是採用flux的結構,action處理請求,而後將請求dispatch到store中,這樣設計也十分契合react單向數據流的概念。二者使用flux結構也略有不一樣,mobx在store和view中處理數據是使用雙向綁定。雙向綁定無疑會增長性能消耗,可是mobx在雙向綁定的同時禁掉了react自身的刷新。
(3)框架體驗,開發效率,學習成本方面mobx更好
三、angular和vue的區別?
(1)數據綁定
angular和vue都是雙向綁定,可是vue在不一樣組件之間強制使用單項數據流,這樣使應用中的數據流更加清晰易懂。
(2)指令和組件
在vue中指令和組件分得很清晰。指令只封裝dom操做,而組件表明自給自足獨立的單元,就是有本身的視圖和數據邏輯。
在angular中,每件事都由指令來作,而組件只是一種特殊的指令。
四、axios
(1)處理併發請求助手函數(兩個請求都完成才執行操做)
axios.all(iterable),axios.spread(callback)
function getUserAccount() {
return axios.get('/user/123456')
}
function getUserPermissions() {
return axios.get('/user/123456/permissions')
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function(acct, perms) {
// 兩個請求如今都執行完成
}))
(2)攔截器:在請求或響應被then或者catch處理以前攔截他們
// 添加請求攔截器
axios.interceptors.request.use(function(config) {
// 在發送請求前作些什麼
return config
}, function(error) {
// 對請求錯誤作些什麼
return Promise.reject(error)
});
// 添加響應攔截器
axios.interceptors.response.use(function(response){
// 對響應數據作些什麼
return response
}, function(error) {
// 對響應錯誤作些什麼
return Promise.reject(error)
})
若是想在稍後移除攔截器:
var myInterceptor = axios.interceptors.request.use(function(){});
axios.interceptors.request.eject(myInterceptor);
(3)、使用cancel token取消請求
可使用CancelToken.source工廠方法建立cancel token:
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/123456', {
cancelToken: source.token
}).catch(function(throw) {
if (axios.isCancel(throw)) {
console.log('request cancel', throw.message)
} else {
// 處理錯誤
}
})
// 取消請求,message參數是可選的
source.cancel('Operation canceled by the user');
還能夠經過傳遞一個executor函數到CancelToken的構造函數來建立cancelToken:
var CancelToken = axiox.CancelToken;
var cancel;
axios.get('/user/123', {
cancelToken: new CancelToken(function executor(c) {
// executor函數接收一個cancel做爲參數
cancel = c
})
})
// 取消請求
cancel();
可使用同一個cancel token取消多個請求。
五、promise
promise是爲了解決回調地獄的問題,是異步編程的一種解決方案。簡單來講,它就是一個容器,裏面存放着某個將來纔會結束的事件(一般是一個異步操做的結果)。從語法上說,他就是一個對象(構造函數),從它能夠獲取異步操做的消息。它提供統一的API,各類異步操做均可以用一樣的方法進行處理。
promise的原理並不難, 它有三個狀態,分別是pending、fulfilled、rejected。pending是對象建立後的初始狀態,當對象fulfill(成功)時變爲fulfilled,當對象reject(失敗)時變爲rejected。且只能從pending變爲fulfilled或rejected,而不能逆向或者從fulfilled變爲rejected或者從rejected變爲fulfilled。
(1)promise.all()方法是等全部異步操做都執行完畢後才執行then回調
(2)promise.race()
race就是賽跑的意思,因此它是指只要有一個異步操做執行完成就會馬上執行then回調,其餘沒有執行完成的異步操做仍然在繼續執行,而不是中止。
(1)less和sass在語法上有些共性:(8個)
-
混合:class中的class(將一個定義好的class A引入到另外一個class B中,從而簡單實現class B繼承了class A的全部屬性)
-
參數混合: 能夠將class像函數的參數同樣進行傳遞
-
嵌套規則:class中嵌套class,從而減小重複的代碼(在一個選擇器中嵌套另外一個選擇器來實現繼承)
-
運算: css中的數學計算(在css中使用加減乘除進行數學計算,主要運用於屬性值和顏色的運算)
-
顏色功能:能夠編輯你的顏色(顏色的函數運算,顏色會被先轉化成HSL色彩空間,而後在通道級別操做)
-
命名空間: 樣式分組,從而方便被調用(將一些變量或者混合模塊打包封裝,更好的組織css和屬性集的重複使用)
-
做用域:局部修改樣式(先從本地查找變量或者混合模塊,若是沒有找到的話就會去父級做用域中查找,直到找到爲止,這一點和其餘程序語言的做用域很是的類似)
-
js表達式:在css樣式中使用js表達式賦值(在less或者sass文件中可使用js的表達式,用來賦值)
(2)less和sass之間的區別:
他們之間的主要區別在於實現方式不一樣,less是基於js運行,因此less是在客戶端處理;sass是基於ruby的,是在服務器端處理的。
不少開發者不選擇less是由於less輸出修改過的css到瀏覽器須要依賴於js引擎,而js引擎須要額外的時間來處理代碼。關於這個有不少種方式,我選擇的是隻在開發環節使用less。一旦開發完成,我就複製粘貼less輸出到一個壓縮器,而後到一個單獨的css文件來替代less文件。另外一種方式是使用less app來編譯和壓縮你的less文件。兩種方式都將是最小化你的樣式輸出,從而避免因爲用戶的瀏覽器不支持js而可能引發的任何問題。
七、es6
(1)、新增了let和const命令
let用來聲明變量,用法相似var,可是所聲明的變量只在let命令所在的代碼塊內有效,const通常用做聲明常量,只聲明不賦值就會報錯;
let和const都不存在變量提高,也就是說只能在聲明後使用,不然報錯;
let和const都存在‘暫時性死區’,就是說只要在塊級做用域內存在const或者let命令聲明的變量,那麼它聲明的變量就綁定這個區域,再也不受到外部的影響,這就叫‘暫時性死區’;
let和const不容許在相同做用域內重複聲明同一個變量;
let和const其實是爲js新增了塊級做用域。
(2)、對字符串進行了擴展
好比模板字符串:
模板字符串是加強版的字符串,用反引號(`)標識,它能夠看成普通字符串使用,也能夠用來定義多行字符串,或者在字符串中嵌入變量。模板字符串中嵌入變量,須要將變量名寫在${}中。
(3)、箭頭函數
箭頭函數在定義以後,this的指向就不會發生改變了,不管用什麼方式調用它,this的指向都不會改變。由於:
函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象;
不能夠看成構造函數,也就是說不可使用new命令,不然報錯;
不可使用arguments對象,該對象在函數體內不存在,若是要用,能夠用rest參數代替;
不可使用yield命令,所以箭頭函數不能用做Generator函數。
eg:
(4)promise
(5)變量的解構賦值
ES6容許按照必定的模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構。本質上,這種寫法屬於‘模式匹配’,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。
對象的解構與數組有一個重要的不一樣,數組元素是按照次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
解構賦值容許指定默認值:
還有不少。。。。。
八、cookie、sessionStorage、localStorage異同點
(1)數據生命週期
cookie生成時就會被指定一個maxAge值,這就是cookie的生存週期,在這個期間內cookie都有效,默認是瀏覽器關閉失效;
sessionStorage頁面會話期間可用;
localStorage除非數據被清除,不然一直存在。
(2)存放數據大小
cookie4k左右,由於每次http請求,都會攜帶cookie;
sessionStorage和localStorage通常5M或者更大;
(3)與服務器通訊
cookie由對服務器的請求來傳遞,每次都會攜帶在http頭中,若是使用cookie保存過多的數據會帶來性能問題;
sessionStorage和localStorage數據不是由每一個服務器請求傳遞的,而是隻有在請求時使用數據,不參與與服務器的通訊
(4)易用性
cookie須要本身封裝setCookie和getCookie;
sessionStorage和localStorage能夠用源生接口,也能夠再次封裝來對object和array有更好的支持
(5)共同點
都是保存在瀏覽器端,和服務器端的session機制不一樣
九、JSONP的原理
ajax請求受到同源策略的影響,不容許進行跨域請求,而script標籤的src屬性中的連接卻能夠訪問跨域的js腳本,利用這個特性,服務端再也不返回json格式的數據,而是返回一段調用某個函數的js代碼,在src中進行了調用,這樣就實現了跨域。
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
(1)beforeCreate:el和data未初始化
(2)created:完成了data數據的初始化,el未初始化
(3)beforeMount:el和data已經初始化,還未渲染好,只是使用虛擬DOM把坑先佔住。
(4)mounted:完成掛載,已經渲染完成。
閉包的概念:
閉包就是可以讀取其餘函數內部變量的函數。在js中,只有函數內部的子函數才能讀取局部變量,因此閉包能夠理解爲‘定義在一個函數內部的函數’。在本質上,閉包是將函數內部和函數外部鏈接起來的橋樑。
閉包的用途:
(1)能夠讀取函數內部的變量
(2)讓這些變量的值始終保持在內存中,由於這些變量始終被引用着,因此不會被垃圾回收機制回收
閉包的注意點:
(1)因爲閉包使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁性能問題,在IE中可能致使內存泄漏。解決辦法:在退出函數以前,將不使用的局部變量所有刪除。
(2)閉包會在父函數外部改變父函數內部變量的值。因此,若是你把父函數看成對象使用,把閉包看成它的公用方法,把內部變量看成它的私有屬性,這時候要當心,不能隨便改變父函數內部變量的值。
十二、原型鏈
(1)、構造函數、原型、實例的關係
構造函數都有一個proptotype屬性;
原型對象prototype裏面有一個constructor屬性,該屬性指向原型對象所屬的構造函數;
實例對象都有一個__proto__屬性,該屬性也指向構造函數的原型對象,他是一個非標準屬性,不能夠用於編程,是瀏覽器本身使用的。
(2)prototype和__proto__關係
prototype是構造函數的屬性,__proto__是實例對象的屬性。這二者都指向同一個對象。
(3)原型鏈屬性搜索(什麼是原型鏈)?
在訪問對象的某個成員的時候,會先從對象自己進行查找,若是對象中查找不到,那麼就會去它的構造函數的原型對象中進行查找,若是沒有找到,那麼就會去它的原型對象的原型對象中查找,這樣一層一層往上查找,直到object的原型對象的原型是null爲止。
1三、如何理解同步和異步?
全部任務均可以分紅兩種,一種是同步任務(syn),另外一種是異步任務(asyn)。同步任務指的是在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;異步任務指的是,不進入主線程,而進入‘任務隊列’的任務,只有‘任務對列’通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。
運行機制以下:
(1)全部同步任務都在主線程上執行,造成一個執行棧
(2)主線程外,還存在一個任務隊列,只要異步任務有了運行結果,就在任務隊列中放置一個事件
(3)一旦執行棧中的全部同步任務執行完畢,系統就會讀取任務隊列,看看裏面有哪些事件。那些對應的異步任務就會結束等待狀態,而進入執行棧,開始執行
(4)主線程上不斷重複上面三步。
1四、webpack
(1)什麼是webpack?
webpack能夠看做是模塊打包機,她作的事情是分析你的項目結構,找到js模塊以及其餘的一些瀏覽器不能直接運行的拓展語言(sass、typescript等),並將其轉換和打包爲合適的格式供瀏覽器使用。
(2)webpack的工做方式
wenpack的工做方式是把你的項目看成一個總體,經過一個給定的主文件(如index.js),webpack將從這個文件開始找到你項目的全部依賴文件,使用loaders處理他們,最後打包爲一個或者多個瀏覽器可識別的js文件
(3)打包原理
把全部依賴打包成一個bundle.js文件,經過代碼分割成單元片斷並按需加載。
(4)webpack的核心思想
一切皆模塊:正如js文件能夠是一個模塊,其餘文件css、image或者html也能夠視做模塊,所以,能夠require('xxx.css'),這意味着咱們將事物分割成更小的易於管理的片斷,從而達到重複利用的目的。
按需加載:傳統的模塊打包工具最終將全部的模塊編譯生成一個龐大的bundle.js文件,可是在真實的app裏面,bundle.js文件可能有10M或者15M之大,可能會致使應用一直處於加載中狀態。所以webpack使用不少特性來分割代碼而後生成多個bundle.js文件,並且異步加載部分代碼以實現按需加載。
1五、vue雙向數據綁定的原理
主要是經過object對象的defineProperty屬性,重寫data的set和get函數來實現的。
1六、React組件生命週期過程說明
(1)實例化
首次實例化:
-
getDefaultProps
-
getInitialState
-
componentWillMount
-
render
-
componentDidMount
實例化完成後的更新:
-
getInitialState
-
componentWillMount
-
render
-
componentDidMount
(2)存在期
組件已存在時的狀態改變:
(3)銷燬&清理期
(4)說明
生命週期共提供了10個不一樣的API
getDefaultProps:做用於組件類,只調用一次,返回對象用於設置默認的props,對於引用值,會在實例中共享。
getInitialState:做用於組件的實例,在實例建立時調用一次,用於初始化每一個實例的state,此時能夠訪問this.props。
componentWillMount:在完成首次渲染以前調用,此時仍能夠修改組件的state。
render:必選的方法,建立虛擬DOM,該方法具備特殊的規則:
componentDidMount:真實的DOM被渲染出來後調用,在該方法中能夠經過this.getDOMNode()訪問到真實的DOM元素,此時已經可使用其餘類庫來操做這個DOM。
在服務器端,該方法不會被調用。
componentWillReceiveProps:組件接收到新的props時調用,並將其做爲參數nextProps使用,此時能夠更改組件props以及state。
componentWillReceiveProps: function(nextProps) { if (nextProps.bool) { this.setState({ bool: true }); } }
shouldComponentUpdate:組件是否應當渲染新的props或state,返回false表示跳事後續的生命週期方法,一般不須要使用以免出現bug。在出現應用的瓶頸時,能夠經過該方法進行適當的優化。
在首次渲染期間或者調用了forceUpdate方法後,該方法不會被調用。
componentWillUpdate:接收到新的props或者state後,進行渲染前調用,此時不容許更改props或者state。
componentDidUpdate:完成渲染新的props或者state後調用,此時能夠訪問到新的DOM元素。
componentWillUnmount:組件被移除以前調用,能夠用於作一些清理工做,在componentDidMount方法中添加的全部任務都須要在該方法中撤銷,好比建立的定時器或者添加的事件監聽器。
1七、React+Mobx核心概念
(1)state----狀態
狀態是驅動應用的數據
(2)observable(value)&&@observable
observable值能夠是JS基本數據類型、引用類型、普通對象、類實例、數組和映射。其修飾的state會暴露出來供觀察者使用。
(3)observer(觀察者)
被observer修飾的組件,將會根據組件內使用到的被observable修飾的state的變化而自動從新渲染
(4)action(動做)
只有在actions中,才能夠修改Mobx中的state的值。
注意:當你使用裝飾器模式時,@action中的this沒有綁定在當前這個實例上,要用@action.bound來綁定使得this綁定在實例對象上
(5)computed
計算值(computed values)是能夠根據現有的狀態或者其餘計算值衍生出的值
getter:獲取計算獲得的新的state並返回
setter:不能用來直接改變計算屬性的值,可是他們能夠用來做‘逆向’衍生。
1八、Vue和React的異同點?
Vue的優點:
(1)模板或渲染的靈活選項
(2)語法以及項目設置的簡單
(3)渲染速度更快,體積更小
React的優點:
(1)更大的規模、更多的使用者、更好的可測試性
(2)同時適用Web和原生App
(3)能提供更多支持和工具的更大的生態系統
二者共同的優點:
(1)都是優秀的UI庫
(2)使用虛擬DOM快速渲染
(3)輕量級
(4)響應式組件
(5)服務端渲染
(6)輕鬆集成的路由、捆綁和狀態管理
(7)強大的支持和社區
(1)內容優化
(2)服務器優化
(3)cookie優化
-
減少cookie大小
-
針對web組件使用域名無關的cookie
(4)css優化
-
將css代碼放在HTML頁面頂部
-
避免使用css表達式
-
使用link代替@import
-
避免使用filters
(5)js優化
(6)圖像優化
-
優化圖片大小
-
經過css Sprites優化圖片
-
不要在HTML中使用縮放圖片
-
favicon.ico要小並且可緩存
20、call()、apply()、bind()區別
概念:
(1)call()、apply()能夠看做是某個對象的方法,經過調用方法的形式來間接調用函數,簡單來講就是讓函數在某個指定的對象下執行。
(2)bind()就是將某個函數綁定到某個對象上。
(3)三個方法的做用都是改變函數的執行上下文。
區別:
(1)call和apply的第一個參數相同,就是指定的對象。這個對象就是該函數的執行上下文。他們的區別在於參數不一樣,call第一個參數以後的其餘全部參數就是傳入該函數的值,以逗號分隔;apply只有兩個參數,第二個是數組,這個數組就是該函數的參數。
(2)bind和二者的區別在於bind方法會返回執行上下文被改變的函數而不會當即執行,前二者是直接執行該函數。bind的參數和call相同。
常問的幾個屬性:
(1)flex-direction項目排列的方向,column垂直排列。
(2)flex-wrap若是一條軸線排不下,如何換行。wrap換行。
(3)justify-content項目在主軸上的對齊方式。canter居中;space-between兩端對齊且項目之間間隔相等;space-around每一個項目兩側間隔相等,因此項目之間的間距大於項目與邊框之間的間距。
(4)align-items項目在交叉軸上的對齊方式。center居中;stretch默認值,若是項目未設置高度或者auto,那麼將佔滿整個容器的高度。
(1)移動端click屏幕產生200-300ms的延時響應
(2)點擊元素產生背景或者邊框怎麼去掉
-
ios用戶點擊一個連接會出現一個半透明灰色遮罩,若是想要禁用,可設置-webkit-tap-highlight-color的alpha值爲0
-
android用戶點擊一個連接,會出現一個邊框或者半透明灰色遮罩,可設置-webkit-tap-highlight-color的alpha值爲0
-
winphone系統,點擊標籤產生的灰色半透明背景,經過設置<meta name="msapplication-tap-highlight" content="no">去掉
-
有些機型去不掉,如小米2,對於按鈕類還有個方法,不要使用a標籤或者input標籤,直接用div標籤
a,button,input,textarea {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-modify: read-write-plaintext-only; // -webkit-user-modify有個反作用,就是輸入法再也不可以輸入多個字符
}
// 或者
* {
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
// winphone下
<meta name="msapplication-tap-highlight" content="no">
(3)美化表單元素
//一、使用appearance改變webkit瀏覽器的默認外觀
input,select { -webkit-appearance: none; appearance: none; }
// 二、winphone下,使用僞元素改變表單元素默認外觀
// 2.1 禁用select默認箭頭,::ms-expand修改表單控制下拉箭頭,設置隱藏並使用背景圖片來修飾
select::ms-expand { display:none; }
// 2.2 禁用radio和checkbox默認樣式,::ms-check修改表單複選框或者單選框默認圖標,設置隱藏並使用背景圖片來修飾
input[type=radio]::ms-check, input[type=checkbox]::ms-check {display: none;}
// 2.3 禁用pc端表單輸入框默認清除按鈕,::ms-clear修改清除按鈕,設置隱藏並使用背景圖片來修飾
input[type=text]::ms-clear,input[type=tel]::ms-clear,input[type=number]::ms-clear {display:none;}
(4)input在ios下,輸入的時候英文首字母默認大寫,怎麼解決?
<input autocapitalize="off" autocorrect="off" />
(5)消除transition閃屏
.css {
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
}
2三、Vue1.0和2.0的區別
(1)生命週期
2.0生命週期變得更加語義化了,增長了beforeUpdate、updated等,刪除了attached、detached。
(2)過濾器
Vue.filter('toDou', function(n, a, b) {
return n < 10? n + a + b : '' + n;
})
//1.0 {{ msg | mimi '12' '5' }}
//2.0 {{ msg | mimi('12', '5') }}
(3)循環
在Vue2.0中丟棄了$index和$key,將track-by替換成key屬性,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素。
(4)片斷代碼
在編寫template的時候,2.0必需要用一個根元素(如div)將代碼片斷包裹起來,不然報錯。1.0則不須要。
(5)el屬性綁定的元素,限制爲一個普通的元素,不能再綁定再body、html元素上。
(6)v-model增長了.trim、.number等後綴修飾符