回顾:
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.外部使用,即内嵌的函数外部调用
对象和闭包,都是为了尽量不使用全局的变量,避免全局污染。