首页 > 试题广场 >

使用闭包

[编程题]使用闭包
  • 热度指数:84475 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
实现函数 makeClosures,调用之后满足如下条件:
1、返回一个函数数组 result,长度与 arr 相同
2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同

示例:
var arr = [1,2,3]; 
var fn = function (x) { 
    return x * x; 
}
var result = makeClosures(arr,fn);
(result[1]() === 4) === (fn(arr[1]) === 4) === true
推荐
简单的描述闭包:如果在函数func内部声明函数inner,然后在函数外部调用inner,这个过程即产生了一个闭包。
题目要求的是返回一个函数数组,如果在循环中直接写result[i] = function(){return fn(arr[i]);}或者result.push(function(){return fn(arr[i]);}),最终的结果是不正确的,因为在每次迭代的时候,那样的语句后面的方法并没有执行,只是创建了一个函数体为“return fn(arr[i]);”的函数对象而已,当迭代停止时,i为最终迭代停止的值,在函数被调用时,i依旧为最终迭代停止的值,因此无法返回正确的结果。
为了解决这个问题,需要声明一个匿名函数,并立即执行它。
function(num){return function(){return fn(arr[num]); }; }(i),函数执行后,i立即传入并被内部函数访问到,因此就能得到正确的结果。闭包允许你引用存在于外部函数中的变量。
下面的代码使用的是forEach循环
function makeClosures(arr, fn) {
  var result = [];
     arr.forEach(function(e){
         result.push(function(num){
             return function(){
                 return fn(num);
             };
         }(e));
     });
     return result;
 }

编辑于 2015-08-18 21:03:19 回复(36)
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
function makeClosures(arr, fn) {
    var result = [];
    for(var i = 0; i < arr.length; i++) {
        result[i] = function(ele) {
            return function() {
                return fn(ele);
            }
        }(arr[i]);
    }
    return result;
}
forEach:
function makeClosures(arr, fn) {
    var result = [];
    arr.forEach((item,index) => {
        result[index] = function(ele) {
            return function() {
                return fn(ele);
            }
        }(item);
    })
    return result;
}



发表于 2022-03-27 21:25:34 回复(0)
function makeClosures(arr, fn) {
    return arr.map(n => () => fn(n))
}

发表于 2021-09-09 19:29:44 回复(0)
就这 ?
function makeClosures(arr, fn) {
    return arr.map(item => () => fn(item))
}


发表于 2021-09-07 22:40:28 回复(0)
function makeClosures(arr, fn) {
    
    return arr.map(i => {
        return () => fn(i)
    })
}

发表于 2021-08-08 21:53:43 回复(0)
我不太懂为什么题目中输出是4
发表于 2021-07-25 07:23:14 回复(0)
function makeClosures(arr, fn) {
    return arr.map(item=>fn.bind(null,item))
}

编辑于 2021-01-06 18:00:44 回复(0)
本质其实就是如何将一个函数放入到一个数组中,可是如果直接 result.push(函数(形参)),则会调用这个函数,就传进去了一个值,所以需要用闭包思想,返回一个函数,就可以传一个函数进去
function makeClosures(arr, fn) {
    let result=[]
    arr.forEach((e)=>{
      result.push(()=>{return fn(e)});
    });
    return result;
}




发表于 2020-12-04 16:15:17 回复(0)
 var makeClosures = (arr, fn) => arr.map((v) => () => fn(v));

编辑于 2020-05-18 15:51:17 回复(0)
function makeClosures(arr, fn) {
    return arr.map(e => function(){ return fn(e) })
}
function makeClosures(arr, fn) {
    return arr.map(e => () => fn(e) )
}
ES6 map
缩短再缩短
编辑于 2020-03-25 11:43:24 回复(0)
精简了下代码
function makeClosures(arr, fn) {  
    return arr.map(item => () => fn(item))   
}


发表于 2020-02-26 20:39:49 回复(0)
function makeClosures(arr, fn) {
    var result=[];
 for(var i in arr) //循环数组
 {  
    result.push(fn.bind(this,arr[i]))  //因为result数组存储的是function,主要是给fn参数绑定arr[i]    再添加到result
 }
    return result;
}
发表于 2019-10-04 14:36:52 回复(0)
function makeClosures(arr, fn) {   
    var result =[];
    //let 声明的变量只在 let 命令所在的代码块 {} 内有效,块级作用域
    for(let i = 0; i < arr.length; i++){
        result[i] = function(){
            return fn(arr[i]);        
        };
    }
    return result;
}

function makeClosures(arr,fn){
    var result = [];
    //array.forEach(function(currentValue, index, arr), thisValue)
    //forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
    //参数1:必需。当前元素,
    //参数2:可选。当前元素的索引值
    //参数3:可选。当前元素所属的数组对象
    arr.forEach(function(num){
        result.push(function(){
            return fn(num);
        })
    })
    return result;
}

发表于 2019-09-12 18:03:39 回复(0)
function makeClosures(arr, fn) {
    let result = []

    for (let i = 0, len = arr.length; i < len; i++) {
        result.push(function() {
            return fn(arr[i])
        })
    }

    return result
}

Tim的资源站

编辑于 2019-08-27 11:12:48 回复(0)

es6方式(结果正确,系统无法通过)

var result = [];
for (let i = 0; i < arr.length; i++) {
    result[i] = function () {
        return fn(arr[i]);
    };
}
return result;

匿名函数

var result = [];
for (var i = 0; i < arr.length; i++) {
    (function (i) {
        result[i] = function () {
            return fn(arr[i]);
        };
    })(i);
}
return result;

ForEach

var result = [];
arr.forEach(function (item) {
    result.push(function () {
        return fn(item);
    });
});
return result;

函数工厂(新闭包)

var result = [];
function makeFnCallback(i){
    return function(){
        return fn(arr[i]);
    }
}
for(var i = 0; i < arr.length; i++){
    result[i] = makeFnCallback(i);
}
return result;

参考资料
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake

编辑于 2019-03-14 16:51:57 回复(0)
function makeClosures(arr, fn) {
    return arr.map(function(cur) {
        return fn.bind(null, cur);
    });
}
发表于 2018-03-30 15:11:29 回复(0)
function makeClosures(arr, fn) {
   return  arr.map(function(v,index){
        return function(){
            return fn(v);
        }
    })
}

编辑于 2017-11-30 16:15:55 回复(0)
闭包 形成私有作用域
function makeClosures(arr, fn) {
    var result=[];
    for(var i=0;i<arr.length;i++){
        !function (j){
            result.push(function (){
                return fn(j);
            })
        }(arr[i])
    }
    return result;
} 


发表于 2017-09-19 11:07:07 回复(1)
function makeClosures(arr, fn) {
    return arr.map(function(val){
        return function(){return fn(val)}
    })
}

发表于 2017-09-16 10:43:17 回复(0)
function makeClosures(arr, fn) {
var result = [];
    arr.forEach(
    function(value){
            result.push(
            function(){
                    return fn(value);
                }
            );
        }
    );
    return result;
}
发表于 2017-09-03 17:53:08 回复(0)
//看到一位同学的回答,精简了自己的代码
function makeClosures(arr, fn) {
    return arr.map(function(curr){
        return function(){
            return fn.call(null, curr);
        };
    })
}

//当然使用bind也可以做到的,这样就不用使用匿名函数包裹了
function makeClosures(arr, fn) {
    return arr.map(function(curr){
        return fn.bind(null, curr);
    });
}

编辑于 2017-08-13 11:25:16 回复(0)