题 :
    如果我们要从query中提取数据的话,可以使用 URLSearchParams ,非常方便。
    你能否自己实现一个和URLSearchParams基本一样的MyURLSearchParams?

    const params = new MyURLSearchParams(‘?a=1&a=2&b=2’)
    params.get(‘a’) // ‘1’
    params.getAll(‘a’) // [‘1’, ‘2’]
    params.get(‘b’) // ‘2’
    params.getAll(‘b’) // [‘2’]

    params.append(‘a’, 3)
    params.set(‘b’, ‘3’)
    params.toString() // ‘a=1&a=2&b=3&a=3’

    1. class MyURLSearchParams {
    2. /**
    3. * @params {string} init
    4. */
    5. constructor(init) {
    6. this.params = init
    7. .replace(/^\?/, '')
    8. .split('&')
    9. .map((param) => param.split('='))
    10. }
    11. /**
    12. * @params {string} name
    13. * @params {any} value
    14. */
    15. append(name, value) {
    16. this.params.push([name, String(value)])
    17. }
    18. /**
    19. * @params {string} name
    20. */
    21. delete(name) {
    22. this.params = this.params.filter((param) => param[0] !== name)
    23. }
    24. /**
    25. * @returns {Iterator}
    26. */
    27. *entries() {
    28. for (let i = 0; i < this.params.length; i++) {
    29. yield [this.params[i][0], this.params[i][1]]
    30. }
    31. }
    32. /**
    33. * @param {(value, key) => void} callback
    34. */
    35. forEach(callback) {
    36. this.params.forEach(param => {
    37. callback.apply(this, [param[1], param[0]])
    38. })
    39. }
    40. /**
    41. * @param {string} name
    42. * returns the first value of the name
    43. */
    44. get(name) {
    45. return this.params.find((param) => param[0] === name)?.[1] || null
    46. }
    47. /**
    48. * @param {string} name
    49. * @return {string[]}
    50. * returns the value list of the name
    51. */
    52. getAll(name) {
    53. return this.params
    54. .filter((param) => param[0] === name)
    55. .map((param) => param[1])
    56. }
    57. /**
    58. * @params {string} name
    59. * @return {boolean}
    60. */
    61. has(name) {
    62. return this.params.some((param) => param[0] === name)
    63. }
    64. /**
    65. * @return {Iterator}
    66. */
    67. keys() {
    68. return this.params.map((param) => param[0])
    69. }
    70. /**
    71. * @param {string} name
    72. * @param {any} value
    73. */
    74. set(name, value) {
    75. const exists = this.params.some((param) => {
    76. if (param[0] !== name) return false
    77. param[1] = String(value)
    78. return true
    79. })
    80. if (!exists) {
    81. this.append(name, value)
    82. }
    83. }
    84. // sort all key/value pairs based on the keys
    85. sort() {
    86. this.params.sort((a, b) => {
    87. if (a[0] > b[0]) return 1
    88. if (a[0] < b[0]) return -1
    89. return 0
    90. })
    91. }
    92. /**
    93. * @return {string}
    94. */
    95. toString() {
    96. return this.params.map((param) => param.join('=')).join('&')
    97. }
    98. /**
    99. * @return {Iterator} values
    100. */
    101. values() {
    102. return this.params.map((param) => param[1])
    103. }
    104. }

    *entries() {} 这个怎么弄? 还不太明白;

    MyURLSearchParams('?a=1&b=2')  
    
    'a=1&b=2' is also acceptable  
    
    MyURLSearchParams doesn't parse full url 'https://google.com?a=1&b=2'  
    
    append() should work for string  
    
    append() should store string values if non-string is passed  
    
    delete() should work,'?a=1&a=1&b=2'  
    
    entries() should work, 'a=1&a=1&a=2&b=2'   
    
    forEach() should work, 'a=1&a=1&a=2&b=2'   
    
    get() should work, 'a=2&a=1&a=2&b=2'   
    
    getAll() should work, 'a=2&a=1&a=2&b=2'   
    
    has() should work, 'a=2&a=1&a=2&b=2'   
    
    keys() should work, 'a=2&a=1&a=2&b=2'   
    
    set() should work, 'a=2&a=1&a=2&b=2'   
    
    sort() should work, 'c=2&a=2&a=1&a=2&b=2'   
    
    toString() should work, '?c=2&a=2&a=1&a=2&b=2'   
    
    values() should work, '?c=2&a=2&a=1&a=2&b=2'