zhangxinxu / quiz

小测答题收集区
536 stars 43 forks source link

JS基础测试35期 #35

Open zhangxinxu opened 5 years ago

zhangxinxu commented 5 years ago

本期题目依然非常基础:

答题前不要看别人回答,答题后可以,但不能修改自己回答

大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。

```js
// 你的JS代码写在这里
 ```

其它:

  1. 首位答题者可获得直播翻牌机会;
  2. 本次答疑直播为7月27日上午10:00,大约30分钟;
guqianfeng commented 5 years ago
  1. encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问号和井字号; 而 encodeURIComponent()则会对它发现的任何非标准字符进行编码。
  2. Object.keys(object1).map(key => key + "=" + object1[key]).join("&")
  3. window.location.search
  4. 代码如下
    // zxx: 有bug
    let str = window.location.search;
    let arr = str.substring(1).split("&");
    let res = {};
    arr.forEach(item => {
        let o = item.split("=");
        res[o[0]] = o[1];
    })
    console.log(res);
  5. 代码如下
    let str = window.location.search;
    let arr = str.substring(1).split("&");
    let res = {};
    arr.forEach(item => {
        let o = item.split("=");
        if(!res[o[0]]){
            res[o[0]] = [];
        }
        res[o[0]].push(o[1]);
    })
    console.log(res);
livetune commented 5 years ago

1.encodeURI无法产生适用于http中get和post请求的URI,因为一些请求中的特殊符号如&、=、#之类的符号,而encodeComponentURI会对这些字符进行编码

    //2.
    const object1 = {
        userid: 123,
        username: '王二',
        tel: '13208033621'
    }
    const query = Object.keys(object1).map(v => `${v}=${encodeURIComponent(object1[v])}`).join('&')
    //3.
    const urlQuery =location.search
    //4.
    // zxx: 有bug
    urlQuery.slice(1).split('&').reduce((res, val) => {
        const result = val.split('=');
        res[result[0]] = result[1];
        return res
    }, {})
    //5.
    urlQuery.slice(1).split('&').reduce((res, value) => {
        const result = value.split('=');
        const key = result[0]
        const val = result[1]
        if (key in res) {
            if (Array.isArray(res[key])) {
                res[key].push(val)
            } else {
                res[key] = [res[key], val]
            }
        } else {
            res[key] = val
        }
        return res
    }, {})
ZhangXDong commented 5 years ago
const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
}
// 1. encodeURI 和 encodeURIComponent 区别
encodeURIComponent 会对整个url中的符号进行编码; encodeURI 会保留协议,域名,端口,对参数等进行编码。
// 2
Object.keys(object1).map((key) => `${key}=${encodeURIComponent(object1[key])}`).join('&')
// 3
location.search
// 4
const queryString = {};
location.search.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => queryString[k] = decodeURIComponent(v))
// 5
const queryString = {};
location.search.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => {
    if (queryString[k]) {
    queryString[k] = [queryString[k]]
    queryString[k].push(decodeURIComponent(v))
    } else {
    queryString[k]=decodeURIComponent(v)
    }
})
ghost commented 5 years ago
  1. encodeURI() 函数假设参数是完整的 URIsencodeURIComponent() 函数假设参数是 URI 中单独的一部分

因为这两种假设差异,encodeURI 不会将 URI 保留字符编码,encodeURIComponent 会忽略保留字符,把这些代码当作普通字符编码

  1. 使用 Object.entries 获取 kv 元组,其中对应 [key, value]
    
    let entries = Object.entries(object1)

let kvList = entries.map(kv => { let [key, value] = [...kv] return ${key}=${encodeURIComponent(value)} })

let result = kvList.join('&')

一行版本:
```js
Object.entries(object1).map(kv => `${kv[0]}=${encodeURIComponent(kv[1])}`).join('&')
  1. 当然是 location.search 啦~ 不过也可以用 new URL(location.href).search

  2. 利用 URLSearchParams 对象,使用 entries() 方法获得可迭代对象,然后迭代

    let search = new URLSearchParams(location.search)
    let entries = search.entries()
    let next = entries.next()
    let obj = {}
    while (!next.done) {
    let [key, value] = [...next.value];
    obj[key] = value;
    next = entries.next();
    }
    // result is obj
  3. 修改 while 函数体中内容为:

    let [key, value] = [...next.value];
    if (obj.hasOwnProperty(key)) {
    if (obj[key] instanceof Array) {
        obj[key].push(value)
    } else {
        obj[key] = [obj[key], value]
    }
    } else {
    obj[key] = value
    }
    next = entries.next();
    // result is obj
wingmeng commented 5 years ago
const object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
};

第 1 题:

一句话:两者都会对 URL 中的特殊字符进行编码,区别是两者编码的字符范围不一样,前者不会对属于 URI 的特殊字符进行编码,而后者会。

第 2 题:

Object.keys(object1)
  .map(key => `${key}=${encodeURIComponent(object1[key])}`)  // 转码
  .join('&');

第 3 题:

location.search;

第 4、5 题:

2019-07-25 修改:调整了函数和形参命名,使之更加语义化;增加了测试用例

// zxx: 有bug
function getQueryObj(queryStr = '') {
  // 移除前面的 ? 号(如有)
  queryStr = queryStr.indexOf('?') === 0 ? queryStr.substr(1) : queryStr;
  if (!queryStr) return {};

  return queryStr.split('&')
    .map(s => s.split('='))  // 拆解 key 和 value
    .reduce((obj, [key, value]) => {
      value = value ? decodeURIComponent(value) : '';  // 解码

      if (key in obj) {
        Array.isArray(obj[key]) ? obj[key].push(value) : obj[key] = [obj[key], value];
      } else {
        obj[key] = value;
      }

      return obj;
    }, {});
}

getQueryObj 测试用例:

getQueryObj();  // 参数为空

// 一般情况
getQueryObj('userid=123&username=%E7%8E%8B%E4%BA%8C&tel=13208033621');

// 空值(username 值为空)
getQueryObj('userid=123&username=&tel=13208033621');

// 多个重复的键名(tel、favorite)
getQueryObj('?userid=123&tel=13208033621&username=%E7%8E%8B%E4%BA%8C&favorite=rap&favorite=Hip%20hop&favorite=basketball&tel=15888888888&tel=18099999999');
Seasonley commented 5 years ago

1.前者是对url字符转义(除了URI协议相关的符号比如:/?=&),后者对url?后面的传参部分做转义(比如&=会被误认为参数分隔)

const object1={userid:123,username:'王二',tel:'13208033621'}
//2
var ans2=Object.entries(object1).map(o=>o.map(encodeURIComponent).join('=')).join('&')
//3
var ans3=location.search.split('&')[0]
//4 5
// zxx: encodeURIComponent画蛇添足啦
function search2obj() {
    var ans = {} , str = location.search.slice(1)
    if (str === '') return ans
    str.split('&').forEach(o =>{
        let [k, v] = o.split('=').map(encodeURIComponent)
        if (k in ans && ans[k].push) ans[k].push(v)
        else if (k in ans) ans[k] = [ans[k], v]
        else ans[k] = v
    })
   return ans
}
console.log(ans2,ans3,search2obj())
NeilChen4698 commented 5 years ago
  1. encodeURI 一般用来转义整个URL, 只转义影响判断URL的字符; encodeURIComponent 一般用于转义URL包含的参数,会转义大多数特殊字符

  2. Object.keys(object1).reduce((prev, current) => (prev + (!prev ? '' : '&') + current + '=' + encodeURIComponent(object1[current])), '');
  3. var arr = /([?].*)/.exec(document.URL);
    var result = !arr ? '' : arr[0];

4/5 .

//zxx: 有bug
var obj = [].slice.apply(result .slice(1).split('&')).filter(v => !!v && v.indexOf('=') > 0).reduce((prev, current) => {
    var kv = current.split('=');
    var k = decodeURIComponent(kv[0]);
    var v = decodeURIComponent(kv[1]);
    if (prev[k] === undefined) {
        prev[k] = v;
    } else if (prev[k] instanceof Array) {
        prev[k].push(v);
    } else {
        prev[k] = [].concat.apply([prev[k]],[v]);
    }
    return prev;
}, {});
Despair-lj commented 5 years ago
const object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
}
// 1. encodeURI 与 encodeURIComponent 的主要区别在需要转义的字符范围不一样

// 2.
var objString = new URLSearchParams(object1).toString()

// 3. 这个题目总分两分感觉不简单?
var urlString = window.location.search

// 4.
var urlSearchParams = new URLSearchParams(urlString)
var urlObj = {}
for (let [key, value] of urlSearchParams.entries()) {
  urlObj[key] = value
}

// 5.
var repeatUrlObj = {}
for (let [key, value] of urlSearchParams.entries()) {
  if (!repeatUrlObj[key]) {
    repeatUrlObj[key] = value
  } else if (
    repeatUrlObj[key] &&
    typeof repeatUrlObj[key] === 'string'
  ) {
    repeatUrlObj[key] = [repeatUrlObj[key]]
    repeatUrlObj[key].push(value)
  } else {
    repeatUrlObj[key].push(value)
  }
}
XboxYan commented 5 years ago

1 大概记得是encodeURI不会对:/?#=&等正常的url进行编码,而encodeURIComponent则会全部编码 2

const object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
}
var s = Object.entries(object1).map(([k,v])=>k+'='+encodeURIComponent(v)).join('&');
//console.log(s)

3

location.search

4

var s = decodeURIComponent(location.search);
var p = {}
s.replace(/([^?=&]+)=([^&]+)/g,($,k,v)=>p[k]=v);
//console.log(p)

test

var s =  'userid=123&username=王二&tel=13208033621';
var p = {}
s.replace(/([^?=&]+)=([^&]+)/g,($,k,v)=>p[k]=v);
console.log(p)

5

var p = {}
s.replace(/([^?=&]+)=([^&]+)/g,($,k,v)=>p[k]=p[k]?(Array.isArray(p[k])?[...p[k],v]:[p[k],v]):v);
//console.log(p)

test

var s =  'userid=123&username=王二&tel=13208033621&tel=2222&tel=333';
var p = {}
s.replace(/([^?=&]+)=([^&]+)/g,($,k,v)=>p[k]=p[k]?(Array.isArray(p[k])?[...p[k],v]:[p[k],v]):v);
console.log(p)
liyongleihf2006 commented 5 years ago
/* 测试url使用 http://127.0.0.1:5501/test31.html?a=b&c=???&a=e&a=&d*/
/* 第一题 */
const first = "encodeURIComponent 比 encodeURI 多转义下列字符 ;,/?:@&=+$#";
console.log(first);
const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
}
/* 第二题 */
const second = new URLSearchParams(object1).toString();
console.log(second);
/* 第三题 */
const third = location.search;
console.log(third);
/* 第四题  有个很严重的问题,当有重复的键的时候,后面的值会把前面的值给覆盖掉,这里我就把当有重复值的时候,所有的重复的值使用逗号连接在一起了*/
// zxx: 是会有问题的,如果值本身就带有逗号
const forth = [...new URL(location.href).searchParams.entries()].
reduce((target, [key,value]) => {
    target[key] = target[key]?target[key]+","+value:value;
    return target
}, {});
console.log(forth);
/* 第五题 */
const searchParams = new URL(location.href).searchParams;
const keys = [...new Set(searchParams.keys())];
const sixth = keys.reduce((target,key)=>{
    let values = searchParams.getAll(key);
    values = values.length>1?values:values[0];
    target[key] = values;
    return target;
},{});
console.log(sixth);
fzpijl commented 5 years ago

1、 一个编码整个URI,一个只编码部分

2、

     function encodeObj(obj) {
            let str = ''
            for(let prop in obj) {
                if(obj.hasOwnProperty(prop)){
                    str += prop + '=' + encodeURIComponent(obj[prop]) + '&'
                }
            }
            return str.slice(0, -1);
      }

3、

     function getQueryStr() {
            const reg = /\?[^?]*/
            const res = location.search.match(reg)
            return res ? deocdeURIComponent(res[0]) : null
      }

4、

//zxx: 有 bug 也
    const queryStr = getQueryStr().slice(1)
    function toObject(str) {
            const arr = str.split('&')
            const obj = {};
            for(let i = 0, len = arr.length; i < len; i++) {
                let pairs = arr[i].split('=')
                obj[pairs[0]] = pairs[1]
            }
            return obj
        }
       toObject(queryStr)

5、

      function toObjectArr(str) {
            const arr = str.split('&')
            const obj = {};
            for(let i = 0, len = arr.length; i < len; i++) {
                let pairs = arr[i].split('=')
                if(obj[pairs[0]]){
                    if(typeof obj[pairs[0]] === 'string') {
                        obj[pairs[0]] = [obj[pairs[0]]]
                        obj[pairs[0]].push(pairs[1])
                    } else{
                        obj[pairs[0]].push(pairs[1])
                    }
                }else {
                    obj[pairs[0]] = pairs[1]
                }
            }
            return obj
        }
JaimeCheng commented 5 years ago
  1. encodeURI 通常对整个URI编码并且不影响URI本身的特殊字符,encodeURIComponent 会对所有特殊字符编码,通常用于对查询字符串编码;
  2. Object.entries(object1).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&')
  3. const queryStr = decodeURIComponent(location.search)
  4. // zxx: Object.fromEntries是什么?
    Object.fromEntries(queryStr.split("?")[1].split("&").map(item => item.split('=')))
    // 写到5题发现这题就有问题了,如果有重复的键就会被覆盖,所以4,5一起再写

    4,5.

    const arr = queryStr.split("?")[1].split("&").map(item => item.split('='))
    var res = {}
    arr.forEach(item => {
    if (!res[item[0]]) {
      res[item[0]] = item[1]
    } else {
      res[item[0]] = (res[item[0]]+','+item[1]).split(',')
    }
    })
    console.log(res)
les-lee commented 5 years ago
const object1 = {
  userid: '123',
  name: '王二',
  tel: '13208033621'
}

/*1.*/ console.log('第一题','encodeURI 对&,+,=, 不会进行编码, 而encodeURIComponent 会')

function contactObj (obj) {
  let result = ''
  for(let item in object1) {
    if (object1.hasOwnProperty(item)) {
      result += `${item}=${object1[item]}&`
    }
  }
  return encodeURI(result).replace(/&$/, '')
}

/*2.*/console.log('第二题',contactObj(object1))

/*3.*/ console.log('第三题',document.location.search)

//zxx: 测试显示有 bug
function parseSearch (search) {
  if (!search.match(/[&=]/)) {
    throw Error('argument must be regular search')
  }
  if (search.startsWith('?')) {
    search = search.substr(1)
  }
  return search.split('&').reduce((prev,item) => {
     var key_value = item.split('=')
     if (prev[key_value[0]]) {
       if (Array.isArray(prev[key_value[0]])) {
          prev[key_value[0]].push(key_value[1])
        } else {
          prev[key_value[0]] = [prev[key_value[0]], key_value[1]]
        }
      } else {
        prev[key_value[0]] = key_value[1]
      }
      return prev
   }, {})
}
/*4.*/ console.log('第四题',parseSearch(document.location.search))

/*5.*/ console.log('第五题',parseSearch('?name=gg&name=hh&name=ll'))
wj0075 commented 5 years ago
  1. encodeURI用于转码整个URL,会将URL中的元字符(/、;、:等)和语义字符(字母数字,连字符,下划线等)以外的字符全部转义。 encodeURIComponent不能用来转义整个URL,会把除语义字符之外的所有字符转义。

  2. const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
    };
    var params = new URLSearchParams(object1);
    console.log('第二题', params.toString());
  3. console.log('第三题', location.search)
  4. var params = new URLSearchParams(location.search);
    const obj = {};
    for (key of params) {
      obj[key[0]] = key[1];
    }
    console.log('第四题', obj);
  5. var params = new URLSearchParams('?userid=123&username=王二&tel=132&userid=234');
    console.log('第五题', params.getAll('userid'))
ghost commented 5 years ago
// 1
`对于 URL 中的特殊含义符号(; / ? : @ & = + $ , #), encodeURI 不进行编码操作, encodeURIComponent 进行编码操作`
// 2
// zxx:并无空格, word排版问题
const keys = Object.keys(object1)
const values = Object.values(object1)
const arr = []
for (let i = 0; i < keys.length; i++) {
    let k = keys[i]
    let v = values[i]
    let s = `${k} =${encodeURIComponent(String(v))}&`
    arr.push(s)
}
let result = arr.join(' ')
// 3
let queryStr = location.search
// 4, 5
const queryStrToObj = (string, object) => {
    let [k, v] = string.split('=')
    if (object[k] === undefined) {
        object[k] = v
    } else {
        object[k] = [...object[k], v]
    }
}

let pairs = queryStr.slice(1).split('&')
let o = {}
for (let i = 0; i < pairs.length; i++) {
    let pair = pairs[i]
    queryStrToObj(pair, o)
}
asyncguo commented 5 years ago
1. 遇到保留字符和#,encodeURIComponent会转义,而encodeURI不会。
2. Object.keys(object1).map(key => `${key}=${encodeURIComponent(object1[key])}`).join('&')
3. location.search
4. 
// zxx: 有bug
decodeURIComponent(location.search).match(/([^?=&]+)=([^&]+)/g).reduce((obj, item) =>  {
  let [key, val] = item.split('=')
  obj[key] = val
  return obj
},{})
5. 
decodeURIComponent(location.search).match(/([^?=&]+)=([^&]+)/g).reduce((obj, item) =>  {
  let [key, val] = item.split('=')
  if (obj.hasOwnProperty(key)){
    Array.isArray(obj[key]) ? obj[key].push(val) : obj[key] = [obj[key], val]
  } else {
    obj[key] = val
  }
  return obj
},{})
zzzluyan commented 5 years ago
const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
};

/*
1、 encodeURI 和 encodeURIComponent 都是编码URI的
    但是encodeURIComponent可编码的字符集更广一点
*/

//2、
let arr = [];
for (let i in object1) {
    arr.push(`${i}=${object1[i]}`);
}
encodeURI(arr.join('&'));

//3、
let url = window.location.href;
let query = url.slice(url.indexOf('?'));

//4、
// zxx: 严重bug,object2返回格式类似{0: undefiend, 1: undefined, ...}
let objectArr = query.slice(1).split('&');
let object2 = {};
let splitCon;
for (let item in objectArr) {
    splitCon = item.split('=');
    object2[splitCon[0]] = splitCon[1];
    splitCon = [];
}

//5、
let object3 = {};
for (let item in objectArr) {
    splitCon = item.split('=');
    if (object3.hasOwnProperty(splitCon[0])) {
        Array.isArray(object3[splitCon[0]])
        ? object3[splitCon[0]].push(splitCon[1])
        : object3[splitCon[0]] = [object3[splitCon[0]], splitCon[1]];
    } else {
        object3[splitCon[0]] = splitCon[1];
    }
    splitCon = [];
}
liuyueji commented 5 years ago
1.encodeURI 部分转译,而encodeURIComponent会全部转译非普通字符
2.encodeURI(Object.entries(object1).reduce(function(str,cur){
   str+=`${cur[0]}=${cur[1]}&`
   return str 
},'').slice(0,-1))
3.window.location.search
//zxx: 有bug
4.var obj = {}
location.search.slice(1).split('&').forEach(i => obj[i.split('=')[0]] = decodeURI(i.split('=')[1]))
console.log(obj)
5.var obj = {}
console.log(location.search.slice(1).split('&'))
location.search.slice(1).split('&').forEach(i =>{
 obj[i.split('=')[0]] ===undefined ?
obj[i.split('=')[0]]= decodeURI(i.split('=')[1]): 
obj[i.split('=')[0]] = obj[i.split('=')[0]].split().concat(decodeURI(i.split('=')[1]))
})
console.log(obj)
WGHwebitem commented 5 years ago
var object={
            userid:123,
            username:'王二',
            tel:'123082312'
        };
        //第一题
        encodeURI和encodeURIComponent方法两者都不会对  ASCII字母、数字、
        标点符号: - _ . ! ~ * ' ( ) 进行编码;
        这个字符:;/?:@&=+$,#  encodeURI不能编码而encodeURIComponent方法则可以编码,
        所以encodeURIComponent比encodeURI的编码范围更大;

        //第二题
        var fval={};
        for(var i in object){
           fval=fval+' & '+encodeURIComponent(object[i]);
        }
        console.log('2、',fval.replace(' & ',''));
        //第三题
        console.log('3、',location.search);

        //第四题
        var seachv = decodeURIComponent(location.search).slice(1).split("&");
        var newobj = {}
        for(var i=0;i<seachv.length;i++){
          newobj=newobj+','+seachv[i].replace('=',':').replace(',','');
        }
        console.log('4、',newobj.replace(',',''));

        // 第五题
        var pre5 = {}
        // 创建一个 URLSearchParams 对象
        var searchParams = new URLSearchParams(decodeURIComponent(location.search).slice(1));
          // 显示键/值对
        for(var [key,val] of searchParams.entries()) {
         if(!pre5[key]) {
           pre5[key] = val;
         }else {
           pre5[key] = [pre5[key]];
           pre5[key].push(val);
         }
        }
        console.log('5、',pre5);
EmmaYXY commented 5 years ago
// 1. 猜测答案:encodeURIComponent比encodeURI多了component,即组件一词,
// 推测前者处理字符的能力是后者的一部分,后者是前者的超集。

// 2. 
const obj = {
    'userid': 123,
    'username': '王二',
    'tel': '13223453456'
}
let arr = [], firstAns = '';
for (let key in obj) {
    arr.push(key+'='+obj[key]);
} 
firstAns = arr.join('&');
console.info(firstAns)  // userid=123&username=王二&tel=13223453456

// 3.
let secondAns = '', hrefStr = window.location.href;
secondAns = '?' + hrefStr.split('?')[0];

// 4.  有bug哦
let thirdAns = {}, arr3 = [];
arr3 =  hrefStr.split('?').map(val => val.split('='));
thirdAns = new Map(arr3);

// 5.
let fourthAns = {};
let arr4 = [];
arr3.map((val, index) => {
   arr3.map((secVal, secIndex) => {
     if (val[0]===secVal[0]){
        fourthAns[val[0]] = [val[1]];
     } else {
        fourthAns[val[0]] = val[1];
     }
   })
})
whrice commented 5 years ago

1

encodeURI主要用于对整个URI进行编码,对于URI的特殊字符,会忽略对其的编码,
encodeURIComponent主要用于对URI后的参数进行编码,不会忽略对特殊字符的编码。

2

Object.keys(object1).map(function(index){
         str.push(index+'='+encodeURIComponent(object1[index]))
    });
    var str1=str.join('&')
console.log(str1)

3

   location.search

4,5

//zxx: 有bug 例如?a=1&b=2&url=a.html?b=1,b=1应该忽略
 var str2 = decodeURIComponent(location.search).slice(1).split('&');
        var obj = {}
        for (var i = 0; i < str2.length; i++) {
            var arr = str2[i].split('=');
            var key = arr[0];
            var value = arr[1];
            if (!obj[key]) {
                obj[key] = value;
            } else {
                console.log(value);
               // 有致命问题,如果value本身内容有逗号
                obj[key] = (obj[key] + ',' + value).split(',')
                console.log(obj[key]);
            }
        }
ylqlalala commented 5 years ago

1.encodeURL是对整个url进行编码(合法字符不会被编码),encodeURLComponent编码时,将URL分成不同的部分(比如协议、域名、端口、地址、查询字符串),对分隔各个部分的字符及查询字符串进行编码

2.

let keys = Object.keys(object1);
let values = Object.values(object1);
let newString = '';
for(var i = 0; i < values.length; i++) {
    newString += keys[i] + '=' + encodeURI(values[i]) + '&'
}
newString = newString.slice(0,newString.length - 1)
console.log(newString)

3.

window.location.search

4.

// zxx: 和上一位bug一样,下面也是
let query = window.location.search;
let arr = query.slice(1,query.length).split("&");
let obj = {};
arr.map(item => {
    let newItem = item.split("=");
    obj[newItem[0]] = newItem[1]
})
console.log(obj)

5.

let query = window.location.search;
let arr = query.slice(1,query.length).split("&");
let obj = {};
arr.map(item => {
     if(item) {
         let newItem = item.split("=");
         let keys = Object.keys(obj);
         if(keys.indexOf(newItem[0]) > -1) {
             let value = obj[newItem[0]].split(",");
             value.push(newItem[1])
             obj[newItem[0]] = value
         } else {
             obj[newItem[0]] = newItem[1]  
         }
     }
})
console.log(obj)
bugaosunihhh commented 5 years ago

第一题

编码范围不一样 encodeURI 不编码 # ? / @encodeURIComponent

第二题

var obj={
    userid: 123,
    username: '王二',
    tel: '13838384388'
}

Object.keys(obj).map(key => key + "=" + encodeURIComponent(obj[key])).join("&")

第三题

location.search

第四题

// zxx: 有bug
let search = location.search.substr(1)
let search_arr = search.split("&")
let ret = {};
search_arr.forEach(v=>{
    let arr = v.split('=')
    ret[arr[0]] = decodeURIComponent(arr[1])
})
console.log(ret)

第五题

let search = location.search.substr(1)
let search_arr = search.split("&")
let ret = {};
search_arr.forEach(v=>{
    let arr = v.split('=')
    if(ret[arr[0]]){
        let temp = ret[arr[0]] 
        ret[arr[0]] = [];
        ret[arr[0]].push(temp,arr[1])
    }else{
        ret[arr[0]] = decodeURIComponent(arr[1])
    }
})
console.log(ret)
xuejianrong commented 5 years ago
const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
}

// 1.encodeURI不会对'@#¥&,/?'进行编码,而encodeURIComponent会

// 2.
function getSearch(p) {
    const keys = Object.keys(p);
    let str = '';
    keys.forEach(key => {
        if (str) str += '&';
        str += `${key}=${encodeURIComponent(p[key])}`;
    })
    return str;
}
getSearch(object1);

// 3.
location.search

// 4.
// zxx: 有bug
function getParams() {
    const paramArr = location.search.slice(1).split('&');
    let obj = {};
    paramArr.forEach(item => {
        const keyVal = item.split('=');
        // 排除&&的情况,并且不重复
        if (keyVal[0] && !obj.hasOwnProperty(keyVal[0])) {
            obj[keyVal[0]] = keyVal[1] ? keyVal[1] : '';
        }
    })
    return obj
}
getParams()

// 5.
function getParams2() {
    const paramArr = location.search.slice(1).split('&');
    let obj = {};
    paramArr.forEach(item => {
        const keyVal = item.split('=');
        // 排除&&的情况
        if (keyVal[0]) {
            // 判断是否已有该属性
            if (obj.hasOwnProperty(keyVal[0])) {
                // 判断该属性的值是否为数组
                if (obj[keyVal[0]] instanceof Array) {
                    obj[keyVal[0]].push(keyVal[1] ? keyVal[1] : '');
                } else {
                    // 第二次出现同一参数的处理
                    obj[keyVal[0]] = [obj[keyVal[0]], keyVal[1] ? keyVal[1] : ''];
                }
            } else {
                // 第一次出现该参数的处理
                obj[keyVal[0]] = keyVal[1] ? keyVal[1] : '';
            }
        }
    })
    return obj
}
getParams2()
ziven27 commented 5 years ago

image

const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
};

// 第一题
console.log("第一题:", 'encodeURIComponent 会转换英文符号,encodeURI不会');

// 第二题
let object1String = '';
for (let [key, value] of Object.entries(object1)) {
    object1String += (object1String === '' ? '' : '&') + key + '=' + encodeURI(value);
}
console.log("第二题:", object1String);

// 第三题
const searchString = location.search;
console.log("第三题:", searchString);

// 第四题 和 第五题

// 基于 & 拆分成数组
// zxx: 测试跑下来有bug,复杂的查询例如url=a.html?b=1被舍弃了
const searchArray = searchString.substr(1).split('&');

const searchObject = {};
for (var i = 0, len = searchArray.length; i < len; i++) {
    const itemArray = searchArray[i].split('=');

    // 如果有超出两个等号,则忽略
    if (itemArray.length !== 2) {
        continue;
    }

    const name = itemArray[0];
    const value = decodeURI(itemArray[1]);

    // 如果 name 和 value 有一个不存在则什么都不做
    if (!name || !value) {
        continue;
    }

    // 原来是否有数据
    const hadValue = searchObject[name];

    // 如果对象里面没有则直接设置
    if (!hadValue) {
        searchObject[name] = value;
        continue;
    }

    // 如果原始对象已经是个数组直接push 进去
    if (hadValue instanceof Array) {
        hadValue.push(value);
        continue;
    }

    // 如果原始对象已经存在让这个变成数组
    if (hadValue) {
        searchObject[name] = [hadValue, value];
    }
}

console.log("第四题,第五题:", searchObject);
GitHdu commented 5 years ago

1.encodeURI不转译特殊字符,而encodeURICompoent转译所有字符 2.

  Object.keys(object1).map(key => key + "=" + encodeURIComponent(object1[key])).join("&")

3.

  location.search

4.

 const obj = {}
for (var p of new URLSearchParams(location.search).entries()){
  obj[p[0]]=p[1]
};
console.log(obj)

5.

// 题意是如果只有1个值,还是字符串,多值才是数组
const obj1 = {}
const myParams = new URLSearchParams(location.search)
for (var p of myParams.keys()){
  obj[p]=myParams.getAll(p)
};
console.log(obj1)
// zxx: 调整下
const obj1 = {}
const myParams = new URLSearchParams(location.search)
for (var p of myParams.keys()){
obj[p]=myParams.getAll(p).length > 1 ? myParams.getAll(p) : myParams.get(p);
};
zengqingxiao commented 5 years ago

第一题

 encodeURI无法对";,/?:@&=+$#"这类字符进行编译

第二题

 const object1 = {
      userid: 123,
      username: '王二',
      tel: '13208033621',
    }
    let strUrl = '';
    for (let [key, value] of Object.entries(object1)) {
      strUrl += `${key}=${encodeURI(value)}&`
    }
    strUrl = strUrl.substring(0,strUrl.length-1);

第三题 按照题目意思我觉得应该就是 query的值为 当前URL地址栏中的第一的?后面查询的内容,这里的query就是我们需要的值

 let query = window.location.search.substring(1);

但是如果是将URL地址栏中的第一的?后面查询的内容转为json格式中的第一个键值对那么答案为:

 let vars = query.split('&');
    console.log(vars);
    let keyOne = vars[0].split('=')[0];
    let valOne = vars[0].split('=')[1];

第四题 和 第五题一起

// 虽然写了很多,可惜有bug
    const urlObj = {};
    vars.forEach( (item) => {
      // 根据urlObj是否含有相同key
      if( !urlObj[item.split('=')[0]] ){
        urlObj[item.split('=')[0]]= decodeURI(item.split('=')[1]);
      } else {
        // 这里不可以连续push 因为push返回的添加项后的数值长度
        // let arr = [].push(item.split('=')[1])
        let val = urlObj[item.split('=')[0]]
        let arr = [val];
       // console.log(val);
       // console.log(item.split('=')[1]);
        let newVal = arr.push(item.split('=')[1]);
        urlObj[item.split('=')[0]] = arr;
      }
    })
347235420 commented 5 years ago

1.encodeURI()是对整个URL进行编码,encodeURIComponent()是对URL中的参数或者URL后面的一部分进行编码。 2. Object.keys(object1).map(key => key + "=" + encodeURIComponent(object1[key])).join("&") 3. window.location.search

4 var key = Object.keys(object1); var value = Object.values(object1); let str = ''; for(var i = 0; i < value.length; i++) { str += keys[i] + '=' + value[i] + '&' } str1 = str.slice(0,str.length - 1)//去除最后一个&

5. //等待大神讲解的细一点

zy017 commented 5 years ago
// 1.encodeURI是对URI进行完整的编码,不能转义分隔URI各个部分的标点符号,
// 而encodeURIComponent可以转义用于分隔URI各个部分的标点符号,常用于查询参数特殊字符的转义

// 2.
var paramStr = Object.keys(object1).map(i => `${i}=${encodeURIComponent(object1[i])}`).join('&')
console.log(paramStr)

// 3.
var searchStr = location.search
console.log(searchStr)

// 4.
// 有bug
var object2 = {}
searchStr.slice(1).split('&').forEach(item => {
    var o = item.split('=')
    object2[o[0]] = o[1]
})
console.log(object2)

// 5.
var object3 = {}
searchStr.slice(1).split('&').forEach(item => {
    var o = item.split('=')
    if (object3.hasOwnProperty(o[0])) {
        object3[o[0]] = [].concat(object3[o[0]], o[1])
    } else {
        object3[o[0]] = o[1]
    }
})
console.log(object3)
sghweb commented 5 years ago
1. encodeURL()不会对本身属性url的特殊字符进行编码,例如“冒号、正斜杠、问号、井号”;而encodeURLComponent()则会对它发现的任何非标准字符进行编码。
2. 
let url1 = encodeURI(JSON.stringify(object1).replace(/:/g,'=').replace(/[{}""]/g,'').replace(/,/g,'&'))
3.
let param = document.location.search
// 因为url中有hash并且在前面时获取不到所以重置
if(!param){
  param ='?'+ document.location.hash.split('?')[1]
}
4.
//zxx: 有bug
let obj = {}
param.split('?')[1].split('&').forEach(item=>{
   let arr = item.split('=')
   obj[arr[0]]=arr[1]
})
5.
let obj = {}
param.split('?')[1].split('&').forEach(item=>{
   let arr = item.split('=')
   if(Object.keys(obj).includes(arr[0])){
     obj[arr[0]]=[].concat(obj[arr[0]],arr[1])
   }else{
    obj[arr[0]]=arr[1]
   }
})
GCGligoudan commented 5 years ago
// 第一题
// encodeURI接收整个URI,对需要的字符进行转码
// encodeURIComponent是对URI中部分需要转码的字符值进行转码

// 第二题
let str = '', arr = [];
Object.keys(object1).forEach((key) => {
  arr.push(key + '=' + encodeURIComponent(object1[key]));
});
str = arr.join('&');

// 第三题
window.location.search

//第四题
// zxx: bug
function parseURISearch() {
  const searchString = window.location.search.slice(1);
  const result = {};
  searchString.split('&').forEach((val) => {
    const item = val.split('=');
    result[item[0]] = decodeURIComponent(item[1]);
  })
  return result;
}

// 第五题
function parseURIsearch() {
  const searchString = window.location.search.slice(1);
  const result = {};
  searchString.split('&').forEach((val) => {
    const item = val.split('=');
    if (result[item[0]]){ // 当有键重复时
      result[item[0]] = (result[item[0]]+','+decodeURIComponent(item[1])).split(',');
    } else {
      result[item[0]] = decodeURIComponent(item[1]);
    }
  })
  return result;
}
frankyeyq commented 5 years ago
1. encodeURIComponent会对 ; , / ? : @ & = + $   #这些字符编码,而encodeURI不会
2. 
function transform(obj) {
    return Object.keys(obj).map(key => encodeURIComponent(key)+'='+encodeURIComponent(obj[key])).join('&')
}
3.
function query() {
    let index = location.herf.indexOf('?')
    if (index > 0) {
        return location.herf.slice(index)
    } else {
        return '?'
    }
}
4 && 5
// zxx: bug
function urlToObj() {
    let url = query().slice(1);
    let res = {}
    if (url.length > 0) {
        let arr = url.split('&')
        arr.forEach(item => {
            let tempArr = item.split('=');
            let key = decodeURIComponent(tempArr[0]);
            let value = decodeURIComponent(tempArr[1]);
            if (res[key]) {
                if (Array.isArray(res[key])) {
                    res[key].push(value)
                } else {
                    res[key] = [res[key], value]
                }
            } else {
                res[key] = value
            }
        })
    }
    return res;
}
leisure-wang commented 5 years ago
 ```
const object1 = {
    userid:123,
    username:'王二',
    tel:'13208033621'
}
1,  encodeURIComponent()会将保留字符转码,encodeURI()不会
2,  function parseParam(param){
        var paramStr = ''
        for(var i in param){
            var k = typeof param[i]==='string'?encodeURIComponent(param[i]):param[i]
            paramStr += '&' + i + '=' + k
        }
        return paramStr.substr(1)
    }
3,  var url = location.search
4,  function getUrl(url){
        var obj = {}
        var urls = url.split('?')
        urls = urls[1].split('&')
        for(var i=0;i<urls.length;i++){
            var arr = urls[i].split('=')
            obj[arr[0]] = arr[1]
        }
        return obj
    }
5, 
smileyby commented 5 years ago

2019-07-26 修改下排版,看着清晰点

第①题

 encodeURI 不会对URI中的特殊字符进行转义(如&),而encodeURIComponent会

第②题

const object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
};
let arr = [];
for (let key in object1) {
  if (object1.hasOwnProperty(key)) {
    arr.push(`${key}=${object1[key]}`);
  }
}
let str = encodeURI(arr.join('&'));
console.log(str);

第③题

location.search

第④⑤题

//zxx: 有bug,?a=1&b=2&url=a.html?b=1&c=1测试未通过
let obj = {};
let testSearch = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=wozenmeshede&rsv_pq=d1031b280000b9e8&rsv_t=60e0knRdrQDz3kIhMimBoNepkB71DXiTeFcCPdZUGduQgYKYq9pjtZv0j1A&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=13&rsv_sug1=13&rsv_sug7=101&rsv_sug2=0&inputT=2408&rsv_sug4=5237&rsv_sug4=1234&rsv_sug4=5678';

// 2019-07-27 修复问题
// 这里的正则写的有问题,没考虑到参数值中可能存在 ? = 
// 正则修改: /([^?=&#]+)=([^&#]*)/
testSearch.replace(/([^?=&#]+)=([^?=&#]*)/g, function(input, key, value) {
  if (obj[key]) {
    if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
      obj[key].push(value);
    } else {
      obj[key] += `&${value}`;
      obj[key] = obj[key].split('&');
    }
  } else {
    obj[key] = value;
  }
});
console.log(obj);
uaison commented 5 years ago

第一题:

encodeURI 不会对属于URI的特殊字符进行编码,例如 :/?# 等;
encodeURIComponent 则会对它发现的任何非标准字符进行编码

第二题

let object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
};
let searchObj= new URLSearchParams(object1);
let searchParams = searchObj.toString();

第三题

let search = location.search;

第四题 / 第五题

let arr= search.slice(1).split('&');
let obj = {};
arr.forEach(item => {
  let [key, value] = item.split('=');
  if(obj.hasOwnProperty(key)) { // 第五题
    obj[key] = [].concat(obj[key], decodeURIComponent(value));
  } else { // 第四题
    obj[key] = decodeURIComponent(value)
  }
});
silverWolf818 commented 5 years ago
encodeURI encodeURIComponent
参数 一个完整的URI URI 的组成部分
转义 不包含;`, / ? : @ & = + $<br />字母 数字-`_ . ! ~ * ' ( )# 不包含字母、数字、().!~*'-_
1. 
const object1 = {
    userid: 123,
    username: '王二',
    tel: '13208033621'
};

//第二题

Object.keys(object1).map(item => `${item}=${encodeURIComponent(object1[item])}`).join('&');

//第三题

location.search;//难道这个有陷阱?

//第四,五题

function urlToObj(url) {
    let obj = {};
    decodeURIComponent(url).replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => {
        if(obj[k]){
            obj[k] = Array.prototype.concat(obj[k],v);
        }else{
            obj[k] = v;
        }
    });
    return obj;
}

urlToObj('userid=123&username=%E7%8E%8B%E4%BA%8C&tel=13208033621&userid=122223&userid=44444')
smiledpeace commented 5 years ago
// 1. encodeURI、encodeURIComponent 要转义的字符范围不一样

    const object1 = {
        userid: 123,
        username: '王二',
        tel: '13208033621'
    }
    // 2
    let url = '';
    url = Object.keys(object1).map(function (key) {
        return key + '=' + encodeURIComponent(object1[key])
    }).join('&');

    // 3
    location.search;
    //4
    const object2 = {};
    location.search.replace(/^\?/g, '').split('&').forEach(item => {
        const key = item.split('=')[0], value = item.split('=')[1];
        object2[key] = decodeURIComponent(value)
    })

    // 5
    const object3 = {};
    location.search.replace(/^\?/g, '').split('&').forEach(item => {
        const key = item.split('=')[0], value = item.split('=')[1];
        if (object3[key]) {
            if (Object.prototype.toString.call(object3[key]) === '[object Array]') {
                object3[key] = [].concat(object3[key]);
            }else {
                object3[key] = [object3[key]]
            }
            object3[key].push(decodeURIComponent(value))
        }else {
            object3[key] = decodeURIComponent(value)
        }
    })
kuikuiGe commented 5 years ago
// 1
/*
encodeURI操作的是完整的 URI,
encodeURIComponent操作的是组成 URI 的个别组件; encodeURIComponent会对保留字符和“#”编码。encodeURI不会。
*/
// 2
const object1 = {
    userid:123,
    username: '王二',
    tel: '13208033621'
}
var result = [];
for(var key in object1){
  result.push(key+"="+encodeURIComponent(object1[key]));
}
console.log(result.join('&'));
// 3
var a = document.createElement("a");
a.href = window.location.href;
var search = a.search;
console.log(search);
// 4 
//zxx: bug
search = decodeURI(search).slice(1);
var result = {};
var arr = search.split("&");
arr.forEach(function(item,index){
  var keyVal = item.split("=");
  var key = keyVal[0],
      val = keyVal[1];
  result[key] = val;
});
console.dir(result);
// 5
var result2 = {};
var arr = search.split("&");
arr.forEach(function(item,index){
  var keyVal = item.split("=");
  var key = keyVal[0],
      val = keyVal[1];

  if(result2[key]){
     var temp = result2[key];
     if(Array.isArray(result2[key])){
         result2[key].push(val);
     }else{
        result2[key] = [temp,val];
     }
  }else{
     result2[key] = val;
  }
});
console.dir(result2);
lifelikejuly commented 5 years ago
const object1 = {
        userid: 123,
        username: '王二',
        tel: '2323232323'

    }

第一题

encodeURI()和encodeURIComponent()都可以对URI进行编码,encodeURI主要针对整段URI,而encodeURIComponent针对URI部分一段用UTF-8编码替换特殊无效字符。

第二题

var result = Object.keys(object1).map((key, index) => `${key}=${encodeURIComponent(object1[key])}`).join('&');
console.log(result);

第三题

var search = window.location.search;
console.log(search);

第四题

search = search.replace("?", "")
if (search == "") return {};
var array = search.split("&");
var searchObject = array.reduce((item, val) => {
    var param = val.split("=");
    var key = param[0];
    var value = param[1];
    item[key] = window.decodeURIComponent(value);
    return item;
}, {})
console.log(searchObject);

第五题

var searchObject = array.reduce((item, val) => {
    var param = val.split("=");
    var key = param[0];
    var value = param[1];
    if (item[key] != null) {
        if (Array.isArray(item[key])) {
            item[key].push(window.decodeURIComponent(value));
        } else {
            item[key] = [item[key], window.decodeURIComponent(value)];
        }
    } else {
        item[key] = window.decodeURIComponent(value);
    }
    return item;
}, {});
console.log(searchObject);
Forx-Js commented 5 years ago
  1. 是否能够解析? & = 等特殊符号
  2. 本来打算放到FormData发起请求,想了想算了
    const obj2FormData = (object = {}) => Object.keys(object).map(key => `${key}=${encodeURIComponent(object[key])}`).join('&')
  3. window.location.search
  4. 两题直接合并
    const data2Obj=(data="")=>{
    const obj={};
    decodeURIComponent(data)   //先 decode还原
    .replace(/^\?/,"")         // 清除首个 '?'
    .split('&')
    .forEach(item=>{
      const values=item.split('='),
            key=values[0],
            value=values[1],
            hasValue=obj[key]!==void(0);
    obj[key]=hasValue?[].concat(obj[key],value):value;         // 更新数据
    }) 
      return obj;       // 将数据返回出来
    }

大半夜想起没小测,赶紧爬起来,得了,估计明早的直播看不见了

zhangxinxu commented 5 years ago

本期要点:

  1. 区别:参见iceytea的回答。
  2. Object.keys遍历(如livetune),记得encodeURIComponent,还有可以借助Object.entries(如iceytea)。
  3. 第2题更简单的回答:使用URLSearchParams,new URLSearchParams(object1).toString(),见Despair-lj 的回答。URLSearchParams IE不支持,但是我们引入polyfill,https://github.com/WebReflection/url-search-params
  4. location.search,2积分,其他回答都是1积分。new URL()方法适用场景就是一个什么角落蹦出来的url地址,例如后端返回的url参数,new URL(json.url).search。
  5. .split('=')实现的小伙伴几乎都有bug,可以检查下自己代码。replace替换是一种方法,代码可以很简短,但是理解比较烧脑子。比较好的实现还是借助URLSearchParams,;例如wj0075,最佳实现人是Despair-lj: var urlSearchParams = new URLSearchParams(urlString) var urlObj = {} for (let [key, value] of urlSearchParams.entries()) { urlObj[key] = value }
  6. urlSearchParams.getAll获取的就是数组,唯一要做的是区分数组长度。get是获取单个,可以参见GitHdu 调整后的回答。