javascript函數的定義與調用以及參數傳遞

案例:菱形的輸出

分析:有多種思考方式,但最關鍵的問題是獲得空格與行號的關係,星號與行號的關係。第一種:行號爲正三角行的行數,總行數實際上是2row-1

<script>

var row = Number(prompt("請輸入行數(奇數)"));

for(var i=1; i<=2*row-1; i++) {

    var blanks = Math.abs(row - i);//空格的個數

    var stars = 2 * row - 1 - 2 * blanks;//星號個數

    for (var j = 1; j <= blanks; j++) {

        document.write(" ");

    }

    for (var k = 1; k <= stars; k++) {

        document.write("*");

    }

    document.write("<br>");

}

</script>

這裏的思路是空格與星號有關係,因爲列數是固定的。

另外一種菱形的行數與實際行數相同,使用函數

var blanks = Math.abs((row+1)/2 - i);//空格的個數

var stars = row - 2 * Math.abs(i - (row+1)/2);//星號個數

函數

6.1函數

爲什麼需要用函數?

首先看看輸出100以內所有素數問題的解決方案

方案一:循環的嵌套

for(var i=2; i<=100; i++){

var flag = true;

        var m = Math.ceil(Math.sqrt(i));//根據相關數學定理

if(i>2){

        for (var j = 2; j <= m; j++) {

            if (i % j == 0) {

                flag = false;

            }

        }

}

        if(flag){

document.write(i+”<br>”);

}

}

這種解決方案程序比較複雜,閱讀也比較困難,需要比較高超的技術。

方案二:運用函數

<script>

    /*

    * 假設系統已經提供了一個判斷素數的函數isPrime(x),那麼問題是不是就特別簡單

    * */

    for(var i=2; i<=100; i++){

        if(isPrime(i)){

            document.write(i+"<br>");

        }

    }

    function isPrime(x){

        var m = Math.ceil(Math.sqrt(x));//根據相關數學定理

        If(x>2){

        for (var i = 2; i <= m; i++) {

            if (x % i == 0) {

                return false;

            }

        }

}

        return true;

    }

</script>

這種解決方案是將一個比較複雜的問題分解爲兩個較爲簡單的問題去解決,實際上是用“量”去克服“難”和“大”的問題。也就是“大事化小”。

這種解決方案給我們提供了一個解決規模大、難度高的問題的解決思路:將它分解爲多個規模相對較小、難度相對較低的問題去解決,如果分解後的問題仍然規模到或者難度高,可以按照這個思路一種分解下去,直到分解後的問題足夠小、簡單。

6.2定義與調用

函數是什麼,怎麼用?

定義:

function isPrime(n) {

……

}

function定義函數的關鍵字

isPrime是函數的名字,和變量名一樣的命名規則和原則

n形式參數(形參)

isPrime(12),12就是實際參數(實參)

函數頭部:體現的是函數的設計

函數體:體現的是函數的實現過程

設計比實現更重要

案例:驗證100以內的數都符合角谷定理

<script>

    var flag = true;

    for(var n=2; n<=100; n++){

        if(!isJiaogu(n)){

            flag = false;

            break;

        }

    }

    alert("角谷定理驗證"+(flag?"成功":"失敗"));

    function isJiaogu(n){

        while(n != 1){

            if(n%2 == 0){

                n /= 2;

            }else{

                n = n*3+1;

            }

        }

        return true;

    }

</script>

    功能:判斷一個數是否符合角谷定理

    名稱:isJiaogu

    輸入參數:待判斷的數

    輸出結果:true/false

案例:驗證10000以內哥德巴赫猜想成立

<script>

    var flag = true;

    for(var i=8; i<=10000; i+=2){

        if(!canSplit(i)){

            flag = false;

            break;

        }

    }

    alert("哥德巴赫猜想驗證"+(flag?"成功":"失敗"));

 

    function canSplit(n){

        for(var a=2; a<=n/2; a++){

            if(isPrime(a) && isPrime(n-a)){

                return true;

            }

        }

        return false;

    }

    function isPrime(x){

        var m = Math.ceil(Math.sqrt(x));//根據相關數學定理

if(x>2){

        for (var i = 2; i <= m; i++) {

            if (x % i == 0) {

                return false;

            }

        }

}

        return true;

    }

</script>

假設系統有一個函數能幫我們判斷大於6的偶數能否分解的

設計一下該函數

功能:判斷一個數能否分解爲兩個素數之和

名稱:canSplit

輸入參數:待分解的數

返回結果:true/false

那麼如何實現這個函數呢,好像還是不夠簡單,那就繼續分解

如果系統有一個能判斷素數的函數,那麼這個問題也簡單

設計

功能:判斷一個數是否爲素數

名稱:isPrime

輸入參數:待判斷的數

輸出結果:true/false

函數的本質:直觀理解就是實現某個獨立功能的代碼段,或者說它就是一個數據加工的黑箱子

輸入參數 輸出結果

所謂“黑箱子”,就是我們只關心外面的東西,比方說它是幹啥的,需要輸入什麼,可以得到什麼結果,而不關心裏面是怎麼工作的。

忽略實現細節

6.3參數傳遞

所謂參數傳遞,就是將實參的值傳遞給形參。通過調試可以確定形參在函數被調用之前是不存在的,當函數被調用的那一刻,形參被創建,並且把實參的值傳遞給形參。

參數傳遞有兩種方式:值傳遞和引用傳遞

<script>

    var a = 5;

    increase(a);

    alert(a);

    function increase(x){

        x++;

    }

</script>

a的值並沒有顯示預期中的6,還是5,。因爲形參x和實參a是兩個不同的變量,x的變化和a沒有任何關係。

<script>

    /*引用傳遞*/

    var a = new Object();

    a.value = 5;

    increase(a);

    alert(a.value);

    function increase(x){

        x.value++;

    }

</script>

a.value沒有被顯示修改,但是a.value確實是加1了,因爲x就是a,或者說x是a的別名,專業一點就叫引用。

常規類型的參數採用的是值的殘敵,比如Number、String、Boolean

對象類型採用的是引用傳遞,Object。

如果希望把參數從函數中帶出來,但是函數的返回值只有一個

6.4變量的作用域

局部變量:在函數內部定義的變量,這個變量只能夠在函數的內部使用,在全局中不能夠使用。比如在三國時期,袁術稱帝后,只有袁術陣營的人才認爲他是皇帝,他發佈的命令只有在本陣營裏面起作用。但是其他人不認爲他是皇帝,他發佈的命令沒有作用。

    function LocalVar(){

        var a = 1;

        alert(a);

    }

LocalVar();

alert(a);

全局變量:在函數外部定義的變量,這個變量可以在全局進行使用。比如漢朝的皇帝發佈了命令,那麼不管是袁紹還是曹操都要聽這個命令。

vara = 1;
function allVar(){
    alert(a);
}
allVar();

衝突處理原則:就近原則。

當函數中定義了一個和全局變量名相同的變量,此時在函數中在定義前使用,那麼這個變量還是函數中的變量,爲undefined,不使用全局變量。

要理解就近原則,而不是從上到下。

vara = 1;
function doubleVar(){
    var a= 2;
    var a= 3;
    alert(a);
}

局部和全局同時定義了一個相同的名字的變量,如何在局部裏面訪問全局變量?在局部中給變量加上window的前綴,就可以訪問到全局的變量。

<script>

    var a = 1;

    function allVar(){

        var a = 2;

        var a = 3;

        //alert(a);

        alert(window.a);

    }

    allVar();

</script>

 注意:在函數內部定義一個變量,如果沒有加上var,那麼這個變量被認作爲全局變量。

<script>

    function LocalAllVar(){

        a = 1;

    }

    function test(){

        alert(a);

    }

    LocalAllVar();

    test();

    alert(a);

</script>

發佈了35 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章