OO Javascript - 适当的范围处理?
问题描述:
我写了一个简短而不完整的例子(为了这个问题),试图使用jQuery来总结一组图像的宽度。我遇到一些问题,弄清楚如何处理复杂的OO javascript应用程序中的范围。OO Javascript - 适当的范围处理?
function imageContainer(){
this.selector = "img.inContainer";
this.width = function(){
var tmp = 0;
$(this.selector).each(function(){
// use load to preload images
$(this).load(function(){
// our 'this' pointer to the original object is long gone,
// so is it even possible to accumulate a sum without using
// globals? Ideally, I'd like to increment a temporary value
// that exists within the scope of this.width();
tmp+=$(this).width();
});
});
// I'm thinking that returning here is problematic, because our
// call to each() may not be complete?
return tmp;
}
this.construct = function(){
alert(this.width());
}
this.construct();
}
我真的不想找解决此问题一个黑客,我想知道如何这样的事情应该被做 - 在不垃圾的封装方式。我错过了明显的东西吗?
非常感谢。
答
function imageContainer() {
this.selector = "img.inContainer";
this.width = function(cb) {
var tmp = 0;
var len = this.length;
var count = 0;
$(this.selector).each(function() {
// use load to preload images
var that = this;
// load is ajax so it is async
$(this).load(function() {
tmp += $(that).width();
if (++count === len) {
// counted all.
cb(tmp);
}
});
});
};
this.construct = function(cb) {
this.width(function(data) {
alert(data);
});
};
this.construct();
}
欢迎来到ajax。异步并行执行一堆操作。所以你需要跟踪完成多少次并完成所有回调。
像.load
这样的任何异步操作都需要您对块进行100s的ms或更改您的API以使用回调。您可以使用$.proxy
来代替。
// load is ajax so it is async
$(this).load($.proxy(function() {
tmp += $(this).width();
if (++count === len) {
// counted all.
cb(tmp);
}
}, this));
既然你有你的射击回调之前做ňAJAX任务的结构,你可以用一些糖概括这一点。
this.width = function(cb) {
// map all images to deferred objects, when deferred objects are resolved
$.when($.makeArray($(this.selector).map(function() {
var def = $.Deferred();
$(this).load(function() {
def.resolve();
});
return def;
// then sum the widths and fire the callback.
}))).then($.proxy(function(data) {
var tmp = 0;
$(this.selector).each(function() {
tmp+=$(this).width();
});
cb(tmp);
}, this));
};
注意这里我真的想用$.fn.reduce
但它不存在。它可能是
// reduce the set of images to the sum of their widths.
cb($(this.selector).reduce(0, function(memo, key, val) {
return memo + $(this).width();
}));
退一步讲这个糖不作任何简单的,至少它看起来更像LISP那么C现在。
非常感谢,这都是非常好的信息。 – user688216 2011-04-16 01:37:04