JavaScript/jQuery 中对象原型方法回调的明智方法?
Sensible approach to callbacks on object prototype methods in JavaScript/jQuery?
我在下面所做的是允许对对象原型中定义的函数进行回调 运行 以使范围正确吗?
当对象的原型方法是 运行 响应可能源自 [=] 的回调时,我一直在努力设置 this
的值34=] 请求或来自点击绑定或其他。
这是一个简化的注释版本:
// everything is inside an object which provides the namespace for the app
var namespace = {
// a fairly vanilla object creation routing, which uses the prototype
// approach for defining the functions on the object
newObj : function(params) {
var MyObj = function(params) {
this.property = params.property
};
MyObj.prototype = namespace.ObjPrototype;
return new MyObj(params);
},
// the prototype itself, which defines 2 related functions
ObjPrototype : {
// The first is called to do some form of asynchronous operation
// In this case it is an ajax call
doAsync: function (params) {
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: namespace.objClosure(this, "asyncSuccess", ["data"]),
});
// the final line above is the key here - it asks a function (below)
// for a closure around "this", which will in turn run the
// function "asyncSuccess" (defined next) with the argument "data"
},
// This is the actual callback that I want to run. But we can't
// pass this.asyncSuccess to the ajax function above, because the
// scope at execution time is all wrong
asyncSuccess : function(params) {
this.property = params.data;
},
},
// This is the bit I sort of invented, to help me around this problem.
// It returns a function which provides a closure around the object
// and when that returned function is run it inspects the requested
// arguments, and maps them to the values in the JS default
// "arguments" variable to build a parameters object which is then
// passed to the function on the object
objClosure : function(obj, fn, args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
obj[fn](params);
} else {
obj[fn]();
}
}
}
}
现在,显然实际的目标回调 MyObj.asyncSuccess
需要知道它将获得一个 params 对象,它将是什么结构,并且调用函数必须共享这些知识 MyObj.doAsync
,但除此之外这似乎运作良好。
我的问题是 - 我完全疯了吗?我是否错过了一些明显的东西,这些东西会以 simpler/less 复杂的方式为我解决这个问题?到这个阶段我是不是离兔子洞太远了?
我已经阅读了很多关于 SO 的问题,它们都解决了我的部分问题,但我似乎还没有深入了解这个问题的普遍接受的解决方案。我不可能是唯一一个想这样做的人:)
编辑
我接受了下面的答案,但您也需要阅读所有评论才能将其整合在一起。感谢大家的帮助!
你是不是把事情复杂化了?看看下面的代码是否对你有帮助。我没有完全理解你的意图,但下面的代码应该可以帮助你
function newObj(params) {
function asyncSuccess(params) {
this.property = params.data;
}
function objClosure(obj, fn, args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
obj[fn](params);
} else {
obj[fn]();
}
}
}
this.property = params.property
this.doAsync = function (params) {
console.log('reached async');
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: objClosure(this, "asyncSuccess", ["data"]),
});
}
}
var k = new newObj({'property':'xyz'});
k.doAsync();
看到 "GameAlchemist" 的评论后,我研究了 objClosure 函数,我认为我们可以使用以下代码进一步改进:我仍然不确定 this.property 或数据的值是什么一个适当的解决方案因此只假设一些事情
function newObj(params) {
function asyncSuccess(params) {
this.property = params ? params.data : null;
}
function objClosure(args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
asyncSuccess(params);
} else {
asyncSuccess();
}
}
}
this.property = params.property
this.doAsync = function (params) {
console.log('reached async');
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: objClosure(["data"]),
});
}
}
这里有几个问题:
如果您已经将 params.data 传递给数据,即 data:params.data,您如何再次分配值 this.property = params.data?有几件事令人困惑,但我希望上述解决方案有效:)
我在下面所做的是允许对对象原型中定义的函数进行回调 运行 以使范围正确吗?
当对象的原型方法是 运行 响应可能源自 [=] 的回调时,我一直在努力设置 this
的值34=] 请求或来自点击绑定或其他。
这是一个简化的注释版本:
// everything is inside an object which provides the namespace for the app
var namespace = {
// a fairly vanilla object creation routing, which uses the prototype
// approach for defining the functions on the object
newObj : function(params) {
var MyObj = function(params) {
this.property = params.property
};
MyObj.prototype = namespace.ObjPrototype;
return new MyObj(params);
},
// the prototype itself, which defines 2 related functions
ObjPrototype : {
// The first is called to do some form of asynchronous operation
// In this case it is an ajax call
doAsync: function (params) {
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: namespace.objClosure(this, "asyncSuccess", ["data"]),
});
// the final line above is the key here - it asks a function (below)
// for a closure around "this", which will in turn run the
// function "asyncSuccess" (defined next) with the argument "data"
},
// This is the actual callback that I want to run. But we can't
// pass this.asyncSuccess to the ajax function above, because the
// scope at execution time is all wrong
asyncSuccess : function(params) {
this.property = params.data;
},
},
// This is the bit I sort of invented, to help me around this problem.
// It returns a function which provides a closure around the object
// and when that returned function is run it inspects the requested
// arguments, and maps them to the values in the JS default
// "arguments" variable to build a parameters object which is then
// passed to the function on the object
objClosure : function(obj, fn, args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
obj[fn](params);
} else {
obj[fn]();
}
}
}
}
现在,显然实际的目标回调 MyObj.asyncSuccess
需要知道它将获得一个 params 对象,它将是什么结构,并且调用函数必须共享这些知识 MyObj.doAsync
,但除此之外这似乎运作良好。
我的问题是 - 我完全疯了吗?我是否错过了一些明显的东西,这些东西会以 simpler/less 复杂的方式为我解决这个问题?到这个阶段我是不是离兔子洞太远了?
我已经阅读了很多关于 SO 的问题,它们都解决了我的部分问题,但我似乎还没有深入了解这个问题的普遍接受的解决方案。我不可能是唯一一个想这样做的人:)
编辑
我接受了下面的答案,但您也需要阅读所有评论才能将其整合在一起。感谢大家的帮助!
你是不是把事情复杂化了?看看下面的代码是否对你有帮助。我没有完全理解你的意图,但下面的代码应该可以帮助你
function newObj(params) {
function asyncSuccess(params) {
this.property = params.data;
}
function objClosure(obj, fn, args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
obj[fn](params);
} else {
obj[fn]();
}
}
}
this.property = params.property
this.doAsync = function (params) {
console.log('reached async');
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: objClosure(this, "asyncSuccess", ["data"]),
});
}
}
var k = new newObj({'property':'xyz'});
k.doAsync();
看到 "GameAlchemist" 的评论后,我研究了 objClosure 函数,我认为我们可以使用以下代码进一步改进:我仍然不确定 this.property 或数据的值是什么一个适当的解决方案因此只假设一些事情
function newObj(params) {
function asyncSuccess(params) {
this.property = params ? params.data : null;
}
function objClosure(args) {
return function() {
if (args) {
var params = {};
for (var i = 0; i < args.length; i++) {
params[args[i]] = arguments[i];
}
asyncSuccess(params);
} else {
asyncSuccess();
}
}
}
this.property = params.property
this.doAsync = function (params) {
console.log('reached async');
$.ajax({
type: "get",
url: params.url,
data: params.data,
dataType: params.datatype,
success: objClosure(["data"]),
});
}
}
这里有几个问题: 如果您已经将 params.data 传递给数据,即 data:params.data,您如何再次分配值 this.property = params.data?有几件事令人困惑,但我希望上述解决方案有效:)