1. 程式人生 > >前端面試資料整理

前端面試資料整理

建立物件的方式
(1)使用new關鍵字

var start = new Object;

(2)使用花括號

var start = {};

建立類
ES6之前使用function關鍵字模擬:function Person(){};
ES6中類的建立方式:class Person{}

非同步傳輸實現方式:
(1)ajax
(2)iframe(加上target)實現

JavaScript 中應該用 “==” 還是 “===”
絕大多數場合應該使用 === ,只有檢測 null/undefined 的時候可以使用 x == null

javascript的typeof返回哪些資料型別


Object number function boolean underfind

例舉3種強制型別轉換和2種隱式型別轉換?
強制(parseInt,parseFloat,number)
隱式(== – ===)

split() join() 的區別
前者是切割成陣列的形式,後者是將陣列轉換成字串

陣列方法pop() push() unshift() shift()
Push()尾部新增 pop()尾部刪除
Unshift()頭部新增 shift()頭部刪除

slice
(1)slice() 方法可從已有的陣列中返回選定的元素。
(2)slice()方法可提取字串的某個部分,並以新的字串返回被提取的部分。
注意: slice() 方法不會改變原始陣列。

sort
sort() 方法用於對陣列的元素進行排序。按字母順序值排序;

call和apply的區別
apply:應用某一物件的一個方法,用另一個物件替換當前物件。
call:呼叫一個物件的一個方法,以另一個物件替換當前物件。

apply:最多隻能有兩個引數——新this物件和一個數組 argArray。
call:則是直接的引數列表,主要用在js物件各方法互相呼叫的時候,使當前this例項指標保持一致,或在特殊情況下需要改變this指標。如果沒有提供 thisObj 引數,那麼 Global 物件被用作 thisObj。

apply和call功能一樣,只是傳入的引數列表形式不同:
apply的寫法:func.apply(func1,[var1,var2,var3])
call的寫法:func.call(func1,var1,var2,var3)

substring和substr的區別

var v1 = 'Hello World';
//如果只是寫一個引數,兩者的作用都是一樣的:就是擷取字串當前下標以後直到字串最後的字串片段。
console.log(v1.substring(1));   //ello World
console.log(v1.substr(1));      //ello World

console.log('**********************************');

// 當寫第二個引數的時候,兩者就會有完全不同的含義;
// substring(a,b)
// 第二個引數是擷取到字串最終的下標(實際擷取位置是1-7)
console.log(v1.substring(1,8));      //ello Wo
// substr(a,b)
// 第二個引數是擷取字串的長度(實際擷取8個字元長度值)
console.log(v1.substr(1,8));        //ello Wor

事件委託是什麼
利用事件冒泡的原理,自己所觸發的事件,讓他的父元素代替執行!

Javascript的事件流模型都有什麼?
(1).冒泡型事件:指事件按照從最精確的物件到最不精確的物件的順序逐一觸發

(2).捕獲型事件:它與冒泡型事件相反,指事件按照從最不精確到最精確的物件的順序逐一觸發

JS物件與JSON格式的互相轉換
①JSON的解析(json資料轉換成JS物件):

var myObject=JSON.parse(myJSONtext);

②JSON的序列化(JS物件轉換成JSON資料):

var myJSONtext=JSON.stringify(myObject);

列舉瀏覽器物件模型BOM裡常用的至少4個物件,並列舉window物件的常用方法至少5個
物件:Window location screen history navigator
方法:Alert() confirm() prompt() open() close() setinterval() settimeout()

documen.write和 innerHTML 的區別?
document.write 只能重繪整個頁面;innerHTML 可以重繪頁面的一部分

閉包是什麼,有什麼特性,對頁面有什麼影響
閉包就是能夠讀取其他函式內部的區域性變數的函式,或者定義在一個函式內部的函式。

閉包的好處:
(1)不增加額外的全域性變數;
(2)執行過程中所有變數都在匿名函式內部
閉包的壞處:
(1)記憶體消耗大,會影響網頁的效能
(2)會改變父函式內部變數的值

如何阻止事件冒泡和預設事件
阻止事件冒泡:w3c的方法是e.stopPropagation(),IE則是使用e.cancelBubble = true;

阻止預設事件:w3c的方法是e.preventDefault(),IE則是使用return false;

瀏覽器渲染頁面的過程
1、使用者輸入URL地址
2、瀏覽器解析URL解析出主機名
3、瀏覽器將主機名轉換成伺服器ip地址(瀏覽器先查詢本地DNS快取列表 沒有的話 再向瀏覽器預設的DNS伺服器傳送查詢請求 同時快取)
4、瀏覽器將埠號從URL中解析出來
5、瀏覽器建立一條與目標Web伺服器的TCP連線(5、6、7三次握手)
6、瀏覽器向伺服器傳送一條HTTP請求報文
7、伺服器向瀏覽器返回一條HTTP響應報文
8、關閉連線 瀏覽器解析文件

HTTP狀態碼知道哪些?
狀態程式碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:
1xx:指示資訊–表示請求已接收,繼續處理
2xx:成功–表示請求已被成功接收、理解、接受
3xx:重定向–要完成請求必須進行更進一步的操作
4xx:客戶端錯誤–請求有語法錯誤或請求無法實現
5xx:伺服器端錯誤–伺服器未能實現合法的請求

200 OK                        //客戶端請求成功
400 Bad Request               //客戶端請求有語法錯誤,不能被伺服器所理解
401 Unauthorized              //請求未經授權,這個狀態程式碼必須和WWW-Authenticate報頭域一起使用 
403 Forbidden                 //伺服器收到請求,但是拒絕提供服務
404 Not Found                 //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error     //伺服器發生不可預期的錯誤
503 Server Unavailable        //伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常

JS的原型和原型鏈
(1)原型和原型鏈是JS實現繼承的一種模型;
(2)原型鏈的形成依靠 * _proto_ *而不是prototype
(3)在js中每一個物件都可以看成是一個原型物件,通過proto可以把所有原型物件串聯成一條原型鏈;

cookies、localStorage、sessionStorage的理解
localStorage:長期儲存資料。瀏覽器關閉不丟失;
sessionStorage:儲存的資料在瀏覽器關閉後刪除;

cookies:儲存的資料在瀏覽器和伺服器之間傳遞,資料是加密的;儲存資料大小是4k;
localStorage、sessionStorage儲存的資料在本地,儲存資料大小是5M;

作用域
指對某一屬性(變數)或者方法(函式)具有訪問許可權的程式碼空間,在JS中作用域在函式中進行維護;

this在js中(當前物件)是一個依賴於使用它的執行環境中被解析的關鍵字;

input輸入框提示資訊

<input type="text" placeholder="請輸入資訊"/>
<input type="text" placeholder="請輸入資訊" onfocus="if(value=='請輸入資訊'){value=''}" onblur="if(value==''){value='請輸入資訊'}"/>

第一種情況只有IE10以上版本才會提示請輸入資訊,第二種placeholder+onfocus+onblur可以相容到IE7

HTML中href、src區別

<link href="reset.css" rel=”stylesheet“/>  
<script src="script.js"></script>  

src用於替換當前元素;href用於在當前文件和引用資源之間建立聯絡

js內建物件:
Data、Math、Array、String、Number、Boolean、function

JQuery中的選擇器
JQuery中的選擇器分為:基本選擇器、層次選擇器、過濾選擇器、屬性過濾選擇器、表單選擇器

基本選擇器:

  1. ID選擇器:$(ID)
  2. Class選擇器:$(className)
  3. 萬用字元選擇器:$(“*”)

層次選擇器

  1. $(“body div”)
  2. $(“body > div”)
  3. $(“body + div”)
  4. $(“body ~ div”)

過濾選擇器

  1. $(“div:first”) $(“div:last”)
  2. $(“div:even”) $(“div:odd”)
  3. $(“div:eq(3)”) $(“div:gt(3)”) $(“div:lt(3)”)

jQuery有兩種用法($和jquery)使用上有什麼區別呢?

這兩種用法沒什麼區別,只是別名而已,用 $ 要比jQuery簡短一些、
方便一些,另外其他的前端框架也都用到$符號,如果想不跟其他框架衝突,
建議使用jQuery方式。

還有種方法就是換一個新的縮寫:
1、呼叫jquery的noConflict函式
JQuery.noConflict();//讓jquery放棄對$的使用權,
交給其他js框架使用  

$和$()的區別:
  $可以呼叫那些不需要操作物件的方法(像Java程式碼中的靜態方法,不用宣告物件就可以操作),如$.prototype、$.post()、$.get()、$.ajax()等;如果是給某個物件賦值(注意,這裡有操作物件),就需要用$('#abc').val('123')的方式,因為像val()等方法中會用到$(this)去操作當前物件。

children()
該方法用來獲取子元素的集合

prev()
獲得匹配元素集合中每個元素緊鄰的前一個同胞元素,通過選擇器進行篩選是可選的

siblings()
獲得匹配集合中每個元素的同輩元素,通過選擇器進行篩選是可選的

parent()、
parent() 獲得當前匹配元素集合中每個元素的父元素,使用選擇器進行篩選是可選的。
parents() 獲得當前匹配元素集合中每個元素的祖先元素,使用選擇器進行篩選是可選的。

closest()
closest() 方法獲得匹配選擇器的第一個祖先元素,從當前元素開始沿 DOM 樹向上。

ajax
ajax的優缺點:
優點:

  1. 不需要外掛支援
  2. 優秀的使用者體驗
  3. 提高web的效能
  4. 減輕伺服器和頻寬的負擔

缺點:

  1. 瀏覽器對XMLHttpRequest 物件的支援度不好
  2. 破壞瀏覽器前進後退按鈕的正常功能
  3. 開發和除錯工具的缺乏

設計模式
總體來說設計模式分為三大類:

建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

23中設計模式中沒有MVC的原因
MVC屬於架構模式,是觀察者模式、策略模式、組合模式三種設計模式的演變

link和@important的區別

  1. link無相容性,支援使用jsvascript改變模式,而@important不可以
  2. 內聯樣式與@important相比較,@important的優先順序更高
  3. 匯入樣式時,link會直接載入,而@important會等頁面載入完成才載入樣式

一、IE6雙倍邊距bug
當頁面上的元素使用float浮動時,不管是向左還是向右浮動;只要該元素帶有margin畫素都會使該值乘以2,例如“margin-left:10px” 在IE6中,該值就會被解析為20px。想要解決這個BUG就需要在該元素中加入display:inline 或 display:block 明確其元素型別即可解決雙倍邊距的BUG

二、IE6中3畫素問題及解決辦法

當元素使用float浮動後,元素與相鄰的元素之間會產生3px的間隙。詭異的是如果右側的容器沒設定高度時3px的間隙在相鄰容器的內部,當設定高度後又跑到容器的相反側了。要解決這類BUG的話,需要使佈局在同一行的元素都加上float浮動。

三、IE6中奇數寬高的BUG

IE6中奇數的高寬顯示大小與偶數高寬顯示大小存在一定的不同。其中要問題是出在奇數高寬上。要解決此類問題,只需要儘量將外部定位的div高寬寫成偶數即可。

四、IE6中圖片連結的下方有間隙

IE6中圖片的下方會存在一定的間隙,尤其在圖片垂直挨著圖片的時候,即可看到這樣的間隙。要解決此類問題,需要將img標籤定義為display:block 或定義vertical-align對應的屬性。也可以為img對應的樣式寫入font-size:0

五、IE6下空元素的高度BUG

如果一個元素中沒有任何內容,當在樣式中為這個元素設定了0-19px之間的高度時。此元素的高度始終為19px。

解決的方法有四種:

1.在元素的css中加入:overflow:hidden

2.在元素中插入html註釋:<!– >

3.在元素中插入html的空白符: 

4.在元素的css中加入:font-size:0

六、重複文字的BUG

在某些比較複雜的排版中,有時候浮動元素的最後一些字元會出現在clear清除元素的下面。

解決方法如下:

1.確保元素都帶有display:inline

2.在最後一個元素上使用“margin-right:-3px

3.為浮動元素的最後一個條目加上條件註釋,<!–[if !IE]>xxx<![endif]–>

4.在容器的最後元素使用一個空白的div,為這個div指定不超過容器的寬度。

七、IE6中 z-index失效

具體BUG為,元素的父級元素設定的z-index為1,那麼其子級元素再設定z-index時會失效,其層級會繼承父級元素的設定,造成某些層級調整上的BUG。詳細解釋可以閱讀IE6中部分情況下z-index無效的原因,以及解決辦法

實際上IE6中,很多BUG的解決方法都可以使用display:inline、font-size:0、float解決。因此我們在書寫程式碼時要記住,一旦使用了float浮動,就為元素增加一個display:inline樣式,可以有效的避免浮動造成的樣式錯亂問題。使用空DIV時,為了避免其高度影響佈局美觀,也可以為其加上font-size:0 這樣就很容易避免一些相容上的問題。

css reset的作用是重置瀏覽器的css預設屬性
css Sprite的作用是把一堆小圖片整合到一張大圖片上,減少伺服器對圖片的請求次數,減輕負擔

移動端如何畫出1px

  1. 使用css設定border為0.5px,js檢車是否支援0.5px
  2. 直接用圖片實現
  3. 偽元素+transform實現:before或者after重做border,並將transform的scale值減小一半
  4. 設定meta標籤

js中的垃圾回收機制—GC
Javascript中的GC垃圾回收機制(GC:Garbage Collecation)

  1. 標記清除
    js中最常用的垃圾回收方式就是標記清除。當變數進入環境時,就將這個變數標記為“進入環境”。而當變數離開環境時,則將其標記為“離開環境”。對標記為“離開環境”的變數進行排除釋放記憶體

  2. 引用計數
    引用計數的含義是跟蹤記錄每個值被引用的次數。當聲明瞭一個變數並將一個引用型別值賦給該變數時,則這個值的引用次數就是1。如果同一個值又被賦給另一個變數,則該值的引用次數加1。相反,如果包含對這個值引用的變數又取得了另外一個值,則這個值的引用次數減1。當這個值的引用次數變成0時,則說明沒有辦法再訪問這個值了,因而就可以將其佔用的記憶體空間回收回來。這樣,當垃圾回收器下次再執行時,它就會釋放那些引用次數為0的值所佔用的記憶體。

JS事件輪詢
一、為什麼JavaScript是單執行緒?
javascript語言的一大特點就是單執行緒,也就是說,同一個時間只能做一件事。那麼,為什麼JavaScript不能有多個執行緒呢?這樣能提高效率啊。
JavaScript的單執行緒,與它的用途有關。作為瀏覽器指令碼語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單執行緒,否則會帶來很複雜的同步問題。比如,假定JavaScript同時有兩個執行緒,一個執行緒在某個DOM節點上新增內容,另一個執行緒刪除了這個節點,這時瀏覽器應該以哪個執行緒為準?
所以,為了避免複雜性,從一誕生,JavaScript就是單執行緒,這已經成了這門語言的核心特徵,將來也不會改變。
為了利用多核CPU的計算能力,HTML5提出Web Worker標準,允許JavaScript指令碼建立多個執行緒,但是子執行緒完全受主執行緒控制,且不得操作DOM。所以,這個新標準並沒有改變JavaScript單執行緒的本質。

二、任務佇列
單執行緒就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。
如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO裝置(輸入輸出裝置)很慢(比如Ajax操作從網路讀取資料),不得不等著結果出來,再往下執行。
JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO裝置,掛起處於等待中的任務,先執行排在後面的任務。等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。
於是,所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是,在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務指的是,不進入主執行緒、而進入”任務佇列”(task queue)的任務,只有”任務佇列”通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。
具體來說,非同步執行的執行機制如下。(同步執行也是如此,因為它可以被視為沒有非同步任務的非同步執行。)
(1)所有同步任務都在主執行緒上執行,形成一個執行棧(execution context stack)。
(2)主執行緒之外,還存在一個”任務佇列”(task queue)。只要非同步任務有了執行結果,就在”任務佇列”之中放置一個事件。
(3)一旦”執行棧”中的所有同步任務執行完畢,系統就會讀取”任務佇列”,看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。
(4)主執行緒不斷重複上面的第三步。只要主執行緒空了,就會去讀取”任務佇列”,這就是JavaScript的執行機制。這個過程會不斷重複。

三、事件和回撥函式
“任務佇列”是一個事件的佇列(也可以理解成訊息的佇列),IO裝置完成一項任務,就在”任務佇列”中新增一個事件,表示相關的非同步任務可以進入”執行棧”了。主執行緒讀取”任務佇列”,就是讀取裡面有哪些事件。
“任務佇列”中的事件,除了IO裝置的事件以外,還包括一些使用者產生的事件(比如滑鼠點選、頁面滾動等等)。只要指定過回撥函式,這些事件發生時就會進入”任務佇列”,等待主執行緒讀取。
所謂”回撥函式”(callback),就是那些會被主執行緒掛起來的程式碼。非同步任務必須指定回撥函式,當主執行緒開始執行非同步任務,就是執行對應的回撥函式。
“任務佇列”是一個先進先出的資料結構,排在前面的事件,優先被主執行緒讀取。主執行緒的讀取過程基本上是自動的,只要執行棧一清空,”任務佇列”上第一位的事件就自動進入主執行緒。但是,由於存在後文提到的”定時器”功能,主執行緒首先要檢查一下執行時間,某些事件只有到了規定的時間,才能返回主執行緒。

四、Event Loop
主執行緒從”任務佇列”中讀取事件,這個過程是迴圈不斷的,所以整個的這種執行機制又稱為Event Loop(事件迴圈)。

五、定時器
除了放置非同步任務的事件,”任務佇列”還可以放置定時事件,即指定某些程式碼在多少時間之後執行。這叫做”定時器”(timer)功能,也就是定時執行的程式碼。
定時器功能主要由setTimeout()和setInterval()這兩個函式來完成,它們的內部執行機制完全一樣,區別在於前者指定的程式碼是一次性執行,後者則為反覆執行。

判斷一個單詞是否是迴文?
迴文是指把相同的詞彙或句子,在下文中調換位置或顛倒過來,產生首尾迴環的情趣,叫做迴文,也叫回環。比如 mamam redivider

function checkPalindrom(str) {  
    return str == str.split('').reverse().join('');
}

reverse() 方法用於顛倒陣列中元素的順序。

去掉一組整型陣列重複的值

比如輸入: [1,13,24,11,11,14,1,2] 
輸出: [1,13,24,11,14,2]
需要去掉重複的111 這兩個元素。

let unique = function(arr) {  
  let hashTable = {};
  let data = [];
  for(let i=0,l=arr.length;i<l;i++) {
    if(!hashTable[arr[i]]) {
      hashTable[arr[i]] = true;
      data.push(arr[i]);
    }
  }
  return data

}

module.exports = unique;

ES6的陣列去重方式
利用展開運算子和Set成員的唯一性

let arr = [1, 2, 3, 2, 1];

function unique(arr){
    return [...new Set(arr)];
}

console.log(unique(arr))  // [1, 2, 3]

獲取淘寶首頁共用了多少種標籤:

new Set([...document.querySelectorAll("*")].map(v=>v.nodeName)).size

統計一個字串出現最多的字母

輸入 : afjghdfraaaasdenas 
輸出 : a

function findMaxDuplicateChar(str) {  
  if(str.length == 1) {
    return str;
  }
  let charObj = {};
  for(let i=0;i<str.length;i++) {
    if(!charObj[str.charAt(i)]) {
      charObj[str.charAt(i)] = 1;
    }else{
      charObj[str.charAt(i)] += 1;
    }
  }
  let maxChar = '',
      maxValue = 1;
  for(var k in charObj) {
    if(charObj[k] >= maxValue) {
      maxChar = k;
      maxValue = charObj[k];
    }
  }
  return maxChar;

}

module.exports = findMaxDuplicateChar;

排序演算法

氣泡排序
function bubbleSort(arr) {  
    for(let i = 0,l=arr.length;i<l-1;i++) {
        for(let j = i+1;j<l;j++) {
          if(arr[i]>arr[j]) {
                let tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
            }
        }
    }
    return arr;
}
module.exports = bubbleSort;


快速排序
function quickSort(arr) {

    if(arr.length<=1) {
        return arr;
    }

    let leftArr = [];
    let rightArr = [];
    let q = arr[0];
    for(let i = 1,l=arr.length; i<l; i++) {
        if(arr[i]>q) {
            rightArr.push(arr[i]);
        }else{
            leftArr.push(arr[i]);
        }
    }

    return [].concat(quickSort(leftArr),[q],quickSort(rightArr));
}

module.exports = quickSort;

找出下列正陣列的最大差值比如:

輸入 [10,5,11,7,8,9]
輸出 6

function getMaxProfit(arr) {

    var minPrice = arr[0];
    var maxProfit = 0;

    for (var i = 0; i < arr.length; i++) {
        var currentPrice = arr[i];

        minPrice = Math.min(minPrice, currentPrice);

        var potentialProfit = currentPrice - minPrice;

        maxProfit = Math.max(maxProfit, potentialProfit);
    }

    return maxProfit;
}

webpack打包AMD、CMD、Common、UMD理解
webpack可以實現的功能:可以打包 AMD、CMD、Common、css\、coffee、json、Image 等均可打包,也可以打包自定義字尾的檔案,如:.vue、.jsx 等,都可以通過loaders載入器進行處理打包。

webpack特性:

  1. 將js、css等檔案視為一個模組,將外部或者第三方檔案也視為一個模組
  2. 實現按需載入,是瀏覽器能夠在最短時間開啟專案
  3. 適合大型專案操作

AMD/CMD/CommonJs是JS模組化開發的標準,目前對應的實現是RequireJs/SeaJs/nodeJs.

CommonJs主要針對服務端,AMD/CMD主要針對瀏覽器端,所以最容易混淆的是AMD/CMD

CommonJS
CommonJS 載入模組是同步的,所以只有載入完成才能執行後面的操作。

CommonJS定義的模組分為:{模組引用(require)} {模組定義(exports)} {模組標識(module)}

CommonJs 是伺服器端模組的規範,Node.js採用了這個規範。

根據CommonJS規範,一個單獨的檔案就是一個模組。載入模組使用require方法,該方法讀取一個檔案並執行,最後返回檔案內部的exports物件。

AMD((Asynchromous Module Definition)
AMD 是 RequireJS 在推廣過程中對模組定義的規範化產出

AMD非同步載入模組。它的模組支援物件 函式 構造器 字串 JSON等各種型別的模組。

CMD
CMD是SeaJS 在推廣過程中對模組定義的規範化產出

AMD/CMD區別
很多人說requireJS是非同步載入模組,SeaJS是同步載入模組,這麼理解實際上是不準確的,其實載入模組都是非同步的,只不過AMD依賴前置,js可以方便知道依賴模組是誰,立即載入,而CMD就近依賴,需要使用把模組變為字串解析一遍才知道依賴了那些模組,這也是很多人詬病CMD的一點,犧牲效能來帶來開發的便利性,實際上解析模組用的時間短到可以忽略。

  1. AMD是預載入,在並行載入js檔案同時,還會解析執行該模組(因為還需要執行,所以在載入某個模組前,這個模組的依賴模組需要先載入完成);而CMD是懶載入,雖然會一開始就並行載入js檔案,但是不會執行,而是在需要的時候才執行。
  2. AMD優點:載入快速,尤其遇到多個大檔案,因為並行解析,所以同一時間可以解析多個檔案。
    AMD缺點:並行載入,非同步處理,載入順序不一定,可能會造成一些困擾,甚至為程式埋下大坑。
  3. CMD優點:因為只有在使用的時候才會解析執行js檔案,因此,每個JS檔案的執行順序在程式碼中是有體現的,是可控的。
    CMD缺點:執行等待時間會疊加。因為每個檔案執行時是同步執行(序列執行),因此時間是所有檔案解析執行時間之和,尤其在檔案較多較大時,這種缺點尤為明顯。

UMD
UMD是AMD和CommonJS的糅合

AMD模組以瀏覽器第一的原則發展,非同步載入模組。
CommonJS模組以伺服器第一原則發展,選擇同步載入,它的模組無需包裝(unwrapped modules)。
這迫使人們又想出另一個更通用的模式UMD (Universal Module Definition)。希望解決跨平臺的解決方案。

UMD先判斷是否支援Node.js的模組(exports)是否存在,存在則使用Node.js模組模式。
在判斷是否支援AMD(define是否存在),存在則使用AMD方式載入模組。

web前端效能優化

轉載:http://blog.csdn.net/mahoking/article/details/51472697
一、瀏覽器訪問優化
1、減少http請求,合理設定 HTTP快取
2、使用瀏覽器快取
3、啟用壓縮
4、CSS Sprites:合併 CSS圖片,減少請求數的又一個好辦法。
5、LazyLoad Images(圖片懶載入)
6、CSS放在頁面最上部,javascript放在頁面最下面
7、非同步請求Callback(就是將一些行為樣式提取出來,慢慢的載入資訊的內容)
8、減少cookie傳輸
9、Javascript程式碼優化
10、CSS選擇符優化
11、CDN加速
12、反向代理:傳統代理伺服器位於瀏覽器一側,代理瀏覽器將http請求傳送到網際網路上,而反向代理伺服器位於網站機房一側,代理網站web伺服器接收http請求。

前端js圖片壓縮
FileReader()
toDataURL()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js壓縮圖片</title>
    <script src="jquery.js"></script>
</head>
<body>
    <input type="file" name="file" id="file">
    <div id="container"></div>

    <script>
    /*圖片地址
    https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E9%AB%98%E6%B8%85%E7%BE%8E%E5%A5%B3%20%E4%B8%9D%E8%A2%9C%E5%B7%A8%E4%B9%B3&step_word=&hs=0&pn=1&spn=0&di=57234189540&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=2&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs=3589338782%2C536437810&os=3988412231%2C488396405&simid=3515890414%2C233897128&adpicid=0&lpn=0&ln=1389&fr=&fmq=1490709487003_R&fm=result&ic=0&s=undefined&se=&sme=&tab=0&width=&height=&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fwww.bz55.com%2Fuploads%2Fallimg%2F150416%2F139-1504161AK9.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Bkzcc_z%26e3Bv54AzdH3F4jtgektzitAzdH3F8l9c9_z%26e3Bip4s&gsm=0&rpstart=0&rpnum=0
    */
    $(function(){
        $("#file").on("change",function(){
            var file=this.files[0];
            photoCompress(file,50,$("#container")[0])

        });
    })


/*
三個引數
file:一個是檔案(型別是圖片格式),
w:一個是檔案壓縮的後寬度,寬度越小,位元組越小
objDiv:一個是容器或者回調函式
photoCompress()
 */
    function photoCompress(file,w,objDiv){
        var ready=new FileReader();
            /*開始讀取指定的Blob物件或File物件中的內容. 當讀取操作完成時,readyState屬性的值會成為DONE,如果設定了onloadend事件處理程式,則呼叫之.同時,result屬性中將包含一個data: URL格式的字串以表示所讀取檔案的內容.*/
            ready.readAsDataURL(file);
            ready.onload=function(){
                var re=this.result;
                canvasDataURL(re,w,objDiv)
            }
    }
    function canvasDataURL(re,w,objDiv){
        var newImg=new Image();
        newImg.src=re;
        var imgWidth,imgHeight,offsetX=0,offsetY=0;
        newImg.onload=function(){
            var img=document.createElement("img");
            img.src=newImg.src;
            imgWidth=img.width;
            imgHeight=img.height;
            var canvas=document.createElement("canvas");
            canvas.width=w;
            canvas.height=w;
            var ctx=canvas.getContext("2d");
            ctx.clearRect(0,0,w,w);
            if(imgWidth>imgHeight){
                imgWidth=w*imgWidth/imgHeight;
                imgHeight=w;
                offsetX=-Math.round((imgWidth-w)/2);
            }else{
                imgHeight=w*imgHeight/imgWidth;
                imgWidth=w;
                offsetY=-Math.round((imgHeight-w)/2);
            }
            ctx.drawImage(img,offsetX,offsetY,imgWidth,imgHeight);
            var base64=canvas.toDataURL("image/jpeg",0.7);
            if(typeof objDiv == "object"){
                objDiv.appendChild(canvas);
            }else if(typeof objDiv=="function"){
                objDiv(base64);
            }
        }

    }

    </script>
</body>
</html>

photoCompress()
傳進引數就可以實現壓縮了,這是上傳圖片的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js壓縮圖片</title>
    <script src="jquery.js"></script>
</head>
<body>
    <input type="file" name="file" id="file">
    <div id="container"></div>

    <script>
    /*跨域是無法做的*/
    $(function(){

        var newImg=new Image();
        newImg.src="./timg.jpg";
        newImg.onload=function(){
            var currentImg=document.createElement("img");
            currentImg.src=newImg.src;
            photoCompress(currentImg,50,$("#container")[0])
        }
    })


/*
三個引數
file:一個是檔案(型別是圖片格式),
w:一個是檔案壓縮的後寬度,寬度越小,位元組越小
objDiv:一個是容器或者回調函式
photoCompress()
 */
    function photoCompress(file,w,objDiv){
        if(file.tagName.toLocaleLowerCase()=="img"){
            canvasDataURL(file.src,w,objDiv);
            return false;
        }
        var ready=new FileReader();
            /*開始讀取指定的Blob物件或File物件中的內容. 當讀取操作完成時,readyState屬性的值會成為DONE,如果設定了onloadend事件處理程式,則呼叫之.同時,result屬性中將包含一個data: URL格式的字串以表示所讀取檔案的內容.*/
            ready.readAsDataURL(file);
            ready.onload=function(){
                var re=this.result;
                canvasDataURL(re,w,objDiv)
            }
    }
    function canvasDataURL(re,w,objDiv){
        var newImg=new Image();
        newImg.src=re;
        var imgWidth,imgHeight,offsetX=0,offsetY=0;
        newImg.onload=function(){
            var img=document.createElement("img");
            img.src=newImg.src;
            imgWidth=img.width;
            imgHeight=img.height;
            var canvas=document.createElement("canvas");
            canvas.width=w;
            canvas.height=w;
            var ctx=canvas.getContext("2d");
            ctx.clearRect(0,0,w,w);
            if(imgWidth>imgHeight){
                imgWidth=w*imgWidth/imgHeight;
                imgHeight=w;
                offsetX=-Math.round((imgWidth-w)/2);
            }else{
                imgHeight=w*imgHeight/imgWidth;
                imgWidth=w;
                offsetY=-Math.round((imgHeight-w)/2);
            }
            ctx.drawImage(img,offsetX,offsetY,imgWidth,imgHeight);
            var base64=canvas.toDataURL("image/jpeg",0.7);
            if(typeof objDiv == "object"){
                objDiv.appendChild(canvas);
            }else if(typeof objDiv=="function"){
                objDiv(base64);
            }
        }

    }

    </script>
</body>
</html>

前端跨域知識總結

產生跨域的原因
1、瀏覽器限制
2、傳送xhr請求
3、跨域:只要協議、域名、埠有任何一個不同,都被當作是不同的域。

URL 說明 是否允許通訊
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://70.32.92.74/b.js
域名和域名對應ip 不允許
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同 不允許
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二級域名(同上) 不允許(cookie這種情況下也不允許訪問)
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名 不允許

特別注意兩點:
第一,如果是協議和埠造成的跨域問題“前臺”是無能為力的,
第二:在跨域問題上,域僅僅是通過“URL的首部”來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and ports must match”。

  1. document.domain + iframe (只有在主域相同的時候才能使用該方法)
  2. jsonp:動態建立script
  3. location.hash + iframe
  4. window.name + iframe
  5. postMessage(HTML5中的XMLHttpRequest Level 2中的API)
  6. CORS
  7. web sockets

跨域解決辦法之jsonp:
jsonp傳送的不是xhr請求,一般ajax請求(xhr)返回的是json物件,而jsonp返回的是script程式碼

jsonp的弊端:
1、伺服器需要改動程式碼支援
2、只支援Get
3、傳送的不是xhr請求