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

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. MVC的博客

    一个基于Asp.net MVC的博客类网站开源了!   背景说明: 大学时毕业设计作品,一直闲置在硬盘了,倒想着不如开源出来,也许会对一些人有帮助呢,而且个人觉得这个网站做得还是不错了,毕竟是花了不少 ...

  2. windows下mysql配置

    windows下mysql配置   忙活了大半天,总算配置好了,本文献给windows下没试用过Mysql的小白,勿喷 http://blog.csdn.net/z1074907546/article ...

  3. 模拟app端上传图片

    使用插件模块管理模式: jsp页面: <sys:fileUpload fieldName="picList" contentId="true" value ...

  4. [漏洞分析]phpyun系统重装安全隐患#影响从phpyun4.2部分,4.3到4.5全版本

    0x00 之前在t00ls上看到的,漏洞原理很简单,但是都是细节问题,很值得去学习. 感谢bypass师傅. 也发了邮件给官方,但没有任何回复,估计是漏洞作者bypass师傅报备了吧.   0x01 ...

  5. 使用Synchronized关键字同步类方法

    要想解决“脏数据”的问题,最简单的方法就是使用synchronized关键字来使run方法同步,代码如下: public synchronized void run() { } 从上面的代码可以看出, ...

  6. Android-多进程初识

    Android-多进程初识 学习自 <Android开发艺术探索> https://baike.baidu.com/item/%E8%BF%9B%E7%A8%8B/382503?fr=al ...

  7. 无线网络实体图生成工具airgraph-ng

    无线网络实体图生成工具airgraph-ng   airgraph-ng是aircrack-ng套件提供的一个图表生成工具.该工具可以根据airodump工具生成的CSV文件绘制PNG格式的图.绘制的 ...

  8. mobile开发备忘

    css -webkit-tap-highlight-color   webkit点击时会反色,可以清楚 -webkit-appearance   设为none时自带组建样式清除

  9. 如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接(转)

    前期准备: 关于什么是Hierarchy Viewer,请查看官方文档:http://developer.android.com/tools/debugging/debugging-ui.html.个 ...

  10. 使用CefSharp在.Net程序中嵌入Chrome浏览器(四)——启动优化

    在实际使用过程中,发现有的客户端会出现chrome加载网页过慢问题,定位后发现很多是因为设置系统代理所致,此时可以通过如下启动参数禁止系统代理. {"proxy-auto-detect&qu ...