昨天写了一个计时器,代码比较简单。效果图是这样的。
功能性描述:1.点击启动,倒计时开始。
2.点击取消,倒计时停止。
3.倒计时为00,00时,取消点击按钮。(这时点击效果无效)
代码如下。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>倒计时</title> <style type="text/css"> body{font:18px/1.5 arial;color:#fff;text-align:center;} .clock{width:280px;margin:0 auto;background:#000;padding:10px;} span{width:50px;height:50px;padding:5px;background:#fff;border:2px solid #ccc;margin:5px;color:#000;} input{width:283px;height:50px;background:url(btn-1.png) no-repeat;border:none;margin-top:10px;cursor:pointer;} </style> <script type="text/javascript"> var timer=null; var num=record=100; window.onload=function(){ var aSpan=document.getElementsByTagName("span"); var oBtn=document.getElementsByTagName("input")[0]; update(aSpan,num); var i=1; oBtn.onclick=function(){ if(i++%2==0){ clearInterval(timer); oBtn.style.backgroundPositionY="top"; } else{ low(aSpan,record); //问题发生点1 oBtn.style.backgroundPositionY="-50px"; } } } function update(ele,num){ ele[0].innerText=parseInt(num/60)<10?"0"+parseInt(num/60):parseInt(num/60); ele[1].innerText=num%60<10?"0"+num%60:num%60; } function low(aEle,num){ timer=setInterval(function(){ record=num--; //修正点1 if(num%60==0&&parseInt(num/60)==0) { clearInterval(timer); update(aEle,num); //问题发生点2 document.getElementsByTagName("input")[0].onclick=null; } else update(aEle,num); },1000) } </script> </head> <body> <div class="clock"> <span></span> 分 <span></span> 秒 <input type="button" /> </div> </body> </html>
问题发生点1:
第一次在写该函数调用时传的第二个参数是num,然后运行程序。发现每次点击启动取消后,倒计时都会重置为01分40秒。
问题发生点2:
倒计时开始后直到最后结束,定时器被清除。秒的显示区还是01秒。
问题核心所在:1.函数传参的理解有偏差
2.逻辑不严谨
1.函数参数误区
记忆中对函数参数是有所理解的,并且知道JavaScript函数传参只有一种传参方式(按值传)。但由于数据类型分为基本类型和引用类型,函数传参的本质上与这两种类型的复制是一样的。
误区示例:
var obj={"name":"Mr_White","age":"18"}; function test(value){ console.log(value); } test(obj.name);
因为name是obj的属性,所以误以为obj.name是引用类型数据。造成这种误解的主要原因是在写面向对象程序时常用this指代,并在this下挂各种方法和属性名。
2.逻辑不严谨
关于这点,个人感受是多练,多写,多想。
两种数据类型的复制(函数传参的本质)
var string="unchanged"; function baseTest(baseType){ baseType="changed"; console.log("里面的我是否变化"+baseType); } baseTest(string); console.log("外面的我是否变化"+string); var outMe={name:"White"}; function test(inMe){ console.log("里面的我已经指向外面白色的你"+inMe.name); inMe.name="Black"; console.log("在里面的我已经变黑"+inMe.name); return inMe; } test(outMe); console.log("外面的我是否变黑"+outMe.name);
这段代码能清晰看引用类型和基本类型作为参数传递的不同。
一些其他的感受:
1.越是精简的代码,蕴涵的东西越多。 2.技术需要沉淀,不浮躁,不急躁。 3.一个效果1000个写法 4.探索问题本质的能力一定不能丢