React和Vue對比
相同點:
數據驅動視圖,提供了響應式(Reactive)和組件化(Composable)的視圖組件。
都有Virtual DOM,組件化開發,通過props參數進行父子組件數據的傳遞,都實現webComponents規范
數據流動單向
都支持服務端渲染
都有支持native的方案,React的React native,Vue的weex
不同點:
社區:React社區還是要比Vue大很多;
開發模式:React在view層侵入性還是要比Vue大很多的,React嚴格上只針對MVC的view層,Vue則是MVVM模式的一種實現;
數據綁定:Vue有實現了雙向數據綁定,React數據流動是單向的
數據渲染:對于大規模數據渲染,React要比Vue更快,渲染機制啟動時候要做的工作比較多;
數據更新方面:Vue 由于采用依賴追蹤,默認就是優化狀態:你動了多少數據,就觸發多少更新,不多也不少。React在復雜的應用里有兩個選擇:
(1). 手動添加 shouldComponentUpdate 來避免不需要的 vdom re-render。
(2). Components 盡可能都用 pureRenderMixin,然后采用 redux 結構 + Immutable.js;
開發風格的偏好:React 推薦的做法是 JSX + inline style,也就是把 HTML 和 CSS 全都寫進 JavaScript 了,即”all in js”;Vue進階之后推薦的是使用 webpack + vue-loader 的單文件組件格式,即html,css,js寫在同一個文件;
使用場景:React配合Redux架構適合超大規模多人協作的復雜項目;Vue則適合小快靈的項目。對于需要對 DOM 進行很多自定義操作的項目,Vue 的靈活性優于 React;
Vue要比React更好上手,具體可能體現在很多人不熟悉React的JSX語法和函數式編程的思想,以及想要發揮出React的最大威力需要學習它一系列生態的緣故;
Vue著重提高開發效率,讓前端程序員更快速方便的開發應用。React著重于變革開發思想,提升前端程序員編程的深度與創造力,讓前端工程師成為真正的程序員而不是UI的構建者;
gulp和webpack區別
gulp是一種工具,我們可以用它來優化前端的工作流程,比如自動刷新頁面、combo、壓縮css、js、編譯less等等。具體體現為:在gulp的配置文件中書寫一個個的task,webpack則是一種打包工具,或者說是一種模塊化解決方案,實際上很大一部分人剛開始使用webpack的方式就是通過gulp-webpack這個插件,寫好task來使用webpack對前端的一些文件進行打包;
gulp的處理任務需要自己去寫,webpack則有現成的解決方案,只需要在webpack.config.js配置好即可;
事件模型
1、事件捕獲階段(capturing phase)。事件從document一直向下傳播到目標元素, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
2、事件處理階段(target phase)。事件到達目標元素, 觸發目標元素的監聽函數。
3、事件冒泡階段(bubbling phase)。事件從目標元素冒泡到document, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
js中event的target和currentTarget的區別
arget:觸發事件的元素。點了那個標簽獲取哪個標簽
currentTarget:事件綁定的元素。
currentTarget始終是監聽事件者,而target是事件的真正發出者
兩者在沒有冒泡的情況下,是一樣的值,但在用了事件委托的情況下,就不一樣了,例如:
事件捕獲階段:事件從最上一級標簽開始往下查找,直到捕獲到事件目標(target)。
事件冒泡階段:事件從事件目標(target)開始,往上冒泡直到頁面的最上一級標簽
DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件,但是,捕獲型事件先發生。兩種事件流會觸及DOM中的所有對象,從document對象開始,也在document對象結束
假設一個元素div,它有一個下級元素p。
<div>
? ? ?<p>元素</p>
</div>
這兩個元素都綁定了click事件,如果用戶點擊了p,它在div和p上都觸發了click事件,那這兩個事件處理程序哪個先執行呢?事件順序是什么?
兩種模型
以前,Netscape和Microsoft是不同的實現方式。
Netscape中,div先觸發,這就叫做事件捕獲。
Microsoft中,p先觸發,這就叫做事件冒泡。
兩種事件處理順序剛好相反。IE只支持事件冒泡,Mozilla, Opera 7 和 Konqueror兩種都支持,舊版本的Opera's 和 iCab兩種都不支持 。
事件捕獲
當你使用事件捕獲時,父級元素先觸發,子級元素后觸發,即div先觸發,p后觸發。
事件冒泡
當你使用事件冒泡時,子級元素先觸發,父級元素后觸發,即p先觸發,div后觸發。
W3C模型
W3C模型是將兩者進行中和,在W3C模型中,任何事件發生時,先從頂層開始進行事件捕獲,直到事件觸發到達了事件源元素。然后,再從事件源往上進行事件冒泡,直到到達document。
程序員可以自己選擇綁定事件時采用事件捕獲還是事件冒泡,方法就是綁定事件時通過addEventListener函數,它有三個參數,第三個參數若是true,則表示采用事件捕獲,若是false,則表示采用事件冒泡。
ele.addEventListener('click',doSomething2,true)
true=捕獲
false=冒泡
傳統綁定事件方式
在一個支持W3C DOM的瀏覽器中,像這樣一般的綁定事件方式,是采用的事件冒泡方式。
ele.onclick = doSomething2
IE瀏覽器
如上面所說,IE只支持事件冒泡,不支持事件捕獲,它也不支持addEventListener函數,不會用第三個參數來表示是冒泡還是捕獲,它提供了另一個函數attachEvent。
ele.attachEvent("onclick", doSomething2);
附:事件冒泡(的過程):事件從發生的目標(event.srcElement||event.target)開始,沿著文檔逐層向上冒泡,到document為止。
事件的傳播是可以阻止的:
? 在W3c中,使用stopPropagation()方法
? 在IE下設置cancelBubble = true;
在捕獲的過程中stopPropagation();后,后面的冒泡過程也不會發生了~
3.阻止事件的默認行為,例如click 后的跳轉~
? 在W3c中,使用preventDefault()方法;
? 在IE下設置window.event.returnValue = false;
瀏覽器緩存機制
可參考地址:瀏覽器緩存機制
Expires策略
Expires是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數據,而無需再次請求。Expires 是HTTP 1.0的東西,現在默認瀏覽器均默認使用HTTP 1.1,所以它的作用基本忽略。
Cache-Control策略
Cache-Control與Expires的作用一致,都是指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩讀取數據還是重新發請求到服務器取數據。只不過Cache-Control的選擇更多,設置更細致,如果同時設置的話,其優先級高于Expires。
以上是設置緩存時間的兩種方法。那么當緩存時間過了咋整呢?有人肯定說了,那就再次發起請求啊,這是對的。問題是如果服務器資源并沒有更新呢?比如說我有一個jQuery.js文件已經緩存了,當它的緩存時間到了之后服務器的jQuery.js文件也沒有更新,那實際上我們直接使用本地緩存的文件就可以啊!沒必要浪費帶寬和時間去重新請求一個新的文件啊!這時候我們就需要再進一步看一下HTTP協議里這幾個參數的作用了。
Last-Modified/If-Modified-Since
首先Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:標示這個響應資源的最后修改時間。web服務器在響應請求時,告訴瀏覽器資源的最后修改時間(這個參數是和Cache-Control一起過來的)。
If-Modified-Since:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Last-Modified聲明,則再次向web服務器請求時帶上頭If-Modified-Since,表示請求時間。web服務器收到請求后發現有頭If-Modified-Since ,則與被請求資源的最后修改時間進行比對。若最后修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最后修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。
ETag/If-None-Match
Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(生成規則由服務器覺得)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最后修改時間(MTime)進行Hash后得到的。
If-None-Match:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Etage聲明,則再次向web服務器請求時帶上頭If-None-Match(Etag的值)。web服務器收到請求后發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
ETag和Last-Modified
HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:
Last-Modified標注的最后修改只能精確到秒級,如果某些文件在1秒鐘以內,被修改多次的話,它將不能準確標注文件的修改時間
如果某些文件會被定期生成,當有時內容并沒有任何變化,但Last-Modified卻改變了,導致文件沒法使用緩存
有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的唯一標識符,能夠更加準確的控制緩存。Last-Modified與ETag是可以一起使用的,服務器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最后才決定是否返回304。
Ajax的狀態值與HTTP狀態碼
Ajax的狀態值
0: (未初始化)還沒有調用open()方法;
1: (載入)已經調用open()方法,正在派發請求,send()方法還未被調用;
2: (載入完成)send()已經調用,響應頭和響應狀態已經返回;
3: (交互)響應體下載中; responseText中已經獲取了部分數據;
4: (完成)響應內容已經解析完成,用戶可以調用。
HTTP狀態碼
200 & OK: 請求成功;
204 & No Content: 請求處理成功,但沒有資源可以返回;
206 & Partial Content: 對資源某一部分進行請求(比如對于只加載了一般的圖片剩余部分的請求);
301 & Move Permanently: 永久性重定向;
302 & Found: 臨時性重定向;
303 & See Other: 請求資源存在另一個URI,應使用get方法請求;
304 & Not Modified: 服務器判斷本地緩存未更新,可以直接使用本地的緩存;
307 & Temporary Redirect: 臨時重定向;
400 & Bad Request: 請求報文存在語法錯誤;
401 & Unauthorized: 請求需要通過HTTP認證;
403 & Forbidden: 請求資源被服務器拒絕,訪問權限的問題;
404 & Not Found: 服務器上沒有請求的資源;
500 & Internal Server Error: 服務器執行請求時出現錯誤;
502 & Bad Gateway: 錯誤的網關;
503 & Service Unavailable: 服務器超載或正在維護,無法處理請求;
504 & Gateway timeout: 網關超時;
什么是原型鏈
詳細地址:原型鏈詳解
訪問一個對象的屬性時,先在基本屬性中查找,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。
? 在執行代碼之前,把將要用到的所有的變量都事先拿出來,有的直接賦值了,有的先用undefined占個空——執行上下文環境。
? 作用域鏈,是由當前環境與上層環境的一系列變量對象組成,它保證了當前執行環境對符合訪問權限的變量和函數的有序訪問。
? 每一個對象都會在內部鏈接到另一個對象(該對象的原型對象),該對象有一個原型prototype,當訪問對象的屬性或是方法的時候,不僅僅會在原對象上查找,還會順著原型鏈在原型對象的原型鏈上查找,直到查到null(所有原型鏈的頂層)為止。原型是JavaScript實現繼承的基礎,new關鍵字做的主要的事情就是將實例對象的__proto__屬性指向原型對象的prototype。
什么是閉包
閉包是javascript支持頭等函數的一種方式,它是一個能夠引用其內部作用域變量(在本作用域第一次聲明的變量)的表達式,這個表達式可以賦值給某個變量,可以作為參數傳遞給函數,也可以作為一個函數返回值返回。
閉包是函數開始執行的時候被分配的一個棧幀,在函數執行結束返回后仍不會被釋放(就好像一個棧幀被分配在堆里而不是棧里!)
閉包的應用:
比如寫柯里化函數的時候利用閉包,保存參數在內存中;
varcurrying =function(fun){
//格式化arguments
varargs =Array.prototype.slice.call(arguments,1);
returnfunction(){
//收集所有的參數在同一個數組中,進行計算
var_args = args.concat(Array.prototype.slice.call(arguments));
returnfun.apply(null, _args);
? ? };
}
圖片懶加載與預加載
圖片懶加載的原理就是暫時不設置圖片的src屬性,而是將圖片的url隱藏起來,比如先寫在data-src里面,等某些事件觸發的時候(比如滾動到底部,點擊加載圖片)再將圖片真實的url放進src屬性里面,從而實現圖片的延遲加載
圖片預加載,是指在一些需要展示大量圖片的網站,實現圖片的提前加載。從而提升用戶體驗。常用的方式有兩種,一種是隱藏在css的background的url屬性里面,一種是通過javascript的Image對象設置實例對象的src屬性實現圖片的預加載。相關代碼如下:
CSS預加載圖片方式:
#preload-01{background:url(http://domain.tld/image-01.png) no-repeat -9999px-9999px; }
#preload-02{background:url(http://domain.tld/image-02.png) no-repeat -9999px-9999px; }
#preload-03{background:url(http://domain.tld/image-03.png) no-repeat -9999px-9999px; }
Javascript預加載圖片的方式:
functionpreloadImg(url){
varimg =newImage();
img.src = url;
if(img.complete) {
//接下來可以使用圖片了
//do something here
}else{
img.onload =function(){
//接下來可以使用圖片了
//do something here
};
}
}
跨域
跨域的方式有很多種,最常用的是jsonp主要利用了script的開放策略:通過script標簽引入一個js或者是一個其他后綴形式(如php,jsp等)的文件,此文件返回一個js函數的調用。缺點在于只支持get請求而且存在安全問題,可能會導致CSRF,因為請求的數據來源于其他網站,因為惡意攻擊者可以利用這段代碼進行請求,獲取數據,有可能會泄露用戶密碼等重要信息
關于cors在維基百科上的定義是這樣的:跨域資源共享(CORS )是一種網絡瀏覽器的技術規范,它為Web服務器定義了一種方式,允許網頁從不同的域訪問其資源。而這種訪問是被同源策略所禁止的。CORS系統定義了一種瀏覽器和服務器交互的方式來確定是否允許跨域請求。它是一個妥協,有更大的靈活性,但比起簡單地允許所有這些的要求來說更加安全。
CORS跨域,關鍵在于服務器,如果服務器實現了CORS跨域的接口,那么就可以使用ajax(請求路徑為絕對路徑)進行跨域請求。CORS請求分為兩種,一種是簡單請求,一種是非簡單請求。簡單請求是指請求方法在HEAD,GET,POST三者之間并且請求頭信息局限在
Accept
Accept-Language
Content-Language
Content-Type:只限于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
非簡單請求請求頭:
(1)Access-Control-Request-Method
該字段是必須的,用來列出瀏覽器的CORS請求會用到哪些HTTP方法
(2)Access-Control-Request-Headers
該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段
執行簡單請求的時候,瀏覽器會在請求頭信息增加origin字段,服務器據此來判斷請求域名是否在許可范圍之內,來決定是否返回Access-Control-Allow-Origin字段。響應頭有以下幾種:
(1)Access-Control-Allow-Origin
該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*,表示接受任意域名的請求。
(2)Access-Control-Allow-Credentials
該字段可選。它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。
(3)Access-Control-Expose-Headers
該字段可選。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必須在Access-Control-Expose-Headers里面指定。
(4)Access-Control-Max-Age
Access-Control-Max-Age首部字段指明了預檢請求的響應的有效時間。
(5)Access-Control-Allow-Methods
Access-Control-Allow-Methods首部字段用于預檢請求的響應。其指明了實際請求所允許使用的 HTTP 方法。
(6)Access-Control-Allow-Headers
Access-Control-Allow-Headers首部字段用于預檢請求的響應。其指明了實際請求中允許攜帶的首部字段。
其他方法:document.domin,html5的postMessage,window.name等
函數節流和函數防抖
函數節流讓指函數有規律的進行調用,應用場景:window.resize,游戲中子彈發射(1s只能發射一顆子彈)等;
函數防抖讓函數在”調用’’之后的一段時間后生效,應用場景:輸入框(例:在用戶停止輸入的500ms后再處理用戶數據)。
//函數節流
/*
* @params {Function} fun 調用函數
* @params {delay} number 延遲時間
*/
constthrottle =(fun, delay, ...rest) =>{
? ? ? let last =null;
? ? ? return()=>{
? ? ? ? ? ? ? const now = +newDate();
? ? ? ? ? ? ? if(now - last > delay) {
? ? ? ? ? ? ? ? ? ? fun(rest);
? ? ? ? ? ? ? ? ? ? last = now;
? ? ? ? ? ? ? }
? ? ? ?}
}
//實例
constthrottleExample? = throttle(()=>console.log(1),1000);
//調用
throttleExample();
throttleExample();
throttleExample();
//函數防抖
constdebouce =(fun, delay, ...rest) =>{
? ? ? ? ? ? let timer =null;
? ? ? ? ? ? return()=>{
? ? ? ? ? ? ? ? ? ? ?clearTimeout(timer);
? ? ? ? ? ? ? ? ? ? ?timer = setTimeout(()=>{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fun(rest);
? ? ? ? ? ? ? ? ? ? ? }, delay);
? ? ? ? ? ? ? }
}
//實例
constdebouceExample = debouce(()=>console.log(1),1000);
//調用
debouceExample();
debouceExample();
debouceExample();
AMD和CMD的區別
AMD 是 RequireJS 在推廣過程中對模塊定義的規范化產出。
CMD 是 SeaJS 在推廣過程中對模塊定義的規范化產出。
對于依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
CMD 推崇依賴就近,AMD 推崇依賴前置。
AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啟動。CMD 里,每個 API 都簡單純粹
BFC
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.htmlBFC詳解
浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不為“visiable”的塊級盒子,都會為他們的內容創建新的BFC(塊級格式上下文)。本身根元素就處在一個大的BFC中,BFC中元素豎直排列,IFC(行內格式上文)中的元素橫向排列
塊格式化上下文由以下之一創建:
根元素或其它包含它的元素
浮動 (元素的float不是none)
絕對定位的元素 (元素具有position為absolute或fixed)
內聯塊 inline-blocks (元素具有display: inline-block)
表格單元格 (元素具有display: table-cell,HTML表格單元格默認屬性)
表格標題 (元素具有display: table-caption, HTML表格標題默認屬性)
塊元素具有overflow,且值不是visible
display: flow-root;—來自MDN
用處:
設置父元素為BFC清除子元素浮動;
解決上面的margin合并問題;
用于布局
new關鍵字的過程
創建一個空對象,并且 this 變量引用該對象,同時還繼承了該函數的原型。
屬性和方法被加入到 this 引用的對象中。
新創建的對象由 this 所引用,并且最后隱式的返回 this 。
var obj = {};
obj.__proto__ = Base.prototype;//Base為構造函數
Base.call(obj);
return obj