在Javascript函数中设置JSON对象并将其传递给另一个函数

时间:2013-04-06 03:42:41

标签: javascript json

我正在尝试从Javascript函数设置JSON对象并将其用作另一个函数中的参数,但此obj在函数外部没有任何值。 我在函数外创建了这个json对象:

var obj = {"Level":0, "Index":0, "Count":0, "AABB":[], "Point":[], "Children":[]};

然后

function loadXMLDoc()
  {  
   if(window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
   } else {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send();

   return obj;  
  }

但在我调用函数并传递obj后,就像这样:

    var obj = loadXMLDoc();
    initGL(canvas);
    initShaders();
    initBuffers(obj);

它无法将值传递给initBuffers函数。为什么会发生这种情况,我该如何解决?感谢。

4 个答案:

答案 0 :(得分:2)

当你说你不能将obj作为参数传递时,我不确定你是什么意思,但有一点需要注意的是你的onreadystatechange处理程序在你调用{{1}之后被异步调用}}。也许,当解析JSON响应时,您需要从处理程序内部调用初始化例程。

答案 1 :(得分:0)

由于@akonsu所说的(onreadystatechange的同步特性),{init}函数运行时仍然会运行loadXMLDoc()。因此,当obj运行时,您的initBuffers(obj)变量尚未定义。

一个简单的解决方案是向loadXMLDoc()添加回调:

function loadXMLDoc(objParsed)
  {  
   ...
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
        objParsed(obj);
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send(); 
  }

并像这样使用它(假设initGL()initShaders()不依赖initBuffers()的结果):

loadXMLDoc(initBuffers);
initGL(canvas);
initShaders();

另外,您似乎正在更改obj的价值:

obj = JSON.parse(string);

因此,当您稍后尝试访问obj.Children时,除非您的xmlhttp.responseText是有效的JSON并且根目录下具有Children属性,否则它将不会存在。它还将完全覆盖您在脚本顶部设置的值。

答案 2 :(得分:0)

像@akonsu说的那样,在ajax调用完成之前调用loadXMLDoc函数的返回因为该调用是异步的,所以当你执行ajax时,会创建另一个带有该调用的进程,然后是当前进程(使用函数loadXMLDoc)工作不关心,只有调用结束时调用onreadystatechange函数内的代码,所以我建议你创建一个函数回调,执行ajax onreadystatechange中的代码,如下所示:

function loadXMLDoc()
  {  
   if(window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
   } else {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        var obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
        SOME_CALLBACK(obj)  
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send();

   //return obj;  no needed any more
  }

function SOME_CALLBACK(obj){
    initGL(canvas);
    initShaders();
    initBuffers(obj);
}

所以这样SAVE_CALLBACK函数接收异步obj数据并使用它们。

答案 3 :(得分:0)

函数内部的变量绑定到该特定函数,并且不能从函数外部到达,除非它们在包含变量的函数内或者变量设置为全局变量。

如果只有几个对象是脏的方法是创建一个使用全局容器的跨度。