JS

来源:互联网 发布:mac上有什么好玩的游戏 编辑:程序博客网 时间:2024/05/27 16:40

【1】函数亦对象

在javascript中,函数是比较奇怪的,但它确确实实是对象。确切地说,函数是用Function()构造函数创建的Function对象。Function对象包含一个字符串,字符串包含函数的javascript代码。

对于javascript来说,数据和代码之间的区别是很模糊的。故你可以把函数作为参数在函数间传递—函数的回调。

示例如下:

var fn = new Function("arg1", "arg2", "return arg1 * arg2;");fn(2, 3); //6typeof fn === 'function';instanceof fn === 'object';

【2】回调函数的调用

显示回调函数调用

示例一如下:

function a(callback){   alert("这是parent函数a");   var m =1;   var n=3;   //注意这里,为回调函数传参。  return callback(m,n); } //b作为a的回调函数 function b(m,n){   alert("这是回调函数B");   return m+n; } // 父函数执行 $(function(){     //回调函数作为父函数的参数   var result = a(b);   alert("result = "+ result); });

执行结果如下:

这是parent函数a这是回调函数Bresult = 4

示例一中,b函数作为回调函数在适当时机在a函数内部被调用,并使用了a函数内部的局部变量

在JS-闭包中,说明了闭包常用的两种形式:函数作为返回值,函数作为参数传递。

回调函数的实现形式恰好符合!!

这意味着回调函数本质上是一个闭包。正如我们所知,闭包能够进入包含它的函数的作用域,因此回调函数能获取包含它的函数中的变量,以及全局作用域中的变量。

使用全局变量实现形式如下:

//定义全局变量var m =1;var n=3;function a(callback){   alert("这是parent函数a");   //注意这里,使用全局变量为回调函数传参。  return callback(m,n); } //上同....

匿名回调函数调用

示例二如下:

function foo(){ var a = 10; //匿名回调函数 return function(){  a *= 2;  return a;   }; }var f = foo();f(); //return 20.f(); //return 40.

或如下:

$("#testA").click(function(){    //doSomething;});

其中click函数内部使用了匿名函数作为参数,该匿名函数作为click函数的回调函数。


【3】回调函数参数

三种形式:使用全局变量参数;使用父函数参数;传回调函数的时候同时传参数;

示例一 - 全局变量—–参考【2】中使用全局变量形式
示例二 - 局部变量—–参考【2】中示例一
示例三 - 同时传递回调函数和参数如下:

//定义父函数function a(callback,param){    callback(param);}//定义回调函数function b(param){    return param+2;}//执行函数a(b,2);//4

注意,不能在回调函数作为参数的时候同时赋予参数;即如下示例错误 :

//错误示例a(b(2));//正确示例a(b,2);//4

【4】判断回调函数

最好保证回调存在且必须是函数引用或者函数表达式:

if(callback && typeof(callback) === "function"){                 callback();}

【5】回调函数中的call()和apply()

JS 中函数都有call() apply()方法。说明如下:

call方法:

语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象;即调用对象替换被调用对象。 

call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

apply方法:

语法:apply([thisObj[,argArray]]) ;定义:应用某一对象的一个方法,用另一个对象替换当前对象。 

需要注意的是:如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。 这是与call()参数使用的不同之处。

如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。


修改上文中的例子如下:

<script type="text/javascript">     // 父函数执行     $(function(){         //回调函数作为父函数的参数       var result = a(b);       console.log("result = "+ result);     });     function a(callback){           console.log("这是parent函数a");           var m =1;           var n=3;           //注意这里,为回调函数传参。//        return callback(m,n);           console.log(callback.call(this,m,n));           console.log(this);           return callback.apply(this,[m,n]);         }     //b作为a的回调函数     function b(m,n){       console.log("这是回调函数B");       return m+n;     }</script>

结果如下:

这里写图片描述


修改call方法和b函数如下:

<script type="text/javascript">     // 父函数执行     $(function(){         //回调函数作为父函数的参数       var result = a(b);       console.log("result = "+ result);     });     function a(callback){           console.log("这是parent函数a");           var m =1;           var n=3;            //将this指向b函数           console.log(callback.call(b,m,n));           //a函数上下文中的this--window           console.log(this);           return callback.apply(this,[m,n]);         }     //b作为a的回调函数     function b(m,n){       console.log("这是回调函数B");          //此处this将会是b函数自身        console.log(this);       return m+n;     }</script>

结果如下:

这里写图片描述

当一个函数自执行的时候,this指向的是window,当需要改变这个指向的时候,让函数call执行即可。

call函数执行的时候,第一个参数代表函数内部的this指向,传递的第二个参数对应函数的第一个参数,以此类推。

同样,你可以使用apply()函数改变this指向并传参。

使用场景:

当回调函数是一个含有this对象的方法时,我们必须修改执行回调函数的方法以保护this对象的内容。否则this对象将会指向全局的window对象(如果回调函数传递给了全局函数),或指向包含函数

参考JS中的回调函数
参考JS中的call和apply

原创粉丝点击