js的回调函数详解


Posted in Javascript onJanuary 05, 2015

现在做native App  和Web App是主流,也就是说现在各种基于浏览器的web app框架也会越来越火爆了,做js的也越来越有前途。我也决定从后端开发渐渐向前端开发和手机端开发靠拢,废话不说了,我们来切入正题“js的回调函数”相关的东西。

      说起回调函数,好多人虽然知道意思,但是还是一知半解。至于怎么用,还是有点糊涂。网上的一些相关的也没有详细的说一下是怎么回事,说的比较片面。下面我只是说说个人的一点理解,大牛勿喷。我们来看一下一个粗略的一个定义“函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。”,这句话的意思是函数b以一个参数的形式传入函数a并执行,顺序是先执行a ,然后执行参数b,b就是所谓的回调函数。我们先来看下面的例子。

   function  a(callback){

      alert('a');

      callback.call(this);//或者是 callback(),  callback.apply(this),看个人喜好

   }

   function  b(){

       alert('b');

   }

   //调用

   a(b);

       这样的结果是先弹出 'a',再弹出‘b'。这样估计会有人问了“写这样的代码有什么意思呢?好像没太大的作用呢!”

       是的,其实我也觉得这样写没啥意思,“如果调用一个函数就直接在函数里面调用它不就行了”。我这只是给大家写个小例子,做初步的理解。真正写代码的过程中很少用这样无参数的,因为在大部分场景中,我们要传递参数。来个带参数的:

function  c(callback){

      alert('c');

      callback.call(this,'d');

    }

//调用

c(function(e){

    alert(e);

});

      这个调用看起来是不是似曾相识,这里e参数被赋值为'd',我们只是简单的赋值为字符窜,其实也可以赋值为对象。Jquery里面是不是也有个e参数,下面我们就来讲讲
Jquery里面的e参数是如何被回调赋值的。

       Jquery框架我想大家不陌生了,出来了好久,开发的时候都在用,比较简单,api网上搜起来很方便,上手快。在Jquery框架下,我们有时候要获取事件中的一些参数,比如我要获取当前点击的坐标,点击的元素对象。这个需求在Jquery里面好办  :

        $("#id").bind('click',function(e){

          //e.pageX ,e.pageY ,e.target.....各种数据

        });

        用起来倒是挺方便,其实这个e参数的赋值也是通过回调函数来实现的,这个参数是用回调参数给它赋予了一个对象值,仔细研究过JJquery源码的朋友应该发现了这一点。

还有Ajax里面   $.get('',{},function(data){})    data这个参数也是同样的原理。

        我们来看看Jquery事件对象里面是怎么应用回调函数的。

       为了方便,我简单的写了一下$相关的一些实现,之前写过“小谈Jquery”里面有比较接近框架实现的方法,我下面只是写一个简易的选择器。

<div  id="container"   style="width:200px;height:200px;background-Color:green;">

</div>

<script>

     var   _$=function (id)

               { 

                     this.element=  document.getElementById(id); 

                }

       _$.prototype={

            bind:function(evt,callback)

            {

                var   that=this;

                if(document.addEventListener)

                {

                    this.element.addEventListener(evt, function(e){

                        callback.call(this,that.standadize(e));

                    }  ,false);

                }

                else if(document.attachEvent)

                {

                    this.element.attachEvent('on'+evt,function(e){

                        callback.call(this,that.standadize(e));

                    });

                }

                else

                    this.element['on'+evt]=function(e){

                        callback.call(this,that.standadize(e));

                    };

            },

            standadize:function(e){

                 var  evt=e||window.event;

                 var  pageX,pageY,layerX,layerY;

                 //pageX  横坐标  pageY纵坐标   layerX点击处位于元素的横坐标   layerY点击处位于元素的纵坐标

                 if(evt.pageX)

                 {

                     pageX=evt.pageX;

                     pageY=evt.pageY;

                 }

                 else

                 {

                    pageX=document.body.scrollLeft+evt.clientX-document.body.clientLeft;

                    pageY=document.body.scrollTop+evt.clientY-document.body.clientLTop;

                 }

                 if(evt.layerX)

                 {

                     layerX=evt.layerX;

                     layerY=evt.layerY;

                 }

                 else

                 {

                     layerX=evt.offsetX;

                     layerXY=evt.offsetY;

                 }

                 return  {

                    pageX:pageX,

                    pageY:pageY,

                    layerX:layerX,

                    layerY:layerY

                 }

            }

       }

       window.$=function(id)

       {

          return  new _$(id);

       }

        $('container').bind('click',function(e){

            alert(e.pageX);

        });

        $('container1').bind('click',function(e){

             alert(e.pageX);

        });

</script>

这段代码我们主要看standadize函数的实现,兼容性的代码,就不多说了,返回的是一个对象 

     return  {

                    pageX:pageX,

                    pageY:pageY,

                    layerX:layerX,

                    layerY:layerY

                 }

 然后再看bind函数里面的代码    callback.call(this,that.standadize(e)),这段代码其实就是给e参数赋值了,是用callback回调实现的。

callback 函数被调用的时候传入的是匿名函数

         function(e){

        }

而callback.call(this,that.standadize(e))相当于是执行了这么一段代码 

        (function(e){

        })(standadize(e))

   这也是Jquery用回调函数比较经典的地方,e参数就是这么被赋值的,说了这些你们也大概有个了解了,以及怎么使用了。

    回调在各种框架中应用的比较多,有时候自己写一些东西的时候也可以根据实际情况用用看。

Javascript 相关文章推荐
JS效率个人经验谈(8-15更新),加入range技巧
Jan 09 Javascript
Javascript 表单之间的数据传递代码
Dec 04 Javascript
JS IE和FF兼容性问题汇总
Feb 09 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
Sep 13 Javascript
jquery中post方法用法实例
Oct 21 Javascript
JavaScript实现更改网页背景与字体颜色的方法
Feb 02 Javascript
js+html5实现canvas绘制网页时钟的方法
May 21 Javascript
D3.js实现柱状图的方法详解
Sep 21 Javascript
JS实用的带停顿的逐行文本循环滚动效果实例
Nov 23 Javascript
详解Vue demo实现商品列表的展示
May 07 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
Aug 23 Javascript
卸载vue2.0并升级vue_cli3.0的实例讲解
Feb 16 Javascript
判断浏览器的内核及版本号方法汇总
Jan 05 #Javascript
jQuery中removeProp()方法用法实例
Jan 05 #Javascript
jQuery中prop()方法用法实例
Jan 05 #Javascript
jQuery中removeAttr()方法用法实例
Jan 05 #Javascript
jQuery实现鼠标滚轮动态改变样式或效果
Jan 05 #Javascript
jquery.cookie.js使用指南
Jan 05 #Javascript
在Google 地图上实现做的标记相连接
Jan 05 #Javascript
You might like
完美解决PHP中的Cannot modify header information 问题
2013/08/12 PHP
fckeditor上传文件按日期存放及重命名方法
2015/05/22 PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
2016/11/05 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
2017/10/23 PHP
Yii框架连表查询操作示例
2019/09/06 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
GRID拖拽行的实例代码
2013/07/18 Javascript
JS常见问题整理(持续更新)
2013/08/06 Javascript
AngularJS 整理一些优化的小技巧
2016/08/18 Javascript
简单理解vue中track-by属性
2016/10/26 Javascript
js实现华丽的九九乘法表效果
2017/03/29 Javascript
JS实现获取word文档内容并输出显示到html页面示例
2018/06/23 Javascript
深入解析ES6中的promise
2018/11/08 Javascript
Vue 实现从小到大的横向滑动效果详解
2019/10/16 Javascript
JavaScript 声明私有变量的两种方式
2021/02/05 Javascript
[01:22:10]Ti4 循环赛第二日 DK vs Empire
2014/07/11 DOTA
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
Python 迭代器与生成器实例详解
2017/05/18 Python
python3 面向对象__类的内置属性与方法的实例代码
2018/11/09 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
django 使用 PIL 压缩图片的例子
2019/08/16 Python
Python3.7黑帽编程之病毒篇(基础篇)
2020/02/04 Python
Tensorflow 卷积的梯度反向传播过程
2020/02/10 Python
浅谈Keras中shuffle和validation_split的顺序
2020/06/19 Python
Tensorflow中批量读取数据的案列分析及TFRecord文件的打包与读取
2020/06/30 Python
Giglio英国站:意大利奢侈品购物网
2018/03/06 全球购物
优秀英语专业毕业生求职信
2013/11/23 职场文书
生育关怀行动实施方案
2014/03/26 职场文书
2014年党委工作总结
2014/11/22 职场文书
2014年幼儿园园长工作总结
2014/12/17 职场文书
2014年学生管理工作总结
2014/12/20 职场文书
北京天坛导游词
2015/02/12 职场文书
家庭贫困证明
2015/06/16 职场文书
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
2021/03/31 jQuery
正确使用MySQL update语句
2021/05/26 MySQL