OOJavaScript-正确的作用域处理?

OOJavaScript-正确的作用域处理?,javascript,jquery,scope,Javascript,Jquery,Scope,为了回答这个问题,我编写了一个简短而不完整的示例,试图使用jquery对一组图像的宽度求和。我在弄清楚如何在复杂的OOJavaScript应用程序中处理作用域时遇到了一些问题 function imageContainer(){ this.selector = "img.inContainer"; this.width = function(){ var tmp = 0; $(this.selector).each(function(){

为了回答这个问题,我编写了一个简短而不完整的示例,试图使用jquery对一组图像的宽度求和。我在弄清楚如何在复杂的OOJavaScript应用程序中处理作用域时遇到了一些问题

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
这样的异步操作都需要阻塞100毫秒或更改API以使用回调

您也可以使用
$.proxy
代替
var=this
模式

// load is ajax so it is async
$(this).load($.proxy(function() {
    tmp += $(this).width();
    if (++count === len) {
        // counted all.
        cb(tmp);
    }
}, this));
由于您具有在启动回调之前执行n个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

欢迎来到ajax。您可以异步并行执行一系列操作。因此,您需要跟踪完成了多少次,并在全部完成后发出回调

任何像
.load
这样的异步操作都需要阻塞100毫秒或更改API以使用回调

您也可以使用
$.proxy
代替
var=this
模式

// load is ajax so it is async
$(this).load($.proxy(function() {
    tmp += $(this).width();
    if (++count === len) {
        // counted all.
        cb(tmp);
    }
}, this));
由于您具有在启动回调之前执行n个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