高阶函数(js的问题)

简介: 高阶函数(js的问题)

(1)函数可以作为参数被传递

(2)函数可以作为返回值输出

4-1.函数作为参数传递

Array.prototype.sort方法:

    var array = ['10','5','12','3'];
    array.sort();
    //array:['10','12','3','5']
    //如代码那样,排序的结果并不是我们想要的,这与sort函数的比较规则有关系
    array.sort(function(a,b){return a-b;});
    //array:['3','5','10','12']
    传入一个比较的函数,就可以按照数字大小的规则进行正确的比较了。

4-2.函数作为返回值输出

var getSingle = function ( fn ) {
        var ret;
        return function () {
            return ret || ( ret = fn.apply( this, arguments ) );
        };
    };

4-3.函数作为参数被传递并且返回另一个函数

var getScript = getSingle(function(){
        return document.createElement( 'script' );
    });
    var script1 = getScript();
    var script2 = getScript();
    alert ( script1 === script2 ); // 输出:true

4-4.高阶函数应用

(1)高阶函数实现AOP

AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些业务逻辑无关的功能包括日志统计、控制安全、异常处理等。把这些功能抽离出来之后,再通过“动态织入”的方式掺入业务逻辑模块中。


下面代码通过扩展Function.prototype来实现把一个函数“动态织入”

Function.prototype.before = function( beforefn ){
        var __self = this; // 保存原函数的引用
        return function(){ // 返回包含了原函数和新函数的"代理"函数
            beforefn.apply( this, arguments ); // 执行新函数,修正this
            return __self.apply( this, arguments ); // 执行原函数
        }
    };
 
    Function.prototype.after = function( afterfn ){
        var __self = this;
        return function(){
            var ret = __self.apply( this, arguments );
            afterfn.apply( this, arguments );
            return ret;
        }
    };
 
    var func = function(){
        console.log( 2 );
    };
 
    func = func.before(function(){
        console.log( 1 );
    }).after(function(){
        console.log( 3 );
    });
 
func();

(2)柯里化

一个currying函数首先会接受一些参数,接受了这些参数之后,该函数不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存了下来。待到函数真正需要求值的时候,之前传入的所有参数都会一次性用于求值。


一个经典的柯里化:

function curry(fn){
        var arr1 = Array.prototype.slice.call(arguments,1);
        return function(){
            var arg2 = Array.prototype.slice.call(arguments);
            var array = arr1.concat(arr2);
            return fn.apply(null,array);
        }
    }

不断累积的柯里化:

   var currying = function( fn ){
        var args = [];//外层函数变量:用来累积
        return function(){
            if ( arguments.length === 0 ){
                return fn.apply( this, args );
            }else{
                [].push.apply( args, arguments );
                return arguments.callee;
            }
        }
    };

(3)uncurrying


在javascript中,当我们调用对象的某个方法时,其实不用关心对象原本是否被设计为拥有这个方法,这是动态类型语言的特点,也就是常说的鸭子类型思想。

同理,一个对象也未必只能使用它自己的方法,其实可以借用原本不属于他的方法: call apply

Function.prototype.uncurrying = function () {
        var self = this;
        return function() {
            var obj = Array.prototype.shift.call( arguments );
            return self.apply( obj, arguments );
        };
    };
 
    var push = Array.prototype.push.uncurrying();
var obj = {
    "length": 1,
    "0": 1
};
 
push( obj, 2 );//将2使用push的方法作用到obj上
console.log( obj ); // 输出:{0: 1, 1: 2, length: 2}


相关文章
|
6月前
|
前端开发 JavaScript
前端基础 - JavaScript高级应用(高阶函数)
前端基础 - JavaScript高级应用(高阶函数)
32 0
|
9月前
|
存储 JavaScript 前端开发
js数组高阶函数——includes()方法
js数组高阶函数——includes()方法
194 0
|
9月前
|
JavaScript 前端开发 数据格式
vue写法——使用js高阶函数实现多条件搜索功能
vue写法——使用js高阶函数实现多条件搜索功能
111 0
vue写法——使用js高阶函数实现多条件搜索功能
|
9月前
|
前端开发 JavaScript 数据可视化
React写法——使用js高阶函数实现多条件搜索功能
React写法——使用js高阶函数实现多条件搜索功能
|
9月前
|
JavaScript 索引
js数组高阶函数——map()方法
js数组高阶函数——map()方法
114 0
|
9月前
|
存储 SQL JavaScript
js数组高阶函数——filter()方法
js数组高阶函数——filter()方法
|
10月前
|
JavaScript 前端开发
📕 重学JavaScript:如何手写一个`reduce`高阶函数?
`reduce` 高阶函数是一个非常常用的数组方法,可以让你用一种简单的方法来处理数组里的元素。 数组就是一串有顺序的东西,比如[1, 2, 3, 4]就是一个数组,里面有四个数字。👌
113 0
|
10月前
|
JavaScript 前端开发
📕 重学JavaScript:如何手写一个`push`高阶函数?
`push` 高阶函数是一个非常常用的数组方法,可以让你用一种简单的方法来添加数组里的元素。
97 0
|
10月前
|
JavaScript 前端开发
📕 重学JavaScript:如何手写一个`pop`高阶函数?
`pop` 高阶函数是一个非常常用的数组方法,可以让你用一种简单的方法来删除数组里的元素。
92 0
|
10月前
|
JavaScript 前端开发 索引
📕 重学JavaScript:如何手写一个`map`高阶函数?
`map` 高阶函数是一个非常常用的数组方法,它可以对数组中的每个元素进行操作,然后返回一个新的数组。
82 0