精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

20 個程序員需要知道的 JavaScript 數組方法的實現

開發 前端
我想你們一定對JavaScript中的數組非常熟悉,我們每天都會用到它的各種方法,比如push、pop、forEach、map……等等。

我想你們一定對JavaScript中的數組非常熟悉,我們每天都會用到它的各種方法,比如push、pop、forEach、map……等等。

但是僅僅使用它就足夠了嗎?太棒了,你一定不想在這里停下來。想和你一起挑戰,實現20+個數組方法的功能。

1. forEach

forEach是我們工作中使用頻率非常高的一個數組方法,實現起來也比較簡單。這是我們需要完成的第一個功能。

代碼

Array.prototype.forEach2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  const length = this.length
  let i = 0


  while (i < length) {
    // Deleted, the newly added element index i is not in the array, so it will not be accessed
    if (this.hasOwnProperty(i)) {
      callback.call(thisCtx, this[ i ], i, this)
    }


    i++
  }
}

測試一下

let demoArr = [ 1, 2, 3, 4, , 5 ]


demoArr.forEach2((it, i) => {
  if (i === 1) {
    // 5 will not be printed out
    demoArr.push(5)
  } else if (i === 2) {
    // 4 will not be printed out, but "4-4" will be printed out
    demoArr.splice(3, 1, '4-4')
  }


  console.log(it)
})


/*
 1
 2
 3
 4-4
 5
*/

哇,恭喜!我們已經實現了 forEach 的特性。

2.map

您通常使用map做什么?大多數時候是將一個數組轉換成另一個數組。

代碼

Array.prototype.map2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  const length = this.length
  let i = 0
  // The return value of the map method is a new array
  let newArray = []


  while (i < length) {
    // Deleted and uninitialized values will not be accessed
    if (this.hasOwnProperty(i)) {
      newArray.push(callback.call(thisCtx, this[ i ], i, this))
    }


    i++
  }
  // Return new array
  return newArray
}

測試一下

let arr = [ 0, 1, 2, 3, 4,, 5 ]


let arr2 = arr.map2(function (it, i, array) {
  console.log(it, i, array, this)
  return it * it
}, { name: 'fatfish' })


console.log(arr2) // [0, 1, 4, 9, 16, 25]

朋友們,你們覺得不難嗎?那是因為你太優秀了。

3. every

 every() 方法測試數組中的所有元素是否通過提供的函數實現的測試。它返回一個布爾值。

every方法有3個你以前可能沒有注意到的點,它們是什么?

  • 在空數組上調用 every 方法將返回 true。
  • 回調方法只會被已經賦值的索引調用。
  • 如果值被刪除,回調將不會被調用
let emptyArr = []
// Calling every method on an empty array returns true
console.log(emptyArr.every((it) => it > 0)) // true
// The `callback` method will only be called by an index that has already been assigned a value.
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
// The `callback` method will not be called when an array value is deleted or an index that has never been assigned a value.
delete arr[7]


console.log(arr.every((it) => it >= 0)) // true

代碼

Array.prototype.every2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  const length = this.length
  let i = 0
  // If the length of the array is 0, the while loop will not be entered
  while (i < length) {
    // False will be returned as long as a value does not conform to the judgment of callback
    if (this.hasOwnProperty(i) && !callback.call(thisCtx, this[ i ], i, this)) {
      return false
    }


    i++
  }


  return true
}

測試一下

let emptyArr = []
// Calling every method on an empty array returns true
console.log(emptyArr.every2((it) => it > 0)) // true
// The `callback` method will only be called by an index that has already been assigned a value.
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
// The `callback` method will not be called when an array value is deleted or an index that has never been assigned a value.
delete arr[7]


console.log(arr.every2((it) => it >= 0)) // true

4.some

some() 方法測試數組中的至少一個元素是否通過了由提供的函數實現的測試。

代碼

Array.prototype.some2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  const length = this.length
  let i = 0


  while (i < length) {
    // Returns true if any element meets the callback condition
    if (this.hasOwnProperty(i) && callback.call(thisCtx, this[ i ], i, this)) {
      return true
    }


    i++
  }


  return false
}

測試一下

let emptyArr = []
// An empty array will return false
console.log(emptyArr.some2((it) => it > 0)) // false


let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]


delete arr[7]


console.log(arr.some2((it) => it < 0)) // false
console.log(arr.some2((it) => it > 0)) // true

5. filter

filter() 方法創建一個新數組,其中包含通過提供的函數實現的測試的所有元素。

Array.prototype.filter2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  const length = this.length
  // The return value will be a new array
  let newArray = []
  let i = 0


  while (i < length) {
    if (this.hasOwnProperty(i) && callback.call(thisCtx, this[ i ], i, this)) {
      newArray.push(this[ i ])
    }
    i++
  }


  return newArray
}

測試一下

// The position with index 5 will not be traversed because it has no initialization value
let arr = [ 0, 1, 2, -3, 4,, 5 ]
// we try to remove the last element
delete arr[6]
// filter out values greater than 0
let filterArr = arr.filter2((it) => it > 0)


console.log(filterArr) // [ 1, 2, 4 ]

6. reduce

這個函數有點復雜。讓我們用一個例子來看看它是如何使用的。

const sum = [1, 2, 3, 4].reduce((prev, cur) => {
  return prev + cur;
})


console.log(sum) // 10


// initialization
prev = initialValue = 1, cur = 2


// step 1
prev = (1 + 2) =  3, cur = 3


// step 2
prev = (3 + 3) =  6, cur = 4


// step 3
prev = (6 + 4) =  10, cur = undefined (quit)

代碼

Array.prototype.reduce2 = function (callback, initValue) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }


  let pre = initValue
  let i = 0
  const length = this.length
  // When the initial value is not passed, use the first value of the array as the initial value  
  if (typeof pre === 'undefined') {
    pre = this[0]
    i = 1
  }


  while (i < length) {
    if (this.hasOwnProperty(i)) {
      pre = callback(pre, this[ i ], i, this)
    }
    i++
  }


  return pre
}

測試一下

const sum = [1, 2, 3, 4].reduce2((prev, cur) => {
  return prev + cur;
})
console.log(sum) // 10

7. reduceRight

reduceRight() 方法對累加器和數組的每個值(從右到左)應用函數以將其減少為單個值。

除了reduceRight是從右向左遍歷之外,它與reduce非常相似。

const sum = [1, 2, 3, 4].reduce((prev, cur) => {
  console.log(prev, cur)
  return prev + cur;
})
// 1 2
// 3 3
// 6 4


console.log(sum) // 10
const sum2 = [1, 2, 3, 4].reduceRight((prev, cur) => {
  console.log(cur)
  return prev + cur;
})
// 4 3
// 7 2
// 9 1
console.log(sum2) // 10

代碼

Array.prototype.reduceRight2 = function (callback, initValue) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }
  let pre = initValue
  const length = this.length
  // Start with the last element
  let i = length - 1
  // If no initial value is passed, the last element is taken as the initial value
  if (typeof pre === 'undefined') {
    pre = this[i]
    i--
  }
  while (i >= 0) {
    if (this.hasOwnProperty(i)) {
      pre = callback(pre, this[ i ], i, this)
    }
    i--
  }
  return pre
}

測試一下

const sum = [1, 2, 3, 4].reduceRight2((prev, cur) => {
  console.log(cur)
  return prev + cur;
})
// 4 3
// 7 2
// 9 1
console.log(sum) // 10

8. find

find() 方法返回提供的數組中滿足提供的測試函數的第一個元素。如果沒有值滿足測試函數,則返回 undefined。

代碼

Array.prototype.find2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }
  const length = this.length
  let i = 0
  while (i < length) {
    const value = this[ i ]
    // As long as there is an element that matches the logic of the callback function, the element value is returned
    if (callback.call(thisCtx, value, i, this)) {
      return value
    }
    i++
  }
  // otherwise return undefined  
  return undefined
}

測試一下

let arr = [ 0, 1, 2, 3, 4,, 5 ]
let ele = arr.find2(function (it, i, array) {
  console.log(it, i, array, this)
  return it > 3
}, { name: 'fatfish' })
console.log(ele) // 4

9. findIndex

findIndex() 方法返回數組中滿足提供的測試函數的第一個元素的索引。否則返回-1,表示沒有元素通過測試。

let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.findIndex((it, i, array) => {
  return it > 2
})
console.log(index) // 3

代碼

Array.prototype.findIndex2 = function (callback, thisCtx) {
  if (typeof callback !== 'function') {
    throw `${callback} is not a function`
  }
  const length = this.length
  let i = 0
  while (i < length) {
    // Return index i that conforms to callback logic
    if (callback.call(thisCtx, this[ i ], i, this)) {
      return i
    }
    i++
  }
  return -1
}

測試一下

let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.findIndex2(function (it, i, array) {
  console.log(it, i, array, this)
  return it > 2
}, { name: 'fatfish' })
console.log(index) // 3

10. indexOf

indexOf() 方法返回可以在數組中找到給定元素的第一個索引,如果不存在則返回 -1。

arr.indexOf(searchElement[, fromIndex])

注意:

如果開始搜索的索引值大于等于數組長度,則表示不在數組中進行搜索,返回-1。

如果fromIndex為負數,則按照-1表示從最后一個元素開始查找,-2表示從倒數第二個元素開始查找,以此類推。

如果 fromIndex 為負數,則仍然從前到后查找數組。

const array = [2, 5, 9]
console.log(array.indexOf(2))      // 0
console.log(array.indexOf(7))      // -1
console.log(array.indexOf(9, 2))   // 2
console.log(array.indexOf(2, -1))  // -1
console.log(array.indexOf(2, -3))  // 0
console.log(array.indexOf(2, -4))  // 0

代碼

Array.prototype.indexOf2 = function (targetEle, fromIndex) {
  const length = this.length
  fromIndex = +fromIndex || 0
  // If the array is empty or the search starts from a place greater than or equal to the length of the array, it will directly return -1
  if (length === 0 || fromIndex >= length) {
    return -1
  }
  /*
    1. Search elements from fromIndex
    2. Use it directly when fromindex is greater than 0
    3. If it is less than 0, first subtract the absolute value of fromIndex from the length. If it is still less than 0, take 0 directly
  */
  let i = Math.max(fromIndex >= 0 ? fromIndex : length - Math.abs(fromIndex), 0)
  while (i < length) {
    // element in the array and equal to targetEle
    if (this.hasOwnProperty(i) && targetEle === this[ i ]) {
      return i
    }
    i++
  }
  return -1
}

測試一下

const array = [2, 5, 9]
console.log(array.indexOf2(2))      // 0
console.log(array.indexOf2(7))      // -1
console.log(array.indexOf2(9, 2))   // 2
console.log(array.indexOf2(2, -1))  // -1
console.log(array.indexOf2(2, -3))  // 0
console.log(array.indexOf2(2, -4))  // 0

11. lastIndexOf

lastIndexOf() 方法返回可以在數組中找到給定元素的最后一個索引,如果不存在則返回 -1。從 fromIndex 開始向后搜索數組。

除了 lastIndexOf 從右到左遍歷之外,它與 indexOf 非常相似。

let array = [2, 5, 9, 2]
console.log(array.lastIndexOf(2)) // 3
console.log(array.lastIndexOf(7)) // -1
console.log(array.lastIndexOf(2, 3)) // 3
console.log(array.lastIndexOf(2, 2)) // 0
console.log(array.lastIndexOf(2, -2)) // 0
console.log(array.lastIndexOf(2, -1)) // 3

代碼

Array.prototype.lastIndexOf2 = function (targetEle, fromIndex) {
  const length = this.length
  fromIndex = typeof fromIndex === 'undefined' ? length - 1 : fromIndex
  // // Empty array, when fromIndex is negative and the absolute value is greater than the length of the array, the method returns -1, that is, the array will not be searched.
  if (length === 0 || fromIndex < 0 && Math.abs(fromIndex) >= length) {
    return -1
  }
  let i
  if (fromIndex >= 0) {
    // If `fromIndex` is greater than or equal to the length of the array, the entire array is searched.
    i = Math.min(fromIndex, length - 1)
  } else {
    i = length - Math.abs(fromIndex)
  }
  while (i >= 0) {
    // Returns the index when it is equal to targetEle
    if (i in this && targetEle === this[ i ]) {
      return i
    }
    i--
  }
  // Returns -1 when the current value is not found
  return -1
}

測試一下

let array = [2, 5, 9, 2]
console.log(array.lastIndexOf2(2)) // 3
console.log(array.lastIndexOf2(7)) // -1
console.log(array.lastIndexOf2(2, 3)) // 3
console.log(array.lastIndexOf2(2, 2)) // 0
console.log(array.lastIndexOf2(2, -2)) // 0
console.log(array.lastIndexOf2(2, -1)) // 3

12. includes

includes() 方法確定數組是否在其條目中包含某個值,并根據需要返回 true 或 false。

arr.includes(valueToFind[, fromIndex])

注意:

includes 方法將從 fromIndex 索引開始搜索 valueToFind。

如果 fromIndex 為負數,則開始搜索 array.length + fromIndex 的索引。

如果數組中存在 NaN,則 [..., NaN] Includes (NaN) 為真。

console.log([1, 2, 3].includes(2))     // true
console.log([1, 2, 3].includes(4))     // false
console.log([1, 2, 3].includes(3, 3))  // false
console.log([1, 2, 3].includes(3, -1)) // true
console.log([1, 2, NaN].includes(NaN)) // true

代碼

Array.prototype.includes2 = function (targetEle, fromIndex) {
  const length = this.length
  fromIndex = +fromIndex || 0
  if (length === 0 || fromIndex >= length) {
    return false
  }
  // Search for elements from the position of fromIndex
  let i = Math.max(fromIndex >= 0 ? fromIndex : length - Math.abs(fromIndex), 0)
  while (i < length) {
    const value = this[ i ]
    // Please note NaN
    if (targetEle === value || typeof targetEle === 'number' && typeof value === 'number' && isNaN(targetEle) && isNaN(value)) {
      return true
    }
    i++
  }
  return false
}

測試一下

console.log([1, 2, 3].includes2(2))     // true
console.log([1, 2, 3].includes2(4))     // false
console.log([1, 2, 3].includes2(3, 3))  // false
console.log([1, 2, 3].includes2(3, -1)) // true
console.log([1, 2, NaN].includes2(NaN)) // true

13. push

push() 方法將一個或多個元素添加到數組的末尾并返回數組的新長度。

const animals = ['pigs', 'goats', 'sheep']
animals.push('cows')
console.log(animals, animals.length) 
// ["pigs", "goats", "sheep", "cows"], 4
animals.push('chickens', 'cats', 'dogs')
console.log(animals, animals.length) 
// ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"], 7

代碼

Array.prototype.push2 = function (...pushEles) {
  const pushEleLength = pushEles.length
  const length = this.length
  let i = 0


  while (i < pushEleLength) {
    this[ length + i ] = pushEles[ i ]
    i++
  }
  return this.length
}

測試一下

const animals = ['pigs', 'goats', 'sheep']
animals.push2('cows')
console.log(animals, animals.length) 
// ["pigs", "goats", "sheep", "cows"], 4
animals.push2('chickens', 'cats', 'dogs')
console.log(animals, animals.length) 
// ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"], 7

14. pop

pop() 方法從數組中刪除最后一個元素并返回該元素。此方法更改數組的長度。

let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop(), arr) // 2 [1]
console.log(arr2.pop(), arr2) // undefined []

代碼

Array.prototype.pop2 = function () {
  const length = this.length
  // If it is an empty array, return undefined
  if (length === 0) {
    return undefined
  }
  const delEle = this[ length - 1 ]
  this.length = length - 1
  return delEle
}

測試一下

let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop2(), arr) // 2 [1]
console.log(arr2.pop2(), arr2) // undefined []

15. unshift

unshift() 方法將一個或多個元素添加到數組的開頭并返回數組的新長度。

如果傳入多個參數調用一次unshift,與傳入一個參數多次調用unshift(比如循環調用)得到的結果是不同的。

let arr = [4,5,6]
// Insert multiple elements at once
arr.unshift(1,2,3)
console.log(arr) // [1, 2, 3, 4, 5, 6]
let arr2 = [4,5,6]
// Insert multiple times
arr2.unshift(1)
arr2.unshift(2)
arr2.unshift(3)
console.log(arr2); // [3, 2, 1, 4, 5, 6]

代碼

Array.prototype.unshift2 = function (...unshiftEles) {
  // With "...", Insert the element to be added in front of the array
  let newArray = [ ...unshiftEles, ...this ]
  let length = newArray.length


  let i = 0
  if (unshiftEles.length === 0) {
    return length
  }
  // Recopy to array
  while (i < length) {
    this[ i ] = newArray[ i ]
    i++
  }


  return this.length
}

測試一下

let arr = [4,5,6]
// Insert multiple elements at once
arr.unshift2(1,2,3)
console.log(arr) // [1, 2, 3, 4, 5, 6]
let arr2 = [4,5,6]
// Insert multiple times
arr2.unshift2(1)
arr2.unshift2(2)
arr2.unshift2(3)
console.log(arr2); // [3, 2, 1, 4, 5, 6]

16. shift

shift() 方法從數組中刪除第一個元素并返回刪除的元素。此方法更改數組的長度。

let arr = [ 1, 2 ]
console.log(arr.shift(), arr) // 1 [2]
console.log(arr.shift(), arr) // 2 []

代碼

Array.prototype.shift2 = function () {
  const length = this.length
  const delValue = this[ 0 ]
  let i = 1
  while (i < length) {
    // Starting from the first element, the following elements move forward one bit
    this[ i - 1 ] = this[ i ]
    i++
  }
  // Set the length of the array
  this.length = length - 1
  // Return deleted value
  return delValue
}

測試一下

let arr = [ 1, 2 ]
console.log(arr.shift2(), arr) // 1 [2]
console.log(arr.shift2(), arr) // 2 []

17. reverse

reverse() 方法原地反轉數組。第一個數組元素成為最后一個,最后一個數組元素成為第一個。

const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse()
console.log(arr) // [3, 2, 1]

代碼

Array.prototype.reverse2 = function () {
  let i = 0
  let j = this.length - 1
  while (i < j) {
    [ this[ i ], this[ j ] ] = [ this[ j ], this[ i ] ]
    i++
    j--
  }
  return this
}

測試一下

const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse2()
console.log(arr) // [3, 2, 1]

18. fill

 fill() 方法將數組中的所有元素更改為靜態值,從起始索引(默認 0)到結束索引(默認 array.length)。 它返回修改后的數組。

const array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 4)) // [1, 2, 0, 0]


console.log(array1.fill(5, 1)) // [1, 5, 5, 5]
console.log(array1.fill(6)) // [6, 6, 6, 6]

代碼

Array.prototype.fill2 = function (value, start, end) {
  const length = this.length
  start = start >> 0
  // The default value of end is length
  end = typeof end === 'undefined' ? length : end >> 0
  // The minimum value of start is 0 and the maximum value is length
  start = start >= 0 ? Math.min(start, length) : Math.max(start + length, 0)
  // The minimum value of end is 0 and the maximum value is length
  end = end >= 0 ? Math.min(end, length) : Math.max(end + length, 0)
  // The element that fills the specified range is value
  while (start < end) {
    this[ start ] = value
    start++
  }
  return this
}

測試一下

const array1 = [1, 2, 3, 4];
console.log(array1.fill2(0, 2, 4)) // [1, 2, 0, 0]


console.log(array1.fill2(5, 1)) // [1, 5, 5, 5]
console.log(array1.fill2(6)) // [6, 6, 6, 6]

19. concat

concat() 方法用于合并兩個或多個數組。 此方法不會更改現有數組,而是返回一個新數組。

let num1 = [[1]]
let num2 = [2, [3]]
let num3=[5,[6]]
let nums = num1.concat(num2) // [[1], 2, [3]]
let nums2 = num1.concat(4, num3) // [[1], 4, 5,[6]]

代碼

Array.prototype.concat2 = function (...concatEles) {
  const length = concatEles.length
  // The array itself needs to be expanded one layer
  let newArray = [ ...this ]
  let i = 0
  while (i < length) {
    const value = concatEles[ i ]
    Array.isArray(value) ? newArray.push(...value) : newArray.push(value)
    i++
  }
  return newArray
}

測試一下

let num1 = [[1]]
let num2 = [2, [3]]
let num3=[5,[6]]
let nums = num1.concat2(num2) // [[1], 2, [3]]
let nums2 = num1.concat2(4, num3) // [[1], 4, 5,[6]]

20. join

join() 方法通過連接數組(或類似數組的對象)中的所有元素來創建并返回一個新字符串,以逗號或指定的分隔符字符串分隔。 如果數組只有一項,則將在不使用分隔符的情況下返回該項。

const elements = ['Fire', 'Air', 'Water']
const elements2 = ['Fire']
console.log(elements.join()) // Fire,Air,Water
console.log(elements.join('')) // FireAirWater
console.log(elements.join('-')) //  Fire-Air-Water
console.log(elements2.join('-')) // Fire

代碼

Array.prototype.join2 = function (format = ',') {
  const length = this.length
  // Save the last element because it does not participate in the connection of format
  let lastEle = this[ length - 1 ]
  let string = ''
  if (length === 0) {
    return string
  }
  for (i = 0; i < length - 1; i++) {
    string += this[ i ] + format
  }
  return string + lastEle
}

測試一下

const elements = ['Fire', 'Air', 'Water']
const elements2 = ['Fire']
console.log(elements.join2()) // Fire,Air,Water
console.log(elements.join2('')) // FireAirWater
console.log(elements.join2('-')) //  Fire-Air-Water
console.log(elements2.join2('-')) // Fire

最后

感謝您的閱讀,同時,也期待您的關注,閱讀更多優質文章。

責任編輯:華軒 來源: web前端開發
相關推薦

2022-11-13 15:33:30

JavaScript數組開發

2022-08-10 12:02:52

面試JavaScript

2015-03-24 13:31:06

2022-09-27 14:36:57

JavaScrip數組開發

2014-09-01 14:31:11

2020-03-19 15:30:08

JavaScript數組字符串

2022-03-09 09:56:27

插件開發效率

2022-04-28 08:41:53

JavaScript數組

2019-12-11 09:23:51

JavaScriptHTMLXML

2023-07-04 15:52:49

JavaScript數組

2024-04-03 10:29:13

JavaScrip優化技巧

2019-07-19 09:21:54

Java開源庫程序員

2022-10-18 16:35:51

JavaScrip數組參數

2022-05-06 12:03:16

數組Javascript

2015-10-26 09:08:29

程序員JavaScript理由

2021-11-01 22:39:14

程序員專業技術

2023-03-19 16:02:33

JavaScrip技巧編程語言

2022-11-23 16:12:57

JavaScript數據類型數組

2018-09-20 17:05:01

前端程序員JavaScript

2019-08-13 16:23:19

JavaScript數組方法
點贊
收藏

51CTO技術棧公眾號

综合久久一区| 在线免费成人| 中文字幕乱码一区二区免费| 成人国产精品一区二区| 成人免费看片98| 丝袜久久网站| 欧美久久久久久久久中文字幕| a级片一区二区| 欧美人体大胆444www| 美女视频黄频大全不卡视频在线播放 | 午夜精品久久久久久久99黑人| 国产精品成人一区二区三区电影毛片| 欧美成人一二区| 精品av在线播放| 咪咪色在线视频| 青青久草在线| 国产精品69毛片高清亚洲| 日本精品视频在线播放| 日本中文字幕免费在线观看| 国产一区二区三区四区五区传媒| 欧美一级搡bbbb搡bbbb| 99免费视频观看| 欧美hdxxxxx| 国产精品久久久久久久蜜臀| 久久久久久高清| 99久久精品国产成人一区二区| 美女日韩在线中文字幕| 欧美超级乱淫片喷水| 18精品爽国产三级网站| 国产精品网在线观看| 7777精品伊人久久久大香线蕉超级流畅 | 色欲AV无码精品一区二区久久| 91综合久久爱com| 欧美剧情电影在线观看完整版免费励志电影| a在线视频观看| 手机在线免费看av| 综合久久给合久久狠狠狠97色 | 加勒比一区二区三区在线| 国产福利视频一区二区三区| 国产在线观看一区二区三区| 欧美超碰在线观看| 国产女优一区| 91国内揄拍国内精品对白| a级片在线观看免费| 欧美顶级大胆免费视频| 国产小视频91| 免费网站在线高清观看| 日韩三级毛片| 精品无人国产偷自产在线| 五月天丁香社区| 豆花视频一区二区| 精品国产乱码久久久久久蜜臀 | 久在线观看视频| 丁香花高清在线观看完整版| 亚洲综合色成人| 水蜜桃在线免费观看| 黄色在线免费网站| 亚洲日本欧美天堂| 蜜臀av.com| 国产激情小视频在线| 专区另类欧美日韩| 久久久久久久久影视| 大片免费在线看视频| 亚洲色图在线视频| 日本福利视频在线观看| 色呦呦网站在线观看| 亚洲资源在线观看| av日韩一区二区三区| 美女在线视频免费| 色哟哟一区二区| 蜜桃免费在线视频| 亚洲成人1区| 日韩色视频在线观看| 无码av免费精品一区二区三区| 狠狠一区二区三区| 亚洲精品资源美女情侣酒店 | 亚洲视频在线一区| 国产一级大片免费看| 超碰91在线观看| 日韩欧美高清在线视频| 亚洲色图 在线视频| 国产精品视频首页| 亚洲成人999| 中文字幕 自拍| 国产精品久久久久一区二区三区厕所 | 婷婷五月在线视频| 一二三区精品视频| 黑人糟蹋人妻hd中文字幕| 欧美三级精品| 日韩一区二区三区视频| 欧美深性狂猛ⅹxxx深喉| 国产亚洲一区二区三区啪 | 俺来俺也去www色在线观看| 精品久久久久久中文字幕| 日韩精品你懂的| 国产一精品一av一免费爽爽| 日韩国产欧美精品一区二区三区| 国产精品久久免费观看| 国产精品jizz在线观看美国| 欧美在线欧美在线| 国产又色又爽又黄又免费| 成人精品国产福利| 亚洲欧洲精品一区二区| 免费污视频在线观看| 在线观看三级视频欧美| 日本泡妞xxxx免费视频软件| 精品国产一区二区三区久久久樱花 | 国产中文一区二区三区| 国内一区二区在线视频观看| 在线日本视频| 精品久久久久久久久久久| 最新av免费在线观看| 欧美挤奶吃奶水xxxxx| www日韩欧美| 美日韩一二三区 | 熟女少妇一区二区三区| 亚洲经典一区| 国产精品久久久久久久app| 黄色av网址在线| 亚洲天堂网中文字| 久久久久国产精品熟女影院| 高清在线一区二区| 中文字幕在线成人| 一级片在线观看免费| 国产91色综合久久免费分享| 亚洲狠狠婷婷综合久久久| 好吊日av在线| 日韩视频免费观看高清完整版| 中文字幕免费高清| 国产精品久久久一区二区| av在线亚洲男人的天堂| 在线看av的网址| 在线观看www91| 青青草视频成人| 亚洲三级视频| 国产精品自拍首页| 久草在线视频网站| 欧美一区二区三区四区在线观看 | 中文字幕第六页| 欧美www视频在线观看| 国产精品久久久久久久av大片| 青青草免费观看免费视频在线| 精品福利一区二区| 尤物网站在线观看| 亚洲精品欧美| 精品欧美国产| 亚洲一级少妇| 亚洲女人初尝黑人巨大| 日本一区二区三区精品| 2021久久国产精品不只是精品| 水蜜桃色314在线观看| 激情视频极品美女日韩| 91地址最新发布| 五月婷在线视频| 五月婷婷另类国产| 色天使在线视频| 男人的天堂亚洲| 日本一区视频在线观看| 黑人巨大亚洲一区二区久| 亚洲欧美视频在线| www.亚洲激情| 国产精品麻豆视频| 国产欧美精品一二三| 国产韩国精品一区二区三区| 91久久久久久国产精品| 1区2区在线观看| 精品国产91久久久久久久妲己| 国产精品7777| 26uuu成人网一区二区三区| 三级4级全黄60分钟| 日韩一区三区| 亚洲综合在线小说| 97人人爽人人澡人人精品| 亚洲精品成人av| 无码人妻久久一区二区三区| 国产精品视频看| 妖精视频在线观看| 日韩视频在线一区二区三区| 欧美日韩另类综合| 亚洲免费一区| 国产做受高潮69| 国产在线免费观看| 欧美一区二区福利视频| 中文字幕第15页| 国产精品短视频| 逼特逼视频在线观看| 国产精品普通话对白| 神马一区二区影院| 超碰精品在线| 国产精品久久久久久av| 天堂亚洲精品| 在线电影欧美日韩一区二区私密| www.色呦呦| 色中色一区二区| 懂色av懂色av粉嫩av| www国产精品av| 亚洲制服中文字幕| 国产一区二区三区久久| 欧美少妇一级片| 久久不卡国产精品一区二区| 成人写真视频福利网| 在线视频超级| 欧美成年人视频网站| 可以在线观看的黄色| 欧美成人精精品一区二区频| 波多野结衣不卡| 午夜在线成人av| 三级黄色片在线观看| 久久综合色婷婷| 91精品国产高清91久久久久久 | 亚洲国产日韩在线一区| 久久一综合视频| 欧美狂野激情性xxxx在线观| 日韩综合精品| 久久综合入口| 久久aimee| 91精品网站| 日韩专区视频| 国产精品91在线| 在线观看网站免费入口在线观看国内 | 7777精品伊久久久大香线蕉语言| 奇米777日韩| 91a在线视频| 18video性欧美19sex高清| 美女视频黄免费的亚洲男人天堂| 99视频在线观看地址| 日韩高清有码在线| 姝姝窝人体www聚色窝| 日韩亚洲欧美一区| 97免费观看视频| 精品污污网站免费看| 一级特黄免费视频| 欧美午夜精品在线| 国产精品100| 懂色av影视一区二区三区| 国产午夜精品无码一区二区| 亚洲精品免费在线| 在线免费观看亚洲视频| 亚洲免费看黄网站| 久久久久亚洲AV成人| 亚洲欧洲无码一区二区三区| 国产又黄又粗又猛又爽的| 国产亚洲一区二区在线观看| 熟女俱乐部一区二区| 91麻豆.com| 老鸭窝一区二区| 久久色成人在线| 美女爆乳18禁www久久久久久| 91麻豆国产香蕉久久精品| 男生草女生视频| 国产视频不卡一区| 日本猛少妇色xxxxx免费网站| 久久精品日产第一区二区三区高清版 | 久久手机免费视频| 羞羞网站在线看| 久久久久久高潮国产精品视| 91九色在线播放| 午夜精品久久久久久久99黑人| 国产精品一区二区日韩| 日av在线播放中文不卡| 成人不卡视频| 91在线观看免费观看 | 久久久久99精品| 亚洲不卡av一区二区三区| 国产精品老女人| 色欧美片视频在线观看在线视频| 国产男人搡女人免费视频| 欧美色男人天堂| 精品人妻午夜一区二区三区四区 | 色爱区综合激月婷婷| 亚洲精品无码久久久久| 欧美男生操女生| 丰满少妇被猛烈进入| 亚洲男人的天堂在线| 92国产在线视频| 欧美猛交免费看| 天堂中文在线播放| 国产综合香蕉五月婷在线| 视频精品二区| 欧美日韩一区在线播放| 欧美激情另类| 国产欧美日韩网站| 日韩av一区二| 日本美女视频网站| 国产色91在线| 久久久久久久久久久网 | 中文字幕在线免费不卡| 精品亚洲永久免费| 在线观看日产精品| www.蜜臀av.com| 亚洲天堂精品在线| av网站大全在线| 45www国产精品网站| 国产成人免费视频网站视频社区 | 91在线网站视频| 日韩精品丝袜美腿| 日韩人妻精品一区二区三区| 国产日韩一区| 99九九精品视频| 国产片一区二区| 久久精品视频久久| 欧美日韩成人在线| 三级毛片在线免费看| 成年人精品视频| h1515四虎成人| 国内一区二区在线视频观看| 欧美一区高清| 国产又粗又长又大的视频| www.日韩大片| 日韩视频中文字幕在线观看| 在线免费观看不卡av| 日本高清视频www| 久久av中文字幕| 欧洲亚洲精品| 日韩wuma| 噜噜爱69成人精品| 亚洲v在线观看| 亚洲欧美色一区| 亚洲无码久久久久久久| 亚洲美女久久久| 蜜桃麻豆av在线| 国产精品久久久久久久久婷婷| 国产精品成久久久久| 天堂在线资源视频| 国产人妖乱国产精品人妖| 国产做受高潮漫动| 精品区一区二区| av片在线观看| 成人黄色短视频在线观看| 成人综合久久| 91极品尤物在线播放国产| 久久无码av三级| 精品免费囯产一区二区三区| 欧美精品一区二区三区蜜臀| 羞羞视频在线观看不卡| 91在线|亚洲| 欧美区日韩区| www.欧美com| 亚洲一线二线三线久久久| 国产草草影院ccyycom| 久久成人精品视频| 欧美成人精品一级| 久久最新免费视频| 国产精品自拍网站| 久久久久久久9999| 精品免费一区二区三区| 蜜臀av在线播放| 国产精品裸体一区二区三区| 亚洲第一精品影视| 美女久久久久久久久| 五月婷婷激情综合网| 头脑特工队2免费完整版在线观看 头脑特工队2在线播放 | 欧美日韩成人在线| 黄视频在线观看网站| 91高跟黑色丝袜呻吟在线观看| 欧美激情第8页| 人妻激情偷乱频一区二区三区 | 亚洲一区二区影视| 久久精品亚洲94久久精品| 成人豆花视频| www.xxx麻豆| 91影院在线观看| 日本a级c片免费看三区| 中文字幕不卡在线视频极品| 综合欧美精品| 91亚洲精品国产| 91视频免费观看| 最近中文字幕在线视频| 久久视频在线直播| 美国成人xxx| 天美星空大象mv在线观看视频| 中文字幕日韩精品一区| 精品久久久免费视频| 2020久久国产精品| 四虎国产精品免费观看 | 久久精品夜色噜噜亚洲aⅴ| 国内av在线播放| 九九热99久久久国产盗摄| 欧美精品国产白浆久久久久| 日本久久精品一区二区| 亚洲欧美激情插 | 久久午夜免费电影| 91国内精品视频| 国内精品久久久久久影视8| 久久99性xxx老妇胖精品| 亚洲第一区第二区第三区| 精品福利在线视频| 国产在线高潮| 精品午夜一区二区三区| 久久机这里只有精品| 国产网址在线观看| 在线一区二区日韩| 国产另类在线| 欧美日韩一区二区三区69堂| 亚洲一区二区三区四区在线观看 | 伊人久久大香线蕉无限次| av在线网址导航| 疯狂蹂躏欧美一区二区精品| 超碰在线网址| 日韩精品欧美在线|