JS 函数和参数的传递

来源:互联网 发布:m1头盔淘宝 编辑:程序博客网 时间:2024/06/06 00:27

6函数

 

6.1函数的概念:

    为什么要用函数?

定义:function  isPrime(n){

·············

}

定义名时一定要见名思意

Function:是定义函数的关键字

IsPrime:是函数的名字,和变量名一样的命名规则和原则。

N:形式参数(形参)。

Isprime(12):12这个数字就是实际参数(实参)。

函数头部:体现的是函数的设计。

函数体:体现的是函数过程。

设计比实现更重要。

    首先看一下输入一百所有的素数的问题的解决方案

方案一:

/*
*将麻烦的结构分开来写,可以降低难度,复杂性。
* 创建一个调用结构,调用下面的函数
* */
for(varn=2;n<=100;n++){
    if(isPrime(n)){
        document.write(n+"<br>");
    }
}
/*自己创建一个判断素数的函数,然后供其他的调用
* 以下就是创建的函数:
* */
functionisPrime(n){
    var m=Math.ceil(Math.sqrt(n));
    var found=false;
    for(vari=2;i<=m;i++){
        if(n%i==0){
            return false;
        }
    }
    return true;
}

 

这种解决方案是讲一个复杂的问题分解为两个较为简单的问题去解决了,使用“量”去克服“难”和“大”的问题。也就是“大事化小”。

这种解决方案给我们提供了一个解决大规模,高难度的问题的解决思路:把它分解为多个规模较小的、难度较低的问题去解决,如果分解后的问题仍然复杂,规模大难度高,可以按照这个思路一直将其分解下去,直到问题足够简单。归纳起来就是“大事化小”。

案例:验证100以内的数都符合角谷定理(案例二)。

var flag=true;
for (var n =2; n <=100; n++) {
    if (!isJiaogu(n)) {
        flag = false;
    }
}
alert("角谷定理验证"+ (flag ? "成功": "失败"));
/*切记:要分优先级,加上括号,不然同级的输出会被覆盖掉*/
/*
 *
功能:判断一个给定的数是否符合角谷定理
 *
名称:isjiaogu
 *
输入参数:待判断的数
 *
输出结果:true/false
 * */

function isJiaogu(n) {
    while (n != 1) {
        if (n % 2 == 0) {
            n /= 2;
        } else {
            n = n * 3 + 1;
        }
    }
    return true;
}

案例:验证10000以内的哥德巴赫猜想成立。

/*
 * 假设系统有一个能帮我们判断大于6的偶数能否分解的函数
 * 设计一下该函数
 *
 * 功能:判断一个数是否能分解为两个素数之和
 * 名称:canSplit
 * 输入参数:待分解的数
 * 返回结果:true/false
 * */
flag = true;
for (varn = 6;n <= 10000; n += 2) {
    if(!canSplit(n)) {
        flag = false;
        break;
    }
}
alert("哥德巴赫猜想验证:"+ (flag ? "成功": "失败"))

/*
 * 那么如何实现这个函数,好像还是不够简单,那么就继续分解
 * 如果系统有一个能判断素数的函数,那么这个问题也简单
 * 功能:判断一个数是否为素数
 * 名称:isPrime
 * 输入参数:带判断的数
 * 输出结果:true/false
 * */
function canSplit(n){
    for(vara = 2;a <= n / 2; a++) {
        if(isFinite(a)&&isFinite(n-a)){
            returntrue;
        }
    }
    returnfalse;
}

 函数的内容,本质:

1、         

函数名

 

直观:就是实现某个独立功能的代码段。或者说他是个数据加工的黑箱子。(尽量不要使用全局变量,不然影响其独立性)

输入参数                        输出结果

    所谓的黑箱子,就是我们只关心外面的东西,比如说他是干啥的,需要输入什么,可以得到什么结果,而不关心里面是怎么工作的。

6.3参数的传递:

所谓的参数传递,就是将实参的值传递给形参。通过调试可以确定形参在函数调用之前是不存在的,当函数被调用的那一刻,实参被创建,并且把实参的值传递给形参。

参数传递的两种方式:值传递和引用传递(地址传递)

值传递:

var a=5;

increase(a);
alert(a);
function increase(x){
    x++;
}

a的值没有显示预期的6,还是5,因为形参x和实参a是两个不同的变量,x的变化和a没有变化。

值传递:

/*引用传递*/
var a = new Object();
a.value=5;
increase(a)
alert(a.value)

function increase(x){
    x.value++;
}

a.value没有被显示修改,但是a.value确实加1了,因为x就是a,或者说x是a的别名,专业一点就叫引用。

常规类型的参数采用的是值传递:比如:Number,String,Boolean

对象类型采用的是引用传递:Object。

如果希望把参数从函数中带出来,但是函数的返回值只有一个。

 

 

6.4变量作用域

局部变量:在函数内部定义的变量,这个变量只能够在函数的内部使用,在全局中不能使用。就比如在三国时期,袁绍称帝后,只有它的自己人才认为他是皇帝,它的命令只有在自己阵营里起作用,但其他(曹操)人不认同他,那么袁绍的命令就不会对曹操生效。

        /*局部变量*/
/*   function allvar() {
        var a = 1;
        alert(a);
    }
    allvar();
    alert(a);*/

全局变量:在函数外部定义的变量这个变量可以在全局进行使用。又比如,三国的汉朝的皇帝发布命令,无论是曹操还是孙权,都必须听命令。

    /*全局变量*/
/*    var a = 1;
    function allvar(x) {
        alert(a);
    }
        allvar(a);*/

 

冲突处理原则:就近原则

局部和全局同时定义一个相同的名字的变量时如何在局部里面访问全局变量?

在局部中给变量加上window的前缀,就可以访问到全局变量。

当函数定义了一个和全局变量相同的变量,此时在函数中再定以前使用那么曾格格变量还是函数中的变量,为underline,不使用全局变量。

/*变量就近原则*/
    /*
     var a = 1;
     function allvar() {
     var a=2;
     var a=3
     alert(window.a);/!*取函数外的a*!/
     alert(a);
     }
     allvar();

要理解就近原则,不要以为从上到下。

 

 

在函数内部定义一个变量,如果没有用var,那么这个变量则默认是全局变量。

    function local(){
         a=1;
/*如果在局部变量中写一个var的变量,
那么它是局部变量,不加,默认为是全局变量*/
   
}
    local();
    alert(a);