前端面試題(二)

html5有哪些新特性?如何處理HTML5新標籤的瀏覽器兼容問題?
簡述一下你對HTML語義化的理解?
JSON 的瞭解?
HTTP狀態碼知道哪些?
你有哪些性能優化的方法?
哪些常見操作會造成內存泄漏?
介紹一下css的盒模型
談談你對閉包的理解
你對前端界面工程師這個職位是怎麼樣理解的?
請說出三種減少頁面加載時間的方法。
如何解決跨域問題?
javascript裏面的繼承怎麼實現?
js判斷文字長度(區分中文及英文)?
比較map()、forEach()與for()的區別?


html5有哪些新特性?如何處理HTML5新標籤的瀏覽器兼容問題?

(1)
HTML5 現在已經不是 SGML 的子集,主要是關於圖像,位置,存儲,多任務等功能的增加。
(1)繪畫 canvas;
(2)用於媒介回放的 video 和 audio 元素;
(3)本地離線存儲 localStorage 長期存儲數據,瀏覽器關閉後數據不丟失;
(4)sessionStorage 的數據在瀏覽器關閉後自動刪除;
(5)語意化更好的內容元素,比如 article、footer、header、nav、section;
(6)表單控件,calendar、date、time、email、url、search;
(7)新的技術webworker, websocket, Geolocation;

(2)
IE8/IE7/IE6支持通過document.createElement方法產生的標籤,
可以利用這一特性讓這些瀏覽器支持HTML5新標籤,代碼如下:

var e = "abbr, article, aside, audio, canvas, datalist, details, dialog, eventsource, figure, footer, header, hgroup, mark, menu, meter, nav, output, progress, section, time, video".split(', ');
var i= e.length;
while (i--){
    document.createElement(e[i])
}

瀏覽器支持新標籤後,還需要添加標籤默認的樣式:

article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}
mark{background:#FF0;color:#000}

覽器支持HTML5新標籤,
瀏覽器支持新標籤後,還需要添加標籤默認的樣式。
當然也可以直接使用成熟的框架、比如html5shim;

<!--[if lt IE 9]>
<script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script>
<![endif]-->

簡述一下你對HTML語義化的理解?

HTML標籤可以分爲有語義的標籤,和無語義的標籤。比如table表示表格,form表示表單,a標籤表示超鏈接,strong標籤表強調。無語義標籤典型的有

,等。HTML語義化我的理解就是在頁面中儘量多滴結合場景多使用含有語義的標籤,少使用div,span等無語義的標籤。
  1,現在的開發基本上都是一個團隊合作進行開發。這種情況下,我們寫的代碼不僅要讓我們自己能看懂,而且也應該讓別人也容易理解和閱讀,要保證代碼的可維護性,這一點很重要。
  2,和搜索引擎建立良好溝通,有助於爬蟲抓取更多的有效信息
  3,考慮到代碼的可複用性,可移植性,方便其他設備的解析執行。移動設備、盲人閱讀器等。


JSON 的瞭解?

1。JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
2。JSON 是輕量級的文本數據交換格式,並不是編程語言。一般而言,輕量級(lightweight)等價於耦合度低、侵入性小。不過在這裏既可以指JSON與編程語言的耦合度小,又可以說明JSON文檔儲存相同信息所佔的資源少的。再者,JSON和XML一樣,既可以作爲配置文件、也可以作爲數據傳輸協議存在,當然,在JS中使用JSON比XML更優。
3。JSON 獨立於語言存在
4。JSON 具有自我描述性,更易理解
5。JSON 結構有兩種結構
json簡單說就是javascript中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通過這兩種結構可以表示各種複雜的結構。
1、對象:對象在js中表示爲“{}”括起來的內容,數據結構爲 {key:value,key:value,…}的鍵值對的結構,在面向對象的語言中,key爲對象的屬性,value爲對應的屬性值,所以很容易理解,取值方法爲 對象.key 獲取屬性值,這個屬性值的類型可以是 數字、字符串、數組、對象幾種。
2、數組:數組在js中是中括號“[]”括起來的內容,數據結構爲 [“java”,”javascript”,”vb”,…],取值方式和所有語言中一樣,使用索引獲取,字段值的類型可以是 數字、字符串、數組、對象幾種。
經過對象、數組2種結構就可以組合成複雜的數據結構了。
爲了方便地處理JSON數據,JSON提供了json.js包,下載地址:http://www.json.org/json.js

在數據傳輸流程中,json是以文本,即字符串的形式傳遞的,而JS操作的是JSON對象,所以,JSON對象和JSON字符串之間的相互轉換是關鍵。

詳細請見: http://blog.csdn.net/qq_32528231/article/details/52783210

HTTP狀態碼知道哪些?

1**(信息類):表示接收到請求並且繼續處理
100——客戶必須繼續發出請求
101——客戶要求服務器根據請求轉換HTTP協議版本

2**(響應成功):表示動作被成功接收、理解和接受
200——表明該請求被成功地完成,所請求的資源發送回客戶端
201——提示知道新文件的URL
202——接受和處理、但處理未完成
203——返回信息不確定或不完整
204——請求收到,但返回信息爲空
205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206——服務器已經完成了部分用戶的GET請求

3**(重定向類):爲了完成指定的動作,必須接受進一步處理
300——請求的資源可在多處得到
301——永久重定向
302——臨時重定向
303——建議客戶訪問其他URL或訪問方式
304——自從上次請求後,請求的網頁未修改過,服務器返回此響應時,不會返回網頁內容,代表上次的文檔已經被緩存了,還可以繼續使用
305——請求的資源必須從服務器指定的地址得到
306——前一版本HTTP中使用的代碼,現行版本中不再使用
307——申明請求的資源臨時性刪除

4**(客戶端錯誤類):請求包含錯誤語法或不能正確執行
400——客戶端請求有語法錯誤,不能被服務器所理解
401——請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
402——保留有效ChargeTo頭響應
403——禁止訪問,服務器收到請求,但是拒絕提供服務
404——一個404錯誤表明可連接服務器,但服務器無法取得所請求的網頁,請求資源不存在。eg:輸入了錯誤的URL
405——用戶在Request-Line字段定義的方法不允許
406——根據用戶發送的Accept拖,請求資源不可訪問
407——類似401,用戶必須首先在代理服務器上得到授權
408——客戶端沒有在用戶指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——服務器上不再有此資源且無進一步的參考地址
411——服務器拒絕用戶定義的Content-Length屬性請求
412——一個或多個請求頭字段在當前請求中錯誤
413——請求的資源大於服務器允許的大小
414——請求的資源URL長於服務器允許的長度
415——請求資源不支持請求項目格式
416——請求中包含Range請求頭字段,在當前請求資源範圍內沒有range指示值,請求也不包含If-Range請求頭字段
417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求長。

5**(服務端錯誤類):服務器不能正確執行一個正確的請求
HTTP 500 - 服務器遇到錯誤,無法完成請求
HTTP 502 - 網關錯誤
HTTP 503:由於超載或停機維護,服務器目前無法使用,一段時間後可能恢復正常

http://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81?fr=aladdin


你有哪些性能優化的方法?

  1. 壓縮源碼和圖片(js採用混淆壓縮,css進行普通壓縮,jpg圖片根據具體質量壓縮爲50%到70%,png用來源軟件壓縮24色變成8色,去掉一些png格式信息等)
  2. 選擇合適的圖片格式(顏色數多用jpg,顏色少用png,如果能通過服務器端判斷瀏覽器支持WebP就用WebP或SVG格式)
  3. 合併靜態資源(減少HTTP請求)
  4. 把多個css合併爲一個css,把圖片組合成雪碧圖
  5. 開啓服務端的Gzip壓縮(對文本資源非常有效,對圖片也沒那麼大壓縮率)
  6. 合併靜態資源(減少HTTP請求)
  7. 使用CDN(對公開庫,能和其他網站共享緩存)
  8. 延長靜態資源緩存時間
  9. 把css放頁面頭部,js放底部(這樣不會阻塞頁面渲染,讓頁面出現長時間的空白)
  10. 對於較大的文本資源,必須開啓gzip壓縮

這裏寫圖片描述


哪些常見操作會造成內存泄漏?

內存泄露是指一塊被分配的內存既不能使用,又不能回收,直到瀏覽器進程結束。
JavaScript 是一種垃圾收集式語言,這就是說,內存是根據對象的創建分配給該對象的,並會在沒有對該對象的引用時由瀏覽器收回。JavaScript 的垃圾收集機制本身並沒有問題,但瀏覽器在爲 DOM 對象分配和恢復內存的方式上卻有些出入。

下面是常見的4種內存泄露方式:
(1)意外的全局變量

js中如果不用 var 聲明變量,該變量將被視爲 window 對象(全局對象)的屬性,也就是全局變量.

function foo(arg) {
    bar = "this is a hidden global variable";
}

// 上面的函數等價於
function foo(arg) {
    window.bar = "this is an explicit global variable";
}

所以,你調用完了函數以後,變量仍然存在,導致泄漏.

如果不注意 this 的話,還可能會這麼漏:

function foo() {
    this.variable = "potential accidental global";
}

// 沒有對象調用foo, 也沒有給它綁定this, 所以this是window
foo();

你可以通過加上 ‘use strict’ 啓用嚴格模式來避免這類問題, 嚴格模式會組織你創建意外的全局變量.

(2)被遺忘的定時器或者回調

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
    }
}, 1000);

這樣的代碼很常見, 如果 id 爲 Node 的元素從 DOM 中移除, 該定時器仍會存在, 同時, 因爲回調函數中包含對 someResource 的引用, 定時器外面的 someResource 也不會被釋放.

(3)沒有清理的DOM元素引用

var elements = {
    button: document.getElementById('button'),
    image: document.getElementById('image'),
    text: document.getElementById('text')
};

function doStuff() {
    image.src = 'http://some.url/image';
    button.click();
    console.log(text.innerHTML);
}

function removeButton() {
    document.body.removeChild(document.getElementById('button'));

    // 雖然我們用removeChild移除了button, 但是還在elements對象裏保存着#button的引用
    // 換言之, DOM元素還在內存裏面.
}

(4)閉包

先看這樣一段代碼:

var theThing = null;
var replaceThing = function () {
  var someMessage = '123'
  theThing = {
    someMethod: function () {
      console.log(someMessage);
    }
  };
};

調用 replaceThing 之後, 調用 theThing.someMethod , 會輸出 123 , 基本的閉包, 我想到這裏應該不難理解.

解釋一下的話, theThing 包含一個 someMethod 方法, 該方法引用了函數中的 someMessage 變量, 所以函數中的 someMessage 變量不會被回收, 調用 someMethod 可以拿到它正確的 console.log 出來.

詳情:http://www.tuicool.com/articles/7J3amu


介紹一下css的盒模型

盒模型一共有兩種模式,一種是標準模式,另一種就是怪異模式

  當你用編輯器新建一個html頁面的時候你一定會發現最頂上都會有一個DOCTYPE標籤,例如:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

  <!DOCTYPE HTML>

  以上幾種DOCTYPE都是標準的文檔類型,無論使用哪種模式完整定義DOCTYPE,都會觸發標準模式,而如果DOCTYPE缺失則在ie6,ie7,ie8下將會觸發怪異模式(quirks 模式)。

首先定義一個div塊用來演示標準模式和怪異模式的區別,以下是Css樣式
  box { width: 200px; height: 200px; border: 20px solid black; padding: 50px; margin: 50px; }

  在標準模式下的盒模型如下圖所示,盒子總寬度/高=width/height+padding+border+margin

這裏寫圖片描述

  在怪異模式(ie)下的盒模型如下圖所示,盒子的總寬度和高度是包含內邊距padding和邊框border寬度在內的,盒子總寬度/高度=width/height + margin = 內容區寬度/高度 + padding + border + margin; 也就是盒子寬高 = 內容區域的寬高+padding+border;

這裏寫圖片描述

flex佈局,多列布局等
更詳細的見:http://www.cnblogs.com/jr1993/p/4788718.html


談談你對閉包的理解

js能力提升中無法繞過的一環,幾乎每次面試必問的問題,因爲在回答的時候.你的答案的深度,對術語的理解以及js內部解釋器的運作方式的描述,都是可以看出你js實際水平的.即使你沒答對,也能讓考官對你的水平有個評估.那麼我先來說說我對js中的閉包的理解.

  閉包是很多語言都具備的特性,在js中,閉包主要涉及到js的幾個其他的特性:1.作用域,2.垃圾(內存)回收機制,3.函數嵌套,等等.
  
1.特殊的作用域
變量的作用域無非就是兩種:全局變量和局部變量。
Javascript語言的特殊之處,就在於函數內部可以直接讀取全局變量。
另一方面,在函數外部自然無法讀取函數內的局部變量。
但是很多時候我們需要獲取到函數內部的局部變量,正常情況下,這是辦不到的,只有通過變通方法才能實現。我們在函數裏面在嵌套一個函數。

  
  瞭解了作用域鏈,我們再來看看js的內存回收機制,一般來說,一個函數在執行開始的時候,會給其中定義的變量劃分內存空間保存,以備後面的語句所用,等到函數執行完畢返回了,這些變量就被認爲是無用的了.對應的內存空間也就被回收了.下次再執行此函數的時候,所有的變量又回到最初的狀態,重新賦值使用.但是如果這個函數內部又嵌套了另一個函數,而這個函數是有可能在外部被調用到的.並且這個內部函數又使用了外部函數的某些變量的話.這種內存回收機制就會出現問題.如果在外部函數返回後,又直接調用了內部函數,那麼內部函數就無法讀取到他所需要的外部函數中變量的值了.所以js解釋器在遇到函數定義的時候,會自動把函數和他可能使用的變量(包括本地變量和父級和祖先級函數的變量(自由變量))一起保存起來.也就是構建一個閉包,這些變量將不會被內存回收器所回收,只有當內部的函數不可能被調用以後(例如被刪除了,或者沒有了指針),纔會銷燬這個閉包,而沒有任何一個閉包引用的變量纔會被下一次內存回收啓動時所回收.
閉包就是:可以訪問其他函數內部變量的函數

function foo() {
        var num = 123;

        function fn() {
            return num;//
        }
        return fn;
    }
    var m=foo();
    var f=m();
    console.log(f);//輸出的值爲123,這樣就可以訪問到函數內部變量num。

  //    原理就是利用閉包:在函數foo中嵌套了一個函數fn,利用函數fn可以訪問到其外部的變量,而獲取函數foo中的變量num,當外部調用函數foo()時候,
   //   函數foo中 return返回fn函數的實體,然後我再對函數fn進行調用就在外部訪問到函數內部變量num了。就是利用內部函數的閉包特性把函數foo中的變量取到外邊,
     // 說白了內部函數就相當於一個媒介,就是一個橋樑連接函數內部和外部。這就是閉包作用。
//讓內部函數在循環創建的時候立即執行,並且捕捉當前的索引值,然後記錄在自己的一個本地變量裏.然後利用返回函數的方法,重寫內部函數,讓下一次調用的時候,返回本地變量的值,代碼:
var result=[];
function foo(){
    var i= 0;
    for (;i<3;i=i+1){
        result[i]=(function(j){
            return function(){
                alert(j);
            };
        })(i);
    }
};
foo();
result[0](); // 0
result[1](); // 1
result[2](); // 2

//詳細見  http://www.cnblogs.com/waisonlong/category/714235.html

閉包的特點很鮮明,閉包內,變量無法釋放,無法被直接訪問;閉包可以被延遲執行。所以可以用它來做一些事情:
• 管理私有變量和私有方法,將對變量(狀態)的變化封裝在安全的環境中
• 將代碼封裝成一個閉包形式,等待時機成熟的時候再使用,比如實現柯里化和反柯里化
• 需要注意的,由於閉包內的部分資源無法自動釋放,容易造成內存泄露(使用完值後刪除)


你對前端界面工程師這個職位是怎麼樣理解的?

前端界面工程師是跟用戶接觸最近的一個職位,一個產品好壞並不是由企業說了算,用戶喜歡的纔是好的產品,而用戶所能評價就是他看到的和觸摸到的,前端界面工程師要做的就是呈現給用戶這些信息,一個好的前端界面工程師應該是一個能真正瞭解客戶的人。
前景:
隨着互聯網行業的蓬勃發展和終端設備的更新換代,前端技術也要時刻更新,要用更多的輕量型代碼完成更復雜的工作。
UI、產品經理、前端工程師要緊密配合,力求引領時代而不是跟隨時代

詳細見 http://blog.csdn.net/yisuowushinian/article/details/51412705


請說出三種減少頁面加載時間的方法。

答:1、合併Js文件和CSS 2、Sprites圖片技術3、壓縮文本和圖片 4、延遲顯示可見區域外的內容5、確保功能圖片優先加載6、重新佈置Call-to-Action按鈕7、圖片格式優化8、使用 Progressive JPEGs 9、精簡代碼10、延遲加載和執行非必要腳本11、使用AJAX採用緩存調用 12、自動化的頁面性能優化
13. 儘量減少頁面中重複的HTTP請求數量 14. 服務器開啓gzip壓縮 15. 使用多域名負載網頁內的多個文件、圖片
詳細見http://www.chinaz.com/web/2014/0527/353092.shtml
http://blog.csdn.net/wxzking/article/details/4089384

如何解決跨域問題?

8種解決跨域方案

詳見 轉載:http://blog.csdn.net/joyhen/article/details/21631833
原文 http://www.cnblogs.com/JChen666/p/3399951.html

javascript裏面的繼承怎麼實現?

1)原型繼承

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('hello, my name is ' + this.name);
};
function Man() {
}
Man.prototype = new Person('pursue');
var man1 = new Man();
man1.say(); //hello, my name is pursue
var man2 = new Man();
console.log(man1.say === man2.say);//true
console.log(man1.name === man2.name);//true

這種繼承方式很直接,爲了獲取Person的所有屬性方法(實例上的和原型上的),直接將父類的實例new Person(‘pursue’)賦給了子類的原型,其實子類的實例man1,man2本身是一個完全空的對象,所有的屬性和方法都得去原型鏈上去找,因而找到的屬性方法都是同一個。
所以直接利用原型鏈繼承是不現實的。

2)構造函數實現繼承

<script type="text/javascript">  
    function  Parent(name){  
        this.name=name;  
        this.sayParent=function(){  
            alert("Parent:"+this.name);  
        }  
    }  

    function  Child(name,age){  
        this.tempMethod=Parent;  
        this.tempMethod(name);  
        this.age=age;  
        this.sayChild=function(){  
            alert("Child:"+this.name+"age:"+this.age);  
        }  
    }  

    var parent=new Parent("江劍臣");  
    parent.sayParent(); //輸出:“Parent:江劍臣”  
    var child=new Child("李鳴",24); //輸出:“Child:李鳴 age:24”  
    child.sayChild();  
</script>  

3)call、apply是實現集成

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
    Person.apply(this, arguments);
}
//Man.prototype = new Person('pursue');
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
man1.say(); //say is not a function

這裏子類的在構造函數裏利用了apply去調用父類的構造函數,從而達到繼承父類屬性的效果,比直接利用原型鏈要好的多,至少每個實例都有自己那一份資源,但是這種辦法只能繼承父類的實例屬性,因而找不到say方法,爲了繼承父類所有的屬性和方法,則就要修改原型鏈,從而引入了組合繼承方式。

4)組合繼承

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
    Person.apply(this, arguments);
}
Man.prototype = new Person();
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
console.log(man1.say === man2.say);//true
man1.say(); //hello, my name is joe

需要注意的是man1和man2的實例屬性其實是覆蓋了原型屬性,但是並沒要覆蓋掉原型上的say方法(因爲它們沒有),所以這裏man1.say === man2.say依然返回true,因而需要十分小心沒有覆蓋掉的原型屬性,因爲它是所有實例共有的。

5)寄生組合繼承

function Person (name, age) {
            this.name = name;
            this.age = age;
        }
Person.prototype.say = function(){
    console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
    Person.apply(this, arguments);
}
Man.prototype = Object.create(Person.prototype);//a.
Man.prototype.constructor = Man;//b.
var man1 = new Man('pursue');
var man2 = new Man('joe');
console.log(man1.say == man2.say);
console.log(man1.name == man2.name);

其實寄生組合繼承和上面的組合繼承區別僅在於構造子類原型對象的方式上(a.和b.),這裏用到了Object.creat(obj)方法,該方法會對傳入的obj對象進行淺拷貝,類似於:

function create(obj){
    function T(){};
    T.prototype = obj;
    return new T();
}

因此,a.會將子類的原型對象與父類的原型對象進行很好的連接,而並不像一般的組合繼承那樣直接對子類的原型進行復制(如Man.prototype = new Person();),這樣只是很暴力的在對屬性進行覆蓋。而寄生組合繼承方式則對實例屬性和原型屬性分別進行了繼承,在實現上更加合理。

注意:代碼b.並不會改變instanceof的結果,但是對於需要用到construcor的場景,這麼做更加嚴謹。

http://blog.csdn.net/kkkkkxiaofei/article/details/46474069

http://www.jb51.net/article/81766.htm

http://www.cnblogs.com/humin/p/4556820.html


js判斷文字長度(區分中文及英文)?

方法一:

var len = 0;  
        var v = $.trim($(this).val());  
        for(i=0;i<v.length;i++)  {  
            if(v.charCodeAt(i)>256)  {  
                len += 3;  
            } else {  
                len++;  
            }  
        }  

利用charCodeAt 獲取該字符的unicode編碼來判斷,(unicode編碼:例如,字符A的編碼是65,字符B的編碼是66,以此類推)當大於256時,說明是中文;之後通過判斷服務器對1箇中文的長度 來控制 前臺length 長度。

[javascript] view plain copy
alert("都是a".length);  

結果爲3 可以看出js .length 方法不區分中英文。

方法二:

function isChinese(str){  //判斷是不是中文  
    var reCh=/[u00-uff]/;  
    return !reCh.test(str);  
}  
function lenStat(target){  
    var strlen=0; //初始定義長度爲0  
    var txtval = $.trim(target.val());  
    for(var i=0;i<txtval.length;i++){  
     if(isChinese(txtval.charAt(i))==true){  
      strlen=strlen+2;//中文爲2個字符  
     }else{  
      strlen=strlen+1;//英文一個字符  
     }  
    }  
    strlen=Math.ceil(strlen/2);//中英文相加除2取整數  
    return strlen;  
}  

利用charAt 返回該位置的字符,利用正則表達式判斷。


比較map()、forEach()與for()的區別?

總結:大體是

1、map速度比foreach快

2、map會返回一個新數組,不對原數組產生影響,foreach不會產生新數組,

3、map因爲返回數組所以可以鏈式操作,foreach不能

那麼接下來,我繼續做分析,爲什麼更推薦用.map(),而不是.forEach()?

首先,.map()要比.forEach()執行速度更快。雖然我也說過執行速度不是我們需要考慮的主要因素,但是他們都比for()要更好用,那肯定要選更優化的一個。

第二,.forEach()的返回值並不是array。如果你想用函數式編程寫個鏈式表達式來裝個逼,.map()將會是你不二的選擇。

來看下面這個例子:

var arr = [1, 2, 3];

console.log(
    arr.map(function(i){
        return i+i;
    })
    //鏈式風格
    .sort()
);// [2,4,6]

console.log(
    arr.forEach(function(i){
        return i+i;
    })
    //接不起來,斷了
    .sort()
);//TypeError: Cannot read property 'sort' of undefined

最後,感謝大家耐心的閱讀,排個序

.map() > .forEach() > for()

轉自: http://www.cnblogs.com/chaoyuehedy/p/6905422.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章