亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

Javascript中八種遍歷方法的執行速度深度對比

2019-11-19 16:44:43
字體:
來源:轉載
供稿:網友

前言

遍歷數組或對象是一名程序員的基本素養之一. 然而遍歷卻不是一件簡單的事, 優秀的程序員知道怎么去選擇合適的遍歷方法, 優化遍歷效率. 本篇將帶你走進JavaScript遍歷的世界, 享受分析JS循環的快感. 本篇所有代碼都可以直接運行, 希望您通讀本篇后, 不止是瀏覽, 最好是親手去實踐下.

概述

js有如下兩種數據需要經常遍歷

  • 數組(Array)
  • 對象(Object)

同時又提供了如下8種方法方便我們遍歷元素

  • for
  • while(或do~while)
  • forEach
  • for in
  • $.each
  • $(selecter).each
  • map
  • every

最終我們將分析遍歷效率選出最佳遍歷選手.

本文將針對如下兩種數據進行詳細的分析和舉栗. 下面舉栗中如果不加特殊說明將會用到如下數據.

var array = ["囚徒","過客","領袖"];//職場3種人var o = {0:"linda",1:"style",2:"nick",length:3};

for

語法: for(初始化; 循環執行條件; 每遍歷一個元素后做的事情;){}

(function(){//循環置于閉包之內 for(var i=0,length=array.length;i<length;i++){//緩存數組長度 console.log(array[i]);//內部方法若有可能相互影響,也要置于閉包之內 }})();

for循環只能遍歷數組, 不能遍歷對象. 寫for循環時有兩點需要注意.

  • 其一, 為了避免遍歷時執行多遍計算數組長度的操作, 影響效率, 建議在循環開始以變量的形式緩存下數組長度, 若在循環內部有可能改變數組長度, 請務必慎重處理, 避免數組越界.
  • JavaScript中并沒有類似java的塊級作用域, for循環內部定義的變量會直接暴露在外(如 i,循環退出后,i變量將等于數組長度, 后續代碼將能訪問到 i 變量的值), 因此建議將for循環置于閉包內. 特別要注意的是: 如果在循環內部, 前一個元素的遍歷有可能影響到后一個元素的遍歷, 那么for循環內部方法也需要置于閉包之內.

do/while

語法: do{...}while(true);

 do while(function() { var i = 0, len = array.length; do { if (i == 2) { break; // 循環被終止, 此處如果是continue就會造成循環無法退出 }; console.log('array['+ i +']:' + array[i]); i++;//此句建議放置循環while頭部 } while(i<len);})();

do/while的語法簡化了循環的實現, 只保留對循環條件的判斷, 所以我們要在循環內部構造出循環退出的條件, 否則有可能造成死循環. 特別要注意的是: 使用 continue 跳出本次遍歷時, 要保證循環能夠自動進入到下一次遍歷, 因此保證循環走到下一次遍歷的語句需要放到 continue 前面執行, 建議置于循環頭部.(如上, i++ 語句最好放置循環頭部)

do/while 循環與for循環大體差不多,只支持數組遍歷, 多用于對循環退出條件不是很明確的場景. 一般來說不建議使用這種方式遍歷數組.

forEach

語法: array.forEach(function(item){}) , 參數item表示數組每一項的元素

array.forEach(function(item){ if(item=="囚徒") return;//這里只能使用return跳過當前元素處理 console.log(item);});

forEach回調function默認有三個參數: item, index, array.

使用forEach循環有幾點需要特別注意:

  • forEach無法遍歷對象
  • forEach無法在IE中使用,只是在firefox和chrome中實現了該方法
  • forEach無法使用break,continue跳出循環,使用return時,效果和在for循環中使用continue一致

for in

語法: for(var item in array){}

for(var item in array){ console.log(item);}//0 1 2for(var item in o){ console.log(item);}//0 1 2 length

for in 可用于遍歷數組和對象, 但它輸出的只是數組的索引和對象的key, 我們可以通過索引和key取到對應的值. 如下:

for(var item in array){ console.log(array[item]);}//"囚徒" "過客" "領袖"for(var item in o){ console.log(o[item]);}//"linda" "style" "nick" "length"

$.each

語法: $.each(array|o, function(i, ele){}) 支持數組和對象

$.each(array, function(i, ele){ console.log(i,ele,this==ele);});//0 "囚徒" true//1 "過客" true//2 "領袖" true$.each(o, function(i, ele){ console.log(i,ele,this==ele);});//0 "linda" true//1 "style" true//2 "nick" true

這里我們注意到 this對象 指向當前屬性的值,這是因為:

參考jQuery api:

$.each() 方法會迭代jQuery對象中的每一個DOM元素。每次回調函數執行時,會傳遞當前循環次數作為參數(從0開始計數)。更重要的是,回調函數是在當前DOM元素為上下文的語境中觸發的。因此關鍵字 this 總是指向這個元素。
同時,上述遍歷時, o 對象的屬性中有一個length屬性并沒有被輸出. 這是為什么呢? 請耐心往下看.

首先, 我們來看看遍歷對象o時, 當前的this對象到底是什么?

$.each(o, function(i, ele){ if(this=="linda"){//我們隨機選取第一個屬性 console.log(this,this==ele); $.each(this, function(e, ele2) { console.log(e, ele2); }); }});//String {0: "l", 1: "i", 2: "n", 3: "d", 4: "a", length: 5, [[PrimitiveValue]]: "linda"} true//0 "l"http://1 "i"http://2 "n"http://3 "d"http://4 "a"

我們發現, this對象等于回調函數的第二個形參. 且它的 length 屬性和 [[PrimitiveValue]] 屬性并沒有被打印出來, 為此我們來查看下length的內部屬性.

$.each(o, function(i, ele){ if(this=="linda")//我們還是隨機選取第一個屬性(這還是隨機嗎?) console.log(Object.getOwnPropertyDescriptor(this, 'length'));});//Object {value: 5, writable: false, enumerable: false, configurable: false}

可見, this對象的length屬性的 enumerable 屬性被設置成了false, 這表示該對象不能被列舉或遍歷, 同時還不能被配置(configurable: false) , 也不能被賦值(writable: false) .

此時, 前面遍歷 o 對象時,它的 length 屬性沒有被打印出來的疑問似乎有解了. 讓我們來看看 o.length 的內部屬性吧.

console.log(Object.getOwnPropertyDescriptor(o, 'length'));//Object {value: 3, writable: true, enumerable: true, configurable: true}

o.length 值為3, 可賦值, 可列舉, 可配置. 這可不對, 剛剛不是說 enumerable 屬性被設置成了false 才不會被遍歷嗎. 現在該值為 true, 并且還不可遍歷. 這不合常理, 自然該有別的原因. 我們接著往下看.

var o = {0:"linda",1:"style",2:"nick",length:1}; // 試著改變length的值$.each(o, function(i, ele){//再遍歷一次 console.log(i,ele);});//0 "linda"var o = {0:"linda",1:"style",2:"nick",length:5}; // 堅持改變length的值$.each(o, function(i, ele){//再遍歷一次 console.log(i,ele);});// 0 linda// 1 style// 2 nick// length 5var o = {0:"linda",1:"style",2:"nick"}; // 試試去掉length屬性$.each(o, function(i, ele){//再遍歷一次 console.log(i,ele);});// 0 linda// 1 style// 2 nick

現象明了, 結合jquery源碼, 當對象中存在length屬性時, $.each 內部使用for循環去遍歷對象, 否則它將使用for in循環去遍歷, 因此$.each遍歷對象遵循如下規律:

  • 如果對象中存在 length 屬性, 遍歷深度以length屬性為準, 即length多大, 遍歷多少個元素.
  • 如果對象中不存在 length 屬性, 遍歷深度以實際內部屬性個數為準.

不僅如此, $.each的具體使用過程中還有以下幾點需要注意:

  • 使用 return 或者 return true 為跳過一個元素,繼續執行后面的循環;
  • 使用 return false 為終止循環的執行, 這是因為在 jquery.each 中, 若返回值指定為false, 才跳出循環, 如果感興趣請翻看 jquery.each 源碼;
  • 無法使用 break 與 continue 來跳過循環.

$(selecter).each

語法: $(selecter|array|o).each(function(i, ele){}) 支持數組和對象, 該方法基本上與$.each方法相同.

$('div').each(function(i,ele){ console.log(this,i,this == ele);});//dom... 0 dom.... true$(array).each(function(i,ele){//處理數組 if(this == "領袖") console.log(this,i,this == ele);});//String {0: "領", 1: "袖", length: 2, [[PrimitiveValue]]: "領袖"} 2 true$(o).each(function(i,ele){//處理對象 if(this == "nick") console.log(this,i,this == ele);});//String {0: "n", 1: "i", 2: "c", 3: "k", length: 4, [[PrimitiveValue]]: "nick"} 2 true

dom表示div元素, 由于this恒等ele, 說明this也表示div元素, 所以this并不是jquery對象, 而是普通的DOM對象(可以在this上隨意使用DOM方法). 使用$(selecter).each方法,請注意以下幾點:

  • i: 即序列值 ele: 表示當前被遍歷的DOM元素
  • this 表示當前被遍歷的DOM元素,不能調用jQuery方法, 如需調用jquery方法需要用$符號包裹.如, $(this)

map

Array.prototype.map,該方法只支持數組

語法: array.map(callback[,thisArg]) map方法使用其提供函數的每次返回結果生成一個新的數組.

var array = [1, 4, 9];var roots = array.map(Math.sqrt);//map包裹方法名// roots is now [1, 2, 3], array is still [1, 4, 9]var array = [1, 4, 9];var doubles = array.map(function(num) {//map包裹方法實體 return num * 2;});// doubles is now [2, 8, 18]. array is still [1, 4, 9]

實際上,由于map方法被設計成支持 [鴨式辨型][] , 該方法也可以用來處理形似數組的對象, 例如 NodeList.

var elems = document.querySelectorAll('select option:checked');var values = Array.prototype.map.call(elems, function(obj) { return obj.value;});

甚至還可以用來處理字符串, 如下:

var map = Array.prototype.map;var array = map.call('Hello 中國', function(x) {  return x.charCodeAt(0);});console.log(array);//[72, 101, 108, 108, 111, 32, 20013, 22269]

map處理字符串的方式多種多樣, 例如 反轉等.

var str = '12345';var output = Array.prototype.map.call(str, function(x) { return x;}).reverse().join('');console.log(output);//54321

例如 將字符串數組轉換為數字數組, 只需一條語句, 如下:

console.log(['1', '2', '3'].map(Number));//[1,2,3]

目前map方法被大部分瀏覽器支持, 除了IE 6,7,8.

every

Array.prototype.every, 該方法同上述map方法也只支持數組

語法: arr.every(callback[, thisArg]) every 方法用于檢驗數組中的每一項是否符合某個條件, 若符合則放回true, 反之則返回false.

function isBigEnough(element, index, array) { return element >= 10;}[12, 5, 8, 130, 44].every(isBigEnough); // false[12, 54, 18, 130, 44].every(isBigEnough); // true

該方法還有簡寫方式, 如下:

[12, 5, 8, 130, 44].every(elem => elem >= 10); // false[12, 54, 18, 130, 44].every(elem => elem >= 10); // true

以上, 遍歷數組和對象的8種方法簡單的介紹完, 小結如下:

  • for in , $.each , $().each 既支持對象也支持數組遍歷;
  • for , do/while , forEach 只支持數組;
  • Array.prototype.map, Array.prototype.every 只支持數組和形似數組的對象;
  • forEach不能退出循環,只能通過return來進入到下一個元素的遍歷中(相當于for循環的continue), 且在IE沒有實現該方法;
  • $.each和$().each循環只能通過return false 來退出循環, 使用return 或 return true 將跳過一個元素, 繼續執行后面的循環.

測試各方法效率

下面我們來測試下上述方法的效率.

注: array數組默認為空, 依次賦值數組長度為1 000 000, 10 000 000, 100 000 000, 分別在 Chrome, Firefox, Safari 瀏覽器上進行兩輪測試, 取測試時間平均值作為比較對象, 時間單位為ms. 如下是測試代碼:

var array = [], length = array.length = 10000000;//(一千萬)//for(var i=0;i<length;i++){// array[i] = 'louis';//}console.log(array[0]);//-------------------------forvar t1 = +new Date();for(var i=0;i<length;i++){}var t2 = +new Date();console.log('for:' + (t2-t1));//-------------------------do/whilevar t1 = +new Date();var i = 0;do { i++;} while(i<length);var t2 = +new Date();console.log('do while:' + (t2-t1));//-------------------------forEachvar t1 = +new Date();array.forEach(function(item){});var t2 = +new Date();console.log('forEach:' + (t2-t1));//-------------------------for invar t1 = +new Date();for(var item in array){}var t2 = +new Date();console.log('for in:' + (t2-t1));//------------------------- $.eachvar t1 = +new Date();$.each(array, function(i, ele){});var t2 = +new Date();console.log('$.each:' + (t2-t1));//-------------------------$().eachvar t1 = +new Date();$(array).each(function(i,ele){});var t2 = +new Date();console.log('$(ele).each:' + (t2-t1));//-------------------------mapvar t1 = +new Date();array.map(function(num){});var t2 = +new Date();console.log('map:' + (t2-t1));//-------------------------everyvar t1 = +new Date();array.every(function(e,i,arr){});var t2 = +new Date();console.log('every:' + (t2-t1));

測試機器正常運行 IDE, 編輯器, 瀏覽器, qq, 微信等常用應用, 系統空閑. 硬件設備如下:

  • 操作系統: OSX EI Capitan 版本 10.11.5
  • MacBook Pro(13 英寸,2015 年初期)
  • 處理器: 2.7 GHz Intel Core i5
  • 內存: 8 GB 1867 MHz DDR3

以上多輪測試結果匯總如下三張表(單位:ms):

數組長度為10^6


數組長度為10^6 chrome 52.0.2743.116 (64-bit) Firefox Developer Edition 49.0a2 (2016-08-01) Safari 9.1.1 (11601.6.17)
for (16+19)/2 = 17.5 (6+7)/2 = 6.5 (6+7)/2 = 6.5
do while (24+17)/2 = 20.5 (7+5)/2 = 6 (5+5)/2 = 5
for in (19+28)/2 = 23.5 (0+0)/2 = 0 (0+0)/2 = 0
forEach (41+28)/2 = 34.5 (4+4)/2 = 4 (31+29)/2 = 30
map (26+32)/2 = 28 (4+4)/2 = 4 (32+26)/2 = 28
every (22+24)/2 = 23 (4+5)/2 = 4.5 (41+45)/2 = 43
$.each (29+27)/2 = 28 (306+311)/2 = 308.5 (111+97)/2 = 104
$(e).each (94+98)/2 = 96 (484+488)/2 = 486 (79+64)/2 = 71.5

數組長度為10^7


數組長度為10^7 chrome 52.0.2743.116 (64-bit) Firefox Developer Edition 49.0a2 (2016-08-01) Safari 9.1.1 (11601.6.17)
for (164+161)/2 = 162.5 (26+30)/2 = 28 (30+31)/2 = 30.5
do while (163+157)/2 = 160 (27+25)/2 = 26 (28+27)/2 = 27.5
for in (78+86)/2 = 82 (0+0)/2 = 0 (0+0)/2 = 0
forEach (211+205)/2 = 208 (31+30)/2 = 30.5 (291+289)/2 = 290
map (349+282)/2 = 315.5 (24+22)/2 = 23 (259+260)/2 = 259.5
every (221+219)/2 = 220 (24+24)/2 = 24 (251+257)/2 = 254
$.each (210+215)/2 = 212.5 (2868+2789)/2 = 2828.5 (699+724)/2 = 711.5
$(e).each (730+669)/2 = 699.5 (4674+4722)/2 = 4698 (523+546)/2 = 534.5

數組長度為10^8


數組長度為10^8 chrome 52.0.2743.116 (64-bit) Firefox Developer Edition 49.0a2 (2016-08-01) Safari 9.1.1 (11601.6.17)
for (1486+1583)/2 = 1534.5 (222+238)/2 = 230 (261+251)/2 = 256
do while (1548+1608)/2 = 1578 (236+247)/2 = 241.5 (272+265)/2 = 268.5
for in (0+0)/2 = 0 (0+0)/2 = 0 (0+0)/2 = 0
forEach (25838+22307)/2 = 24072.5 (212+209)/2 = 210.5 (2565+2568)/2 = 2566.5
map (23795+22787)/2 = 23291 (215+206)/2 = 210.5 (2556+2573)/2 = 2564.5
every (22393+22378)/2 = 22385.5 (212+215)/2 = 213.5 (2550+2548)/2 = 2549
$.each (14523+14776)/2 = 14649.5 (28007+27698)/2 = 27852.5 (7109+7156)/2 = 7132.5
$(e).each chrome 奔潰了... (49352+49530)/2 = 49441 (5505+4616)/2 = 5060.5

綜上, 我們發現for in 循環的性能不穩定, 猜測它可能沒有進入循環. 因此將數組各元素進行如下賦值. 重新進行如下兩輪測試.

var array = [], length = array.length = 1000000;for(var i=0;i<length;i++){ array[i] = 'louis';}

數組賦值后, 數組長度為10^6


數組長度為10^6 chrome 52.0.2743.116 (64-bit) Firefox Developer Edition 49.0a2 (2016-08-01) Safari 9.1.1 (11601.6.17)
for (21+22)/2 = 21.5 (8+10)/2 = 9 (6+5)/2 = 5.5
do while (22+19)/2 = 20.5 (6+6)/2 = 6 (6+5)/2 = 5.5
for in (178+184)/2 = 181 (318+268)/2 = 293 (413+464)/2 = 438.5
forEach (42+45)/2 = 43.5 (4+4)/2 = 4 (21+24)/2 = 22.5
map (137+153)/2 = 145 (9+8)/2 = 8.5 (38+43)/2 = 40.5
every (0+0)/2 = 0 (0+0)/2 = 0 (0+0)/2 = 0
$.each (85+84)/2 = 84.5 (15+19)/2 = 17 (37+25)/2 = 31
$(e).each (81+83)/2 = 82 (34+31)/2 = 32.5 (37+46)/2 = 41.5

數組賦值后, 數組長度為10^7


數組長度為10^7 chrome 52.0.2743.116 (64-bit) Firefox Developer Edition 49.0a2 (2016-08-01) Safari 9.1.1 (11601.6.17)
for (171+157)/2 = 164 (27+26)/2 = 26.5 (26+28)/2 = 27
do while (168+158)/2 = 163 (27+27)/2 = 27 (28+29)/2 = 28.5
for in (1469+1715)/2 = 1592 (2922+3123)/2 = 3022.5 (5755+5742)/2 = 5748.5
forEach (347+329)/2 = 338 (32+36)/2 = 34 (171+174)/2 = 172.5
map (1320+1335)/2 = 1327.5 (147+137)/2 = 142 (448+469)/2 = 458.5
every (0+0)/2 = 0 (0+0)/2 = 0 (0+0)/2 = 0
$.each (438+441)/2 = 439.5 (142+141)/2 = 141.5 (254+248)/2 = 251
$(e).each (876+935)/2 = 905.5 (315+328)/2 = 321.5 (450+402)/2 = 426

可見, 對數組進行賦值后, 代碼運行基本穩定.(every還不清楚為什么執行時間為0.歡迎大神告知原因.)

分析總結

通過以上 30 次運行測試(實際上為了得到比較穩定的數據, 擯棄了許多異常的測試數據), 我們發現在數組長度為10^6, 10^7, 10^8 時, 代碼運行基本穩定. 各方法運行需要的時間大致排序如下:

for ~= do while < forEach ~= map ~= every < $.each < $(e).each < for in

根據統計數據, 可得這8個方法的運行速度大致排序為:

  1. for 與 do while
  2. forEach map every (這3個不相上下,可認為運行速度差不多)
  3. $.each
  4. $(e).each
  5. for in

我們翻看jquery代碼就會知道, $.each方法內部通過調用for循環來實現, 而$().each是先用jquery包裹數組對象, 然后再調用for循環, 因此后者效率略低于前者.

綜上, 最佳遍歷選手是 for/do while循環, 推薦大家優先考慮使用它. ( Firefox瀏覽器由于對forEach循環做了底層優化, 效率接近native,不在我們考慮范圍內 ).

基于測試結果的兩點思考

從測試數據上猜測, Firefox 與 Safari 似乎對于 for, do while 等都進行了底層優化. 循環執行效率明顯優于Chrome.

每次瀏覽器執行到 for in 循環處, 便會出現卡頓, 猜測瀏覽器可能正在預加載循環所需資源(后續我將專門分析此處).

想要進一步優化循環效率, 推薦您閱讀下篇 《JS作用域鏈及閉包》.

聲明: 本文所有數據均為單機測試, 難免存在誤差, 如果發現本文測試數據不對之處, 歡迎批評斧正.

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久99精品久久久久久琪琪| 欧美精品18videos性欧| 最新国产精品拍自在线播放| 欧美高清视频在线观看| 国产精品老女人精品视频| 国产mv免费观看入口亚洲| 久久亚洲影音av资源网| 久久精品久久久久电影| 国产精品jvid在线观看蜜臀| 欧美在线视频免费观看| 欧美亚洲视频一区二区| 国产精国产精品| 欧美日韩色婷婷| 国产日韩欧美在线观看| 久热精品视频在线观看一区| 欧美一级片免费在线| 亚洲自拍av在线| 日韩理论片久久| 亚洲jizzjizz日本少妇| 69影院欧美专区视频| 欧美激情影音先锋| 欧美一级视频免费在线观看| 欧美性视频网站| 97精品国产97久久久久久春色| 国产精品久久久久久久久久东京| 欧美一区二区三区艳史| 色综合久久天天综线观看| 色妞在线综合亚洲欧美| 亚洲女人初尝黑人巨大| 亚洲欧美日韩中文在线制服| 97色在线播放视频| 97国产成人精品视频| 欧美性猛交99久久久久99按摩| 国产精品成人va在线观看| 久久精品中文字幕一区| 欧美性视频在线| 亚洲人成啪啪网站| 亚洲专区国产精品| 国产亚洲视频在线观看| 欧美黑人视频一区| 日韩美女在线观看| 日韩精品一区二区视频| 午夜精品在线观看| 91精品综合久久久久久五月天| 色噜噜狠狠色综合网图区| 热久久免费视频精品| 精品欧美国产一区二区三区| 日本精品一区二区三区在线播放视频| 久久精品久久久久久| 精品久久久久久中文字幕大豆网| 日本精品性网站在线观看| 国产精品久久久久久久久久三级| 国产福利视频一区二区| 欧美中文字幕视频在线观看| 亚洲福利视频网| 国产日韩在线观看av| 久久精品一区中文字幕| 隔壁老王国产在线精品| 国产精品成人一区二区| 日韩精品视频在线免费观看| 久久国产精彩视频| 日韩成人av在线播放| 国产精品免费一区二区三区都可以| 欧美激情18p| 欧美一区二粉嫩精品国产一线天| 中文字幕av日韩| 日韩视频免费在线观看| 中文字幕精品在线| 色综合久久中文字幕综合网小说| 国产精品免费久久久久影院| 国产一区二区香蕉| 色偷偷偷亚洲综合网另类| 亚洲美女又黄又爽在线观看| 久久久久久亚洲精品中文字幕| 成人精品aaaa网站| 欧美日韩国产成人在线观看| 亚洲国产成人精品久久| 精品国产91久久久久久| 亚洲肉体裸体xxxx137| 亚洲精品按摩视频| 国产91精品久久久| 欧美在线视频一区| 亚洲韩国欧洲国产日产av| 亚洲一区二区三区四区视频| 欧美激情性做爰免费视频| 精品国产一区二区三区久久久狼| 中文亚洲视频在线| 国产欧美婷婷中文| 日本免费一区二区三区视频观看| 亚洲人成在线观| 日韩美女免费视频| 这里只有精品久久| 亚洲欧美国产一区二区三区| 91午夜理伦私人影院| 午夜精品一区二区三区在线| 色综合导航网站| 色悠久久久久综合先锋影音下载| 国产精品999| 久久久精品一区二区三区| 欧美色视频日本高清在线观看| 日韩国产精品一区| 日av在线播放中文不卡| 久久久亚洲影院你懂的| 国产精品欧美日韩| 国产日韩欧美黄色| 高潮白浆女日韩av免费看| 亚洲精品国精品久久99热一| 亚洲xxx大片| 91精品久久久久久| 亚洲精品美女视频| 伊人久久五月天| 色吧影院999| 国产精品第一视频| 久久色免费在线视频| 久久亚洲精品成人| 国产成人亚洲综合91精品| 国产成人在线一区二区| 一本大道香蕉久在线播放29| 九九热精品在线| 亚洲免费av电影| 日韩在线观看免费av| 久久91亚洲精品中文字幕| 高清欧美一区二区三区| www.久久色.com| 亚洲高清免费观看高清完整版| 国产精品久久中文| 疯狂欧美牲乱大交777| 91成人国产在线观看| 亚洲xxxx做受欧美| 国产精品久久久久久久av电影| 日韩av在线高清| 亚洲午夜未满十八勿入免费观看全集| 亚洲欧洲日韩国产| 欧美高清视频在线播放| 欧美大片欧美激情性色a∨久久| 成人激情视频在线| 日韩专区在线观看| 姬川优奈aav一区二区| 亚洲在线视频观看| 国产98色在线| 一区二区在线视频播放| 日韩av在线免费观看| 欧美精品18videos性欧| 日本精品va在线观看| 在线观看日韩欧美| 欧美成人精品激情在线观看| 91麻豆国产语对白在线观看| 欧美高清视频一区二区| 91在线视频导航| 日韩美女免费观看| 91精品久久久久久| 亚洲高清久久久久久| 91精品国产高清久久久久久91| 亚洲国产中文字幕久久网| 人人爽久久涩噜噜噜网站| 性欧美在线看片a免费观看| 日韩美女免费视频| 伊人久久男人天堂| 欧美成人国产va精品日本一级| 日本韩国在线不卡| 成人欧美在线观看| 久久久亚洲成人| 色婷婷久久一区二区| 国产精品扒开腿爽爽爽视频|