本文用于复习JS相关知识点,相当于知识简单的梳理. So, It's not be Detailed introduction
数组
- 数组方法概览
var arr = [3, 4, 5, 6]
console.log(arr.length) //4
console.log(arr[0]) //3
console.log(arr[3]) //6
console.log(arr[4]) //undefined
arr[4] = 'hello'
console.log(arr[4]) // 'hello'
arr.push('jirengu') //再数组最后添加一个元素
console.log(arr) // [3, 4, 5, 6, 'hello', 'jirengu']
var value = arr.pop() //把数组最后一位弹出来,返回
console.log(value) //'jirengu'
console.log(arr) //[3, 4, 5, 6, 'hello']
arr.unshift('ruoyu') //在数组第一位新增
console.log(arr) //['ruoyu', 3, 4, 5, 6, 'hello']
var value2 = arr.shift() //把数组第一位拿出来返回,数组发生变化
console.log(value2) // 'ruoyu'
console.log(arr) //[3, 4, 5, 6, 'hello']
var arr2 = arr.splice(1, 2) //从下标为1的元素开始,拿出来2个元素作为一个数组返回,原数组发生改变
console.log(arr) // [3, 6, 'hello']
console.log(arr2) // [4, 5]
arr.splice(1, 0, 8,9) //从下标为1的位置(元素6)开始,删除0个,新增两个元素(在6前面新增8,9)
console.log(arr) //[3, 8, 9, 6, 'hello']
var arr3 = arr.slice(2,3) //从 arr 下标为2开始,到下标为3结束(不包括3),做为新数组,原数组不变
console.log(arr3) // [9]
console.log(arr) //[3, 8, 9, 6, 'hello']
var str = arr.join('-')
console.log(str) // "3-8-9-6-hello"
var arr4 = [3, 5, -1, 18, 9, 27]
arr4.reverse() //倒序,本身发生变化
arr4.sort(function(v1, v2){ //排序,本身发生变化
return v1-v2; //v2-v1
})
- 终极神器
JavaScript提供了一个splice方法用于一次性解决数组添加、删除(这两种方法一结合就可以达到替换效果),方法有三个参数
1.开始索引
2.删除元素的位移
3.插入的新元素,当然也可以写多个
splice方法返回一个由删除元素组成的新数组,没有删除则返回空数组
look here
//删除
var a = [1, 2, 3, 4, 5];
console.log(a.splice(1,3));//[2, 3, 4]
console.log(a.length);//2
console.log(a);//[1,5]
//插入与替换
var a = [1,2,3,4,5];
a.splice(1,0,9,99,999);
console.log(a.length); //8
console.log(a);//[1, 9, 99, 999, 2, 3, 4, 5]
a.splice(1,3,8,88,888);
console.log(a.length);//8
console.log(a);//[1, 8, 88, 888, 2, 3, 4, 5]
- 常规操作
join(char)
这个方法在C#等语言中也有,作用是把数组元素(对象调用其toString()方法)使用参数作为连接符连接成一字符串,不会修改原数组内容
var a = [1,2,3,4,5];
console.log(a.join(',')); //1,2,3,4,5
console.log(a.join(' ')); //1 2 3 4 5
slice(start,end)
不要和splice方法混淆,slice方法用于返回数组中一个片段或子数组,如果只写一个参数返回参数到数组结束部分,如果参数出现负数,则从数组尾部计数(-3意思是数组倒第三个,一般人不会这么干,但是在不知道数组长度,想舍弃后n个的时候有些用,不过数组长度很好知道。。。。,好纠结的用法),如果start大于end返回空数组,值得注意的一点是slice不会改变原数组,而是返回一个新的数组
var a = [1,2,3,4,5];
console.log(a); //[1, 2, 3, 4, 5]
console.log(a.slice(1,2));//2
console.log(a.slice(1,-1));//[2, 3, 4]
console.log(a.slice(3,2));//[]
console.log(a); //[1, 2, 3, 4, 5]
concat(array)
看起来像是剪切,但这个真不是形声字,concat方法用于拼接数组,a.concat(b)返回一个a和b共同组成的新数组,同样不会修改任何一个原始数组,也不会递归连接数组内部数组
var a = [1,2,3,4,5];
var b = [6,7,8,9];
console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(a); //[1, 2, 3, 4, 5]
console.log(b); //[6, 7, 8, 9]
reverse()
方法用于将数组逆序,与之前不同的是它会修改原数组
var a = [1,2,3,4,5];
a.reverse();
console.log(a); //[5, 4, 3, 2, 1]
sort
sort方法用于对数组进行排序,当没有参数的时候会按字母表升序排序,如果含有undefined会被排到最后面,对象元素则会调用其toString方法,如果想按照自己定义方式排序,可以传一个排序方法进去,很典型的策略模式,同样sort会改变原数组
var a=[5,4,3,2,1]
a.sort()
console.log(a) //[1, 2, 3, 4, 5]
var a = [7,8,9,10,11]
a.sort(function(v1,v2){
return v1-v2
})
console.log(a) //[7, 8, 9, 10, 11]
var users = [
{
name: 'aaa',
age: 21
},
{
name: 'baa',
age: 18
},
{
name: 'abc',
age: 24
}
]
// 按age 从小到大排序
var sortByAge = users.sort(function(v1, v2){
return v1.age > v2.age
})
// 按name从大到小排序
var sortByName = users.sort(function(v1, v2){
return v1.name > v2.name
})
ES5数组扩展
Array.isArray(obj)
这是Array对象的一个静态函数,用来判断一个对象是不是数组
var a = [];
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
.indexOf(element)/.latIndexOf(element)
顾名思义,这两个方法用于查找数组内指定元素位置,查找到第一个后返回其索引,没有查找到返回-1,indexOf从头至尾搜索,lastIndexOf反向搜索。
var a = [1,2,3,3,2,1]
console.log(a.indexOf(2)) //1
console.log(a.lastIndexOf(2)) //4
.forEach(element,index,array)
遍历数组,参数为一个回调函数,回调函数有三个参数:
1.当前元素
2.当前元素索引值
3.整个数组
var a = new Array(1,2,3,4,5,6);
a.forEach(function(e,i,array){
array[i]= e + 1;
});
console.log(a); //[2, 3, 4, 5, 6, 7]
.every(function(element,index,array))/.some(function(element,index,array))
这两个函数类似于离散数学中的逻辑判定,回掉函数返回一个布尔值
- every是所有函数的每个回掉函数都返回true的时候才会返回true,当遇到false的时候中止执行,返回false
- some函数是存在有一个回调函数返回true时,终止执行返回true,否则返回false
在空数组上调用every返回true,some返回false
var a = [1, 2, 3, 4, 5, 6]
console.log(a.every(function(e, i, arr){
return e < 5
}))
console.log(a.some(function(e,i,arr){
return e > 4
}))
.map(function(element))
与forEach类似,遍历数组,回调函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组不变
var a = [1, 2, 3, 4, 5, 6]
console.log(a.map(function(e){
return e * e
})) // [1, 4, 9, 16, 25, 36]
console.log(a) //[1, 2, 3, 4, 5, 6]
filter(function(element))
返回数组的一个子集,回调函数用于逻辑判断是否返回,返回true则把当前元素加入到返回数组中,false则不加
新数组只包含返回true的值,索引缺失的不包括,原数组保持不变
var a = [1, 2, 3, 4, 5, 6]
console.log(a.filter(function(e){
return e % 2 == 0;
})) // [2, 4, 6]
console.log(a) //[1, 2, 3, 4, 5, 6]
.reduce(function(v1,v2),value)/.reduceRight(function(v1,v2),value)
遍历数组,调用回掉函数,将数组元素合成一个值,reduce从索引最小值开始,reduceRight反向。方法有两个参数
- 回调函数:把两个值合为一个,返回结果
- value:一个初始值可选
var a = [1, 2, 3, 4, 5, 6]
var b = a.reduce(function(v1, v2){ return v1 + v2 }) console.log(a) // 21
var b = a.reduceRight(function(v1, v2){ return v1 - v2 }, 100)
console.log(b) // 79
字符串
- 字符串模板(ES6)
var name = '饥人谷'
var website = 'jirengu.com'
var str = `你好, 这里是${name},${website},开启你的前端之路`
//"你好, 这里是饥人谷,jirengu.com,开启你的前端之路"
- 长度计算,连接
var str = "hello";
console.log( str.length );
console.log( str[0] );
console.log( str[str.length - 1] );
console.log( str.charAt(0) );
console.log( str.charCodeAt(0) );//返回匹配位置元素的Unicode码
var str2 = " world";
var str3 = str1 + str2;
cosnole.log( str3 );
- 字符串截取
var str = "hello world";
var sub1 = str.substr(1, 3); // 第一个是开始位置, 第二个是长度 ell
var sub2 = str.substring(1, 3); // 第一个是开始位置,第二个是结束位置,长度为第二个-第一个 el
var sub3 = str.slice(1, 3); // 同上 允许负参
字符串操作不会修改原来的字符串
- 查找
var str = "hello my world";
var s1 = str.search('my'); //6 找不到为-1
var s2 = str.replace('my', 'your'); //
var s3 = str.match('my'); //返回匹配的数组
- 大小写
var str = "Hello";
str.toUpperCase();
str.toLowerCase();
字符串操作不会修改原来的字符串
Math
Math对象是JavaScript的内置对象,提供一系列数学常数和数学方法。Math对象只提供了静态的属性和方法,所以使用时不用实例化
列几个常用的方法
- abs,max,min
Math.abs(1) // 1
Math.abs(-1) // 1
Math.max(2, -1, 5) // 5
Math.min(2, -1, 5) // -1
- floor,ceil
floor方法返回小于参数值的最大整数
Math.floor(3.2) // 3
Math.floor(-3.2) // -4
ceil方法返回大于参数值的最小整数
Math.ceil(3.2) // 4
Math.ceil(-3.2) // -3
- random
该方法返回0到1之间的一个伪随机数,可能等于0,但是一定小于1
Math.random() // 0.7151307314634323
// 返回给定范围内的随机数
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
// 返回给定范围内的随机整数
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Date
时间的表示方式
- Javascript中的Date
var d = new Date()
console.log(d.toString()) //"Wed Feb 28 2018 17:18:26 GMT+0800 (CST)"
console.log(d.toGMTString()) //"Wed, 28 Feb 2018 09:18:26 GMT"
console.log(d.toUTCString()) //"Wed, 28 Feb 2018 09:18:26 GMT"
console.log(d.toISOString()) //"2018-02-28T09:18:26.967Z"
- new Date()
使用Date构造函数创建一个Date的实例
var d = new Date()
d.getTime() //返回实例对象距离1970年1月1日00:00:00对应的毫秒数
d.getDate() //返回实例对象对应每个月的几号(从1开始)
d.getDay() //返回星期,星期日为0,星期一为1,以此类推
d.getFullYear() //返回四位的年份
d.getMonth() //返回月份(0表示1月,11表示12月)
d.getHours() //返回小时(0~23)
d.getMilliseconds() //返回毫秒(0-999)
d.getMinutes() //返回分钟(0-59)
d.getSeconds() //返回秒(0-59)
var d2 = new Date()
d2.setDate()
- new Date(milliseconds)
Date对象接受从1970年1月1日00:00:00 UTC开始计算的毫秒数作为参数。这意味着如果将Unix时间戳作为参数,必须将Unix时间戳乘以1000。
new Date(1378218728000); // Tue Sep 03 2013 22:32:08 GMT+0800 (CST)
// 1970年1月2日的零时
var Jan02_1970 = new Date(3600*24*1000); // Fri Jan 02 1970 08:00:00 GMT+0800 (CST)
- 静态方法
Date.now()
now方法返回当前距离1970年1月1日00:00:00的毫秒数
Date.now(); // 1427974222853
Date.parse()
parse方法用来解析日期字符串,返回距离1970年1月1日 00:00:00的毫秒数
日期字符串的格式应该完全或者部分符合YYYY-MM-DDTHH:mm:ss.sssZ格式,Z表示时区,是可选的
如果解析失败,返回NaN
Date.parse("January 26, 2011 13:51:50")
Date.parse("Mon, 25 Dec 1995 13:30:00 GMT")
Date.parse("Mon, 25 Dec 1995 13:30:00 +0430")
Date.parse("2011-10-10")
Date.parse("2011-10-10 20:00:00")
Date.parse("2011-10-10T14:48:00")
正则表达式
正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
- 创建
JavaScript通过内置对象RegExp支持正则表达式,有两种方式创建正则表达式对象,如果我们想匹配字符串中<%xxx%>两个百分号分割的字符串可以这么写
构造函数
var reg=new RegExp('<%[^%>]+%>','g');
字面量
var reg=/<%[^%>]%>/g;
最后的g代表全局,还有几个修饰符g:global,全文搜索,不添加的话搜索到第一个结果停止搜索
i:ingore case,忽略大小写,默认大小写敏感
m:multiple lines,多行搜索
-
元字符
- 字符类
我们可以使用元字符[]来构建一个简单的类, 比如[abcd]代表一个字符,这个字符可以是 abcd四个字符中的任意一个 - 取反
元字符[]组合可以创建一个类,我们还可以使用元字符^创建反向类/负向类,反向类的意思是不属于XXX类的内容,表达式 [^abc] 表示一个不是字符a或b或c的字符 - 范围类
按照上面的说明如果希望匹配单个数字那么表达式是这样的
//匹配一个字符,这个字符可以是0-9中的任意一个
var reg1 = /[0123456789]/
//匹配一个字符,这个字符可以是0-9中的任意一个
var reg2 = /[0-9]/
//匹配一个字符,这个字符可以是a-z中的任意一个
var reg3 = /[a-z]/
//匹配一个字符,这个字符可以是大写字母、小写字母、数字中的任意一个
var reg3 = /[a-zA-Z0-9]/
-
预定义类
有了这些预定义类,写一些正则就很方便了,比如我们希望匹配一个可以是 ab+数字+任意字符 的字符串,就可以这样写了 /ab\d./
-
边界
正则表达式还提供了几个常用的边界匹配字符
var str = 'hello1 world hello2 123456 \t \r jirengu \n ruoyu hello3'
str.match(/hello\d/g) // ["hello1", "hello2", "hello3"]
str.match(/^hello\d/g) // ["hello1"]
str.match(/hello\d$/g) // ["hello3"]
var str2 = 'hello1 whello9orld hello2 12-hello8-3456 \t \r jirengu \n ruoyu hello3'
str2.match(/\bhello\d\b/g) //["hello1", "hello2", "hello8", "hello3"]
//注意-也用于区分单词边界
例子
变量 className 为页面DOM元素对应的class 属性字符串,以下代码是检测 className 中是否包含值为"header"的 class
var reg = /(^|\s)header($|\s)/g
-
量词
var str1 = 'http://jirengu.com'
str1.match(/https?:\/\/.+/) //匹配
str1.match(/https+:\/\/.+/) //不匹配
str1.match(/https*:\/\/.+/) //匹配
var str2 = 'https://jirengu.com'
str2.match(/https?:\/\/.+/) //匹配
str2.match(/https+:\/\/.+/g) //匹配
str2.match(/https*:\/\/.+/g) //匹配
var str3 = 'httpssssss://jirengu.com'
str3.match(/https?:\/\/.+/g) //不匹配
str3.match(/https+:\/\/.+/g) //匹配
str3.match(/https*:\/\/.+/g) //匹配
- 测试题
如何匹配一个合法的 url?提示:url 以 http 或者 https 或者 // 开头
var reg = /^(https?:)?\/\/.+/
如何匹配一个手机号?提示手机号以1开头,长度为11位数字
var reg = /1[3578]\d{9}/ // 错误
var reg2 = /^1[3578]\d{9}$/ //正确
- 贪婪模式和非贪婪模式
看了上面介绍的量词,也许爱思考的同学会想到关于匹配原则的一些问题,比如{3,5}这个量词,要是在句子中出现了十次,那么他是每次匹配三个还是五个,反正3、4、5都满足3~5的条件
量词在默认下是尽可能多的匹配的,也就是大家常说的贪婪模式
'123456789'.match(/\d{3,5}/g); //["12345", "6789"]
既然有贪婪模式,那么肯定会有非贪婪模式,让正则表达式尽可能少的匹配,也就是说一旦成功匹配不再继续尝试,做法很简单,在量词后加上?即可
'123456789'.match(/\d{3,5}?/g); //["123", "456", "789"]
正则表达式的相关方法
RegExp.prototype.test(str)
方法用于测试字符串参数中是否存正则表达式模式,如果存在则返回true,否则返回false
var reg = /\d+\.\d{1,2}$/g;
reg.test('123.45'); //true
reg.test('0.2'); //true
reg.test('a.34'); //false
reg.test('34.5678'); //false
RegExp.prototype.exec(str)
方法用于正则表达式模式在字符串中运行查找,如果exec()找到了匹配的文本,则返回一个结果数组,否则返回 null
除了数组元素和length属性之外,exec()方法返回对象还包括两个属性。
- index 属性声明的是匹配文本的第一个字符的位置
- input 属性则存放的是被检索的字符串string
String.prototype.search(reg)
search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
search() 方法不执行全局匹配,它将忽略标志g,它同时忽略正则表达式对象的lastIndex属性,并且总是从字符串的开始进行检索,这意味着它总是返回字符串的第一个匹配的位置
'a1b2c3'.search(/\d/g); //1
'a1b2c3'.search(/\d/); //1
String.prototype.match(reg)
match()方法将检索字符串,以找到一个或多个与regexp匹配的文本。但regexp是否具有标志 g对结果影响很大。
String.prototype.replace(reg, replaceStr)
关于string对象的replace方法,我们最常用的是传入两个字符串的做法,但这种做法有个缺陷,只能replace一次
'abcabcabc'.replace('bc','X'); //aXabcabc
'abcabcabc'.replace(/bc/g,'X'); //aXaXaX
'abcaBcabC'.replace(/bc/gi,'X'); //aXaXaX
String.prototype.split(reg)
我们经常使用split方法把字符串分割为字符数组
'a,b,c,d'.split(','); //["a", "b", "c", "d"]
和replace方法类似,在一些复杂的分割情况下我们可以使用正则表达式解决
'a1b2c3d'.split(/\d/); //["a", "b", "c", "d"]