【问题标题】:Scope of function parameters in JavaScriptJavaScript中函数参数的范围
【发布时间】:2013-10-01 17:10:29
【问题描述】:

我试图让一些 jQuery 函数更容易实现,因此我尝试将一些自动完成逻辑封装到一个函数中,以允许用户发送 URL 的变量、Web 服务的参数和控制我们需要取谁的值。使用以下脚本,我得到错误:response is not defined。这个想法是,在这个 Web 服务中将有许多不同的方法具有自动完成功能,我可以简单地将适当方法的名称及其参数传递给 Complete 方法,并在多个文本框上拥有该功能。
为什么会这样

 $(document).ready(function ()
        {

            $('#auto').autocomplete(
            {

                source: function (request, response)
                {
                    Complete('GetNames', 'hospitalName', '#auto');
                }
            });
            function Complete(url, varName, target)
            {
                $.ajax(
                    {

                        type: "POST",
                        url: "Service.asmx/" + url,
                        data: "{'" + varName + "':'" + $(target).val() + "'}",
                        dataType: "json",
                        contentType: "application/json",
                        success: function (data)
                        {
                            //uncaught reference error response is not defined
                            response(data.d);
                        },
                        error: function (xhr)
                        {
                            console.log(xhr.status);
                        }
                    });
            }

        });

在我尝试取出 AJAX 调用并使其成为自己的方法之前,这一切正常。我想知道

  1. 源函数正在调用 Complete 函数,而源函数有 requestresponse 作为参数,那么为什么它们在我的脚本中未定义?
  2. 如何解决此问题并避免在 #1 中出现问题。

【问题讨论】:

  • 参数的作用域就是那个函数体。由于Complete 不在source: 函数的主体内,所以response 超出范围。
  • 那么在源代码范围内调用 Complete 没关系?嗯..更多的阅读要做。感谢您的洞察力。
  • 你需要了解lexical作用域和dynamic作用域的区别。 JS 使用词法作用域,这意味着作用域是指函数的文本体。
  • @Barmar 是的。现在我知道名字是什么,我知道要找什么了。 :)

标签: javascript jquery ajax scope


【解决方案1】:

以前它可以工作,因为变量 response 在 ajax 成功回调方法的闭包范围内可用。由于您现在创建了一个单独的方法,因此 ajax 回调不在源方法的闭包范围内,因此您需要将 requestresponse 参数作为参数传递给 Complete 方法

$(document).ready(function () {

    $('#auto').autocomplete({
        source: function (request, response) {
            Complete(request, response, 'GetNames', 'hospitalName', '#auto');
        }
    });

    function Complete(request, response, url, varName, target) {
        $.ajax({

            type: "POST",
            url: "Service.asmx/" + url,
            data: "{'" + varName + "':'" + $(target).val() + "'}",
            dataType: "json",
            contentType: "application/json",
            success: function (data) {
                //uncaught reference error response is not defined
                response(data.d);
            },
            error: function (xhr) {
                console.log(xhr.status);
            }
        });
    }

});

【讨论】:

  • 我对闭包有一点了解(我认为)。据我了解,闭包允许您获取函数范围之外的变量值。这是正确的吗?
  • @wootscootinboogie 不在函数范围之外,在函数中声明的变量将在外部函数中定义的函数中可用。在thisthis 阅读更多内容
【解决方案2】:

您可以通过将值传递给 Complete 来做到这一点,如 Arun P Johny 的回答所示。您还可以在 source: 函数中使 Complete 成为闭包:

$(document).ready(function () {
    $('#auto').autocomplete({
        source: function (request, response) {
            Complete('GetNames', 'hospitalName', '#auto');
            function Complete(url, varName, target) {
                var data = [];
                data[varname] = $(target).val();
                $.ajax({

                    type: "POST",
                    url: "Service.asmx/" + url,
                    data: JSON.stringify(data),
                    dataType: "json",
                    contentType: "application/json",
                    success: function (data) {
                        response(data.d);
                    },
                    error: function (xhr) {
                        console.log(xhr.status);
                    }
                });
            }
        }
    });
});

由于它嵌套在该函数中,因此可以访问其局部变量。

但是,如果您首先将 AJAX 代码拉到 source: 选项之外的原因是因为您希望能够从其他地方调用它(因此您可以传递不同的 URL、目标或变量名) ,这不起作用 - 该函数只能从该函数内部访问。

附:不要尝试以这种方式构建自己的 JSON,如我所示使用 JSON.stringify()

【讨论】:

  • 你说得对,我之所以尝试隔离AJAX调用是为了方便从其他地方调用。我设想了类似 control.Complete(parameters) 的东西。我很高兴我提出了要求,而不是尝试做半个下午不可能做的事情。感恩。
猜你喜欢
  • 2017-12-07
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 2017-12-28
  • 2014-01-13
  • 1970-01-01
相关资源
最近更新 更多