从已定义的函数创建闭包
Create a closure from already defined function?
我想扩展Array.sort()以接受另一个参数。这个问题有一个使用闭包的解决方案,所以这个代码有效:
var create_comparator = function(c) {
return function(a,b) { console.log(c); return a-b };
};
arr.sort( create_comparator('test') );
然而,在我的情况下,我已经定义了这样的函数:
var myComp1 = function(a,b) { console.log(c); return a-b };
返回预定义的函数不起作用:
var create_comparator = function(sortfn, c) {
// Uncaught ReferenceError: c is not defined
return sortfn;
};
var arr = [7, 4, 9, 2, 1];
arr.sort( create_comparator(myComp1, 'test') );
我想这是因为c
在创建原始函数时没有定义。我尝试用return function(a,b) { sortfn(a,b); }
创建一个新的闭包,但也不起作用。
使用这种设置,是否可以为预定义的功能提供额外的参数?这个问题还有别的解决办法吗?
您的示例并没有真正说明您对其他参数所做的操作。我仍然会尝试并建议使用分部。。。类似:
var myComp1 = function (c, a, b) { console.log(c); return a-b };
arr.sort(myComp1.bind(null, "test"));
或者,如果您仍然想将其抽象为生成器函数:
var myComp1 = function (c, a, b) { console.log(c); return a-b };
var create_comparator = function(sortfn, c) {
return sortfn.bind(null, c);
};
编辑:另一种方式!这可能是你努力实现的最好结果。这很酷的一点是,您可以将任意数量的参数附加到排序函数中,这使得额外的参数是可选的,因此您也可以将它们用作普通排序比较器。
var myComp1 = function (a, b, c) { if (c) { console.log(c); } return a-b };
var create_comparator = function() {
var sortfn = arguments[0],
partial = Array.prototype.slice.call(arguments, 1);
return function() {
var args = Array.prototype.slice.call(arguments).concat(partial);
return sortfn.apply(null, args);
}
};
您当然不能追溯修改myComp1
以关闭来自不同范围的局部变量c
;这根本不是闭包的工作方式,也不是局部变量的工作方式。首先,您应该简单地正确定义myComp1
。
但如果你不能做到这一点,那么就有一种解决方案。
因为myComp1
引用的c
是而不是范围内的局部变量,所以它真正引用的是global变量c
;也就是说,它引用全局对象上名为'c'
的属性(如果主机是Web浏览器,则为window
)。因此,您可以创建一个包装器函数,将局部变量复制到全局对象上,然后调用myComp1
;像这样的东西:
var wrapped_myComp1 = function (a,b,c) {
window.c = c;
var ret = myComp1(a,b);
delete window.c;
return ret;
};
它非常难看,这意味着这个函数是不可重入的(因为每次调用都会覆盖其他调用的c
),但它应该可以工作。
函数myComp1的问题是函数试图使用未定义的全局变量c。在JavaScript中,函数具有词法作用域,这意味着函数使用定义它们的作用域。只有关闭不足以解决你的问题。尝试在闭包中分配c变量,比如id这个代码:
var arr = [1,4,3,5,7,1,2],
c;//it's a global variable, this is not a good approach. Good approach is change myComp1 definition, if you can.
var myComp1 = function(a,b) { console.log(c); return a-b };
var comp = function(prop) {
c = prop; //this assignment push prop variable to global variable c, that uses in your function
return myComp1;
}
console.log(arr.sort(comp('additional_param')));
这将适用于
var c = 'test'
var myComp1 = function(a,b) { console.log(c); return a-b };
arr.sort( myComp1 );
这里闭包定义了c(但你需要如上所述定义它,如果你没有定义c,那么你会得到你得到的错误)。
- 使用闭包创建原型中引用的私有属性
- 如何使用继承创建类似谷歌闭包的结构
- 为什么需要在这个闭包中创建一个变量
- 是否可以在Javascript中创建外部闭包
- React js:为什么我无法创建闭包
- Javascript:是为所有变量创建的闭包,还是只为内部函数可能使用的变量创建的闭包
- 在闭包上创建多个元素的列表器
- 创建带有回调的动态 JSON 数组(内部闭包问题)
- 为什么咖啡脚本创建此闭包
- 我们是否可以使用谷歌闭包创建一个带有复选框和组合框的对话框
- 闭包可以使用new关键字和区别,例如,在创建新对象/类时
- 在javascript中,当原型继承比闭包更适合创建对象时
- 使用闭包创建的私有函数如何访问构造函数中定义的变量
- 无法创建闭包中定义的函数的对象
- 在for循环中创建闭包——我这样做对吗
- 参数变量在JavaScript中创建闭包
- 如何在承诺链中继承数据而不创建闭包
- 如何为必应地图事件创建闭包
- 从已定义的函数创建闭包
- 如何在循环中创建闭包并将其存储在变量中以供以后执行