转载请注明来源:http://blog.csdn.net/caoshiying?viewmode=contents。这篇文章针对的是有2年以上编程经验的朋友们参考的,作参考资料之用,不从基础讲起。
1.1.1. 函数字面量
函数字面量包括四个部分,第一部分是关键字,第二部分是函数名,把函数赋值给一个对象的时候可以省略函数名。第三部分是圆括号包括起来的一组参数,第四部分是函数的主体。
函数字面量可以出现在任何允许表达式出现的地方,也可以被定义在其它函数中。内部函数可以访问自己的参数和变量,也可以访问嵌套它的函数与变量。通过函数字面量创建的函数对象包含一个连到外部的上下文的连接。这被称为闭包。
JavaScript中函数就是对象。每个函数对象在创建时带有prototype和constructor属性。它既可以像普通对象一样使用,又可以调用它的函数。
调用一个函数将中断当前函数的执行。除函数声明定义的参数,每个函数都有两个附加的参数:this和arguments。this的值取决于调用模式。JavaScript函数一共有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。
函数调用符是跟在任何产生一个函数值的表达式之后的一对圆括号。圆括号内可以包含0个或者1个或者用逗号隔开的多个参数。参数不会进行类型检查。
1.1.2. 匿名闭包
匿名闭包是让一切成为可能的基础,而这也是JavaScript最好的特性,我们来创建一个最简单的闭包函数,函数内部的代码一直存在于闭包内,在整个运行周期内,该闭包都保证了内部的代码处于私有状态。范式:
(function(){ . . . . . . })();
或者
(function(){ . . . . . . }());
临时使用的不属于任何类型的函数和变量建议都放进匿名闭包中。
1.1.3. 方法调用模式
当一个函数被保存为对象的一个属性时,我们称之为方法。this是调用函数的对象。示例工程:J431。
var student1={ value:0,increment:function(inc){ this.value+=typeofinc == "number" ? inc :1; } }; student1.increment(); document.writeln(student1.value); document.write("<br/>"); student1.increment(10); document.write(student1.value);
1.1.4. 函数调用模式
当函数不是一个对象的属性时,我们称之为函数。这个调用模式下this的值是全局对象,内部函数无法通过this访问嵌套它的函数对象。有一个解决方法是在调用内部函数之前在函数对象中增加一个成员记录this,然后内部函数用记录this的成员变量访问this。示例工程:J432。
var student1={ name:"李婷",getName:function () { functionwriteInformation() { console.log(this); document.write(typeofthis.name+","+this.name); document.write("<br/>"); } writeInformation(); } }; var student2={ name:"李婷",getName:function() { varthat=this; functionwriteInformation() { console.log(that); document.write(typeofthat.name+","+that.name); document.write("<br/>"); } writeInformation(); } }; student1.getName(); student2.getName(); document.write("---------------------分隔线-----------------------<br/>"); varStudentClass=function () { this.name="李婷"; var that=this; functiongetName1() { console.log(this); document.write(typeofthis.name+","+this.name); document.write("<br/>"); } functiongetName2() { console.log(that); document.write(typeofthat.name+","+that.name); document.write("<br/>"); } this.getName=function(){ getName1(); getName2(); } } var student=newStudentClass(); student.getName();
1.1.5. 构造器调用模式
这个模式的关键在于用函数声明类型后用类型的prototype的属性定义函数。示例工程:J433。
varStudentClass=function (s) { this.status=s; } StudentClass.prototype.getStatus=function() { returnthis.status; } var student=new StudentClass("很好"); document.write(student.getStatus());
1.1.6. Apply调用模式
这种模式的关键在于调用不属于任何对象的函数是不直接调用函数本身,而是调用函数的apply成员函数。示例工程:J434。
var student1={ name:"李婷",age:22,getDescription:function(){ varparams=[this.name,this.age]; functionwriteDescription(name,age) { vars="我叫"+name+",我今年"+age+"岁了。"; console.log(this); document.write(s); } writeDescription.apply(null,params); } }; student1.getDescription();
1.1.7. 私有成员
闭包的一个重要作用是保护私有成员不被外部随意更改,增加程序的可控性与可靠性与可阅读性。全局变量与全局函数JavaScript程序的一大弊端。与Java相比,JavaScript可以借用生命周期模拟出私有成员变量与私有成员方法,方法是在声明它们的时候不与this绑定。对象的公有方法可以调用私有方法。示例程序:J410。
var fade=function(node) { var level=1; var step=function () { varhex=level.toString(16); node.style.backgroundColor="#FFFF"+hex+hex; if(level<15){ level+=1; setTimeout(step,200); } } setTimeout(step,200); }; fade(document.body); varstudent=function () { var value=0; return { increment:function(inc){ value+=typeofinc == "number" ? inc : 1; },getValue:function() { returnvalue; },name:"李婷" }; }(); student.increment(); document.write(student.getValue()); document.write("<br/>"); student.increment(10); document.write(student.getValue()); document.write("<br/>"); document.write(student.name);
1.1.8. 回调(Callbacks)
回调的思想是把函数作为参数传递给另外一个函数,另外一个函数通过回调可以把它的参数传递给当前函数,这个函数在访问当前上下文的同时可以访问另外一个函数发回的值。典型的回调是setTimeout。
1.1.9. 模块(Module)
模块是一个提供接口却隐藏状态与实现的函数或者对象。可以使用函数或者闭包构造模块。通过模块可以降低JavaScript全局变量带来的负面影响。示例工程:J412。
String.prototype.deentityify=function() { var entity={ quot:"\"",lt:"<",gt:">" }; var that=this; return function() { returnthat.replace(/&([^&;]+);/g,function (a,b) { varr=entity[b]; returntypeof r === 'string' ? r : a; }); }(); }; document.write("<">".deentityify());
1.1.10.级联(Cascade)
varStudentClass=function () { this.name="李婷"; this.age=22; this.mark=100; this.writeName=function(){ document.write(this.name); document.write("<br/>"); returnthis; }; this.writeAge=function(){ document.write(this.age.toString()); document.write("<br/>"); returnthis; }; this.setName=function(name){ this.name=name; returnthis; } this.setAge=function(age){ this.age=age; returnthis; } }; var student=newStudentClass(); student. writeName(). writeAge(). setName("你好"). setAge(21). writeName(). writeAge();
1.1.11.套用(Curry)
套用指的是一个函数返回自己的时候,接收返回值的对象保存了原来的函数的状态。它的调用可以基于原来的函数的状态继续执行。示例工程:J414。
var add=function (){ var value=0; var func=null; vargetValue=function (inc) { value+=typeofinc == "number" ? inc : 1; document.write(value.toString()+"<br/>"); returnfunc; } func=getValue; returngetValue; } varfunc1=add(10);//此时没有运算 curry1=func1(10); curry2=curry1(10); console.log(func1); console.log(curry1); console.log(curry2);
1.1.12.记忆(Memoization)
函数可以用对象去记住先前的操作结果,从而避免无谓的运算。这种优化被称为记忆。示例工程:J415。
varfibonacci=function (n) { return n < 2? n : fibonacci(n - 1) + fibonacci(n - 2); }; for(vari=0;i<=10;i++){ document.write(fibonacci(i).toString()+"<br/>"); }