javascript”面向對象編程”- 3 function是方法(函數)

      在進行編程時,必免不了要碰到複雜的功能。初學者最怕複雜的功能,因爲不能夠很好的進行功能邊界劃分,只能一大串if、循環加case堆疊在一起,結果出來的程序自己看着暈,別人看着更暈。好程序不是寫給computer的,而是寫給human的。遇到複雜功能,應該想着把它簡化、組件化,把小功能封裝成小組件,小功能塊可以任意的組合得到千變萬化的複雜功能。function就可以幫助我們把功能進行封裝。那什麼是封裝呢。要我說,只要把具體實現給打包,對外提供調用接口那就是封裝,方法也好、類也好就做了這些事。

      javascript中的function可以用來創建方法、也可以用來創建類,實際上我們可以認爲是用function來模擬出的類(說到類一般都會要去了解閉包的知識)。還是先看一下方法吧。

       javascript函數分爲有名函數、匿名函數和在匿名函數基礎上延伸出來的立即執行函數。

       普通函數就是用function直接聲明的有名函數。

        function Hello() {
            alert("hello , everybody!");
        };
 
        Hello();
 
        function SayHelloTo(somebody) {
            alert("hello , " + somebody + "!");
        };
 
        SayHelloTo("張三");

<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>       上面分別創建了Hello和SayHelloTo方法。Hello不帶有參數,直接通過Hello()來完成調用。SayHelloTo方法帶有一個參數,向誰問候時需要知道是在問候誰。在調用SayHelloTo(“張三”)時要傳入參數。這些代碼和java、C#都沒有什麼太大區別。在方法重載上卻有較大改變,javascript本身並不支持什麼重載,一個方法名就對應一個方法。如果強制的寫出多個同名方法,其實會出現先寫的方法被覆蓋掉的情況。

        function Hello() {
            alert("hello , everybody!");
        };
 
        Hello();
 
        function Hello(somebody) {
            alert("hello , " + somebody + "!");
        };
 
        Hello("張三");
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

 

               image image

      第一個Hello方法被覆蓋掉,執行時直接調用Hello()則認爲調用第二個Hello方法但沒有傳遞參數值,所以彈出了undefined信息。調用Hello(“張三”)時很正常的完成執行。其實javascript也可以用一些直白的方式來完成重載。學過C#的人都會知道有個params關鍵字,通過它可以實現向方法傳遞不定個數的參數。我們可以通過對參數的信息做手動的判斷也可以模擬出類似重載的效果。而在javascript中根本就不需要什麼params關鍵字,就可以很自然的實現任意個數參數的傳遞。function中有個arguments屬性,可以把它看成一個數組,它按傳遞進來的參數的順序來保存所有的參數。也就是說我們在定義方法時可以不聲明參數名。

        function ShowArguments() {
            var args = "";
            for (var i = 0; i < arguments.length; i++) {
                args += arguments[i] + ",";
            };
            alert(args.substr(0, args.length - 1));
        };
 
        ShowArguments(1, 2, 3, 4, 5, 6, 7);
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

          image
      試着用argements來模擬一下重載。

        function Hello() {
            if (arguments.length == 0) {
                alert("hello , everybody!");
            }
            else {
                alert("hello , " + arguments[0] + "!");
            };
        };
 
        Hello();
        Hello("張三");

<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>       基於參數個數不同的重載。

        function Increase(arg) {
            if (typeof arg == "undefined") {
                alert("請輸入參數");
            }
            if (typeof arg == "string") {
                alert(String.fromCharCode(arg.charCodeAt(0) + 1));
            }
            if (typeof arg == "number") {
                alert(arg + 1);
            }
        };
        Increase();
 
        Increase("a");
        Increase(1);
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>       基於參數類型不同的重載。

      函數除了有名函數之外也可以是匿名函數,匿名函數就是沒有名子的函數,不論函數有名還是沒有名子,都是一個完整的函數對象。匿名函數還是用function來聲明,但不用爲它指定名稱。其它的方面,比如參數等等和有名函數沒什麼區別。

        function() {
            ……
        };
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      匿名函數一般可以滿足臨時的函數需求,不需要有變量對其進行引用(有名的函數可以認爲是有變量引用的函數)。比如需要一個函數做爲值對象做爲參數傳入方法、需要編程的方式爲對象添加事件,用匿名函數都可以很好的完成。當然你也可以單獨聲明變量來引用某個匿名函數對象,這和普通有名函數就沒什麼區別了。

        function Each(array, fun) {
            for (var i = 0; i < array.length; i++) {
                fun(array[i]);
            };
        };
        var nums = [1, 2, 3, 4, 5, 6, 7];
        Each(nums, function(arg) {
            alert(arg);
        });
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      上面代碼執行,依次輸出數組中的元素。

        //在窗體加載時,在標題上顯示當前時間
        window.onload = function() {
            document.title = new Date().toString();
        };
 
        //也可以將匿名方法傳入定時器中
        setInterval(function() {
            document.title = new Date().toString();
        }, 1000);
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      使用匿名函數綁定事件和進行定時操作。

        var Hello = function() {
            alert("hello , everybody!");
        };
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      如果將匿名函數賦給變量,那和有名的普通函數就沒區別了。但不管是變量引用還是普通地有名函數,這樣的函數在內存上都持久的佔有一定資源。有時候我們只想執行一次大不必使用有引用的函數,直接執行匿名函數可能是最好的選擇。把匿名函數包起來,加個括號執行,一切ok,這就是由匿名函數延伸出來的立即執行函數。

        (function() {
            alert("hello ,  everybody!");
        })();
 
        (function(somebody) {
            alert("hello , " + somebody + "!");
        })("張三");
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      立即執行函數在做事件綁定,設置回調函數等方面往往會有意想不到的效果,可以解決諸如對象引用等問題。

        var student = {
            Name: "張三",
            Age: 20,
            Introduce: function() {
                alert("我叫" + this.Name + ",今年" + this.Age + "歲了!");
            } };
        window.onload = (function(obj) { return function() { obj.Introduce(); }; })(student);
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      因爲javascript中函數的這些特點加之它的對象的特徵,我們還可以寫出一些有functional意味的程序出來。其實javascript中function真的是老大。

        function Sum(fun, x) {
            if (x <= 0)
                return 0;
            return fun(x) + Sum(fun, x - 1);
        };
  
        alert(Sum(function(i) { return i * i; }, 100));
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      下面這又是什麼呢?是方法嗎?是類嗎?

        function Point() {
            
        };
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

      先囉嗦到這,下次再看看類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章