一、获取 url 中的参数
1. 指定参数名称,返回该参数的值 或者 空字符串
2. 不指定参数名称,返回全部的参数对象 或者 {}
3. 如果存在多个同名参数,则返回数组
看到牛客一位大神的代码非常简洁,如下:
function getUrlParam(sUrl, sKey) {
var result = {};
// replace()方法的参数replacement可以是函数。此时,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。
// 该函数的第一个参数是匹配模式的字符串,接下来的参数是与模式中的子表达式匹配的字符串,可以有0个或多个。
// 再接下来的参数是一个整数,声明了匹配在stringObject中出现的位置,最后一个参数是stringObject本身
sUrl.replace(/\??(\w+)=(\w+)&?/g, function (a, k, v) {
// console.log(a);
// console.log(k);
// console.log(v);
// void 0 === undefined, void 0比undefined占用的字节少,多用在压缩文件上
if (result[k] !== void 0) {
var t = result[k];
result[k] = [].concat(t, v);
} else {
result[k] = v;
}
});
if (sKey === void 0) {
return result;
} else {
return result[sKey] || '';
}
}
console.log(getUrlParam("http://www.baidu.com/#/?t1=1&t3=2&t5=3"));
打印出来的a, k, v的值和最后结果如下:
a对应匹配的字段,k对应参数,v对应参数值。
对于replace结合正则表达式的运用,可以看一下这篇:replace()结合正则表达式
二、根据包名,在指定空间中创建对象
如题:根据包名,在指定空间中创建对象
输入描述:namespace({a: {test: 1, b: 2}}, 'a.b.c.d')
输出描述:{a: {test: 1, b: {c: {d: {}}}}}
通俗说,就是:根据包名,比较指定空间中有没有与包名对应的对象,有则保留,无则创建一个空对象。
function isObj(value) {
return Object.prototype.toString.call(value) == "[object Object]";
}
function namespace(oNamespace, sPackage) {
var scope = sPackage.split('.');
var ns = oNamespace;
for (var i = 0; i < scope.length; i++) {
if (!ns.hasOwnProperty(scope[i]) || !isObj(ns[scope[i]])) {
ns[scope[i]] = {};
}
ns = ns[scope[i]];
}
return oNamespace;
}
console.log(namespace({ a: { test: 1, b: 2 } }, 'a.b.c.d'));
这里有两点需要注意:
1、判断指定空间里是否存在于包名对应的对象,用hasOwnProperty判断是否存在,如果存在,接着判断是否为对象,正确的判断是:Object.prototype.toString.call(value) == "[object Object]";
2、对最后直接return oNamespace;的理解:Object是引用赋值,将对象赋值给某个变量,实际上相当于把指向引用类型的地址指针赋予给这个变量。两个变量都指向了堆内存中的同一个对象,他们中任何一个做出的改变都会反应在另一个身上。
三、数组去重
输入:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]
输出:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']
可以看出,需要对NaN去重, {}则不需要
1、使用indexOf()方法
Array.prototype.uniq = function (){
var newarr = [];
var flag = true;
for(var i = 0;i < this.length;i++) {
if(newarr.indexOf(this[i]) == -1) {
if(this[i] != this[i]) {
if(flag) {
newarr.push(this[i]);
flag = false;
}
}else {
newarr.push(this[i]);
}
}
}
return newarr;
}
需要注意的点:
在indexOf判断中,NaN和空对象{}均返回-1,需要单独判断。而NaN和{}又有区别:
var a = NaN;
var b = NaN;
var c = {};
var d = {};
console.log(a == b); // false
console.log(c == d); // false
console.log(a == a); // false
console.log(c == c); // true
以上代码可以看出:NaN != NaN, {} != {},但NaN不等于它自己本身,{}会等于自己本身,可以以此来区分NaN和{}, 对NaN去重。
2、ES6 的Set方法
Array.prototype.uniq = function () {
return [...new Set(this)];
}
有兼容性问题
3、使用splice直接在数组本身操作
Array.prototype.uniq = function() {
var hasNaN = false;
for(var i = 0;i < this.length;i++) {
if(this[i] !== this[i]) {
hasNaN=true;
}
for(var j = i+1;i < this.length;) {
if(this[i] === this[j] || (hasNaN && this[j] !== this[j])) {
this.splice(j, 1);
}else{
j++;
}
}
}
return this;
}
四、时间格式化输出
描述:
按所给的时间格式输出指定的时间
格式说明
对于 2014.09.05 13:14:20
yyyy: 年份,2014
yy: 年份,14
MM: 月份,补满两位,09
M: 月份, 9
dd: 日期,补满两位,05
d: 日期, 5
HH: 24制小时,补满两位,13
H: 24制小时,13
hh: 12制小时,补满两位,01
h: 12制小时,1
mm: 分钟,补满两位,14
m: 分钟,14
ss: 秒,补满两位,20
s: 秒,20
w: 星期,为 ['日', '一', '二', '三', '四', '五', '六'] 中的某一个,本 demo 结果为 五
输入: formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w')
输出: 2014-09-05 13:14:20 星期五
function formatDate(oDate, sFormation) {
var obj = {
yyyy: oDate.getFullYear(),
yy: ("" + oDate.getFullYear()).slice(-2),
M: oDate.getMonth() + 1,
MM: ("" + (oDate.getMonth()+1)).slice(-2),
d: oDate.getDate(),
dd: ("0" + oDate.getDate()).slice(-2),
H: oDate.getHours(),
HH: ("0" + oDate.getHours()).slice(-2),
h: oDate.getHours() % 12,
hh: ("0" + oDate.getHours() % 12).slice(-2),
m: oDate.getMinutes(),
mm: ("0" + oDate.getMinutes()).slice(-2),
s: oDate.getSeconds(),
ss: ("0" + oDate.getSeconds()).slice(-2),
w: ['日', '一', '二', '三', '四', '五', '六'][oDate.getDay()]
};
return sFormation.replace(/([a-z]+)/ig, function($1){return obj[$1]});
}
console.log(formatDate(new Date(1409894060000),'yy-MM-dd HH:mm:ss 星期w'));
$1 表示正则表达式第一个小括号中匹配项的值。
比如 /gai([\w]+?)over([\d]+)/
匹配 gainover123
$1= 括号里的 n
$2= 第2个括号里的 123