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

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. Ubuntu编译gdb-ARM调试环境

    参考Qt可用的gdb编译,以及交叉编译gdbserver,以及配置QtCreator远程调试 编译脚本 如下: #!/bin/bash echo -e "\033[32m 正在执行步骤一:检 ...

  2. Qt QByteArray或者Char转十六进制 QString

    1.QByteArray转十六进制 QByteArray buff = sp->readAll(); qDebug() << buff.toHex() << " ...

  3. 利用openssl构建根证书-服务器证书-客户证书

    利用openssl构建根证书-服务器证书-客户证书 OpenSSL功能远胜于KeyTool,可用于根证书,服务器证书和客户证书的管理 一.构建根证书 1.构建根证书前,需要构建随机数文件(.rand) ...

  4. bzoj 1103

    题目大意:有一棵树根为1,刚开始每条边的权值为1,  现在有m + n - 1 个操作, A :x  y  , 将x和y相连的边权值变为1, W:x, 询问x到1路径上的权值和. 思路 : 方法一: ...

  5. 2018年湘潭大学程序设计竞赛 F - maze

    把点抽出来 跑个最短路就好啦. #include<bits/stdc++.h> #define LL long long #define pii pair<int,int> # ...

  6. Pandas常用命令

    一.数据导入和导出 (一)读取csv文件 1.本地读取 import pandas as pd df = pd.read_csv('tips.csv') #根据自己数据文件保存的路径填写(p.s. p ...

  7. UML用例图之间的关系

    在画用例图的时候,理清用例之间的关系是重点.用例的关系有泛化(generalization).扩展(extend)和包含(include).其中include和extend最易混淆.下面我们结合实例彻 ...

  8. Java 内存模型 ,一篇就够了!

    Java 虚拟机   我们都知道 Java 语言的可以跨平台的,这其中的核心是因为存在 Java 虚拟机这个玩意.虚拟机,顾名思义就是虚拟的机器,这不是真实存在的硬件,但是却可以和不同的底层平台进行交 ...

  9. Linux-C基础编程

    GCC工作流程 工作流程 1.预处理 -E xxx.c —> xxx.i 宏替换:头文件展开:注释去掉: gcc -E hello.c -o hello.i 2.编译 -S xxx.i —> ...

  10. Python join() 方法与os.path.join()的区别

    Python join() 方法与os.path.join()的区别 pythonJoinos.path.join 今天工作中用到python的join方法,有点分不太清楚join() 方法与os.p ...