从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 相关文章推荐
parseInt parseFloat js字符串转换数字
Aug 01 Javascript
javascript学习笔记(二) js一些基本概念
Jun 18 Javascript
浅析2种JavaScript继承方式
Dec 04 Javascript
js实现图片轮播效果
Dec 19 Javascript
JavaScript的Backbone.js框架环境搭建及Hellow world示例
May 07 Javascript
将html页面保存成图片,图片写入pdf的实现方法(推荐)
Sep 17 Javascript
jquery 判断是否支持Placeholder属性的方法
Feb 07 Javascript
深入浅析JS中的严格模式
Jun 04 Javascript
微信小程序使用swiper组件实现层叠轮播图
Nov 04 Javascript
vue请求服务器数据后绑定不上的解决方法
Oct 30 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
Sep 02 Javascript
Vue proxyTable配置多个接口地址,解决跨域的问题
Sep 11 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
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
2018/04/20 PHP
phpcmsv9.0任意文件上传漏洞解析
2020/10/20 PHP
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
javascript延时加载之defer测试
2012/12/28 Javascript
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
如何设置iframe高度自适应在跨域情况下的可用方法
2013/09/06 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
2020/06/23 Javascript
简单学习JavaScript中的for语句循环结构
2015/11/10 Javascript
JavaScript代码判断点击第几个按钮
2015/12/13 Javascript
理解javascript封装
2016/02/23 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
2016/12/27 Javascript
JS生成一维码(条形码)功能示例
2017/01/19 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
JavaScript实现一个空中避难的小游戏
2017/06/06 Javascript
Angular.JS中select下拉框设置value的方法
2017/06/20 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
浅谈angular4实际项目搭建总结
2017/12/01 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
解决vue router组件状态刷新消失的问题
2018/08/01 Javascript
快速解决处理后台返回json数据格式的问题
2018/08/07 Javascript
VUE 实现动态给对象增加属性,并触发视图更新操作示例
2019/11/29 Javascript
浅谈vue项目,访问路径#号的问题
2020/08/14 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
解决python3爬虫无法显示中文的问题
2018/04/12 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
用django-allauth实现第三方登录的示例代码
2019/06/24 Python
将自己的数据集制作成TFRecord格式教程
2020/02/17 Python
化学工程专业求职信
2014/08/10 职场文书
党员教师批评与自我批评发言稿
2014/10/15 职场文书
公务员处分决定书
2015/06/25 职场文书
2016年教师学习廉政准则心得体会
2016/01/20 职场文书
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
2021/06/03 Python
MySql中的json_extract函数处理json字段详情
2022/06/05 MySQL