2

我有一个名为 writeMessage 的函数。writeMessage 调用 ajax 请求来获取本地化内容。一旦从 ajax 请求返回内容,它还会在“n”秒后淡出消息。所以这一切都有效,我已经测试了许多调用,但是,我觉得它过于复杂,因为在处理 javascript 闭包语句时我不完全理解变量的范围。谁能告诉我我是否在这里跳过了太多的箍来完成以下任务。

函数getTextResource接受参数,(字符串、字符串、对象、函数)

  • 'function' 参数是一个回调,在 ajax 请求完成后调用。
  • 'object' 参数是一个 arguments 对象,包含有关如何以及在何处写入消息的所有详细信息。
  • 'string' & 'string' 参数被传递到 ajax 请求中。

在 getTextResource 中,我正在调用一个 ajax 方法,将“object”参数作为上下文以及原始默认文本和回调函数传递 ajax 请求完成后,通过上下文,我现在调用回调函数,将结果传递给它服务调用以及参数。

如果再次调用该函数,我是否需要继续传递上下文,或者传递给 getTextResoruce 的所有内容都不会被分配不同的值?

function writeMessage(args) {
    var d = $('<div></div>');

    getTextResource(args.resourceId, args.message, { args: args, messageElement: d },
        function (text, context) {
            var args = context.args;
            var d = context.messageElement;

            d.empty();
            d.append(text);

            args.element.append(d);

            if (args.fadeTimeOut > 0)
                setTimeout(function () {
                    d.fadeOut('slow', function () {
                        $(this).remove();
                    });
                }, args.fadeTimeOut);
        }
    );
}

var getTextResource = function (resourceId, defaultText, context, cb) {
    resourceId = resourceId + '';
    defaultText = defaultText + '';

    if (resourceId == '') resourceId = defaultText;
    if (defaultText == '') defaultText = resourceId;

    try{
        var request = $.ajax({
            type: 'GET',
            url: 'http://localhost/EaiCCM/api/' + BusinessScope.Version + '/' + BusinessScope.CampaignSegment + '/TextResource',//?' + qs,
            data:  {ResourceId: resourceId, DefaultText: defaultText},
            cache: false,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            context: { defaultText: defaultText, context: context, cb: cb }
        });

        request.done(function (result) {
            var txt = this.defaultText;
            try {
                if ($.isPlainObject(result))
                    txt = result.Detail;
            }
            catch (e) {
            }
            finally {
                if (typeof this.cb == 'function')
                    this.cb(txt, this.context);
            }
        });

        request.fail(function (jqXHR, textStatus, context) {
            if (typeof this.cb == 'function')
                this.cb(this.defaultText, this.context);
        });
    }
    catch (e) {
        if (typeof cb == 'function')
            cb(defaultText, context);
    }
};
4

1 回答 1

0

不,context如果您在writeMessage. (作用域对于函数的每次调用都是本地的。)

这个:

    function (text, context) {
        var args = context.args;
        var d = context.messageElement;

可以很容易地:

    function (text) {

并且request.done可以阅读:

    request.done(function (result) {
        var txt = defaultText;
        try {
            if ($.isPlainObject(result))
                txt = result.Detail;
        }
        catch (e) {
        }
        finally {
            if (typeof cb == 'function')
                cb(txt);
        }
    });

参数的范围仅限于作为参数的函数的每次调用。var变量的范围仅限于语句function上方第一个的调用。范围仅持续到关闭它的大括号varfunction

所以,在这段代码中:

function writeMessage(args) {
  var d = $('<div></div>');
  var rid = args.resourceId;

  var cb = function (text) {
    var exampleVar = text.toUpper();
    d.textContent = exampleVar + rid;
  }

  getTextResource(rid+'-san', 'foo', cb)
  getTextResource(rid+'-chan', 'bar', cb)
}

function getTextResource(resourceId,defaultText,cb) {
  // for simplicity's sake let's just simulate a default scenario

  // Note that the `resourceId` passed to `getTextResource`
    // is in no way passed to the callback here

  cb(defaultText);
}
  • args, rid, 和d对 的每次调用都是本地的writeMessage
  • text并且exampleVar对于回调的每个调用都是本地的cb
  • resourceId并且对于 .defaultText的每次调用都是本地的getTextResource
  • cb是我们构造的writeMessage回调,也是我们传入的回调getTextResource。尽管它们具有相同的名称,但不同的作用域意味着它们实际上被视为两个不同的变量。(如果这令人困惑,请参见下面的类比。)
  • 当使用getTextResource调用回调时'bar',它会修改与d调用回调时相同的修改'foo',因为回调中使用的是构造它d的本地的。writeMessage
  • exampleVar但是,textContentof设置为的值d在每次调用中都会有所不同,因为它是回调本地的。
  • 的值exampleVar不会以附加的 or 结尾'-san'因为'-chan'它们被附加到resourceId的范围内getTextResource,这对范围是不可见的writeMessage(变量被调用的地方ridresourceId无论如何也不可见)。

不同作用域同名变量的类比

变量名称在不同的上下文中指代不同的值,例如“Bob”在Bob's Burgers中的含义与在Bob the Builder中的含义不同。然而,在一个上下文中,“Bob”可能指的是在其原始上下文中也被称为“Bob”的东西,例如在Archer第 4 季的第一集中,Sterling 被称为“Bob”并在“Bob's Burgers”工作"(作为参考 H. Jon Benjamin 为两个角色提供声音)。您可以声称这是一个巧合,“真正的”鲍勃汉堡“鲍勃”存在于Archer世界的其他地方,但无论他是否是同一个“鲍勃”弓箭手到下一个。

于 2013-03-02T17:10:46.900 回答