简析JavaScript中的Function类型(三)——作为值的函数

因为在ECMAScript中,函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。

1. 作为参数

来看一个示例:

function callFn(fn, param){
  return fn(param);
}

function add5(num){
  return num + 5;
}

var value = callFn(add5, 10);
console.log(value);//15

首先声明了一个callFn函数,它接收两个参数,一个是要调用的函数,另一个是传递给要调用函数的参数。接下来创建了add5函数,然后使用callFn调用了add5,返回了add5的结果。

其实这里使用匿名函数作为参数也是可以的,还是这个例子:

var value = callFn(function(num){
  return num + 5;
}, 10);
console.log(value);//15

看到这是不是觉得有点熟悉呢?其实类似的,我们一直在用:

setTimeout(function(){
  console.log('hello world');
}, 1000);

上面这段代码我想读者一定不陌生吧,这是一个延迟函数,1秒钟后执行第一个参数——匿名函数。setTimeout是一个定义在window上的全局函数,第一个参数是要执行的回调函数,第二个参数是延迟的毫秒数。

再来看另一个例子:

$('#id').click(function(){
  console.log('点击了');
});

这是jQuery中的写法,$()是一个函数调用,这个函数接收的参数是'#id',返回了一个jQuery对象,在这个对象上再调用click()方法,这个方法接收一个匿名函数作为参数,这样就完成了click事件的绑定。

下面是jQuery 3.3.1版本131~144行的代码,我们看到jQuery就是一个函数。

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    return new jQuery.fn.init( selector, context );
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

这是第10333~10358行:

var
  // Map over jQuery in case of overwrite
  _jQuery = window.jQuery,

  // Map over the $ in case of overwrite
  _$ = window.$;

  jQuery.noConflict = function( deep ) {
    if ( window.$ === jQuery ) {
      window.$ = _$;
    }

    if ( deep && window.jQuery === jQuery ) {
      window.jQuery = _jQuery;
    }
    return jQuery;
  };
  // Expose jQuery and $ identifiers, even in AMD
  // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  // and CommonJS for browser emulators (#13566)
  if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
  }

对于其中的逻辑我们大可不必理会,从中可以看出,这段代码大致做了这样一件事:

window.jQuery = window.$ = jQuery;

这样就能理解,为什么我们可以使用$()了,$()jQuery()是等同的。

2. 作为返回值

先来看一段代码:

var arr = [8, 1, 35, 3, 10];

//升序
function ascSort(v1, v2) {
  return v1 - v2;
}
arr.sort(ascSort);
console.log(arr);//[1, 3, 8, 10, 35]

//降序
function descSort(v1, v2){
  return v2 - v1;
}
arr.sort(descSort);
console.log(arr);//[35, 10, 8, 3, 1]

这是JavaScript数组(一)——排序中讲的给数组排序的代码,我们看到升序和降序分别声明了一个函数,现在我们想能不能把这两个函数合并为一个呢?来看下面的代码:

var arr = [8, 1, 35, 3, 10];

function comparisonFn(flag){
  if(flag){
    // true 升序
    return function(v1, v2){
      return v1 - v2;
    }
  }else{
    // false 降序
    return function(v1, v2){
      return v2 - v1;
    }
  }
}

arr.sort(comparisonFn(false));
console.log(arr);//[35, 10, 8, 3, 1]

如代码所示,我们创建了一个函数,把真正的比较函数作为这个函数的返回值,在使用的时候通过给comparisonFn()传递true/false来控制升降序,达到了简化代码的目的。

关于函数作为参数和返回值的例子还有很多,这里就不一一列举了,相信读者随着对JavaScript学习的不断深入,以后还会经常遇到的。

转载于:https://my.oschina.net/bob1900/blog/3026710

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值