在学习微信现金红包接口调用时遇到一个参数转换为查询字符串的需求,为此设计了一个通用函数:
假设参数如下:
const params = {
act_name: '答题抢红包活动', //活动名称 是否必填:是
mch_billno: generate_mch_billno(mchid), //商户订单号 是否必填:是
mch_id: mchid, //商户号 是否必填:是
nonce_str: generateRandomString(32), //随机字符串 是否必填:是
re_openid: re_openid, //用户openid 是否必填:是
remark: '答题满分可抢红包!', //备注 是否必填:是
client_ip: clientip, //Ip地址 是否必填:是
sign: mysign, //签名 是否必填:是 generateSign(/* 传入相关参数进行签名 */) // 你需要实现generateSign函数
略
};
函数如下:
//把params中的各项转换为url查询字符串,结果字符串不包含sign项,先对params中的key除了sign按ASCII码升序排序在转换为url查询字符串
function buildQueryStringWithoutSign(params) {
// 创建一个不包含sign的新对象
const sortedParams = Object.keys(params)
.filter(key => key !== 'sign') // 排除sign字段
.sort() // 按ASCII码升序排序
.reduce((result, key) => {
result[key] = params[key];
return result;
}, {});
// 使用qs.stringify将对象转换为查询字符串
const queryString = qs.stringify(sortedParams);
return queryString;
}
说明如下:
这段代码是使用JavaScript的数组方法来处理一个对象params
,并生成一个新的对象sortedParams
,其中排除了'sign'
字段,并且其余字段的键(key)按照ASCII码升序排序。下面是这段代码的逐步解释:
-
Object.keys(params)
Object.keys()
是一个内置方法,用于获取一个对象的所有可枚举属性的键(key),并返回一个由这些键组成的数组。- 在这里,它返回
params
对象所有属性的键的数组。
-
.filter(key => key !== 'sign')
filter()
是一个数组方法,用于创建一个新数组,新数组中的元素是通过检查指定函数实现的测试的所有元素。- 在这里,它遍历
Object.keys(params)
返回的数组,并返回一个不包含'sign'
键的新数组。
-
.sort()
sort()
是一个数组方法,用于对数组的元素进行排序,并就地(in-place)返回排序后的数组。- 默认情况下,
sort()
方法将元素转换为字符串(如果它们不是),然后比较它们的UTF-16代码单元值序列作为字符。这意味着它实际上是按照ASCII码进行排序的。 - 在这里,它按照ASCII码升序对过滤后的键数组进行排序。
-
.reduce((result, key) => { ... }, {})
reduce()
是一个数组方法,它接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。- 累加器函数接收四个参数:累加器累加值(
accumulator
)、当前值(currentValue
)、当前索引(currentIndex
)和源数组(sourceArray
)。然而,在大多数情况下,我们只使用前两个参数。 - 在这里,累加器函数(箭头函数)接收两个参数:
result
(累加器累加值,初始化为一个空对象{}
)和key
(当前值,即排序后的键)。 - 在函数体中,它将
params
对象中的每个值(通过params[key]
)添加到result
对象中,键保持不变(因为我们已经按照正确的顺序遍历了键)。 - 最后,函数返回
result
对象,该对象将在每次迭代中更新,并包含按ASCII码升序排序的所有params
对象的属性(除了'sign'
)。
最终,sortedParams
将是一个新的对象,它包含params
对象中除'sign'
之外的所有属性,并且这些属性的键按照ASCII码升序排序。
需要的可直接复制应用。