我想扩展Array.sort()以接受另一个参数。 This question有一个使用闭包的解决方案,所以这段代码有效:
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); }
来创建一个新的闭包,但这也不起作用。
使用此设置是否可以将额外参数用于预定义功能?这个问题还有另一个解决方案吗?
答案 0 :(得分:2)
您的示例并未真正说清楚您正在使用其他参数做什么。我仍然会采取刺激并建议使用偏见......如:
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);
}
};
答案 1 :(得分:2)
您当然无法追溯修改myComp1
以关闭来自其他范围的本地变量c
;这根本不是闭包的工作方式,也不是局部变量的工作原理。您应该首先正确定义myComp1
。
但如果你不能这样做,那么就有一种解决方案。
因为myComp1
引用的c
不是范围内的局部变量,所以它真正引用的是 global 变量{{ 1}};也就是说,如果主机是Web浏览器,它会在全局对象(c
)上引用名为'c'
的属性。所以你可以做的是,你可以创建一个包装函数,将局部变量复制到全局对象上,然后调用window
;像这样的东西:
myComp1
这非常难看,这意味着这个函数是不可重入的(因为每个调用都会覆盖彼此的调用var wrapped_myComp1 = function (a,b,c) {
window.c = c;
var ret = myComp1(a,b);
delete window.c;
return ret;
};
),但它应该可以工作。
答案 2 :(得分:0)
函数问题myComp1是你的函数尝试使用未定义的全局变量c。 在JavaScript函数中有词法范围,而不是函数使用它们定义的范围。只有关闭不足以解决您的问题。尝试在闭包中分配c变量,例如id this code:
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')));
答案 3 :(得分:0)
这将有效
var c = 'test'
var myComp1 = function(a,b) { console.log(c); return a-b };
arr.sort( myComp1 );
这里的闭包定义了c(但你需要它定义如上,如果你没有定义c,那么你将得到你得到的错误。)