JavaScript中的方法、方法引用和參數


首先,我們來看一段代碼,如果覺得不甚明白的,則本文會對你有益:

    var player = function (e) {
            return (function f(m) {
                return m ? (function (n) {
                    return $('#Player', n).get(0) || f($('iframe', n).get(0));
                })(m.contentWindow.document) : null;
            })($(e).get(0));
        };

該段代碼涉及到的知識點包括:方法、匿名方法、匿名方法的立即執行、JQuery對象及Dom對象的互轉等。現在,我們回過頭來從基礎的出發,爭取對於JavaScript中的方法、方法引用和參數弄得概念清楚一些。

一:示例代碼

首先,先看測試代碼:

<!DOCTYPE html>
<head>
</head>
<body>
    <script src="scripts/jquery.min.js"></script>
    <script language="javascript">
        window.console.log("=================================");
        var p0 = function (e) {
            window.console.log("self:" + e);
        };
        p0("outp0");
        var A = new p0("p0");

        window.console.log("=================================");
        var p00 = function (e) {
            window.console.log("self:" + e);
            return function f(m) {
                window.console.log("newo:" + m);
            };
        };
        var B = new p00("outp00B");
        B("BB");
        var C = new B("outp00C");
       
       
        window.console.log("=================================");
        var p01 = function (e) {
            window.console.log("self:" + e);
            return (function f(m) {
                window.console.log("newo:" + m);
            })("p01");
        };
        var D = new p01("outp01D");
       
        window.console.log("=================================");
        var p1 = (function (e) {
            window.console.log("self:" + e);
        })("p1");

        window.console.log("=================================");
        var p11 = (function (e) {
            window.console.log("self:" + e);
            return function (m) {
                window.console.log("newo:" + m + e);
            };
        })("p11");
        p11("outp11_2");
        var E = new p11("outp11");
       
        window.console.log("=================================");
        var p12 = (function (e) {
            window.console.log("self:" + e);
            return {
                p121: function (m) { window.console.log("newo:" + m); },
                p122: function (options, fn) {
                    fn(e + options);
                }
            };
        })("p12");
        p12.p121("outp121");
        p12.p122("outp122", function (e) {
            window.console.log("invoker:" + e)
        });
    </script>
</body>
</html>

該代碼的執行結果為:

=================================
self:outp0
self:p0
=================================
self:outp00B
newo:BB
newo:outp00C
=================================
self:outp01D
newo:p01
=================================
self:p1
=================================
self:p11
newo:outp11_2p11
newo:outp11p11
=================================
self:p12
newo:outp121
invoker:p12outp122

 

二:示例代碼的講解

1:對象,即 new

由於 p0 是一個 function,所以可以被 new,function 本身就相當於構造器了。不過過因為 p0 本身內部沒有參數、方法或者 return,所以 A 基本沒什么用處。

image

由於 p00 return 一個 function,所以 B 可以執行自己,即被調用;
        B("BB");
上面說了,由於 B 是一個 function,所以可以被 new

image

 

2:匿名方法及立即執行

p01 return 的本身是一個立即執行的匿名方法,
於是很不幸,D 本身變成什么也不是了,以下代碼不能執行
   D("DD");
不同於 B,B 是 function 本身,所以可以執行:

image

 

p1 是定義了一個匿名方法,並立即執行它,並且說明也沒返回(或者說返回 null),所以:
      1: p1 即不能被 new ,即 new p1();
      2: 也不能執行,即 p1();

image

p11 定義了一個匿名方法,並且立即執行了它,同時返回了一個方法,所以
         1:p11 本身就代表了這個被 return 的方法,所以可被執行,即 p11("x");
         2:因為 p11 本身是 function,故可以 new
image


現在,為了便於查看,上一個加了注釋的版本:

<!DOCTYPE html>
<head>
</head>
<body>
    <!--<iframe id="m">abc</iframe>-->
    <script src="scripts/jquery.min.js"></script>
    <!--<script src="temp.js"></script>-->
    <script language="javascript">
        window.console.log("=================================");
        var p0 = function (e) {
            window.console.log("self:" + e);
        };
        p0("outp0");
        // 1:由於 p0 是一個 function,所以可以被 new,function 本身就相當於構造器了;
        // 2:不過因為 p0 本身內部沒有參數、方法或者 return,所以 A 基本沒什么用處;
        var A = new p0("p0");

        window.console.log("=================================");
        var p00 = function (e) {
            window.console.log("self:" + e);
            return function f(m) {
                window.console.log("newo:" + m);
            };
        };
        // 構造器就是 p00 這個方法本身;
        var B = new p00("outp00B");
        // 由於 p00 return 一個 function,所以 x 可以執行自己,即被調用;
        B("BB");
        // 上面說了,由於 x 是一個 function,所以可以被 new
        var C = new B("outp00C");
       
       
        window.console.log("=================================");
        var p01 = function (e) {
            window.console.log("self:" + e);
            return (function f(m) {
                window.console.log("newo:" + m);
            })("p01");
        };
        // p01 return 的本身是一個立即執行的匿名方法,
        // 於是很不幸,D 本身變成什么也不是了,以下代碼不能執行
        //   D("DD");
        // 不同於 B,B 是 function 本身,所以可以執行
        var D = new p01("outp01D");
       
        window.console.log("=================================");
        // p1 是定義了一個匿名方法,並立即執行它,並且說明也沒返回(或者說返回 null),所以:
        // 1: p1 即不能被 new ,即 new p1();
        // 2: 也不能執行,即 p1();
        var p1 = (function (e) {
            window.console.log("self:" + e);
        })("p1");

        window.console.log("=================================");
        var p11 = (function (e) {
            window.console.log("self:" + e);
            return function (m) {
                window.console.log("newo:" + m + e);
            };
        })("p11");
        // p11 定義了一個匿名方法,並且立即執行了它,同時返回了一個方法,所以
        // 1:p11 本身就代表了這個被 return 的方法,所以可被執行,即 p11("x");
        // 2:因為 p11 本身是 function,故可以 new
        p11("outp11_2");
        var E = new p11("outp11");
       
        window.console.log("=================================");
        // 1:在這里,對於 p12 而言,實際上 e 永遠等於字符串 “p12”
        // 2:在實際應用中,可能會傳入一個待處理的對象;
        // 3:new p12("outp12"); 
        //    error: 因為 p12 沒有 return 一個 funtion,所以它不能 new 出一個對象;
        // 4:調用 p12.p121 或 p12.p122 實際調用的是其代表的方法。
        // 5:如,調用 p12.p122,
        //      首先執行 p12.p122 方法本身;
        //      其次,方法參數中又有一個方法,p12.p122 調用了它
        //      e 是 p12 這個對象的內部變量,而 options 則是 p122 的參數
        var p12 = (function (e) {
            window.console.log("self:" + e);
            return {
                p121: function (m) { window.console.log("newo:" + m); },
                p122: function (options, fn) {
                    fn(e + options);
                }
            };
        })("p12");
        p12.p121("outp121");
        p12.p122("outp122", function (e) {
            window.console.log("invoker:" + e)
        });
    </script>
</body>
</html>

以上,基本上闡明了全部的Js方法怎么用的做法。如果認真體會上文代碼,並明白其中的輸出,那么基本上對於 JS 的方法的應用可以滿足日常開發了。

 

三:一個實際代碼

現在,我們就可以輕松的看明白下面這段代碼的含義了:

var learning = (function ($) {

    var player = function (e) {
            return (function f(m) {
                return m ? (function (n) {
                    // $('#Player', n) 指的是:在 DOM對象n 中尋找#Player對象
                    return $('#Player', n).get(0) || f($('iframe', n).get(0));
                })(m.contentWindow.document) : null;
            })($(e).get(0));
        };

    var playing = (function () {
        return {
            current: function () {
                return chapter;
            },
            tiny: function (e) {
                tinyObj = e;
            },
            body: function (e) {
                bodyObj = e;
            }
        }
    })();

    return {
        player: player,
        load: function (options, fn) {
            playing.tiny(options.tiny);
            playing.body(options.body);
        }
    };
})(this.jQuery);


$(function () {
    learning.load({
        tiny: $('#player_tiny'),
        body: $('#player_body')
    },
    function (e) {

    });
    var p1 = learning.player($('#player_tiny'));
    var p2 = learning.player($('#player_body'));
    if (p1) p1.pause();
    if (p2) p2.pause();
});

以上代碼中,最后一個方法調用指的是作為頁面 dom 加載完畢執行的代碼,它作為頁面的主方法。在該代碼中, 調用了 learning.load 方法,並且傳入了兩個參數。繼而,我們執行了一個方法,它是:

var p1 = learning.player($('#player_tiny'));

我們可以看到,這個方法本身定義為:

    var player = function (e) {
            return (function f(m) {
                return m ? (function (n) {
                    // $('#Player', n) 指的是:在 DOM對象n 中尋找#Player對象
                    return $('#Player', n).get(0) || f($('iframe', n).get(0));
                })(m.contentWindow.document) : null;
            })($(e).get(0));
        };

執行該方法,執行一個立即執行的匿名方法,該方法返回下面的東西:

m ? (function (n) {
                    // $('#Player', n) 指的是:在 DOM對象n 中尋找#Player對象
                    return $('#Player', n).get(0) || f($('iframe', n).get(0));
                })(m.contentWindow.document) : null;

這個方法本身看上去這么復雜,是因為這里存在一個遞歸調用(雖然該遞歸調用是可以被去掉的),即 f 方法內部,又調用了 f 方法本身。也許,我們把它換成不那么高級的寫法,就好容易理解多了:

var findDoc = function (n) {
    return $('#Player', n).get(0) || findX($('iframe', n).get(0));
};

var findX = function (m) {
    return m ? findDoc(m.contentWindow.document) : null;
};

var player = function (e) {
    findX($(e).get(0));
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM