date对象,定时器

本文详细介绍了JavaScript中的Date对象,包括其构造函数、实例方法和时间戳的概念。此外,还深入讨论了定时器方法setTimeout、clearTimeout、setInterval和clearInterval的使用,分析了它们的运行机制,特别是定时器的异步执行和时间间隔的非精确性。最后,提出了使用迭代setTimeout替代setInterval以避免某些间隔被跳过的问题。
摘要由CSDN通过智能技术生成

一.Date 实例对象

概述

Date是Javascript内置的构造函数。Date实例对象是Javascript中的日期对象(GMT),表示本地日期和时间。Date实例对象是一个静态对象,始终表示创建对象那一刻的日期和时间。

//创建Date实例对象
//Sat Apr 20 2019 16:19:49 GMT+0800 (中国标准时间)
//GMT是格林威治标准时间。GMT时间通常指格林威治中央区时
//GMT+0800表示东八区的区时即北京时间
var date = new Date(); 

时间戳是自1970年1月1日(计算机的纪元时间)起至今的毫秒数。时间戳唯一记录一个时刻,因此它经常作为唯一标识来使用。北京的时区为东8区,计算机的纪元时间实际为1970/01/01 08:00:00。GMT是格林威治标准时间。GMT时间通常指格林威治中央区时,本地时间等于GMT时间加本地区时,如北京的时区为东8区,所以北京时间是GMT+0800。UTC是世界标准时间,全球统一,比GMT更加精准,与地球自转周期一致。

Date实例对象和时间戳可以直接做差,返回结果是两个时间相差的毫秒数。

new Date() - Date.now(); //0

Date实例对象之间进行数学运算(加减乘除、比较大小)时,系统会隐式将其转换为时间戳再运算。

var date0 = new Date('2019/12/01');
var date1 = new Date('2019/12/25');
date0 > date1; //false

概述

Date构造函数

**new Date()**无参,返回一个Date实例对象。

//Sat Apr 20 2019 08:44:58 GMT+0800 (中国标准时间)
console.log(new Date());
Date实例方法

Date的实例方法分为两大类,其一本地时间(北京时间),其二UTC时间(忽略)。方法名中带UTC的就是操作UTC时间的方法

/*0、getFullYear():    从Date实例对象中返回4位数字的年份值
1、getMonth():        从Date实例对象中返回月份值(0~11)
2、getDate():         从Date实例对象中返回日期值
3、getHours():        从Date实例对象中返回小时值(0 ~ 23)
4、getMinutes():      从Date实例对象中返回分钟值(0 ~ 59)
5、getSeconds():      从Date实例对象中返回秒数值(0 ~ 59)
6、getMilliseconds(): 从Date实例对象中返回毫秒值(0 ~ 999)
7、getDay():          从Date实例对象中返回一周中的星期值(0~6)
8、getTime():         获取时间戳
9、Date():            单独使用,以字符串形式返回本地当前时间*/
//{Date}:Sat Apr 20 2019 13:51:24 GMT+0800 (中国标准时间)
var date = new Date();     
console.log(date.getFullYear());     //2019
console.log(date.getMonth());        //3
console.log(date.getDate());         //20
console.log(date.getHours());        //13
console.log(date.getMinutes());      //51
console.log(date.getSeconds());      //24
console.log(date.getMilliseconds()); //456
console.log(date.getDay());          //6
console.log(date.getTime());         //1555739379456(时间戳)
//"Sat Apr 20 2019 13:51:24 GMT+0800 (中国标准时间)"
console.log(Date());

//利用时间戳计算程序运行时间
var startTime = new Date().getTime();
for(var i = 0; i < 10000000; i++){
}
var endTime = new Date().getTime();
console.log(endTime - startTime );

//利用一元加减号获取时间戳
+new Date(); // 1556330809355
-new Date(); //-1556330809355
set方法
0、setFullYear(yyyy[,MM][,dd]): 设置四位数字的年份,返回调整后的时间戳
1、setMonth(MM[,dd]):           设置月份,返回调整后的时间戳
2、setDate(dd):                 设置日期,返回调整后的时间戳
3、setHours(HH[,mm][,ss][,ms]): 设置小时,返回调整后的时间戳               
4、setMinutes(mm[,ss][,ms]):    设置分钟,返回调整后的时间戳
5、setSeconds(ss[,ms]):         设置秒钟,返回调整后的时间戳
6、setMilliseconds(ms):         设置毫秒,返回调整后的时间戳
var date = new Date();
date.setFullYear(2019);
date.setMonth(3);       
date.setDate(20);              
date.setHours(14)           
date.setMinutes(5)
date.setSeconds(30)
date.setMilliseconds(16);
//Sat Apr 20 2019 14:05:30 GMT+0800 (中国标准时间)
console.log(date); 

定时器方法

setTimeout()

创建一个普通定时器,返回结果是一个纯数字(定时器的唯一标识)。该方法有两个参数,第一个参数是一个内部函数或一个字符串(可以当作js代码来执行),第二个参数是时间间隔,单位毫秒。普通定时器用来指定某个函数或字符串在指定毫秒数后执行。普通定时器创建出来后只会执行一次。普通定时器和循环定时器产生的唯一标识不会重叠,会顺序递增。

//格式一:参数1是一个函数
setTimeout(function(){ },1000); 
//格式二:参数1是一个字符串
setTimeout("console.log(1)", 1000);

setTimeout的第一个参数虽然可以是一个字符串,但这种形式会造成Javascript引擎解析两次,降低了性能,所以不建议使用。如果省略第二个参数,则该参数默认为0。setTimeout创建定时器时可以向内部函数中传递实参。

setTimeout((function(p1, p2){
    
})(1,1),1000);

var Timer = setTimeout(function(){
    console.log(Timer); //1,函数内部能识别到该定时器的返回值
});
clearTimeout()

清除指定的普通定时器。接受一个参数即普通定时器的唯一标识。

var timer = setTimeout(function(){}, 1000);
clearTimeout(timer);
setInterval()

创建循环定时器,返回结果是一个纯数字(定时器的唯一标识)。循环定时器和普通定时器用法完全一致。唯一不同是循环定时器每隔一段固定时间执行一次指定任务即无限次的定时执行。循环定时器的时间间隔只会识别一次。

var time = 1000;
setInterval(function(){ }, time); //时间间隔只识别一次
time = 2000; //不会改变定时器的时间间隔

//不是很准
var startTime = new Date().getTime();
setInterval(function(){
    var endTime = new Date().getTime();
    console.log(endTime - startTime);
    startTime = endTime;
},1000);
/*
    打印结果:
    999
    1000
    999
    1002
    ...
*/

clearInterval()

清除指定的循环定时器。接受一个参数即循环定时器的唯一标识

var timer = setInterval(function(){}, 1000);
cleatInterval(timer);

定时器运行机制

setTimeout(function(){
    console.log(1);
});
console.log(0);
/*
    返回结果:
    0
    1
*/

为什么0会出现在1的前面?

实际上,setTimeout的第二个参数设置为0ms,并不是立即执行函数的意思,只是把函数放入异步队列。浏览器先执行完同步队列里的任务,才会去执行异步队列中的任务。

setTimeout和setInterval两种类型的定时器在时间的控制上并不精确。它们的运行机制决定了时间间隔参数实际上只是自定时器被创建那一刻起到定时器任务代码被执行的最短等待时间。定时器被创建后,定时器的任务代码会被添加到执行队列,如果队列在定时器任务代码之前有其他任务,就要等到前面的任务完成后再执行定时器任务代码(任务代码执行的时间=其他任务执行时间+时间间隔参数)

btn.onclick = function(){
    setTimeout(function(){
        console.log(1);
    },1000);
}

上面例子中,点击事件设置了一个1000ms后调用的定时器。点击事件被触发时,首先将事件处理程序加入执行队列,该程序被执行后才会设置定时器,再过1000ms,定时器中的任务代码才会被添加到执行队列等待执行。如果点击事件的程序代码执行了2000ms,那么定时器的任务代码至少要在定时器设置后的2000ms后才会被执行。

setInterval()

使用循环定时器时,任务代码会被循环不断的添加到执行队列,仅当执行队列中该定时器的任务代码执行完后才能再次添加即同一时间执行队列中不会出现同一个定时器的任务代码。循环定时器的这种机制存在两个问题,其一某些间隔会被跳过,其二多个定时器任务代码之间的间隔可能比预期的小

迭代setTimeout
setTimeout(function fn(){
    console.log(1);
    setTimeout(fn,1000);
},1000);

为避免循环定时器存在的问题,可以使用迭代setTimeout的方式(链式setTimeout调用)。每次函数执行时创建一个与当前定时器执行函数相同的新定时器。这样做可以保证在前一个定时器任务代码执行完之前,不会向队列中插入新的定时器代码,确保不会有任何缺失的间隔。而且可以保证定时器任务代码执行之间等待指定间隔,避免计划外的连续执行

计时器小荔枝

<style type="text/css">
			input{
				border:1px solid rgba(0,0,0,0,8);
				text-align:right;
				font-size:20px;
				font-weight: bold;
			}
	</style>
</head>
<body>
	minutes:<input type="text" value="0">
	seconds:<input type="text" value="0">

	<script type="text/javascript">
		var minutesNode = document.getElementsByTagName('input')[0];
		var secondsNode = document.getElementsByTagName('input')[1];
		var minutes=0,seconds=0;
		timer = setInterval(function(){
			seconds ++;
			if(seconds == 60){
				seconds=0;
				minutes ++;
			}
			secondsNode.value=seconds;
			minutesNode.value=minutes;
			if(minutes===3){
				clearInterval(timer);
			}
		},10);


	</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值