变量未定义范围

时间:2014-08-02 01:17:47

标签: javascript jquery html css

这是我的代码:

function example() { 
     var post = object.get("owner");
         post.fetch({
            success: function(post) {
               window.titles = post.get("username");
               console.log(window.titles);
            }
         });
     console.log(window.titles);
} 

第一个日志成功运行。在该方法之外,第二个日志打印为未定义。为什么呢?

4 个答案:

答案 0 :(得分:1)

这是异步调用。内部将在POST成功后执行。同时在你开始发送POST后执行外部执行。 POST成功时定义window.titles

因此,在执行外部调用时,window.titles未定义。 你应该看看这个http://api.jquery.com/jquery.ajax/

答案 1 :(得分:0)

post.fetch函数是异步的,这意味着它需要回调才能完成调用,否则你永远不会知道函数何时完成。异步函数与其余代码分开运行。

当您致电post.fetch时,它会自行启动并且不会停止脚本,因此在调用post.fetch之后,会执行下一行代码,实际上是console.log(window.titles) 。但window.titles尚未定义,因为post.fetch仍然有效。

post.fetch完成工作时,执行给定的回调函数,然后定义window.titles变量。因此,如果您要记录window.titles,则必须将console.log()仅放在post.fetch的回调中。

答案 2 :(得分:0)

它适用于外部功能,但不能立即使用,因为异步调用需要一些时间。这就是JS的本质。

最简单的方法"其中"是将所有直接依赖于异步函数结果的代码移动到另一个函数中,然后从成功回调中运行它。

这样的事情:

function example() { 
     var post = object.get("owner");
         post.fetch({
            success: function(post) {
               window.titles = post.get("username");
               otherImportantCode(); // call the remaining code from here
            }
         });
     console.log(window.titles); // won't work here
} 

function otherImportantCode() {
     console.log(window.titles); // see, it works here, outside the example function
     // ... the rest of the code depending on window.titles
}

当您准备好更高级地处理此类问题时,请了解承诺和事件。

答案 3 :(得分:0)

将异步数据视为仅在成功回调中定义是有帮助的。虽然它可能并非总是如此,但这是它始终定义的唯一时间。如果您在成功回调之外的任何时候,可能尚未检索到数据,并且回调可能尚未运行。

如果删除异步调用,这就是您的程序的样子:

function example() { 
     var post = object.get("owner");
     post.fetch();
     console.log(window.titles);
}

这里更明显的是window.titles未定义。

在其他地方的一个单独的线程上,一旦post.fetch()完成,这将被执行(在将来的某个时间,谁知道...它可能在1毫秒内,可能需要1天,你真的不知道):

(function(post) {
   window.titles = post.get("username");
   console.log(window.titles);
})()

你现在看到问题是什么吗? window.titles尚未设置。 post.fetch()已被调用,但成功回调尚未返回。

在您实际检索数据之前,没有办法做您要求的,即检索数据。任何需要获取数据的可预测性的东西都必须在回调中发生(编辑:或者你可以使用promises或deferreds等等......但是这些对于你在这里尝试做的事情来说更复杂)。这就是为什么成功回调中的console.log()工作原理,外面的那个可能永远不会工作。