面试题之解析URL Params 为对象

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>String</title>
</head>

<body>
    <script src="../js/jquery-3.5.1.min.js"></script>
    <script>
        /**
         *解析URL Params 为对象
         *注意:
         *    1.重复key的问题
         *    2.解码问题
         *    3.未指定值的value,约定为Boolean值true
         *    4.能转成数字类型的转成数字类型
         *步骤:
         *    1.获取?后字符串
         *        a.正则
         *            . 匹配除换行符 
 之外的任何单字符。要匹配 . ,请使用 . 。
         *            + 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +
         *            ()标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。
         *        b.exec()
         *            用于检索字符串中的正则表达式的匹配,返回值是一个数组(存放匹配结果),未找到匹配,返回null.
         *            var regResult= RegExpObject.exec(string);
         *            I. 未匹配到 : regResult = null;
         *            II.匹配到:
         *                regResult[0]:与正则表达式相匹配的文本
         *                regResult[1]:第一个子表达式相匹配的文本(如果有)
         *                regResult[2]:第二个子表达式相匹配的文本(如果有)
         *                ...
         *                regResult包含属性:
         *                    length:数组长度
         *                    index:匹配文本的第一个字符的位置
         *                    input:存放被检索的字符串
         *                    groups:是一个{},多个key为捕获组名字value为该捕获匹配的字符串的键值对集合,捕获组的信息,并且是实名捕获
         *                        /(d+)/:捕获
         *                        /(?<test>d+)/:实名捕获(名字为test),regResult.groups.test获取对应匹配信息
         *    2.将字符串分割成数组
         *        str.split(&)
         *    3.将值存入对象
         *        a.指定value的参数
         *            I.解码 decodeURLComponent()  
         *            II. 能转成数字类型的转成数字类型  
         *            III.存储
         *                对象中已存有key,添加值Obj.hasOwnProperty(key)
         *               未存key,存入
         *        b.未指定value的参数,直接约定value为true
         */
        let url = http://www.domain.com/?username=zhangsan&id=888&id=666&city=%E5%8C%97%E4%BA%AC&checked;
        console.log(parseParamsToObj(url)); //{checked: true,city: "北京",id:[888, 666],username: "zhangsan"}

        function parseParamsToObj(url) {
            const paramsStr = /.+?(.+)$/.exec(url)[1]; // 匹配?后字符串
            const paramsArr = paramsStr.split(&); // 将字符串以&分割成数组
            let paramsObj = {};
            paramsArr.forEach(param => {
                // 处理已指定value的参数
                if (/=/.test(param)) {
                    let [key, val] = param.split(=);
                    val = decodeURIComponent(val);
                    val = /^d+$/.test(val) ? parseFloat(val) : val;
                    // 对象有key,添加值
                    if (paramsObj.hasOwnProperty(key)) {
                        paramsObj[key] = [].concat(paramsObj[key], val);
                    } else {
                        paramsObj[key] = val;
                    }
                } else {
                    // 处理未指定value的参数
                    paramsObj[param] = true;
                }
            })
            return paramsObj;
        }
    </script>
</body>

</html>
经验分享 程序员 微信小程序 职场和发展