首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >无法访问JavaScript中函数内的函数中的变量

无法访问JavaScript中函数内的函数中的变量
EN

Stack Overflow用户
提问于 2012-08-05 23:34:47
回答 2查看 117关注 0票数 1
代码语言:javascript
代码运行次数:0
运行
复制
function updateRoomsList() {
    //empty the rooms list
    $("#rooms").empty();
    //fetch the non-joined rooms, id and name
    $.get('JoinPart', {
        goal: 5,
        userName: $("#userName").html()
    }, function (responseText) {
        var i = 0;
        id = "";
        while (i < responseText.length) {
            if (responseText.charAt(i) == '.') {
                //Now we got the full Id of a room, lets add it
                $.get('JoinPart', {
                    goal: 6,
                    roomId: id
                }, function (responseText) {
                    roomName = responseText;
                    $("#rooms").append('<div id="room' + id + '" class="listItem"><span title="Join Room" class="joinButton">+</span><div class="listItemContent">' + roomName + '</div></div>');
                });
                id = "";
            } else {
                id = id + responseText.charAt(i);
            }
            i++;
        }
    });
}

在这个函数中有一个变量id,如果我在

代码语言:javascript
代码运行次数:0
运行
复制
if(responseText.charAt(i)=='.')

我得到了在else中计算的id的正确值,但是当我在$.get中执行alert(id);时,id是空的"",这意味着在append函数中,id没有值,我如何才能让这个id在$.get函数之外具有值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-05 23:46:02

这是因为id的作用域是在外部闭包中,所以内部回调将获得在while循环末尾设置的最后一个值的引用。如果在第二个$.get()回调函数中需要id变量的私有副本,则需要编写

代码语言:javascript
代码运行次数:0
运行
复制
$.get('JoinPart', {goal :6, roomId :id }, (function (id) {
  return function (responseText) {
    roomName = responseText;
    $("#rooms").append('<div>' + id + '</div>');
  }
})(id));

当你这样做的时候,你用一个局部变量id创建了一个新的作用域,它被赋予了id在当前迭代中的确切值,而不是局部变量id本身,在循环结束时(或者实际上是在下一次迭代中),它可以是任何东西。

构造(function(arg){})(arg)称为。请注意,此函数返回一个新的函数对象,即$.get()所需的对象

闭包是定义在另一个闭包中的函数。根据定义,闭包可以访问外部函数的所有局部变量。当您为稍后执行$.get()提供一个回调时,您实际上是在使用一个闭包:当执行回调时(可能在几秒钟之后),JS引擎将使id仍然可访问,但它的值显然取决于代码的其余部分。

如果你需要存储一个变量的当前快照供以后阅读,你需要创建一个新的闭包(即一个新的作用域):我们使用IIFE来实现这个目的。scope是在实际的HTTP请求被触发之前执行的(即在调用$.get()之前执行),而且它是最近的回调作用域,所以当回调将被执行时,它将用于解析id引用。

您可以通过确定以下代码段将打印的内容来测试您是否理解了这个概念

代码语言:javascript
代码运行次数:0
运行
复制
function inner() {
  console.log(i);          
}

for (var i = 0; i < 3; i++) {
  inner();
  setTimeout(inner, 1000);
}​
票数 1
EN

Stack Overflow用户

发布于 2012-08-05 23:40:46

代码流不是你想的那样的顺序。

代码语言:javascript
代码运行次数:0
运行
复制
            id="";

在函数内函数之前发生,这被称为闭包(顺便说一句,这应该有助于您的googling搜索)。添加print语句

代码语言:javascript
代码运行次数:0
运行
复制
alert("here 1");
alert("here 2"); 

在闭包中,在id="";和这之前应该跳出来。

最简单的修复方法可能是在闭包中将idroomId互换,因为作为简单的字符串或整数,值完全复制到roomId中,即使id发生更改,它也是安全的(好的,更准确地说,id=...只更改引用,因此roomId引用的值保持不变。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11817701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档