JavaScript(二)基本引用类型

本文最后更新于:8 个月前

基本引用类型(Date、RegExp、JSON、原始值包装对象)

JavaScript(二)基本引用类型

引用值(或者对象)是某个特定引用类型的实例。在ECMAScript中,引用类型是把数据和功能组织到一起的结构。

新对象通过使用new操作符后跟一个构造函数(constructor)来创建

1
2
var now = new Date()
var now = new Date

在这里,Data()就是一个构造函数(constructor),不加()也可以

一、Date

1
2
3
4
5
6
7
8
9
10
11
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳

1.1、创建Date对象

1
2
var d = new Date(2015, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)

特别注意:月份下标是0-11,所以定义的时候要比真实月份减一,获取的月份也比真实小一

1.2、格式化Date

1
2
3
4
5
6
7
8
let D = new Date();

D.toLocaleString() //'2022/5/3 20:29:53'
D.toString() //'Tue May 03 2022 20:29:53 GMT+0800 (中国标准时间)'
D.valueOf() //1651580993637

D.toDateString() //'Tue May 03 2022'
D.toTimeString() //'20:33:55 GMT+0800 (中国标准时间)'

1.3、时间加减

1
2
3
4
5
var now = new Date()
var base = 1000 * 60 * 60 * 24
var days = 3
var targetDate = now - days*base //1679017120045
targetDate = new Date(targetDate) //Fri Mar 17 2023 09:38:40 GMT+0800 (中国标准时间)

1.4、时间比较

1
2
3
// 接上面的now和targetDate
now > targetDate //true
now < targetDate //false

二、RegExp

参考文章:正则表达式 – 语法 | 菜鸟教程 (runoob.com)

2.1、语法

1
2
3
4
5
6
7
var reg = /pattern/flags				//定义方式一
var reg = new RegExp('pattern','flags') //定义方式二
//pattern,正则表达式
//flags,用于控制正则表示式的行为。如g:全局模式,查找字符串的全部内容;i:不区分字符大小写

var reg1 = /\d{3}\-\d{3,8}/ ;
var reg2 = new RegExp('abc') //reg2等于 /abc/

需要特别注意反斜杠\在RegExp构造器中的写法,示例如下:

1
2
3
var reg = /^\d*$/
var reg = new RegExp('^\\d*$') //reg等于 /^\d*$/
// 反斜杠,在RegExp里面需要用双反斜杠的形式,否则会出错!!

2.2、正则表达式符号

  • 普通符号
. 除了换行符之外的任何单个字符 \s\S 匹配所有,\s是所有空白符号,\S是所有非空白符(不包括换行)
[ABC] 匹配[…]中的所有字符 [^ABC] 匹配除了[…]里面的所有字符
[a-zA-Z] 匹配所有大小写字母 \w 匹配字母、下划线、数字,等价于[a-zA-Z0-9_]
\d 匹配一个数字
  • 特殊字符
* 匹配前面的子表达式0或多次 + 匹配前面的子表达式1或多次
匹配前面的子表达式0或1次 \ 将下一个字符标记为特殊字符
[ 中括号表达式的开始 | 指明两项之间的一个选择
() 标记一个子表达式的开始和结束的位置
子表达式可以获取供以后使用
{n} 匹配确定的n次,如o{2}匹配’food’中的’oo’
{n,} 至少匹配n次 {n,m} 至少匹配n次,至多匹配m次
  • 非打印字符
\f 换页符 \r 换行符
\n 换行符 \t 制表符
  • 定位符
^ 匹配字符串开始的位置 $ 匹配字符串结束的位置
\b 单词边界 \B 非单词边界

()(com|org)表示从com或org当中选一个。()还表示捕获分组,()会把每个分组里匹配的值保存到一个数组中。

()的副作用就是使相关的匹配被缓存,在第一个选项前放 ?: 可以消除这种副作用,即放弃当前括号捕获的内容(不会出现在结果数组中)

2.3、实例方法

  • 实例.exec(),传入一个字符串参数,(找到匹配项)返回第一个匹配信息的数组,(没找到匹配项)返回null

    两个额外属性:indexinputindex表示字符串中匹配的起点,input表示查找的字符串

  • 实例.test(),传入一个字符串参数,返回一个boolead值

1
2
3
4
5
6
7
8
var reg = /\d{3}\-\d{3,8}/g 
var phone = '020-10016'
reg.test(phone) //true
reg.exec(phone) //null

var reg = /(\d{3})\-(\d{3,8})/g
var phone = '020-10016'
reg.exec(phone) // ['020-10016', '020', '10016', index: 0, input: '020-10016', groups: undefined]

2.4、贪婪匹配

正则匹配默认为贪婪匹配,就是匹配尽可能多的字符,但这有时并不是我们多希望的,比如

1
2
var re = /^(\d+)(0*)$/;
re.exec('102300'); //['102300','102300',''] 这里\d+匹配了后面所有的0

通过添加一个?后缀采取非贪婪匹配

1
2
var re = /^(\d+?)(0*)$/;
re.exec('102300'); //['102300','1023','00']

2.5、反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数

反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词/字符的匹配项的能力

1
2
var str = "Is is the cost of of gasoline going up up";
var reg = /([a-z])\1/gi

2.6、?=、?<=、?!、?<!

exp1(?=epx2) 查找exp2前面的exp1
(?<=exp2)exp1 查找exp2后面的exp1
exp1(?!exp2) 查找后面不是exp2的exp1
(?<!exp2)exp1 查找前面不是exp2的exp1

2.7、实例属性

1
2
3
4
5
let re = /[bc]at/gi;
re.global //true
re.ignoreCase //true
re.source //'[bc]at'
re.flags //'gi'

2.8、功能

  • 切分字符串,用正则表达式作为切分字符,比固定字符更加灵活

    1
    'a,b;; c  d'.split(/[\s+\,\;]+/); //结果为:['a', 'b', 'c', 'd']
  • 分组,正则表达式还有提取子串的功能,用()表示的就是要提取的分组(Group),匹配失败的时候返回null

    1
    2
    var re = /^(\d{3})\-(\d{3,8})$/;
    re.exec('010-12345'); //结果为 [ "010-12345", "010", "12345" ]

2.9、全局搜索

在正则表达式后面添加g,表示全局匹配,全局匹配表示可以多次执行exec()进行匹配,需要一次接一次地执行exec()方法

1
2
3
4
5
6
7
var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;
re.exec(s); //['JavaScript', index: 0, ...]
re.exec(s); //['VBScript', index: 0, ...]
re.exec(s); //['JScript', index: 0, ...]
re.exec(s); //['ECMAScript', index: 0, ...]
re.exec(s); //null

2.10、常用正则表达式

场景 正则表达式
提取url后缀里面的参数 /(\w+)=(\w+)/g
解析URL

let reg = /(\w+://)?(www.\w+(.(com|cn|\w+))(:\d)?([?]\w+=\w*(&\w+=\w*))?(#\w+)?)/g
第一部分:(\w+)://,匹配协议类型
第二部分:www.\w+(.(com|cn||w+)),匹配域地址,,域名不止于com和cn,所以添加了\w+
第三部分:(:\d
)?,匹配端口号,可有可无
第四部分:([?]\w+=\w
(&\w+=\w*)*)?,匹配URL携带的参数,可有可无
第五部分:(#\w+)?,匹配路径,可有可无

手机号码 /^1[3-9][0-9]{9}$/
身份证号

/(^\d{15}$)|(^\d{17}([0-9]|X)$)/
/^(\d{6})(\d{8})(\d{3})([0-9]|X)$/,捕获地域编码、出生日期、顺序码、校验码

Email /^[\da-zA-Z_\.]+@\w+\.com(\.cn)?$/,名称+域名
文件扩展名 /.[a-z]+$/i,捕获文件扩展名
1
2
3
let str = '比如https://www.baidu.com,或者 www.baidu.com?from=onlineExam,如果出现链接文本';
let reg = /(https?:\/\/)?(www\.\w+(\.(com|cn))*(\?\w+=\w*(&\w+=\w*)*)?(#\w+)?)/g
reg.exec(str)

三、JSON

JavaScript Object Notation的缩写,JS对象符号,它是一种数据交换格式。

为了统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""

3.1、序列化

JSON.stringify(objectName)

1
2
var xiaoming = {...};
var s = JSON.stringify(xiaoming);

还可以加上一些参数

  • JSON.stringify(xiaoming,null,' ')' '表示按缩进输出

  • JSON.stringify(xiaoming,['name','skills'],' '):传入一个Array[],筛选输出的值

  • 传入一个函数,如下:把所有属性值变成大写

    1
    2
    3
    4
    5
    6
    7
    8
    function convert(key,value){
    if(typeof value == 'string'){
    return value.toUpperCase();
    }
    return value;
    }
    JSON.stringify(xiaoming,convert,' ');
    var s2 = JSON.stringify(xiaoming,['name'],convert,' '); //错误,不能这么传递参数
  • 还可以控制序列化的规则,在对象内部定义一个toJSON()方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var xiaoming = {
    ...
    toJSON: function(){
    return{
    'Name': this.name,
    'Age': this.age
    };
    }
    }
    JSON.stringify(xiaoming); //只返回{"Name":"小明","Age":14}',不返回其余属性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var xiaoming = {
    name:"xiaoming",
    age:18,
    toJSON: function(){
    return{
    'Name': this.name.toUpperCase(),
    'Age': this.age
    };
    }
    }
    var s = JSON.stringify(xiaoming,['Name'],' ');
    s //输出为:"{\"Name\": \"XIAOMING\"}"

3.2、反序列化

JSON.parse()

1
2
JSON.parse('[1,2,3,true]');	//[1,2,3,true]
JSON.parse('{"Name":"xiaoming"}'); //Object { Name: "xiaoming" }

JSON.parse()还可以接收一个函数,用来转换解析出的属性:

1
2
3
4
5
6
7
var obj = JSON.parse('{"Name":"小明","age":"20"}',function(key,value){
if(key === 'age'){
return value+"岁";
}
return value;
})
obj; //Object { Name: "小明", age: "20岁" }

四、原始值包装类型

ECMAScript提供了3种特殊的引用类型:Boolean、Number和String

1
2
let s1 = "text";
let s2 = s1.substring(2);

s1是一个string原始值变量,逻辑上本不应该有诸如substring的方法,但是它又成功运行了,这是因为,在此期间后台做了一些操作:

(1)创建一个String类型的实例;(2)调用实例上的特定方法;(3)销毁实例。

引用类型与原始值包装类型的主要区别在于对象的生命周期

由于String不属于集合引用类型,所以把String的诸多性质放到《JavaScript基础》-【基本数据类型】里面探究了。


JavaScript(二)基本引用类型
http://timegogo.top/2022/05/13/JavaScript/JavaScript(二)基本引用类型/
作者
丘智聪
发布于
2022年5月13日
更新于
2023年7月16日
许可协议