《JavaScript高级程序设计》(第4版)阅读笔记(二十四)

这篇文章开始分享第五章的内容了。

 

第 5 章 基本引用类型
 

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

对象被认为是某个特定引用类型的实例。新对象通过使用 new 操作符后跟一个构造函数(constructor)来创建。构造函数就是用来创建新对象的函数,比如下面这行代码:

let now = new Date();

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

5.1 Date
 

ECMAScript的 Date 类型参考了Java早期版本中的java.util.Date 。为此, Date 类型将日期保存为自协调世界时(UTC,Universal Time Coordinated)时间1970年1月1日午夜(零时)至今所经过的毫秒数。使用这种存储格式, Date 类型可以精确表示1970年1月1日之前及之后285 616年的日期。

要创建日期对象,就使用 new 操作符来调用 Date 构造函数:

let now = new Date();

在不给 Date 构造函数传参数的情况下,创建的对象将保存当前日期和时间。基于其他日期和时间创建日期对象,必须传入其毫秒表示(UNIX纪元1970年1月1日午夜之后的毫秒数)。ECMAScript为此提供了两个辅助方法: Date.parse() 和 Date.UTC() 。

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

“月/日/年”,如 "5/23/2019" ;
“月名 日, 年”,如 "May 23, 2019" ;
“周几 月名 日 年 时:分:秒 时区”,如 "Tue May 23 2019 00:00:00GMT-0700" ;
ISO 8601扩展格式“YYYY-MM-DDTHH:mm:ss.sssZ”,如 2019-05-23T00:00:00 (只适用于兼容ES5的实现)。

比如,要创建一个表示“2019年5月23日”的日期对象,可以使用以下代码:

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

如果传给 Date.parse() 的字符串并不表示日期,则该方法会返回NaN 。如果直接把表示日期的字符串传给 Date 构造函数,那么 Date 会在后台调用 Date.parse() 。换句话说,下面这行代码跟前面那行代码是等价的:

let someDate = new Date("May 23, 2019");

注意 不同的浏览器对 Date 类型的实现有很多问题。比如,很多浏览器会选择用当前日期替代越界的日期,因此有些浏览器会将 "January 32, 2019" 解释为 "February 1, 2019" 。Opera则会插入当前月的当前日,返回 "January 当前日, 2019" 。就是说,如果是在9月21日运行代码,会返回 "January 21, 2019" 。

 Date.UTC() 方法也返回日期的毫秒表示,但使用的是跟Date.parse() 不同的信息来生成这个值传给 Date.UTC() 的参数是年、零起点月数(1月是0,2月是1,以此类推)、日(1~31)、时(0~23)、分、秒和毫秒。这些参数中,只有前两个(年和月)是必需的。如果不提供日,那么默认为1日。其他参数的默认值都是0。下面是使用Date.UTC() 的两个例子:

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

这个例子创建了两个日期 。第一个日期是2000年1月1日零点(GMT), 2000 代表年, 0 代表月(1月)。因为没有其他参数(日取1 ,其他取 0 ),所以结果就是该月第1天零点。第二个日期表示2005年5月5日下午5点55分55秒(GMT)。虽然日期里面涉及的都是5,但月数必须用 4 ,因为月数是零起点的。小时也必须是17,因为这里采用的是24小时制,即取值范围是0~23。其他参数就都很直观了。

与 Date.parse() 一样, Date.UTC() 也会被 Date 构造函数隐式调用,但有一个区别:这种情况下创建的是本地日期,不是GMT日期。不过 Date 构造函数跟 Date.UTC() 接收的参数是一样的。因此,如果第一个参数是数值,则构造函数假设它是日期中的年,第二个参数就是月,以此类推。前面的例子也可以这样来写:

// 本地时间2000年1月1日零点
let y2k = new Date(2000, 0);
// 本地时间2005年5月5日下午5点55分55秒
let allFives = new Date(2005, 4, 5, 17, 55, 55);

以上代码创建了与前面例子中相同的两个日期,但这次的两个日期是(由于系统设置决定的)本地时区的日期。(也就是说,我们直接调用Date.UTC(),得到的是GMT日期,但是通过Date(),得到的是本地日期)ECMAScript还提供了 Date.now() 方法,返回表示方法执行时日期和时间的毫秒数。这个方法可以方便地用在代码分析中:(比如计算干某事所需的时间)

// 起始时间
let start = Date.now();
// 调用函数
doSomething();
// 结束时间let stop = Date.now(),
result = stop - start;

 

5.1.1 继承的方法
 

与其他类型一样, Date 类型重写了 toLocaleString() 、toString() 和 valueOf() 方法。但与其他类型不同,重写后这些方法的返回值不一样Date 类型的 toLocaleString() 方法返回与浏览器运行的本地环境一致的日期和时间。这通常意味着格式中包含针对时间的AM(上午)或PM(下午),但不包含时区信息(具体格式可能因浏览器而不同)。 toString() 方法通常返回带时区信息的日期和时间,而时间也是以24小时制(0~23)表示的。下面给出了 toLocaleString() 和toString() 返回的2019年2月1日零点的示例(地区为 "en-US" 的PST,即Pacific Standard Time,太平洋标准时间):

toLocaleString() - 2/1/2019 12:00:00 AM
toString() - Thu Feb 1 2019 00:00:00 GMT-0800(Pacific Standard Time)

现代浏览器在这两个方法的输出上已经趋于一致。在比较老的浏览器上,每个方法返回的结果可能在每个浏览器上都是不同的。这些差异意味着 toLocaleString() 和 toString() 可能只对调试有用,不能用于显示。

Date 类型的 valueOf() 方法根本就不返回字符串,这个方法被重写后返回的是日期的毫秒表示。因此,操作符(如小于号和大于号)可以直接使用它返回的值。比如下面的例子:

let date1 = new Date(2019, 0, 1); // 2019年1月1日
let date2 = new Date(2019, 1, 1); // 2019年2月1日
console.log(date1 < date2); // true
console.log(date1 > date2); // false

(注意,这里是两个对象在比较大小,所以比较之前调用了valueOf方法日期2019年1月1日在2019年2月1日之前,所以说前者小于后者没问题。因为2019年1月1日的毫秒表示小于2019年2月1日的毫秒表示,所以用小于号比较这两个日期时会返回 true 。这也是确保日期先后的一个简单方式。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值