这可能是一个愚蠢的问题,但由于所有“关闭101”链接,我似乎无法利用谷歌......
总之,给定依赖于闭包上下文的重复代码,是否有一种方法可以将代码重复数据删除到函数调用中,同时仍然让新函数仅依赖于闭包而不是通过参数传递它所需的一切?
粗略的代码示例可能如下所示:
function doWork(){
// initialize variables
// manipulate variables
// ...
$.ajax({
//...
success: function(data){
// DUPLICATE CODE INSTANCE 1 HERE
// RELIES ON VARIABLES IN THE CLOSURE
}
});
// More code
$.ajax({
//...
success: function(data){
// DUPLICATE CODE INSTANCE 2 HERE
// RELIES ON VARIABLES IN THE CLOSURE
}
});
}
据我所知,如果我将成功块中的逻辑删除为
function onSuccess(...){
// ...
}
然后onSuccess不再是闭包的一部分,因此需要将所有闭包变量作为参数传递,当前逻辑使用闭包来访问。
我对闭瓶的工作原理有误吗?有没有办法“将闭包”传递给onSuccess函数而不是传递单个变量?
答案 0 :(得分:4)
关闭行为你没有错。您可以做的是在onSuccess
内声明doWork
函数。
function doWork(...) {
function onSuccess(...) {
// ...
}
$.ajax({
//...
success: onSuccess
});
$.ajax({
//...
success: onSuccess
});
}
答案 1 :(得分:2)
除非你在闭包中定义它
function doWork(){
// initialize variables
// manipulate variables
// ...
function onSuccess(data){
// DUPLICATE CODE INSTANCE 2 HERE
// RELIES ON VARIABLES IN THE CLOSURE
}
$.ajax({
//...
success: onSuccess
});
// More code
$.ajax({
//...
success: onSuccess
});
}
答案 2 :(得分:0)
您可以做的是使用public
将您需要的内容转换为等效于this.var
变量的JavaScript。然后,您可以将this
的引用传递给闭包范围之外的对象,并访问您传递的闭包的属性和方法(来自this
)。以下面的代码为例:
从@ danp的指导编辑:
var Work = function Work() {
this.closureVar = "hello";
this.closureOnSuccess = function () {
console.log("Inner call:" + this.closureVar);
}
this.someCall = function() {
globalOnSuccess(this); //Give the global function a reference to this closure
this.closureOnSuccess();
}
this.someCall();
}
var globalOnSuccess = function (context) { //context is a reference to a closure
console.log("Outer call:" + context.closureVar);
}; //Globally scoped function
var work = new Work();
另一个例子:
var Work = function Work() {};
Work.prototype = {
closureVar: "hello",
closureOnSuccess: function () {
console.log("Inner call:" + this.closureVar);
},
someCall: function () {
globalOnSuccess(this);
this.closureOnSuccess();
}
};
var globalOnSuccess = function (context) {
console.log("Outer call:" + context.closureVar);
};
var work = new Work();
work.someCall();