「30s代码解析挑战」获取URL参数

我心飞翔 分类:javascript

每日解析一个30 seconds of code网站代码片段

获取URL参数

const getURLParameters = (url) =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (preVal, curVal) => (
      (preVal[curVal.slice(0, curVal.indexOf('='))] = curVal.slice(curVal.indexOf('=') + 1)), preVal
    ),
    {}
  );
 

流程解析

  1. 通过String.prototype.match()方法匹配到所有参数的键值对;
  2. 通过Array.prototype.reduce()将参数键值对全部整合在一个对象中;
  3. window.location.search取到URL中后的参数字符串可以作为参数传给函数getURLParameters的url参数。也可以直接传递整个url链接字符串。

技术解析

输入:URL字符串

输出:参数对象

match

match方法:match(reg)根据正则reg将字符串分割后返回数组,如果全部都匹配不到就返回null

正则表达式

[^?=&]:[]表示或,类似|,[^]表示查找?=&字符之外的字符;后面的=[^&]表示将参数中的值带上=的符号;

// 一般url格式http://url.com/page?name=Adam&surname=Smith
// 首先是?+&之外并且有=,或者&之外:name=Adam,surname=Smith
url.match(/([^?=&]+)(=([^&]*))/g)
 

reduce

reduce方法:reduce(callback, initVal)方法用以做累加的操作。initVal表示初值,callback函数里的参数固定function(preVal, curVal, index, array) { ... }分别表示之前的值/当前的值/当前值的索引/当前操作的数组本身。

reduce会遍历数组的每一个元素,每一次遍历的结果作为preVal,下一个元素为curVal,依次循环。

// 本例的结构可以看出初始值是空对象,也就是初始时preVal={}
arr.reduce(
  (preVal, curVal) => {...},
  {}
)
 

箭头函数

箭头函数的规则:

  • 如果只有一条语句可以不用写{}return
  • 没有{}=>和函数体必须在同一行,不能换行。可以利用()进行换行。
// 本例利用()换行
(a, v) => (
    ....
);

// 等价于
(a, v) => {
  return ....
}

// 等价于
(a, v) => ....
 

逗号操作符

逗号操作符,:对每个操作数求值(从左到右)并返回最后一个操作数的值。当你想要在期望一个表达式的位置包含多个表达式时,可以使用逗号操作符。

let x = 1;
x = (x++, x); // 2

let fn = () => (1,2,3);
fn(); //3
 

在本例中:

// preVal[curVal.slice(0, curVal.indexOf('='))] = curVal.slice(curVal.indexOf('=') + 1
// 上面一串代码作用是将URL参数键值对一一对应放入对象
 (......, preVal)   //最终返回preVal的值
 

结合到箭头函数可能有点不太好懂,括号里面套括号,其实第一层括号为了换行,第二层括号是为了一行多操作表达式。

flush points

在动态语言里使用任何方法都要考虑边界条件。很容易出现运行时出错。

url.match(/([^?=&]+)(=([^&]*))/g) || []中,match匹配不到字符串返回null,如果没有|| []程序就会抛出错误停止执行,因为null没有reduce方法。

thinking

这样子写程序在工作中应该会被打吧。。。。太简化了,没有注释真的不太好懂

简化了一下:

const getURLParameters = (url) => {
  const urlParamArr = url.match(/([^?=&]+)(=([^&]*))/g) || [];
  const urlParamObj = urlParamArr.reduce(
    (preVal, curVal) => {
      preVal[curVal.slice(0, curVal.indexOf('='))] = curVal.slice(curVal.indexOf('=') + 1);
      return preVal;
    },
    {}
  );
  return urlParamObj;
}

 

回复

我来回复
  • 暂无回复内容