JavaScript基础知识(9)

本文深入探讨JavaScript中日期对象的使用方法与注意事项,包括日期计算、格式化及跨浏览器兼容性问题。同时,介绍了Number、Boolean等内置对象的高级应用,以及函数对象的多种定义方式、模拟重载技巧、匿名函数的应用场景和闭包的设计原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 回顾:
 Date对象:内部封装一个毫秒数
 创建日期对象:
 var date=new Date("2015/6/9");PPT上的横线“-”仅兼容chrome,其他浏览器是不能用!!!
 API:
 1.每个分量都有一对儿get/set方法
 2.命名:年月日星期,不带s;时分秒,带s
 3.值范围:月中的日:1-31
           其他:0-减1

 计算:
 1.两日期相减,得到毫秒数
 2.日期+/-天小时分秒:用毫秒算
    3步:1.var ms=data.getTime();得到毫秒数
         2.ms=ms+/-毫秒数; 得到新的毫秒数
         3.var newDate=new Date(ms);   封装
 3.任意分量的计算:
 先取出分量值,然后做计算,再set回去!注意set方法会直接修改原日期对象


 var now=new Date();
 //先取出分量,做计算,set回去
 var d=now.getDate();   //取出多少号,date是日期
 d+=3;   //3天后
 now.setDate(d);
 console.log(now);


 set方法可以根据日期自动调整时间,不用管是什么值。另外,set方法可以直接修改原日期对象

 如何保留原日期对象?先new出新Date对象,再set
 如:
 var now=new Date();
 var next=new Date(now.getTime());  //now.getTime()得到的是一个毫秒数,要使用函数new Date()将next设置为一个日期对象
 var d=now.getDate();   //取出多少号
 d+=3;   //3天后
 now.setDate(d);  //怎么取出,就怎么set回去
 console.log(now);
 console.log(next);

 例:
 var now=new Date("2012-6-29");
 var next=new Date(now.getTime());
 var year=next.getFullYear();
 year+=3;
 next.setFullYear;
 console.log("到期时间:"+next)

 例:
 var hire=new Date("2012/6/30");
 hire.setFullYear(hire.getFullYear()+3);
 document.write("到期时间"+hire+"<br/>"); 
 hire.setMonth(hire.getMonth()-1);
 //判断是否是周末,如果周六需要提前一天,周日需要提前两天
 if(hire.getDay()==6){       
 hire.setDate(hire.getDate()-1);
 }
 else if(hire.getDay()==0){
 hire.setDate(hire.getDate()-2);
 }
 document.write("续签时间"+hire+"<br/>"); 
 hire.setDate(hire.getDate()-7);
 document.write("提醒时间"+hire+"<br/>");

 日期格式转换:在不同浏览器中显示格式是不一样的,在实际中都要自定义format方法来实现日期格式转换。
 date.toLocaleString();  //获得日期和时间的本地格式
 date.toLocaleDateString();  //仅获得日期部分的本地格式
 date.toLocaleTimeString();  //仅获得时间部分的本地格式


 上述例子可以调用日期格式化方法来输出想要的格式:
 var hire=new Date("2012/6/30");
 hire.setFullYear(hire.getFullYear()+3);
 document.write("到期时间"+format(hire)+"<br/>"); 
 hire.setMonth(hire.getMonth()-1);
 if(hire.getDay()==6){
 hire.setDate(hire.getDate()-1);
 }
 else if(hire.getDay()==0){
 hire.setDate(hire.getDate()-2);
 }
 document.write("续签时间"+format(hire)+"<br/>"); 
 hire.setDate(hire.getDate()-7);
 document.write("提醒时间"+format(hire)+"<br/>");
 //自定义日期格式化方法
 function format(date){
 var week=['日','一','二','三','四','五','六'];
 var y=date.getFullYear()+"年";
 var m=date.getMonth()+1+"月";
 var d=date.getDate()+"日";
 var w=" 星期"+week[date.getDay()];
 //12:00:00.000将上午和下午分开
 var h=date.getHours();
 var am=h>=12?" 下午 ":" 上午 ";
 h>12?h-12:h;
 h=h<10?"0"+h:" "+h;   //三目运算
 var mi=date.getMinutes();
 mi=mi<10?"0"+mi:" "+mi;
 var s=date.getSeconds();
 s=s<10?"0"+s:" "+s;
 var str=y+m+d+w+am+h+":"+mi+":"+s;
 return str;
 }

 今后可直接调用自定义日期格式:
 function format(date){
 var week=['日','一','二','三','四','五','六'];
 var y=date.getFullYear()+"年";
 var m=date.getMonth()+1+"月";
 var d=date.getDate()+"日";
 var w=" 星期"+week[date.getDay()];
 //12:00:00.000
 var h=date.getHours();
 var am=h>=12?" 下午 ":" 上午 ";
 h>12?h-12:h;
 h=h<10?"0"+h:" "+h;
 var mi=date.getMinutes();
 mi=mi<10?"0"+mi:" "+mi;
 var s=date.getSeconds();
 s=s<10?"0"+s:" "+s;
 var str=y+m+d+w+am+h+":"+mi+":"+s;
 return str;
 }

 调用:console.log(format(new Date()));

 Number对象:专门封装数字原始类型的
 var num=Number(5);  -->字符串类型转换,结果仍然是原始类型
 var num=new Number(5);  -->创建对象,创建的额结果是引用类型

 Number对象API:
 num.toFixed(n):按n位小数四舍五入,返回一个字符串
 Math.round(num):只能取整。返回一个数Number

 一般在计算中时不toFixed的,否则会变成字符串。何时使用toFixed:计算之后,显示结果时,最后调用toFixed方法。

 num.toString(n):按n进制输出数字的字符串格式,不写n的时候默认是10进制输出

 var str="张";
 var code=str.charCodeAt(0);
 document.write(code.toString(2)); //按2进制输出,二进制从右往左数,每8位一字节,一个汉字两个字节。


 boolean对象:
 new和不new的区别就是,new创建了方法,不new就是类型转换


 错误处理:
 什么是错误:导致程序运行停止的运行时异常状态。
 什么是错误处理:在出现异常状态时,保证程序不停止的机制。

 如何错误处理:
 EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError
 错误类型:Error类型,是所有错误对象的父类型
 6种子类型:EvalError
 RangeError:代表参数超出范围,比如num.toFixed(n),n取值是0~20,如果超出范围都会抛出RangeError。注意,这不是数组越界,数组越界是不会出错的,会自动扩容的。
 ReferenceError:引用错误,即找不到对象,只要使用未声明的变量时,都抛出ReferenceError
 SyntaxError:语法错误,修改源代码就可以解决。
 TypeError:错误的使用了类型和类型的方法。
 URIError:URI错误

 如何处理错误:
 try{
 可能出错的代码
 }catch(err){
 只要抛出错误,都会创建一个Error对象
 错误处理的代码
 }finally{
 无论是否出错,都必须执行的代码
 }
 释放对象时,要放到finially里面。finally是善后,不加也没事的。在语法中,finally是可有可无的额,但是如果在程序中使用了大对象,一定要在finally中主动释放。


 try里面是可能出错的代码
 catch里面是错误处理的代码:1.获得错误的信息:err.message-->各个浏览器错误信息不一样,且含义晦涩难懂;err.name-->获得错误的类型
 2.根据错误的类型,执行不同的处理
 finally里面是无论是否出错,都必须执行的代码

 如果不出错,则try-finally;如果出错,则try-catch-finally

 如果将“对象=null”放在try里面,可能会由于在出错代码后面而无法执行,但是放在finally里面,则不论是否出错都会执行


 例:
 var str="no zuo no die";
 var reg=/no/g;
 var arr=str.match(reg);
 document.write("共找到"+arr.length+"个");//如果arr==null,此时.length就会出错

 改进方案:
 var str="no zuo no die";
 var kw=prompt("search");
 var reg=new RegExp(kw,"g");
 var arr=str.match(reg);
 //try包裹的范围要越小越好
 try{
 document.write("共找到"+arr.length+"个");  //如果arr==null,此时.length就会出错
 }catch(err){
  if(err.name=="TypeError"){
 document.write("没找到");
 }
 }finally{
 arr=null;
 reg=null;
 kw=null;
 str=null;
 console.log("释放对象");
 }



 能用if...else解决的问题,就尽量不要用try...catch!
 何时使用try catch?try catch处理的是无法预料的问题!
 try catch一般只能接住异常,但是如果想要主动抛出异常(框架中会用到),如何告知方法调用者出错?通过throw new Error("自定义的错误信息")


 Function对象:
 两种定义方法:
 1.以声明方式定义方法:可以在使用前定义
 function 方法名(参数列表){方法体;return 返回值}
 2.以创建对象方式定义方法:只能在使用后定义
 var 方法名=new Function("参数1",...."方法体;reurn 返回值")

 例:
 function compare(a,b){
 return a-b;
 }  //变量声明和方法声明提前。提前到当前作用域的顶端。
 var arr=[1,22,31,123,13,3];
 arr.sort(compare);   //sort可直接修改数组
 document.write(arr);

 下面方法function要先声明才能使用,放在后面就会出错
 var compare=new Function("a","b","return a-b"){
 return a-b;
 }
 var arr=[1,22,31,123,13,3];
 arr.sort(compare);   //sort可直接修改数组
 document.write(arr);

 在js中一切都是对象。

 重载:一个方法,根据传入的参数列表不同,执行不同的任务
 比如:function jz(money){
 //现金结账:验钞,找零
 }
 function jz(cardId,pwd){
 //刷卡结账:验证卡号,验证密码
 }
 jz(300); ——》根据传入的参数来执行不同的任务

 js中语法是不支持重载的,但是可以用arguments对象去模拟!!!


 <script>
 //如果给1个参数,就执行平方
 function calc(n){
 alert(n*n);
 }
 //如果给2个参数,就执行加法
 function calc(n,m){
 alert(n+m);
 }
 </script>

 <button onclick="calc(13)">算平方</button>  //这个不能正常执行
 ,其实执行的是13+undefined
 <button onclick="calc(13,45)">算加法</button>



 <script>
 var calc=new Function("n",alert(n*n)");
 var calc=new Function("n","m","alert(n+m)");
 </script>
 <button onclick="calc(13)">算平方</button>  //这个不能正常执行
 ,其实执行的是13+undefined
 <button onclick="calc(13,45)">算加法</button>

 arguments对象:方法对象中,保存所有参数的类数组对象。
 类数组对象(object like array):长的像数组的对象,不是数组,但
 是可以当数组使用
 arguments.length:保存变量的个数
 arguments[i]:访问传人的第i个变量
 arguments方法是在方法内,自动创建的,可以直接使用!




 修改第一步:
 <script>
 function calc(){
 //arguments
 if(arguments.length==1){
 alert("算平方");
 }else{
 alert("算加法");
 }
 }
 </script>
 <button onclick="calc(13)">算平方</button>  //这个不能正常执行
 ,其实执行的是13+undefined
 <button onclick="calc(13,45)">算加法</button>

 修改第二步:
 <script>
 function calc(){
 //arguments
 if(arguments.length==1){
 var n=parseFloat(arguments[0]);
 alert(n*n);
 }else{
 var n=parseFloat(arguments[0]);
 var m=parseFloat(arguments[1]);
 alert(n+m);
 }
 }
 </script>
 <button onclick="calc(13)">算平方</button>  //这个不能正常执行
 ,其实执行的是13+undefined
 <button onclick="calc(13,45)">算加法</button>


 所有方法都要有参数,但是遇到极特殊情况,需要使用模拟时,可以不
 用参数。arguments方法不是任何情况下都可以用的。


 例:
 function add(){
 var sum=0;
 for(var i=0;i<arguments.length;i++){
 var n=parseInt(arguments[i]);
 sum+=n;
 }return sum;
 }
 document.write(add(5,7,9,4,6,9));



 就页面加载中就已经顺序执行的,document.write是没有问题的,但是
 在页面加载流关闭之后,又在按钮中打开的,此时不能用
 document.write,否则会另开一个新流,前面所有的都会被清掉


 JavaScript中创建函数的三种方式:
 使用function
 使用
 使用直接量方式创建函数(使用匿名函数赋值的方式定义方法):

 匿名函数:没法方法名的函数的定义,本身也是个对象,

 js中创建方法的三种方式:
 function(a,b){return a-b;}   -->这个就是匿名方法
 var compare=function(a,b){return a-b;} 
 var compare=new Function("a","b","a-b;")-->圆括号里面参数和方
 法体必须用引号!
 第一种方式放前面后面都可以,但是下面两种方式必须写在使用之前

 例:
 function isEmpty(str){
  if(str==undefined){
    return true;
  }else if(str==null){
    return true;
   }else{
     var reg=/^\s*$/;    //正则表达式验证,验证不加g
     return reg.test(str);
    }
 }
 while(true){
   var input=prompt("输入");
   if(!isEmpty(input)){
     document.write("<br/>"+input);
     break;
    }else{
     alert("输入不能为空!");}
 }


 例:
 var ltrim=function(str){
    var reg=/^\s+/;     ///匹配前空格,不加g,只用替换一个
    return str.replace(reg,"");   
 }
 var rtrim=function(str){
    var reg=/\s+$/;     ///匹配后空格
    return str.replace(reg,"");   
 }



 匿名函数2个用途:
 1.回调函数:函数何时执行,程序员不需要控制,由所在环境自动调用
 执行!
 比较器是最典型的回调函数:
 function(a,b){return a-b;} --》调用arr.sort(compare);
 直接将匿名函数作为对象传进来:arr.sort(function(a,b){return
 a-b;});
 事件处理函数:都是回调函数,onclick="calc(13)"
 2.自调函数:匿名函数自己调用自己。
 当函数不需要重复使用时,使用匿名函数自调。
 语法:
 (function(参数...){
   方法体;
 })(参数值);
 在函数定义时立即执行!

 例:
 (function(){
 console.log("it begin...");
 })();   //写个匿名函数,然后用圆括号括起来,立即调用


 函数如果不重用可以用匿名函数,如果要反复利用,就得命名


 闭包:
 变量作用域:程序中定义这个变量的区域,通俗的讲就是变量可以使用
 的范围


 var n=0;  //全局变量
 function getUnique(){
   var n=0;
   return ++n;
 }
 console.log(n);  //n为0,全局变量
 console.log(getUnique());  //n为1

 在方法内声明的变量和方法的参数,都是局部变量。

 作用域链:一般方法没有嵌套的话,作用域链里面存的是两个活动对象,一个是自己的活动对象,一个是window的。如果有嵌套的话,还有个是指向方法的父级。
 链条自下向上记录着每一级可用的东西
 每个函数被调用时,都会创建一个环境变量。

 例:获得不重复的序号
  var n=0; 
  function getUnique(){
   return n++;
  }
 console.log(getUnique()); //这样调用只能在全局变量里面找n
 console.log(getUnique());
 n=0;   //修改了n的值,会对下面的输出结果造成影响
 console.log(getUnique());
 console.log(getUnique());



 //为使n只能被getUnique使用,需要将二者进行封装
 function counter(){
  var n=0;   //如果放在getUnique里面,每次都会从0开始,导致功能无法实现
  function getUnique(){
   return n++;
  }
  return getUnique;  //这个getUnique不用加圆括号,只是将方法作为对象传递
 }
 var c=counter();  //c中保存的是可以执行的方法对象。counter里面有三个对象。counter后面加圆括号,因为需要将这个方法立即执行,将执行的结果返回给c
 console.log(c()); //此时不能直接调用getUnique了,要使用c
 console.log(c());
 n=0;   //从来没声明过,会自动声明为全局。修改n的值,不能改变方法里面的n值
 console.log(c()); //虽然又有n=0,但是对输出结果是不会造成任何影响的
 console.log(c());  //c后面不加圆括号就变成传值了,但是此处是需要调用方法的,只要调用方法就要用到圆括号
 c=null;    //释放闭包占用的资源!
 c=counter(); 
 console.log(c());   //释放了c之后再重新创建活动对象,旧值就会丢失,会将counter方法重新读一遍,得到的结果是0



 var c=counter();的原理和var counter=function()是一样的,c是一个方法。c指向的是getUnique()环境

 方法名后何时加圆括号?调用方法,立即执行,就加();将方法作为对象传递,不加()

 闭包:函数外使用了不属于自己的局部变量,这种现象就叫作闭包。
 何时使用闭包?保护局部变量时使用。

 上述例子中,只要将c=null,所有对象都会被释放,但是如果只是释放counter的话,闭包就会一直使用。

 闭包三个特点:
 1.得有局部变量:定义全局变量会造成全局污染
 2.得有函数的内嵌
 3.外部使用,即内嵌的函数外部调用

 对象和闭包,都是为了尽量不使用全局的变量,避免全局污染。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值