Date
在JavaScript中,Date对象用来表示日期和时间。
要获取系统当前时间,用:
1 | const date = new Date();// 注意要new 否则调用不了方法 |
如果要创建一个指定日期和时间的Date对象,可以用:
1 | const next = new Date(2021,1,1,1,1,1); |
更有意思的是,还能够用来自动更正时间:
1 | // 传入一个错误的时间 会自动校正 |
第二种创建一个指定日期和时间的方法是解析一个符合ISO 8601格式的字符串:
1 | const isoDate = Date.parse('2021-02-01T22:49:22.875+08:00'); |
但返回的不是Date对象,而是一个时间戳。不过时间就可以很容易地转换为一个Date:
1 | const timeStampDate = new Date(1612190962875); |
时区
Date对象表示的时间总是按浏览器所在时区显示的,不过我们既可以显示本地时间,也可以显示调整后的UTC时间:
1 | const localDate = new Date(); |
时间的计算
比较两个时间的大小
1 | const date1 = new Date('2021-02-01 17:23:13'); |
加上一段时间
1 | const date = new Date(); |
Math
JavaScript Math 对象允许您对数字执行数学任务.
1 | const pi = Math.PI; // 3.141592653589793 |
Proxy
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
1 | var proxy = new Proxy(target, handler); |
Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
下面是另一个拦截读取属性行为的例子。
1 | var proxy = new Proxy({}, { |
上面代码中,作为构造函数,Proxy接受两个参数。第一个参数是所要代理的目标对象(上例是一个空对象),即如果没有Proxy的介入,操作原来要访问的就是这个对象;第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作。比如,上面代码中,配置对象有一个get方法,用来拦截对目标对象属性的访问请求。get方法的两个参数分别是目标对象和所要访问的属性。可以看到,由于拦截函数总是返回35,所以访问任何属性都得到35。
注意,要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作。
正则表达式
JS 的正则表达式跟 Java 的正则表达式类似。
用\d可以匹配一个数字,\w可以匹配一个字母或数字, .可以匹配任意一个字符。
要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符。
\s 可以匹配一个空格(包括Tab等空白符)。
要做更精确地匹配,可以用[]表示范围,比如:
[0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;[0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100','0_Z','js2015'等等;[a-zA-Z\_\$][0-9a-zA-Z\_\$]*可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;[a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
A|B可以匹配A或B,所以(J|j)ava(S|s)cript可以匹配'JavaScript'、'Javascript'、'javaScript'或者'javascript'。
^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。
你可能注意到了,js也可以匹配'jsp',但是加上^js$就变成了整行匹配,就只能匹配'js'了。整行匹配就是要全部匹配,不能多也不能少。
1 | const js = /^js$/; |
切分字符串
用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:
1 | 'a b c'.split(' '); // ['a', 'b', '', '', 'c'] |
嗯,无法识别连续的空格,用正则表达式试试:
1 | 'a b c'.split(/\s+/); // ['a', 'b', 'c'] |
无论多少个空格都可以正常分割。加入,试试:
1 | 'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd'] |
再加入;试试:
1 | 'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd'] |
如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。
分组
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。比如:
^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:
1 | var re = /^(\d{3})-(\d{3,8})$/; |
如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。
exec()方法在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。
exec()方法在匹配失败时返回null。
贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0:
1 | var re = /^(\d+)(0*)$/; |
由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:
1 | var re = /^(\d+?)(0*)$/; |
全局搜索
JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配:
1 | var r1 = /test/g; |
全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:
1 | var s = 'JavaScript, VBScript, JScript and ECMAScript'; |
全局匹配类似搜索,因此不能使用/^...$/,那样只会最多匹配一次。
正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配。
语法
1 | /正则表达式主体/修饰符(可选) |
正则表达式主体即正则表达式。
修饰符的话,则有三种,如下:
| 修饰符 | 描述 |
|---|---|
| i | 执行对大小写不敏感的匹配。 |
| g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
| m | 执行多行匹配。 |
对于字符串而言,正则表达式通常有两个方法:search() 和 replace(),显然前者是检索后者是替换。
现在我们来尝试一下:
1 | var str = "Hello World"; |
以上是字符串的方法。
对于正则表达式,JavaScript 里有一个预定义了属性和方法的正则表达式对象 RegExp 。
该对象有两个方法:test() 和 exec().
现在尝试一下:
1 | var rep = /a/i; |
JSON
JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。
JSON实际上是JavaScript的一个子集。在JSON中,一共就这么几种数据类型:
- number:和JavaScript的
number完全一致; - boolean:就是JavaScript的
true或false; - string:就是JavaScript的
string; - null:就是JavaScript的
null; - array:就是JavaScript的
Array表示方式——[]; - object:就是JavaScript的
{ ... }表示方式。
以及上面的任意组合。
并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""。
由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,可以直接使用JSON,因为JavaScript内置了JSON的解析。
序列化
1 | const person = { |
要输出得好看一些,可以加上参数,按缩进输出:
1 | JSON.stringify(person,null," "); |
第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array:
1 | JSON.stringify(person,["name","age"]," "); |
