异常
异常是干扰程序的正常流程的不寻常的事故,当发现这样的事故时,你的程序应该抛出一个异常:
var add = function(a,b){ if(typeof a!== 'number'||typeof b!== 'number'){ throw{ name:'TypeError', message:'add needs number' } } return a+b; } var try_it = function(){ try{ add("seven"); }catch(e){ document.writeln(e.name+':'+e.message); } } try_it();
?throw语句中断函数的执行,它应该抛出一个exception对象,该对象包括一个用来识别异常类型的name属性和一个描述性的message属性,还可以添加其他属性
该exception属性被传递到一个try语句的atch从句:
如果在try代码块内抛出一个异常,控制权跳转到catch从句。
一个try语句只会有一个捕获所有异常的catch代码块,如果异常处理手段取决于异常的类型,那么异常处理器必须检查异常对象的name属性来确定异常类型。
?
扩充类型的功能
javascript允许给语言的基本类型扩充功能,举例说我们可以给 Function.prototype增加方法来使得该方法对所有函数可用:
Function.prototype.method = function(name,func){ this.prototype[name] = func; return this; }
通过给Function.prototype增加一个method方法,我们下次给对象增加方法的时候就不用键入prototype这几个字符。
为Number类添加一个integer方法,它会根据数字的正负来判断使用Math.ceilig还是Math.floor
Number.method('integer',function(){ return Math[this<0?'ceil':'floor'](this); }); document.writeln((-10/3).integer());
?javascript还缺少一个移除字符串首尾空白的方法,这个小疏忽很容易弥补:
String.method('trim',function(){ return this.replace(/^\s+|\s+$/g,''); }); document.writeln('""'+" neat ".trim() + '""');
?另一个要注意的是for in
语句在原型上表现很糟糕,可以使用hasOwnProperty方法筛选出继承而来的属性
?
递归
递归函数就是会直接或者间接调用自身的一种函数。递归把一个问题分解为一组相似的子问题,每一个都用寻常解去解决,一般来说,一个递归函数调用自身去解决他的子问题
var hanoi = function(disc,src,aux,dst){ if(disc>0){ hanoi(disc-1,src,dst,aux); document.writeln('move dist'+disc + ' from ' + src +' to ' + dst); hanoi(disc-1,aux,src,dst); } }
?经典汉诺塔问题,结果
move dist1 from 起始柱 to 目标柱 move dist2 from 起始柱 to 中间柱 move dist1 from 目标柱 to 中间柱 move dist3 from 起始柱 to 目标柱 move dist1 from 中间柱 to 起始柱 move dist2 from 中间柱 to 目标柱 move dist1 from 起始柱 to 目标柱
?其他的递归例子
//定义walk_the_DOM函数,它从某个指定节点开始,按照html源码中的顺序 //访问该树的每个节点 //它会调用一个函数,并依此传递每个节点给他 //walk_the_DOM调用自身去处理每一个子节点 var walk_the_DOM = function walk(node,func){ func(node); node = node.firstChild; while(node){ walk(node,func); node = node.nextSibling; } }
?
//它以一个属性名称字符串和一个可选的匹配值作为参数 //调用walk_the_DOM,传递一个用来查找节点属性名的函数作为参数 //匹配结果累加到结果数组 var getElementsByAttribute = function(att,value){ var result = []; walk_the_DOM(document.body,function(node){ var actual = node.nodeType === 1&&node.getAttribute(att); if(typeof actual === 'string' && (actual === value||typeof value!=='string')){ result.push(node); } }); return result; }
?尾递归:在函数的最后执行递归调用的语句的特殊递归
?
作用域
在javascript中函数内的参数和变量在函数外是不可见的,在一个函数内部定义的变量,在函数内任何位置都可见,最好的做法是在函数体顶部声明函数中可能用到的所有变量
var foo = function(){ var a = 3,b = 5; var bar = function(){ var b= 7,c = 11; //a=3,b=7,c=11 a+= b+c; //a=21,b=7,c=11 } bar(); //a=21,b=5,a变了,b没变是因为a是全局的,而b是局部的 } foo();
?