函数就是对象
【1】、函数字面量即(函数表达式)包括四部分:
第一部分:保留字function;
第二部分:函数名称,可有可无;
第三部分:包围在一对小括号的一组参数,参数用逗号隔开;
第四部分:包围在一对花括号的一组语句,是函数的主体;
函数字面量可以出现在任何允许表达式出现的地方。
【2】、调用有四种调用模式:
除了声明时定义的形参,每个函数接收附加的的参数:this和arguments ,this的值取决于调用的模式.
第一种:方法调用模式:
var aa={
value:0,
increment:function(inc){
this.value+=typeof inc ==='number'?inc:1; //面向对象编程,方法里面就可以直接调用对象中的属性
}
};
aa.increment();
document.writeln(aa.value);//1
aa.increment(2);
document.writeln(aa.value);//3
第二种:函数调用模式:
function add(a,b)
{
return a+b;
}
aa.double1=function(){
var that=this; //把this赋值给一个变量
var hepler=function(){
that.value=add(that.value,that.value);
};
hepler();//以函数的形式调用helper
};
aa.double1();
document.writhln(aa.value); //aa.value,value在第一种方法中已经写了。结果为6,因为在第一种方法中,已经给value赋了值3,所以,3+3=6
第三种:构造器调用模式:
var Quo=function(string){
this.status=string;
};
Quo.prototype.get_status=function(){
return this.status;
};
var myquo=new Quo("confused");
document.write(myquo.get_status()); //confused
第四种:Apply调用模式:
apply()接收两个参数:第一个是将被绑定给this的值,第二个就是一个参数数组
var array=[3,4];
var sum=add.apply(null,array); //add是前面的第二种模式里面的add()
alert(sum);
var statusObject={
status:'OK'
};
var status=Quo.prototype.get_status.apply(statusObject);//上面get_status第三种模式里面创建了
document.write(status);//OK
【3】、参数--arguments类似于数字,但不是数组
var sum=function(){
var i,sum=0;
for(i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
};
document.write("<br/>"+sum(1,2,3,4,5));//可以添加任意数量的参数
【4】、返回--return语句
调用函数前面加上new前缀方式,且返回的结果不是一个对象类型,那么返回的就是这个对象的新对象
【5】、异常
var add=function(a,b){
if(typeof a!=='number'||typeof b!=='number'){
throw{ //该异常类型中的属性可以自定义
name:"TypeError",
message:"add needs number",
notice:"请注意看清楚类型"
};
}
return a+b;
};
var try_it=function(){
try{
add("seven");
}
catch(d){
document.write(d.name+":"+d.message+"<br/>"+d.notice);
}
};
try_it();
【6】、给类型增加方法
Function.prototype.method=function(name,func){
if(!this.prototype[name]){
this.prototype[name]=func;
}
return this;
};
Number.method('integer',function(){
return Math[this<0?'ceil':'floor'](this); //哈哈,我闹了一个笑话,就是总觉得是-4不是-3,-4<-3呀!别被带进去了
});
document.write((10/3).integer());
String.method('trim',function(){
return this.replace(/^\s+|\s+$/g,'');
/** /^\s+|\s+$/g 的解释就是:\s: space, 空格
+: 一个或多个
^: 开始,^\s,以空格开始
$: 结束,\s$,以空格结束
|:或者
/g:global, 全局
**/
});
document.write("<br/>"+'"'+" neat ".trim()+'"');
【7】、递归
var fat=function fac(i,a){
a=a||1;//这句代码的意思就是当a不存在的时候,取值1,也就是a=a?a:1
if(i<2)
{
return a;
}
return fac(i-1,a*i); //a*i的过程==> 1*4-->4*3-->12*2
};
document.write("<br/>"+fac(4));//24
【8】、作用域--缺少块级作用域,所以最好是在函数体的顶部把要的变量全部声明好
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
};
//此处,a=3,b=5,c为定义
bar();
//此处,a=21,b=5,c未定义
document.write("<br/>a:"+a+"<br/>b:"+b+"<br/>");
};
foo();
【9】、闭包
示例1:
//设置一个DOM节点的为黄色,然后把它渐变为白色,使得背景颜色渐变
var fade=function(node){
var level=1;
var step=function(){
var hex=level.toString(16);
node.style.backgroundColor='#FFFF'+hex+hex;
if(level<15)
{
level+=1;
setTimeout(step,500);
}
}
setTimeout(step,500);
}
fade(document.body);
示例2:
var add_the_handle=function(nodes){
var i;
for(i=0;i<nodes.length;i++){
nodes[i].click=function(i){
return function(e){
alert(e);
};
alert(nodes[i]);
}(i);
}
};
【10】、模块
示例1:
String.method('deentityfiy',function(){
var entity={
quot:'""',
lt:'<',
gt:'>'
};
return function(){
return this.replace(/&([^&;]+);/g,
function(a,b){
var r=entity[a];
return typeof r==='string'?r:a;
});
};
}());
document.write("<br/>"+'<>"'.deentityfiy());
示例2:生成唯一的序列号
var serial_maker=function(){
var prefix='';
var seq=0;
return{
set_prefix:function(p){
prefix=String(p);
},
set_seq:function(s){
seq=s;
},
gensym:function(){
var result=prefix+seq;
seq+=1;
return result;
}
};
};
var seqer=serial_maker();
seqer.set_prefix("Q");
seqer.set_seq(1000);
document.write("<br/>"+seqer.gensym());
【11】、级联
注意:启用了级联的Ajax类库,才会允许以下的编码形式
getElement('myBoxDiv') //id为myBoxDiv的DOM元素
.move(350,150)
.width(100)
.height(100)
.color('green')
.border('10px outset')
.padding('4px')
.appendText('Please stand by')
.on('mousedown',function(m){
this.startDrag(m,this.getNinth(m));
})
.on('mousemove','drag')
.on('mouseup','stopDrag')
.later(2000,function(){
this.color('yellow')
.setHTML('你有病吧?')
.slide(400,40,200,200);
})
.tip('This box is resizeable');
【12】、套用--将一个函数和传递给它的参数相结合产生一个新的函数
Function.method('curry',function(){
var sli=Array.prototype.slice,
arg=sli.apply(arguments), //使的arg拥有sli的slice中的concat方法
that=this;
return function(){
return that.apply(null,arg.concat(sli.apply(arguments)));
};
});
var add1=add.curry(1);//这里就是套用,add是之前写的一个两两相加的函数
document.write("<br/>"+add1(6));//7
【13】、记忆
var ss=function(n){
return n<2?n:ss(n-1)+ss(n-2);
};
for(var i=0;i<=10;i++){
//document.write("<br/>"+i+":"+ss(i));同下
}
var aa=function(){
var demo=[0,1];
var fab=function(n){
var result=demo[n];
if(typeof result!=='number'){
result=fab(n-1)+fab(n-2);
demo[n]=result;
}
return result;
};
return fab;
}();
for(var i=0;i<=10;i++){
//document.write("<br/>"+i+":"+aa(i));
结果是:0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
}
var memoizer=function(memo,fundamental){
var shell=function(n){
var result=memo[n];
if(typeof result!=="number"){
result=fundamental(shell,n);
memo[n]=result;
}
return result;
};
return shell;
};
var fibonacci=memoizer([0,1],function(shell,n){
return shell(n-1)+shell(n-2);
});
for(var j=0;j<=10;j++){
document.write("<br/>"+j+":"+fibonacci(j));//同上
}