亲宝软件园·资讯

展开

JS引用类型Date和 RegExp

​ 方木头​ 人气:0

引用类型 & 引用值的理解

引用值(或者对象)是某个特定引用类型实例。 在ECMAScript中,引用类型是把数据和功能组织到一起的结构,经常被人错误的称作“类”。虽然从技术上讲JavaScript 是一门面向对象语言,但ECMAScrtipt 缺少传统的面相对象语言所具备的某些基本结构,包括类和接口。引用类型有时候也被称为对象定义,因为它们描述了自己的对象应有的属性和方法。
对象被认为是某个特定引用类型的实例。新对象通过使用new 操作符后跟一个构造函数来创建。构造函数就是用来创建新对象的函数。

let now = new Date();

这行代码代码创建了引用对象Date 的一个新实例,并将它保存在变量now 中。Date()在这里就是构造函数,它负责创建一个只有默认属性和方法的简单对象。ECMAScript 提供了很多像Date这样的原生引用类型,帮助开发者实现常见的任务。函数也是一种引用类型。

Date 引用类型

ECMAScript 的Date 类型参考了Java 早期版本中的java.until.Date.为此,Date类型将日期保存为自协调世界时(UTC)时间1970年1月1日午夜(零时)至今所经过的毫秒数。使用这种存储方式,Date类型可以精确的标识1970年1月1日之前及之后285616年的日期。
要创建日期对象,就是用new 操作符来调用Date构造函数:

let now = new Date();
console.log(now);//   Mon Jul 18 2022 15:36:02 GMT+0800 (中国标准时间)

在不给Date 构造函数传递参数的情况下,创建的对象,保存的是当前的日期和时间。要基于其他日期和时间创建日期对象,必须穿入其毫秒标识。ECMAScript 为此提供了两个辅助方法:Date.parse()和Date.UTC();

Date.parse()方法

Date.parse()方法接收一个表示日期和的字符串函数,尝试将这个字符串转换为表示该日期的毫秒数。 ECMA-262 第5版 定义了Date.parse()应该支持的日期格式。所有实现必须支持一下列日期格式:

如果传给Date.parse()的字符串并不表示日期,则该方法返回NaN。如果直接把表示日期的字符串传给Date的构造函数,那么Date 会在后台调用Date.parse()。换句话说,如下两行代码代表的意思一致。

let someDate = new Date(Date.parse("May 23,2022"));
let someDateTwo = new Date("May 23,2022");

Date.UTC()方法

Date.UTC()方法也返回日期的毫秒标识,但使用的是跟Date.parse()不同的信息来生成这个值。传给Date.UTC()的参数时年,零起点月数(1月是0,2月是1,依次类推),日(1-31),时(0-23),分,秒和毫秒。这些参数中,只有(年和月)是必须的。如果不提供日,那么默认为1日。其他的默认值都是0.

let y2k = new Date(Date.UTC(2000,0)); //GMT 时间2000年1月1日零点。
let allLives = new Date(Date.UTC(2005,3,5,17,55,55));// 2005年5月5日下午5点55分55秒

与Date.parse()一样,Date.UTC也会被Date的构造函数隐式调用,但有一个区别,这种情况下创建的时本地日期,不是GMT日期。 也就是说,隐式调用情况下下,我们传递给Date.UTC()方法的返回的毫秒数是本地时间距离1970年1月1日的毫秒数,我们传递的这个日期,在JavaScript看来是UTC时间,它默认已经加上了时区插值的毫秒数。但是显示的调用UTC()方法时,传递的日期就是GMT时间。GMT 时间与UTC 时间的关系为:GMT = UTC + 0.

  let utc = new Date(2022, 6, 18, 17, 15);// 
  console.log(utc.toString());//Mon Jul 18 2022 17:15:00 GMT+0800 (中国标准时间)
  console.log(new Date(Date.UTC(2022, 6, 18, 17, 15)));//Tue Jul 19 2022 01:15:00 GMT+0800 (中国标准时间)

Date.parse()方法 与Date.UTC()方法 的使用注意 首先parse方法和UTC 方法都可以隐式调用。所以我们可以这么理解,有两种方式可以创建日期。给Date构造函数传入的是一个日期字符串时,会默认调用parse方法,传入以整数的形式表示的日期会调用UTC方法。但是默认情况下我们传递的日期是加上了时区的毫秒数的,这个一定要清楚。 如果要使用UTC方法的传递GMT时间,一定要显示的调用UTC()方法。
当要明确的求取某个时区的某个时间的毫秒时,需要使用parse()方法。

继承的方法

Date 继承自Object 方法,因此也会有toLocaleString,toString()和valueOf方法。

Date 类型重写了这三个方法的实现:

下面是toLocaleString,toString()和valueOf的测试打印数据,可供参考。

 Date(2022, 6, 14, 10, 50)
 toString: Thu Jul 14 2022 10:50:00 GMT+0800 (中国标准时间)
 toLocaleString: 2022/7/14 10:50:00
 valueOf: 1657767000000

 ****************************
 Date.UTC(2022, 6, 14, 10, 50)
 toString: Thu Jul 14 2022 18:50:00 GMT+0800 (中国标准时间)
 toLocaleString: 2022/7/14 18:50:00
 valueOf: 1657795800000

 ****************************
Date.parse("Thur 07 14 2022 10:50:00 GMT+0800")
toString: Thu Jul 14 2022 10:50:00 GMT+0800 (中国标准时间)
toLocaleString: 2022/7/14 10:50:00
valueOf: 1657767000000
****************************
Date("Thur 07 14 2022 10:50:00 GMT+0800")
toString: Thu Jul 14 2022 10:50:00 GMT+0800 (中国标准时间)
toLocaleString: 2022/7/14 10:50:00
valueOf: 1657767000000
 ****************************
Date.now()
toString: 1657767000086
toLocaleString: 1,657,767,000,086
valueOf: 1657767000086

RegExp

ECMAScript 通过RegExp 类型支持正则表达式。正则表达式使用类似Perl 的简介语法来创建。

let expersiion = /pattern/flags

这个正则表达式的pattern(模式)可以时任何简单或复杂的正则表达式,包括字符类,限定符,分组,向前查找和反向引用。每个正则表达式可以带零个或多个flags(标记),用于控制正则表达式的行为。

下面给出了匹配模式的标记:

使用不同模式和标记可以创建出各种正则表达式,比如:

//匹配字符串中的所有“at”
let pattern = /at/g;

//匹配第一个“bat”或“cat”,忽略大小写
let pattern2 = /[bc]at/i;

//匹配所有以“at”结尾的三字符组合,忽略大小写。
let pattern3 = /.at/gi

与其他语言的正则表达式类似,所有元字符在模式中也必须转义,包括: ( [ \ ^ $ |)] ? * + .
元字符在正则表达式中都有一种或多种特殊功能,所有要匹配上面这些字符本身,就必须使用反斜杠来转义

//匹配第一个“bat”或“cat”,忽略大小写
let pattern2 = /[bc]at/i;

//匹配第一个“[bc]at”,忽略大小写
let pattern2 = /\[bc\]at/i;

//匹配所有以“at”结尾的三字符组合,忽略大小写。
let pattern3 = /.at/gi

//匹配所有".at",忽略大小写。
let pattern3 = /\.at/gi

前面例子中的正则表达式都是使用字面量形式定义的。正则表达式也可以使用RegExp 构造函数来创建,它接收两个参数:模式字符串和(可选的)标记字符串。任何使用字面量定义的正则表达式也可以通过构造函数来创建:

//匹配第一个“bat”或“cat”,忽略大小写
let pattern1 = /[bc]at/i;

//跟pattern1一样,只不过是用构造函数创建的。
let pattern2 = new RegExp("[bc]at","i");

这里的pattern1 和pattern2 是等效的正则表达式。注意,RegExp构造函数的两个参数都是好字符串。因为RegExp的模式参数是字符串,所以某些情况下需要二次转义。所有元字符都必须二次转义,包括转义字符,如\n(\转义后的字符串是\,在正则表达式中则要写成\\).

字面量模式对应的字符串
/[bc]at/"\[bc]\]at"
/.at/"\at."
/name/age/"name\/age"
/\d/\d{1,2}"\d.\d{1,2}"
/\w\hello\123"\w\\hello\\123"

RegExp 实例方法

exec()

RegExp的主要方法是exec(),主要用于配合捕获组使用。这个方法只接受一个参数,即要应用模式的字符串。如果找到了匹配项,则返回包含第一个匹配信息的数组;如果没有找到匹配项,则返回null。返回的数组虽然是Array的实例,。但包含两个额外的属性:index和input。index是字符串中匹配模式的起始位置,input 是要查找的字符串。这个数据的第一个元素是匹配整个模式的字符串,其他元素食欲表达式中的捕获组匹配的字符串。如果模式中没有捕获组,则数组只包含一个元素。

let text = "mom and dad and baby";
let pattern = /mom( and dad( and baby)?)?/gi

let matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches.input); //"mom and dad and baby"
console.log(matches[0]);// "mom and dad and baby"
console.log(matches[1]);// " and dad and baby"
console.log(matches[2]);// " and baby"

在这个例子中,模式包含两个捕获组:最内部的匹配项“ and baby”,以及外部的匹配项“ and dad” 或“ and dad and baby”。调用exec()后找到了一个匹配项。因为整个字符串匹配模式,所以matches数组的index 属性就是0。数组的第一个元素是匹配的整个字符串,第二个元素是匹配第一个捕获组的字符串,第三个元素是匹配第二个捕获组的字符串。 如果模式设置了全局标记,则每次调用exec()方法会返回一个匹配的信息。如果没有设置全局标记,则无论对同一个字符串调用多少次exec(),也只会返回第一个匹配的信息。

let text = "cat, bat, sat, fat";
let pattern = /.at/;
let matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//0

matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//0

上面的例子没有设置全局标记,因此调用exec()只返回第一个匹配项("cat").lastIndex 在非全局模式下始终不变。
如果在这个模式上设置了g标记,则每次调用exec()都会在字符串向前搜索下一个匹配项。

let text = "cat, bat, sat, fat";
let pattern = /.at/g;

let matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//3

matches = pattern.exec(text);
console.log(matches.index);//5
console.log(matches[0]);//bat
console.log(pattern.lastIndex);//8
matches = pattern.exec(text);
console.log(matches.index);//10
console.log(matches[0]);//sat
console.log(pattern.lastIndex);//13

如果设置了粘附标记y,则每次调用exec()就只会在lastIndex的位置上寻找匹配项。

粘附标记会覆盖全局标记:

let text = "cat, bat, sat, fat";
let pattern = /.at/y;
let matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//3

//以索引3对应的字符开头找不到匹配项,因此exec() 返回null
//
matches = pattern.exec(text);
console.log(matches);//null
console.log(pattern.lastIndex);//0

//向前设置lastIndex 可以让粘附的模式通过exec()找到下一个匹配项。
pattern.lastIndex = 5;
matches = pattern.exec(text);
console.log(matches.index);//5
console.log(matches[0]);//bat
console.log(pattern.lastIndex);//8

test()

正则表达式的另一个方法是test(),接收一个字符串参数。如果输入的文本与模式匹配,则参数返回true,否则返回false。这个方法适用于只想测试模式是否匹配,而不需要世界匹配内容的情况。

let  text = "000-00-0000";
let pattern = /\d{3}-\d{2}-\d{4}/;
if(pattern.test(test)){
    console.log("The pattern was matched.");
}

继承的方法

无论正则表达式怎么创建的,继承的方法toLocalString()toString()都返回正则表达式的字面量表示。

   let pattern = new RegExp("\\[bc]\\at]at","gi");
   console.log(pattern.toString()); ///\[bc\]at/gi
   console.log(pattern.toLocaleString()); // /\[bc\]at/gi
   console.log(pattern.valueOf());///\[bc]\at]at/gi

加载全部内容

相关教程
猜你喜欢
用户评论