1.函数功能:将代码组织为可复用的单位,可以完成特定任务并返回数据
2.函数定义:
JaveScript中函数属于Function对象,因此可以使用Function对象的构造函数来创建一个函数(变量方式),同时也可以使用function 关键字以普通的形式定义一个函数(普通方式)
a.函数的普通定义方式,使用关键字function(最常用的方式)
function 函数名(参数1,参数2...){
语句组;
return 表达式;
}
function必选项,定义函数用的关键字;
函数名:必选项,合法的JavaScript标识符;
参数:可选项,合法的JavaScript标识符,外部数据通过参数传送到函数内部;
语句组:可选项,为空时函数没有任何动作
return:可选项,遇到此指令函数执行结束并返回,如果省略该项函数将在右花括号处结束
表达式:可选项,其值作为函数返回值
<script language="JavaScript">
function sum(a,b){ <!--求和函数-->
return a+b;
}
var a=3;
var b=4;
var c=sum(a,b);
alert("a 和 b 的和是 " + c);
</script>
复杂代码
代码先判断传入的两个参数是否符合要求,如果参数为空或有数字以外的符号则抛出异常,否则计算两个参数的和
<body>
<script language="JavaScript">
function Sum(a,b){ <!--求和函数-->
var arg1=new String(a);
var arg2=new String(b);
if(arg1==""||arg2==""){
var e0=new Error();
e0.Serial=1000001;
if(arg1==""){
e0.message="sun函数参数非法:第一个参数为空!";
}
else{
e0.message="sun函数参数非法:第二个参数为空!";
}
throw e0;
}
for(i=0;i<arg1.length;i++){
for(j=0;j<10;j++){
if(arg1.charAt(i)==j)break;
else{
if(j==9){
var e1=new Error();
e1.Serial=1000001;
e1.message="sum函数参数: "+arg1+"是非法数字!";
throw e1;
}
}
}
}
for(i=0;i<arg2.length;i++){
for(j=0;j<10;j++){
if(arg2.charAt(i)==j)break;
else{
if(j==9){
var e2=new Error();
e2.Serial=1000001;
e2.message="sum函数参数: "+arg2+"是非法数字!";
throw e2;
}
}
}
}
return Number(arg1)+Number(arg2);
}
function Button1_onclick(){
try{
var Text1=document.getElementById("Text1");
var Text2=document.getElementById("Text2");
var Text3=document.getElementById("Text3");
var sum=Sum(Text1.value,Text2.value);
Text3.value=sum;
}
catch(e){
alert(e.message);
if(e.Serial==1000001){
alert(e.message);
e=null;
}
}
}
</script>
<input id="Text1" type="text" style="width:84px" maxlength="20"/>
+<input id="Text2" type="text" style="width:75px" maxlength="20"/>
=<input id="Text3" type="text" style="width:69px"/>
<input id="Button1" type="button" value="计算" onclick="return Button1_onclick()"/> <!--按钮-->
</body>
b.函数的变量定义方式
以定义变量的方式定义函数,JavaScript中所有函数都属于Function对象,于是可以使用Function对象的构造函数来创建一个函数
var 变量名=new Function(参数1,参数2,函数体);
变量名:必须项,代表函数名,要求是合法的JavaScript标识符
参数:可选项,作为函数参数的字符串,必须是合法的标识符,如果函数没有参数可省略该项
函数体:可选项,一个字符串,相当于函数体内的程序语句序列,各语句使用分号隔开,当忽略此项时函数不执行任何操作
<body>
<script language="JavaScript">
var calArea=new Function("r","return Math.PI*r*r");
var r=2;
var area=calArea(r);
alert("半径为" + r + "的圆的面积为 " + area);
</script>
</body>
3.函数的指针调用方式(通常是用在自己定义功能而由第三方去实现的场合)
<html>
<head>
<title>JavaScript练习</title>
</head>
<body>
<script language="javascript">
function SortArray(obj,func){
if(!(obj instanceof Array) || !(func instanceof Function)){
<!--检查参数正确性-->
var e=new Error();
e.number=100000;
e.message="参数错误";
throw e;
}
for(i in obj){
for(j in obj){
if(func(obj[i],obj[j])){
var temp=obj[i];
obj[i]=obj[j];
obj[j]=temp;
}
}
}
return obj;
}
function greatThan(arg1,arg2){
return arg1>arg2;
}
try{
var numArray=new Array(5,8,6,32,1,45,7,25);
document.write("<li>排序前: " + numArray);
SortArray(numArray,greatThan);
document.write("<li>排序后: " + numArray);
}
catch(e){
document.write(e.number+" "+e.message);
}
</script>
</body>
</html>
SortArray函数并没有定义给数组排序的功能,greatThan函数实现比较两个数大小的功能,并作为参数传给函数SortArray,在 SortArray函数中通过
函数指针调用比较大小函数,并定义了异常处理功能(检测传入的两个参数是否是数组类型和函数类型)。
4.函数参数
函数参数是函数与外界交换数据的接口,外部数据通过参数传入函数内部进行处理,同时函数内部的数据也可以通过参数传到 外界(形式参数、实际参数),JavaScript的函数参数信息由arguments对象管理
5.关于arguments对象
arguments对象代表正在执行的函数和调用它的参数,函数对象的length属性说明函数定义时指定的参数个数,arguments对象 的length属性说明调用函数时实际传递的参数个数,arguments对象不能显示创建,函数在被调用时由JavaScript运行时环境创 建并设定各个属性值
通常使用arguments对象来验证所传递的参数是否符合函数要求
<html>
<head>
<title>JavaScript练习</title>
</head>
<body>
<script language="javascript">
function sum(arg1,arg2){
var len1=sum.length; <!--保存函数参数个数-->
var len2=arguments.length; <!--保存实际参数个数-->
if(len1>len2){ <!--实际传入的参数个数小于函数要求参数个数-->
var e=new Error();
e.number=100000;
e.message="实际参数个数不符合要求";
throw e;
}
return arg1+arg2;
}
try{
document.write("<p><h1>arguments对象测试</h1></p>");
document.write("正确调用的结果: " + sum(10,20));
document.write("<br>不符合规则的调用结果: ");
document.write(sum(10));
}
catch(e){
alert(e.message);
e=null;
}
</script>
</body>
</html>
尽可能地在通用函数中检查参数是否符合要求
6.函数的返回类型
a.值类型(返回数据本身的副本,相当于复制了一份传递出去) 一般来说,函数返回的非对象数据都使用值传递返回方式
如上面例子中计算两个值的和时使用值传递方式,通常该方式使用在返回的数据量比较小时,数据量比较大时使用引用类型的 返回方式
b.引用类型(返回数据地址,而非数据本身)通常返回复合类型数据时使用引用传递方式
<script language="javascript">
function createArray(){
var list=new Array(1,2,3,4,5);
return list;
}
var newlist=createArray();
document.write("创建的数组是: " + newlist);
newlist=null;
</script>
上面代码中函数createArray()创建一个数组对象list并将其地址(引用)返回,变量newlist将获得数组对象list的一个引用,使用 newlist=null断开
变量newlist对数组对象的引用,使用newlist=null操作将删除数组对象
值传递和引用传递的区别在于前者将数据的值复制传递,后者仅传送数据的地址
7.返回函数
函数可以返回一个函数指针,外部代码可以通过指针调用其引用的函数对象,调用方式和一般函数完全一样,一般情况下私有 函数不能被外界直接访问, 因此可以将私有函数的地址作为结果返回给外界使用
<script language="javascript">
function getSum(){
function sum(a,b){
return a+b;
}
return sum;
}
var getfunc=getSum(); <!--获得sum函数的指针-->
var result=getfunc(1,2);
alert("1 + 2 = " + result);
</script>
上面代码中函数getSum()将其内部的函数sum()的地址当做返回值返回,通过调用getSum()可以得到sum()函数的指针并赋给 getfunc变量,然后通过getfunc变量调用sum()函数
8.函数分类
a.构造函数
类用于创建新对象的函数,一般在该函数中对新建的对象做初始化工作,JavaScript是基于对象而不是真正面向对象的语言,它 没有类的概念,完成一个对象"类"的定义仅需要定义一个构造函数即可
<script language="javascript">
function Employee(name,sex,age){ <!--构造函数-->
this.name=name;
this.sex=sex;
this.age=age;
this.getName=getName; <!--方法,取得姓名-->
}
function getName(){ <!--定义普通函数作为Employee对象的方法-->
return this.name;
}
var employee=new Employee("Alice","F",18);
alert(employee.getName() + " " + employee.sex + " " + employee.age);
</script>
b.有返回值的函数(函数执行结束时将有一个结果返回给调用者的函数)
c.无返回值的函数(函数执行结束后不返回结果)
9.函数作用域
10.公有函数(定义在全局作用域中,每一个代码都可以调用的函数)
<script language="javascript">
function getType(obj){
return typeof(obj);
}
function fruit(name,price){
if(getType(price)!="number"){
var e=new Error();
e.number=100000;
e.message="price is not a number";
throw e;
}
this.name=name;
this.price=price;
}
try{
var apple=new fruit("apple",10);
alert(apple.name + " " + apple.price);
}
catch(e){
alert(e.message);
}
</script>
函数getType()处于顶级作用域,任何代码都可以调用它
11.私有函数
处在局部作用域中的函数,当函数嵌套定义时,子级函数就是父级函数的私有函数,外界不能调用私有函数,私有函数只能被 拥有该函数的函数代码调用
<script language="javascript">
function a(){
function b(){
function c(){
document.write("<li>C");
}
document.write("<li>B");
}
document.write("<li>A");
b(); <!--a的代码调用a的私有函数-->
c(); <!--a的代码尝试调用b的私有函数,将发生一个错误-->
}
a(); <!--在外部调用函数a-->
</script>
运行结果:
A
B
(并没有报错)
上面代码中定义了处于顶级作用域的函数a(),其内又定义了一个私有函数b(),函数b中又定义了属于它的函数c(),函数a()调用它的 私有函数b()是正确的,a()尝试调用函数b的私有函数c()结果引发一个错误
12.this关键字
引用上下文中的当前对象,如果没有指定当前对象,则调用函数的默认当前对象是Global,使用call方法可以改变当前对象为指 定的对象
<script language="javascript">
var chair="公园里的椅子"; <!--公物,谁都可以用-->
function TomHome(){
this.chair="Tom家的椅子";
}
function useChair(){ <!--使用椅子-->
document.write("<li>此时使用的椅子是: " + this.chair + "<br>"); <!--输出当前椅子信息-->
}
var tom=new TomHome();
useChair(); <!--当前所在场景是公园里-->
useChair.call(tom); <!--当前所在场景是Tom家-->
</script>
全局变量chair属于Global对象的属性,第一次使用默认的当前对象调用useChair()函数(因为没有指明当前对象),Global对象被 默认使用,于是产生的效果是使用公园里的椅子,而接下来指定了当前对象,this指向Tom家的tom,于是Tom家的椅子被使用this 关键字极其重要,使用时必须确定当前上下文对象是什么