前端常見問題總結

補:get請求傳參長度的誤區

  • 實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求參數的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。

  • 不同的瀏覽器和WEB服務器,限制的最大長度不一樣要支持IE,則最大長度為2083byte,若只支持Chrome,則最大長度 8182byte

補:get和post請求在緩存方面的區別

  • get請求類似于查找的過程,用戶獲取數據,可以不用每次都與數據庫連接,所以可以使用緩存
  • post不同,post做的一般是修改和刪除的工作,所以必須與數據庫交互,所以不能使用緩存。因此get請求適合于請求緩存。

1.三次握手and四次揮手

  • 三次握手
    詳細描述:
    客戶端發送連接請求報文,服務器接受連接后回復ACK報文,并為這次連接分配資源。客戶端接收到ACK報文后也向服務器發生ACK報文,并分配資源,這樣TCP連接就建立了。
    簡單的理解:

    • 客戶端看到服務器,打聲招呼(發送syn);
    • 服務器收到客戶端的招呼,也向客戶端打招呼,表示他看到了(發送syn+ack
    • 客戶端看到服務器的回應,相當建立溝通(發送ack),表示很開心

    詳細過程:

    • 1)第一次握手:A的TCP客戶進程也是首先創建傳輸控制塊TCB,然后向B發出連接請求報文段(首部的同步位SYN=1,初始序號seq=x)
    • 2)第二次握手:B收到連接請求報文段后,如同意建立連接,則向A發送確認,在確認報文段中(SYN=1,ACK=1)
    • 3)第三次握手:TCP客戶進程收到B的確認后,要向B給出確認報文段(ACK=1)
image.png
  • 四次揮手
    TCP斷開鏈接的過程和建立鏈接的過程比較類似,只不過中間的兩部并不總是會合成一步走,所以它分成了4個動作。
    簡單理解:
    • 客戶端揮手(fin)
    • 服務器傷感地微笑(ack)
    • 服務器揮手(fin)
    • 客戶端傷感地微笑(ack)。
      詳細描述:
    • 1)客戶端發出連接釋放報文,并且停止發送數據。釋放數據報文首部,FIN=1,客戶端進入FIN-WAIT-1(終止等待1)狀態
    • 2)服務器收到連接釋放報文,發出確認報文,ACK=1,服務端就進入了CLOSE-WAIT(關閉等待)狀態
    • 3)客戶端收到服務器的確認請求后,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態。
      服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文,FIN=1。服務器就進入了LAST-ACK(最后確認)狀態,等待客戶端的確認。
    • 4) 客戶端收到服務器的連接釋放報文后,必須發出確認,ACK=1。此時,客戶端就進入了TIME-WAIT(時間等待)狀態。
      注意此時TCP連接還沒有釋放,必須經過2個MSL(最長報文段壽命)的時間后(即兩分鐘),當客戶端撤銷相應的TCB后,才進入CLOSED狀態
      服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB后,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
  • 總的說就是:
    客戶端要斷開,告訴服務器,服務器同意斷開連接。
    服務器發送完最后數據,服務器要斷開,告訴客戶端,客戶端同意斷開連接。
    客戶端同意斷開連接,服務器立馬close。但是客戶端還要等待兩分鐘。
image.png
  • 為什么連接的時候是三次握手,關閉的時候卻是四次握手?

答:中間的兩個動作沒有合并,是因為tcp存在「半關閉」狀態,也就是單向關閉。
因為當Server端收到Client端的syn連接請求報文后,可以直接發送syn+ack報文。其中ack報文是用來應答的,syn報文是用來同步的。但是關閉連接時,當Server端收到fin報文時,很可能并不會立即關閉,所以只能先回復一個ack報文,告訴Client端,"你發的fin報文我收到了"。只有等到我Server端所有的數據報文都發送完了,我才能發送fin報文,因此不能一起發送。故需要四步握手。

  • 為什么TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。


2.url到頁面渲染完成的經過

大致分為三步:

  • 1. 域名解析
    • 瀏覽器會將輸入的域名解析成相應的ip地址
      1. 查看瀏覽器內部緩存
      1. 查看本機的host文件,會查看本機的host文件下,是否存了對應的ip地址
      1. 本地路由器的DNS解析
      1. 查看網絡服務DNS
      1. 查詢到ip地址后,開始建立TCP三次握手,與服務器建立連接
      1. 通過協議(http)向目標主機發送請求
  • 2. 服務器接收請求并返回數據
      1. 服務器接收到了瀏覽器發送的請求后,根據某個協議,通過web-server把瀏覽器發送的數據進行打包(包含請求頭,ip地址,請求路徑和查詢參數等)
      1. web-server把數據打包后,發送給網站代碼(比如django、flask、node.js等后端服務)
      1. 后端服務軟件會根據路徑和查詢參數進行相應處理,返回給瀏覽器對應的數據包(包括http協議組成的代碼。里面包含頁面的布局、文字。數據也可能是圖片、腳本程序,反應頭,反應數據,請求頭等)
  • 3. 瀏覽器接收數據并渲染頁面
      1. 瀏覽器接收到返回的數據包,根據瀏覽器的渲染機制對相應的數據進行渲染。
      1. 渲染后的數據,進行相應的頁面呈現和腳步的交互。

3.js引擎的執行機制

(1) JS是單線程語言
(2) JS的 Event Loop是JS的執行機制。

  • js為什么是單線程的呢?
    因為,如果是多線程,若幾個線程同時操作dom的話,瀏覽器該怎么執行呢。

  • js為什么需要異步呢?
    js中不存在異步,是從上而下順序執行的,但是這樣很容易阻塞,若某一句代碼解析執行時間很長,那用戶就需要等待很長時間,所以需要異步執行。

  • js怎么實現異步呢?
    就是通過本節的核心事件循環(Event Loop)了,那事件循環具體是什么呢?
    比如:

cosole.log(1);
setTimeOut(function(){
    cosole.log(2);
},0);
cosole.log(3);
執行的輸出順序是: 1  3  2

js是順序從上到下執行,但是setTimeOut是最后才執行的,就證明了異步的存在。js也就將任務分為:同步任務和異步任務。

  • 那事件循環具體怎么循環?
    • 1.js判斷是同步事件還是異步事件,同步就進入執行棧,異步事件被掛起
      1. 異步事件返回結果后,就進入消息隊列
      1. 同步任務進入執行棧后一直執行,直到執行棧為空時,才會去消息隊列中查看是否有可執行的異步任務,如果有就推入執行棧中

循環執行上述三步,直到執行棧為空,就是事件循環了

所以上面例子的執行順序分析是怎樣的呢?

console.log(1) 是同步任務,放入主線程(執行棧)里
setTimeout() 是 異步任務,被掛起, 0秒之后被推入消息隊列里
console.log(3 是同步任務,放到主線程(執行棧)里

當 1、 3輸出后,主線程去消息隊列(事件隊列)里查看是否有可執行的函數,執行setTimeout里的函數,輸出2

以上就是event loop 的簡單分析了。但是只是很淺的一部分,因為還有下面這樣情況:

setTimeout(function(){
     console.log('定時器')
 });
 
 new Promise(function(resolve){
     console.log('開始for循環');
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log('執行then')
 });
  console.log('執行結束');

對于這樣多個異步的事件,按照之前的分析應該輸出:開始for循環 --> 執行結束 --> 定時器 --> 執行then
但是實際的輸出卻是: 開始for循環 --> 執行結束 --> 執行then --> 定時器

會發現 是 先執行promise 再執行的setTimeOut ,那難道是異步任務的執行順序,不是前后順序,而是另有規定? 事實上,按照異步和同步的劃分方式,并不準確。

而準確的劃分方式是:

  • macro-task(宏任務):包括整體代碼script,setTimeout,setInterval
  • micro-task(微任務):Promise,process.nextTick

按照這種分類方式:JS的執行機制

  • 執行一個宏任務,過程中如果遇到微任務,就將其放到微任務的【事件隊列】里

  • 當前宏任務執行完成后,會查看微任務的【事件隊列】,并將里面全部的微任務依次執行完

重復以上2步驟,再結合前面的事件循環,就是更為準確的JS執行機制了。

所以上面例子的執行順序分析是怎樣的呢?

先執行script宏任務
遇到 setTimeOut 是宏任務,將其放入宏任務隊列
遇到 new Promise直接執行,打印  "開始for循環"
遇到 then 是微任務,將其放入微任務隊列
打印 "執行結束"
本輪宏任務(script)執行完畢,檢查微任務隊列,遇到then,執行輸出 " 執行then",就只有這一個微任務,所以執行結束
本輪 event loop 執行結束
進入下一輪 
執行宏任務 setTimeOut,打印 "定時器"
再查看微任務隊列,沒有微任務
執行完畢

4.hash與history的區別

  • hash模式

    • hash就是指url尾巴后的#號以及后面的字符,hash值變化不會導致瀏覽器向服務器發出請求,而且hash改變會觸發hashchange事件,瀏覽器的進后退也能對其進行控制,所以人們在html5的history出現前,基本都是使用hash來實現前端路由的。
    • hash出現url中,但不會被包含在HTTP請求中,對后端完全沒有影響,因此改變hash不會重新加載頁面
    • hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。其次,hash的傳參是基于url的,如果要傳遞復雜的數據,會有體積的限制
  • history模式

    • history模式不僅可以在url里放參數,還可以將數據存放在一個特定的對象中。
      history——— 利用了HTML5 History Interface 中新增的 pushState()和replaceState()方法。
      (需要特定瀏覽器的支持)history不能運用與IE8一下
  • pushState()和 replaceState()的區別:

    • pushState 是創建新的歷史紀錄
    • replaceState是修改當前歷史紀錄
window.history.pushState(state,title,url)
  state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state里獲取
  title:標題,基本沒用,一般傳null
  url:設定新的歷史紀錄的url。新的url與當前url的origin必須是一樣的,否則會拋出錯誤。url可以時絕對路徑,也可以是相對路徑。
  如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成       https://www.baidu.com/a/qq/,
  執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/

window.history.replaceState(state,title,url)
  與pushState 基本相同,但她是修改當前歷史紀錄,而 pushState 是創建新的歷史紀錄

window.addEventListener("pospstate",function(){
   監聽瀏覽器前進后退事件,pushState與replaceState方法不會觸發
})
window.history.back()   后退
window.history.forward()   前進
window.history.go(1)   前進一部,-2回退兩不,window.history.lengthk可以查看當前歷史堆棧中頁面的數量

這兩個方法應用于瀏覽器的歷史紀錄站,在當前已有的back、forward、go 的基礎之上,他們提供了對歷史紀錄進行修改的功能,只是當他們執行修改使,雖然改變了當前的url,但你的瀏覽器不會立即像后端發送請求

  • 404錯誤

1、hash模式下,僅hash符號之前的內容會被包含在請求中,如 http://www.abc.com 因此對于后端來說,即使沒有做到對路由的全覆蓋,也不會返回404錯誤;
2、history模式下,前端的url必須和實際后端發起請求的url一致,如http://www.abc.com/book/id 。如果后端缺少對/book/id 的路由處理,將返回404錯誤。


5.vue鉤子函數

(1)與生命周期有關的生命周期函數: beforeCreatecreatedbeforeMountedmountedbeforeUpdateupdatedbeforeDestorydestoryed
(2)computedwatchfilter
(3)自定義指令directive的鉤子函數

  • bind : 只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數可以定義一個在綁定時執行一次的初始化動作
  • inserted:被綁定元素插入父節點時調用(父節點存在即可調用,不必存在于 document)
  • update: 被綁定元素所在的模板更新時調用,而不論綁定值是否
  • componentUpdated: 被綁定元素所在模板完成一次更新周期時調
  • unbind: 只調用一次,指令與元素解綁時

常用參考鏈接:http://www.lxweimin.com/p/8314ccd03fa9


6.vue常用指令

  • v-for v-for="字段名 in(of) 數組json" 循環數組或json
  • v-model 數據的雙向綁定
  • v-if 顯示與隱藏 ,是創建和刪除元素
  • v-else-if 必須和v-if連用
  • v-else 必須和v-if連用 不能單獨使用 否則報錯 模板編譯錯誤
    • v-show 顯示內容,只是切換display值
    • v-hidden 隱藏內容
  • v-bind 動態綁定
  • v-bind:class 3種綁定方法
    • 1.對象型 {red:isred}
    • 2.三元型 isred?"red":"blue"
    • 3.數組型 [{red:"isred"},{blue:"isblue"}]
  • v-on 監聽dom事件,可以縮寫為@,例如綁定一個點擊函數 ,函數必須寫在methods里面
  • v-text 解析文本
  • v-html 解析html標簽
  • v-once 進入頁面時 ,只渲染一次,不在進行渲染

常用參考鏈接:https://blog.csdn.net/dz13271116886/article/details/99708315


7.vue常用修飾符

  • 事件修飾符(5個)
    • .stop:阻止事件冒泡
    • .prevent :阻止默認事件
    • .once :只執行一次
    • .capture :捕獲事件,與冒泡相反
    • .self :只觸發自身事件
  • 鍵盤修飾符(9個)
    • .enter:回車鍵
    • .tab:制表鍵
    • .delete:含delete和backspace鍵
    • .esc:返回鍵
    • .space: 空格鍵
    • .up:向上鍵
    • .down:向下鍵
    • .left:向左鍵
    • .right:向右鍵
  • v-modle修飾符(3個)
    • .number:將輸出字符串轉為Number類型
    • .lazy:在改變后才觸發(也就是說只有光標離開input輸入框的時候值才會改變)
    • .trim:自動過濾用戶輸入的首尾空格

詳細參考鏈接:https://blog.csdn.net/qq_42238554/article/details/86592295


8.vue常用組件

  • vue-cli : 項目構建工具
  • vue-router:路由
  • vuex:狀態管理
  • axios:http請求
  • 組件庫的組件 eg:Element-ui 、iview

詳細參考鏈接:sohu.com/a/328202078_120047065


9.vue 過濾器

在vue中提供了Vue.filter('filterName',fn)來定義一個過濾器。
過濾器可以在HTML代碼中使用,對動態拿到的數據進行過濾
filter不會修改原始數據,它的作用是過濾數據。
通過|管道符來過濾前面數據

  • 過濾器參數:
    • 第一個參數 fliterName:是過濾器的名字
    • 第二個參數 fn :是過濾器功能函數(兩個參數)
  • 過濾功能函數參數:
    • 第一個參數是傳入的要過濾數據,即原數據。
    • 第二個參數開始就是html調用過濾器的時候傳入的參數。

用法參考鏈接:https://blog.csdn.net/badmoonc/article/details/81485803


10.MVVM的理解

MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。MVVM 就是將其中的View 的狀態和行為抽象化,讓我們將視圖 UI 和業務邏輯分開。

響應式原理

觀察者-訂閱者(數據劫持):

  • vueObserver 數據監聽器,把一個普通的 JavaScript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象所有的屬性,并使用Object.defineProperty()方法把這些屬性全部轉成setter、getter方法。當data中的某個屬性被訪問時,則會調用getter方法,當data中的屬性被改變時,則會調用setter方法。
  • Compile指令解析器,它的作用對每個元素節點的指令進行解析,替換模板數據,并綁定對應的更新函數,初始化相應的訂閱。
  • Watcher 訂閱者,作為連接 Observer 和 Compile 的橋梁,能夠訂閱并收到每個屬性變動的通知,執行指令綁定的相應回調函數。
  • Dep 消息訂閱器,內部維護了一個數組,用來收集訂閱者(Watcher),數據變動觸發notify 函數,再調用訂閱者的 update 方法

實現方法:

  • 1.實現compile,進行模板的編譯,包括編譯元素(指令)、編譯文本等,達到初始化視圖的目的,并且還需要綁定好更新函數;
  • 2.實現Observe,監聽所有的數據,并對變化數據發布通知;
  • 3.實現watcher,作為一個中樞,接收到observe發來的通知,并執行compile中相應的更新方法。
  • 4.結合上述方法,向外暴露mvvm方法。


    執行過程

過程描述:
(1) 當創建一個vue對象時,先進入初始化階段:(兩部分工作)
一方面:vue 會遍歷data的所有屬性,通過object.defineproprety()方法,將所有屬性變成setter和getter。 另一方面:vue的指令編譯器Complie會解析每個元素節點,初始化視圖,然后由watcher(訂閱者)更新視圖,此時watcher會將自身添加到消息訂閱器(Dep)中,初始化完畢。

(2) 當數據變化時:會觸發 observer數據監聽器中的setter方法,setter 會調用Dep中的方法,此時Dep會去遍歷所有的訂閱者,然后去調用訂閱者的update方法,通知訂閱者進行視圖更新。

參考:https://segmentfault.com/a/1190000018399478


11.vue生命周期

Vue實例有一個完整的生命周期,也就是說從開始創建、初始化數據、編譯模板、掛在DOM、渲染-更新-渲染、卸載等一系列過程

  • beforeCreate :創建之前,在實例初始化之后,數據觀測和事件配置之前被調用。
  • created: 創建完成,實例已完成以下配置:數據觀測、屬性和方法的運算,watch/event事件回調,完成了data 數據的初始化,el沒有。此時dom還沒渲染,可以在此處進行ajax請求。
  • beforeMount : 掛載之前,相關的render函數首次被調用(虛擬DOM),實例已完成以下的配置: 編譯模板,把data里面的數據和模板生成html,完成了el和data 初始化,注意此時還沒有掛在html到頁面上。
  • mounted:掛載完成,此時dom已渲染完成,可以訪問dom元素,只在掛載到vue 對象上執行一次,而后每次更新執行的都是update
  • beforeUpdate:在數據更新之前被調用
  • updated:數據更新之后,該鉤子在服務器端渲染期間不被調用
  • beforeDestroy:銷毀之前,此時vue實例依然可以使用
  • destroyed:銷毀,所有的事件監聽器會被移出,所有的子實例也會被銷毀,該鉤子在服務器端渲染期間不被調用

詳細參考連接:http://www.lxweimin.com/p/672e967e201c


12.vue動態路由

在vue項目中,使用vue-router如果進行不傳遞參數的路由模式,則稱為靜態路由;
如果能夠傳遞參數,對應的路由數量是不確定的,此時的路由稱為動態路由。

比如在寫商品詳情頁面的時候,頁面結構都一樣,只是商品id的不同,所以這個時候就可以用動態路由動態。

冒號后面就是動態的參數
路由配置:
const router = new VueRouter({
    routers:[
      {
        path:'/home:id'
        name:'home'
        component:home
      }
    ]
});

使用:
<template>
  <div>
    <router-link to="/home/10">衣服</router-link>
    <router-link to="/home/11">麻辣火鍋</router-link>
    <router-link to="/home/12">肉夾饃</router-link>
  </div>
</template>

實現參數傳遞的方法:

  1. 使用query傳參,name屬性為要跳轉的組件所對應的name,query為要攜帶的參數
<router-link :to="{name:'main','query':{data:'allData'}}"></router-link>
  1. 使用params傳參,name屬性為要跳轉的組件所對應的name,params為要攜帶的參數
<router-link :to="{name:'main','params':{data:'allData'}}"></router-link>
  • 使用params傳參時,url中不會出現參數,頁面刷新后參數會消失
  • 使用query傳參時,url中會出現參數,頁面刷新后參數不會消失

3.設置頁面默認的路由參數(query/params):

 this.$router.push( {name: 'main', 'query': {data: 'allData'} } )
this.$router.push( {path: '/main', 'query': {data: 'allData'} } )
  • 在組件中接受參數 : this.$route.query.data || this.$route.params.data

13.post、get、put、delete

post、get、put、delete就像對應著數據庫的CRUD(增、刪、改、查)

    post             /url          創建
    delete           /url/xxx       刪除
    put              /url/xxx       更新或創建
    get              /url/xxx       查詢

(1) get請求,請求會向數據庫發索取數據的請求,從而來獲取信息,該請求就像數據庫的select操作一樣,只是用來查詢一下數據,不會修改、增加數據,不會影響資源的內容,即該請求不會產生副作用。無論進行多少次操作,結果都是一樣的,具有冪等性。

(2) put 請求,求是向服務器端發送數據的(與get不同)從而改變信息,該請求就像數據庫的update操作一樣,用來修改數據的內容,但是不會增加數據的種類等,也就是說無論進行多少次put操作,其結果并沒有不同,具有冪等性。

(3) post 請求,與put請求類似。都是向服務器端發送數據求會改變數據的種類等資源,就像數據庫的insert操作一樣,會創建新的內容。幾乎目前所有的提交操作都是用POST請求的。不具有冪等性。

(4) delete 請求,用來刪除某一資源,該請求就像數據庫的delete操作。

put 與post 的共同點及區別?

  • put和post 都是向服務器發送數據
  • post 主要是在一個集合資源之上(url),put 主要作用在一個具體的資源之上(url/xxx)
  • put 通常指定了資源的存放位置,而post沒有。post的數據存放位置由服務器自己決定,如果url可以在客戶端確定,那么可使用put,否則用post
  • put 有等冪性,而post沒有。
    冪等性:冪等意味著對同一個URL的多次請求會返回一樣的結果

14.跨域方法

  • jsonp
  • CORS
  • webSocket
  • postMessage

詳情鏈接:http://www.imooc.com/article/40074


15.vue插件(圖表,excel)


16.callback、promise、async-await

請參考鏈接


17.map、reduce、filter、forEach

  • map、filter、reduce會返回新數組,返回值是新數組或結果
  • forEach會改變原來數組,forEach沒有返回值
  • map:用來迭代對數組進行統一的操作(運算),返回一個新數組
  • reduce: 用來迭代一個數組,并且把它累積到一個值中
  • filter:用來迭代一個數組,并且按給出的條件過濾出符合的元素

18.for、forEach、 for-in 、 for-of

  • for循環
    遍歷數組

  • forEach循環
    遍歷數組,對象(不包括原型上的屬性)
    循環不能中途退出,不能使用break,return

  • for-in
    這個循環是特別針對遍歷對象屬性的。
    會遍歷對象的所有屬性,包括原型上的屬性和自定義屬性
    對象的屬性是沒有順序的,所以for-in遍歷屬性輸出也是沒有順序的
    若對象是null或undefined有可能會報錯

  • for-of
    這個循環是最棒的,不僅支持數組,還支持遍歷類數組對象和其他可迭代對象。
    可以使用 break、continue、return
    for-of循環也支持字符串遍歷,將字符串視為一系列的Unicode字符來進行遍歷
    for-of也支持Map和Set遍歷。
    for-of不遍歷普通對象。

小總結:

  • for-in循環的每次迭代操作會同時搜索實例或者原型屬性,for-in循環的每次迭代會產生很多開銷。除非明確要迭代一個屬性數量未知的對象,否則應該避免使用。 for-in 并不適合用來遍歷數組中的元素,其更適合遍歷對象中的屬性。
  • forEach循環不會遍歷原型鏈上的屬性,不能break和return。
  • for-of 循環這是最直接、最簡潔的遍歷數組的方法。這個方法避開了for-in循環的所有缺陷
  • forEach 的速度不如 for
  • for in循環出的是key,for of循環出的是value
    for-in 、for-of遍歷普通對象
let  arr = {
  name:'aaa',
  age:23,
  sex:'女'
}
普通對象要加可枚舉的屬性Object.keys(),不然報錯
for(let i of Object.keys(arr)){
  console.log(i);
}  //name age sex

for(let i in arr){
  console.log(i);
}  //name age sex

for-of 遍歷 Map ,初始是一個二維數組,對應的鍵值匹配

let test = new Map([['name','aaa'],['age',12],['sex','女']]);
for (var [key, value] of test) {
  console.log(key +" is "+ value);
}
//name is aaa
//age is 12
//sex is 女

for-of 遍歷 Set ,遍歷同時會進行數組的去重

var test = new Set([1,1,2,3,4,5]);
for (var i of test) {
  console.log(i);
}
//1,2,3,4,5
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一、深復制和淺復制的區別? 1、淺復制:只是復制了指向對象的指針,即兩個指針指向同一塊內存單元!而不復制指向對象的...
    iOS_Alex閱讀 1,424評論 1 27
  • 前端目錄 HTML相關 CSS相關 JAVASCRIPT相關 DOM相關 HTTP相關 VUE相關 算法相關 網絡...
    keyuan0214閱讀 457評論 0 2
  • 前端開發面試知識點大綱: HTML&CSS: 對Web標準的理解、瀏覽器內核差異、兼容性、hack、CSS基本功:...
    秀才JaneBook閱讀 2,499評論 0 25
  • 面試題鏈接地址 https://juejin.im/post/5cbff661e51d456e693f48ec#h...
    祝家莊打烊閱讀 539評論 0 1
  • 1,java堆,分新生代老年代,新生代有Eden,from surviver,to surviver三個空間,堆被...
    城市里永遠的學習者閱讀 928評論 0 49