领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

第14节 Javascript函数-零点程序员-王唯

nixiaole 2024-11-25 15:48:18 知识剖析 14 ℃

函数对任何语言来说都是一个核心的概念;

函数是完成特定任务的可重复调用的代码段,是JavaScript组织代码的部分,其只定义一次,就可以被执行或调用任意次;

可以使用JavaScript内置函数,也可以自定义函数;

函数的功能:

函数的主要功能是可以封装任意多条语句,而且可以在任何地方任何时候调用执行;其本质就是将代码组织为可重复使用的部分,可以完成特定的任务并返回数据;其不会主动的运行,需要在程序中手动的调用函数(比如:用户点击的时候),并且可以多次调用;

好处:把程序划分为一些相对独立的部分,各部分充分独立,任务单一,易于维护;

定义函数:

在使用函数之前,必须先定义函数,函数定义的位置可以在任何位置;定义函数的方式有三种方式;

第一种:函数声明式,使用关键字function定义,语法:

function funcname([arg0,arg1,…,argn]) {

statements; // 就是被封装的代码块,称为函数体

[return 表达式;]

}

说明:funcname是函数名,圆括号中的arg是参数列表,参数之间使用逗号分隔;函数体使用花括号;定义的函数不会自动执行,必须经过调用,如:

function showMsg(str){
    console.log("零点程序员" + str);
}
showMsg("开新课了");

函数的命名规则:不能使用保留字,要使用有意义的名称;

function square(x,y){
    return Math.sqrt(x*x + y*y);
}
console.log(square(3,4));  // 5

第二种函数定义方式:

函数本质上是一个对象,该对象是Function类型的实例,因此可以使用Function对象的构造函数来创建一个函数,并被保存在一个变量(函数名)中;其和其他引用类型一样具有属性和方法;由于函数是对象,所以函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。

除了可以被存储在变量中,还可被保存在数组以及对象的属性中,甚至可以作为参数进行传递。

语法:

var 变量名 = new Function(“[形参1]”, “[形参2]”,…”代码体”);

所有的参数必须是字符串;最后一个参数是程序代码语句;

var myFn = new Function("x","y","var sum;sum=x+y;return sum;");
alert(myFn(2,3));

注:从技术角度来说,这就是以下要所说的函数表达式定义方法;不推荐这种方法定义,因为这种方法会导致解析两次代码(第一次是解析常规的ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能;但这种方式有助于理解“函数是对象,函数名是指针(变量)”的概念;

注:此种定义方法的作用是可以动态创建函数;

第三种:函数表达式:

可以直接把定义函数保存在变量中;该变量名实际上就是函数名;

语法:

var myFun=function([参数1,[参数2],…]){

[语句组;]

}

var sum = function(num1,num2){return num1 + num2;};
alert(sum(2,3));

说明:function后面没有函数名,因为没有必须使用函数名,因为myFun变量就要以引用该函数;另外,这种定义函数的方式的末尾有一个分号;

由于函数名仅仅是指向函数的指针,所以可以把函数赋值给多个变量,也就是说,一个函数可能会有多个名字;如:

function sum(num1,num2){return num1+num2;}
var anotherSum = sum;
alert(anotherSum(10,20));  // 30
sum=null;
alert(anotherSum(10,20));  // 30

说明,不能带括号,带括号就代表执行了;此时anotherSum和sum就都指向了同一个函数,因此,anotherSum也可以被调用;即使sum设为null,让它与函数“断绝关系”,anotherSum仍然可以正常调用。

var condition = false;
if(condition){
     function sayHi(){alert("Hi");};
}else{
    function sayHi(){alert("OK");};
}
sayHi();

说明:这种写法在以前会出现许多意想不到的效果;

var sayHi;
var condition = true;
if(condition){
    sayHi = function(){alert("Hi");};
}else{
    sayHi = function(){alert("OK");};
}
sayHi();

函数声明与函数表达式的区别:

函数声明与函数表达式的区别的就在于声明的位置上不同;

解析器在执行环境中加载数据时,会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等解析器执行到它所在的代码行,才会真正被解释执行,如:

alert(sum(2,3));
function sum(num1,num2){return num1+num2;}

说明:以上代码正常运行;因为在代码开始执行之前,解析器就已经通过一个名为函数声明提升(function declaration hoisting)的过程,读取并将函数声明添加到执行环境中;对代码求值时,Javascript引擎在第一遍会声明函数并将它们放到源代码的顶部;所以,声明函数的代码在调用它的代码后面也没有问题;

但函数表达式,就不可以;

alert(sum(2,3));
var sum = function(num1,num2){return num1+num2;}

说明:会产生错误,原因是在于函数位于一个初始化语句中,而不是一个函数声明;换句话说,在执行到函数所在的语句之前,变量sum中不会保存有对函数的引用;而且,由于第一行代码就会导致错误,实际上也不会执行到下一行;

注:两者除了以上的区别,其他都是等价的。

注:也可以同时使用函数声明和函表达式,如:

var sum = function othersum(num1,num2){return num1+num2;}
alert(sum(2,3));

注:没有意义,并且有些浏览器会导致错误;

定义有参函数:

函数是用来完成一个功能的,但是有时需要有其他数据的参与才能完成某些功能,比如,需要计算两个数的和,就需要把这两个数作为参数传递到函数中去。如:

function sum(num1,num2){return num1+num2;}
alert(sum(2,3));

说明:函数的参数是函数与外界交换数据的接口。外部的数据通过参数传入函数内部进行处理,同时函数内部的数据也可以通过参数传到外界;

形式参数:

写在函数定义中,出现在函数名的圆括号()里,就是形参,如:

function 函数名字(形式参数1,形式参数2…){

// 处理代码

}

function showMsg(str){
    document.write(str);
}

说明:如果仅仅是这样的话,没有什么意思,可以改写一下:

使用函数参数的目的是很多的,比如,根据参数输出多行多列的数据:

function printStar(row,col){
    for(var i=1;i<=row;i++){
        for(var j=1;j<=col;j++){
            document.write("*");
        }
        document.write("<br/>");
    }
}
printStar(3,5);

函数调用:

函数定义后,就可以调用;

可以在程序代码中调用,也可以在事件响应中调用,还可以通过链接调用;

语法:

函数名([实参1,实参2,…,实参n])

说明:函数名要与定义函数名相同; 实参的类型,个数,意义及次序原则要与形参相同; 无参数时( )不能省略;

showMsg();  //无返回值调用
showMsg("你好");  //无返回值,有参数调用
var str=showMsg();  //有返回值;

实参的个数多于形参,则忽略多余的实参;

实参的个数小于形参,则将没有接收传递值的参数赋undefined;

对于函数的调用,如果该函数成为一个对象的成员属性,那么就称之为方法的调用;如果使用关键字new的形式调用,称为构造函数调用;另外,也可以间接调用;这些内容今后的课程会讲到。

函数返回值:

如果函数执行的结果需要被其他语句使用,就需要函数的返回值,可以使用return让函数返回一个值;

function 函数名(形参1,形参2){

// 处理语句;

return 返回值;

}

function sum(num1,num2){
    return num1 + num2;
}
function sum(num1,num2){
    return num1 + num2;
    alert("zero"); // 永远不会执行;
}
var result = sum(5,10);
function diff(num1,num2){  // 一个函数中也可以包含多个return语句
    if(num1 > num2){
        return num1 - num2;
    }else{
        return num2 - num1;
    }
}

注:return只能使用在函数中;

函数在执行完return语句之后停止并立即退出;

函数返回值既可以赋值给变量,也可以参与表达式运算;

返回值类型:一般与return返回表达式类型一致,如果不一致,以函数类型为准.

注:return 语句也可以不带有任何返回值;在这种情况下,函数在停止执行并返回undefined值;这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下,如:

function say(){
    return ;
    alert("hi");
}

练习:

// 输出对象的属性和值
function printPro(o){
    for(var p in o)
        console.log(p + ":" + o[p] + "\n");
}
var person = {name:"wangwei",age:18,sex:"男",say:function(){}};
printPro(person);

// 计算两个笛卡尔坐标(x1,y1)和(x2,y2)之间的距离
function distance(x1,y1,x2,y2){
    var dx = x2 - x1;
    var dy = y2 - y1;
    return Math.sqrt(dx * dx + dy * dy);
}
console.log(distance(0,0,3,4));

//  封装一个表格函数
function getTable(n,m){
    var table = document.createElement("table");
    for(var i=1; i<=n; i++){  // 行
        var tr = document.createElement("tr");
        for(var j = 1; j<=m; j++){
            var td = document.createElement("td");
            td.innerHTML = " ";
            tr.appendChild(td);
        }
        table.appendChild(tr);
    }
    return table;
}
document.body.appendChild(getTable(4,5));

嵌套函数:

在Javascript中,函数可以嵌套在其他函数中,即要函数体内定义新的函数,如:

function outerFunc(){
    var i = 0;
    function innerFun(){
        console.log(i);
    }
    innerFun();
}
outerFunc();

嵌套函数只能在内部调用,外部无法使用;内部函数可以访问嵌套它们的函数的参数和变量,即变量的作用域,后面的课程会专门深入。


Tags:

最近发表
标签列表