从JQuery源码分析JavaScript函数的apply方法与call方法


Posted in Javascript onSeptember 25, 2014

最近在使用jQuery的$.each方法时很,突然想到$.each($(‘div'),function(index,entity){});中的这个index和entity是哪冒出来的,而且可有可无的,而且这么高大上的能告诉我们当前遍历的下标和实例。所以看了一下jQuery源代码,是这么写的:

从JQuery源码分析JavaScript函数的apply方法与call方法

调试的时候走的是标红的这段代码,然后用到了callback.call这个函数,于是翻看了一下《js高级程序设计》,其中有比较深的解释。

首先,function是一个指向Function对象,函数名是一个指向函数的指针。那么在函数体内,就会有一个作用域,即this关键字。

this关键字指的是函数运行的作用域,举个例子来说:

<script type="text/javascript">

        function funcA() {

            alert(this);

            alert("Function A");

        }

</script>

上面这段代码中的函数funcA定义在全局环境中,那么函数体内的this即window对象。

下面该到call和apply的说明了。以call函数为例,call的第一个参数,就是改变函数的作用域,后面的参数为传入函数的所需的参数,必须与原函数的参数一直,举例说明:

<script type="text/javascript">

        var testO = { name: "Lily" };

        function funcA(a,b) {

            alert(this);

            alert("Function A");

        }
        function funcB(a, b) {

            funcA.call(testO, a, b);

        }
        funcB(1,2);  //this变成了testO

    </script>

我们定义funcB函数的中,调用了funcA的call函数,这个时候我们改变了funcA中this的指向,原本指向window的,现在指向了call的第一个参数testO这个对象。而且调用call时,因为funcA函数有两个参数,所以如果要想funcA传递参数,必须一一指出参数,即后面的两个参数a和b,或者可以只穿第一个参数

即:funcA.call(testO);或者只传a,即:funcA.call(testO,a);

而apply与call的区别仅在于,apply的第二个参数可以是数组形式,而且不必一一指出参数,funcA.apply(testO,[a,b])

介绍完call与apply的基本用法,该说说他哥俩真正的用武之地了,扩充函数赖以运行的作用域。

<script type="text/javascript">

        window.color = "透明";

        var testObj = { color: "红色" };
        function testFuc() {

            alert(this.color);

        }
        $(function () {

            1.testFuc(); //弹出“透明”

            2.testFuc(this); //弹出“undefined”

            3.testFuc.call(this.parent); //弹出“透明”

            4.testFuc.call(window); //弹出“透明”

            5.testFuc.call(testObj); //弹出“红色”

        });

</script>

上面这段代码演示了call的作用。第一个函数调用,this指向了window,所以弹出了window的color属性。

第二个函数可能有些朋友以为也会弹出透明,但是请先确定我们的函数运行在$(function(){});中,这个jQuery的函数,了解jQuery的朋友都很清楚,在

$(function(){});中this的作用域指向的是document,然后我们调用testFunc,要弹出document的color,当然是未定义的。

第三个函数将testFunc的this指向了document的亲爹window,弹出window的color当然也是没有问题的。

第四个函数就更加直白了,把window传进去了

第五个函数,将testFunc的this指向了testObj,弹出了红色。

讲到这里,用法大家应该都有所了解了,但是具体怎么去理解怎么去使用还是看自己的套路。

我是这么理解的,可以把这种用法看成是C#或者java中的泛型方法。比如一个C#方法的定义

public void Test<T>(T a, T b) { }

这样我们就可以实现对方法的扩展,实现通用的目的。

以上都是本人自己的看法和观点,有什么不对之处还请大家指出来共同学习。

Javascript 相关文章推荐
IE6不能修改NAME问题的解决方法
Sep 03 Javascript
javascript操作html控件实例(javascript添加html)
Dec 02 Javascript
jquery、js操作checkbox全选反选
Mar 12 Javascript
javascript生成随机数的方法
May 16 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
Jun 15 Javascript
使用js实现的简单拖拽效果
Mar 18 Javascript
javascript与jquery中的this关键字用法实例分析
Dec 24 Javascript
字符串反转_JavaScript
Apr 28 Javascript
jQuery中JSONP的两种实现方式详解
Sep 26 Javascript
jquery实现数字输入框
Feb 22 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
node.js如何根据URL返回指定的图片详解
Oct 21 Javascript
JS小游戏之仙剑翻牌源码详解
Sep 25 #Javascript
JS小游戏之宇宙战机源码详解
Sep 25 #Javascript
JS小游戏之极速快跑源码详解
Sep 25 #Javascript
JS小游戏之象棋暗棋源码详解
Sep 25 #Javascript
我用的一些Node.js开发工具、开发包、框架等总结
Sep 25 #Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 #Javascript
用C/C++来实现 Node.js 的模块(二)
Sep 24 #Javascript
You might like
使用php转义输出HTML到JavaScript
2015/03/27 PHP
PHP使用redis实现统计缓存mysql压力的方法
2015/11/14 PHP
PHP实现正则表达式分组捕获操作示例
2018/02/03 PHP
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
Jquery知识点一 Jquery的ready和Dom的onload的区别
2011/01/15 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
jQuery中position()方法用法实例
2015/01/16 Javascript
Node.js开发教程之基于OnceIO框架实现文件上传和验证功能
2016/11/30 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
vue项目中的webpack-dev-sever配置方法
2017/12/14 Javascript
Javascript中绑定click事件的四种方式介绍
2018/10/26 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
js中的reduce()函数讲解
2019/01/18 Javascript
JS数组中对象去重操作示例
2019/06/04 Javascript
electron 如何将任意资源打包的方法步骤
2020/04/16 Javascript
JS数组转字符串实现方法解析
2020/09/04 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python中的装饰器用法详解
2015/01/14 Python
python 中字典嵌套列表的方法
2018/07/03 Python
pycharm新建Vue项目的方法步骤(图文)
2020/03/04 Python
如何基于python实现年会抽奖工具
2020/10/20 Python
HTML5中判断用户是否正在浏览页面的方法
2014/05/03 HTML / CSS
美国定制钻石订婚戒指:Ritani
2017/12/08 全球购物
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
某公司.Net方向面试题
2014/04/24 面试题
介绍一下Python中webbrowser的用法
2013/05/07 面试题
关键字throw与throws的用法差异
2016/11/22 面试题
客户代表自我评价范例
2013/09/24 职场文书
毕业生求职推荐信
2013/11/04 职场文书
先进德育工作者事迹材料
2014/01/24 职场文书
大学社团计划书
2014/05/01 职场文书
村主任个人对照检查材料
2014/10/01 职场文书
起诉书格式范文
2015/05/20 职场文书
Nginx实现高可用集群构建(Keepalived+Haproxy+Nginx)
2021/05/27 Servers
Vue过滤器(filter)实现及应用场景详解
2021/06/15 Vue.js
Java工作中实用的代码优化技巧分享
2022/04/21 Java/Android