首先,我们来看一段代码,如果觉得不甚明白的,则本文会对你有益:

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 基本没什么用处。

由于 p00 return 一个 function,所以 B 可以执行自己,即被调用;
        B("BB");
上面说了,由于 B 是一个 function,所以可以被 new

2:匿名方法及立即执行

p01 return 的本身是一个立即执行的匿名方法,
于是很不幸,D 本身变成什么也不是了,以下代码不能执行
   D("DD");
不同于 B,B 是 function 本身,所以可以执行:

p1 是定义了一个匿名方法,并立即执行它,并且说明也没返回(或者说返回 null),所以:
      1: p1 即不能被 new ,即 new p1();
      2: 也不能执行,即 p1();

p11 定义了一个匿名方法,并且立即执行了它,同时返回了一个方法,所以
         1:p11 本身就代表了这个被 return 的方法,所以可被执行,即 p11("x");
         2:因为 p11 本身是 function,故可以 new

现在,为了便于查看,上一个加了注释的版本:

<!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));
};

JavaScript中的方法、方法引用和参数的更多相关文章

  1. javascript中的splice方法介绍&示例

    javascript 中的 splice 方法很强大,它可以用于插入.删除或替换数组的元素. 下面来一一介绍! 删除:用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数 ...

  2. javascript中的toString()方法

    javascript中的toString()方法,主要用于Array.Boolean.Date.Error.Function.Number等对象.下面是这些方法的一些解析和简单应用,做个纪律,以作备忘 ...

  3. JavaScript中的工厂方法、构造函数与class

    JavaScript中的工厂方法.构造函数与class 本文转载自:众成翻译 译者:谢于中 链接:http://www.zcfy.cc/article/1129 原文:https://medium.c ...

  4. JavaScript中基本数据类型和引用数据类型的区别(栈——堆)

    JavaScript中基本数据类型和引用数据类型的区别 1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据 ...

  5. Javascript中的Callback方法浅析

    什么是callback?  回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数.回调函数不是由该函数 ...

  6. JavaScript中的bind方法及其常见应用

    一.bind()方法的实现 在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用.就拿最常见的console.log("info…")来说,避免书写 ...

  7. javascript中的slice()方法

    JavaScript中的Array对象提供了一个slice()方法,用于从已有的数组中返回选定的元素. arrayObject.slice(start, end) 参数说明 start 必需(否则没有 ...

  8. javascript中的删除方法

    可能呢再开发的过程中呢使用的不是很多,但是碰上呢可以注意下 1.比如: var x = 10; delete x; console.log(x); 结果是多少,是10,不是异常也不是undefined ...

  9. JavaScript中样式,方法 函数的应用

    JavaScript中一个字母都不能错,编写的时候他不报错,也不提示,只有在执行的时候才会提示错误位置 . 一.样式 .waring {background-color:yellow } .highl ...

  10. javascript中的sort()方法

    现在在学习javascript中,发现sort()函数是有点奇怪的东西(可能是本人水平的问题-_-!),于是就在这里记录一下自己找到的东西吧.sort()这个方法的参数很奇怪,必须是函数,但也是可选参 ...

随机推荐

  1. linux convert mp3 to wav and opus to wav

    link :  https://www.cyberciti.biz/faq/convert-mp3-files-to-wav-files-in-linux/ Install mpg321 or mpg ...

  2. 【LOJ】#6435. 「PKUSC2018」星际穿越

    题解 想出70的大众分之后就弃疗了,正解有点神仙 就是首先有个比较显然的结论,就是要么是一直往左走,要么是走一步右边,然后一直往左走 根据这个可以结合RMQ写个70分的暴力 我们就考虑,最优的话显然是 ...

  3. 牛客练习赛16 E - 求值

    题目大意: 链接:https://www.nowcoder.com/acm/contest/84/E 给定n个数字a1, a2, ..., an. 定义f(l, r) = al | al+1| ... ...

  4. jQuery选择器(转)

    原文:http://www.cnblogs.com/qinwang913/p/3444135.html 一.基本分类 jQuery选择器大致可以分为两类,基本选择器和过滤选择器,总体结构体系如下:   ...

  5. cookie之困

    参见http://yun.baidu.com/share/link?shareid=1575530779&uk=1795493794 cookie三元组(name,domain,path),它 ...

  6. Python3 贝叶斯分类

    # -*- coding: utf-8 -*- """ Created on Tue Jan 16 20:11:07 2018 @author: markli " ...

  7. C# Socket异步实现消息发送--附带源码

    前言 看了一百遍,不如动手写一遍. Socket这块使用不是特别熟悉,之前实现是公司有对应源码改改能用. 但是不理解实现的过程和步骤,然后最近有时间自己写个demo实现看看,熟悉熟悉Socket. 网 ...

  8. [代码审计]SRCMS的两点小越权

    0x00 简介 SRCMS是一个开源的企业安全应急响应中心,基于ThinkPHP 3.2框架开发.该系统在2017-09-09已经停止更新了,主要是在翻看p神博客文章时看到这个,随想自己再审一次. p ...

  9. View 事件分发

    View 事件分发 学习自 <Android开发艺术探索> 官方文档-MotionEvent 事件分发机制漫谈 View的事件分发机制,使我们了解View的工作原理继而学习如何自定义Vie ...

  10. 格式化p6spy的输出日志

    众所周知, p6spy打印出来的日志是一行很长很长的内容, 很不容易查看, 牛B的p6spy为什么就不能想hibernate那样有format_sql的功能? 竟然没有, 我只好自己动手写一个日志输出 ...