第二次引用时,变量值会丢失

时间:2013-07-10 01:31:14

标签: javascript google-closure

我有一些Ajax从数据库获取信息并将其存储在名为targetVocab的数组中。此信息用于在调用setVocab()时设置vocab的值。这在第一次工作正常,但是当再次播放按钮按钮并且第二次调用setVocab时,它不起作用。第二次看起来targetVocab是空的。这是我的简化脚本......

var targetVocab;
var vocab;
var request = new goog.net.XhrIo();

goog.events.listen(request, "complete", function(){

    if (request.isSuccess()) {
        response = request.getResponseJson();
        targetVocab = response['targetVocab'];
        setVocab(targetVocab);
    }

});

request.send("load_vocab.php");

var setVocab = function(targetVocab) {
    vocab = targetVocab;
}

var getVocab = function() {
    return vocab;
}


goog.events.listen(playAgainButton, ['mousedown', 'touchstart'], function(e) {
    getVocab();
});

更新 我已经意识到,无论我对vocab做了什么,都同样适用于targetVocab。我最初的想法是,我可以在整个应用中拼接来自vocab的元素,然后通过将vocab重新设置为targetVocab将其重置为原始状态。有没有办法将vocab设置为targetVocab而不保留两个以这种方式连接的?

2 个答案:

答案 0 :(得分:2)

您需要以不同方式定义函数setVocab。

我刚刚意识到的第二件事:你应该编写2个函数,一个集合函数和一个GET函数,这样就不会再拼接了。

e.g。

 function setVocab(targetVocab){
    vocab = targetVocab;       
}

这样您就可以确保将targetVocab作为变量传递给它。 现在GET功能相应:

 function getVocab(){
    return vocab;
}

或将其放入一个(不推荐)

function setVocab(targetVocab){
    if(targetVocab!=""){
     vocab = targetVocab;
    }else{
     return vocab;
    }
}

现在取决于您实施的内容,请致电

goog.events.listen(playAgainButton, ['mousedown', 'touchstart'], function(e) {
getVocab();

});

或者如果您实施了“不推荐”代码,请使用此

goog.events.listen(playAgainButton, ['mousedown', 'touchstart'], function(e) {
setVocab("");

});

goog.events.listen(request, "complete", function(){

if (request.isSuccess()) {
    response = request.getResponseJson();
    targetVocab = response['targetVocab'];
    setVocab(targetVocab); //chaged here
}

});

答案 1 :(得分:1)

我认为您的问题是由将vocab设置为targetVocab引起的。在JavaScript中,当您将新变量设置为对象变量的值时,两个变量都将指向同一个对象:

var a = [{a:0}];
var b = a
a.splice(0,1);
console.log(b);//=[] empty array

你正在寻找的是克隆你的对象,我可以在closure library中找到goog.object.clone和goog.object.unsafeClone。

clone只会执行浅拷贝,所以如果你的数组包含不可变对象或主要类型,你可以使用clone,但是如果你要对克隆数组做一些事情,如下例所示,你需要unsafeClone:

var a = [{a:0}];
var b = goog.object.clone(a);
a[0].a=22;
console.log(b[0]);//=22
// b isn't even an array here so I'm not sure what clone does
//   but it doesn't do much
console.log(b instanceof Array);//false

如果您永远不会更改数组项的值,也从不调用会更改项内部值的函数(例如copiedarray[0].changevalue();copiedarray[index].someval=newval;),那么您可以复制引用新数组中的项目:

var a = [{a:0}];
var b = a.concat([]);
// can't do a[0].a=newValue or it'll permanently change
a.splice(0,1);
console.log(b[0]);//=0

UnsafeClone将完全克隆该对象,但当任何对象(属性)的属性引用自身时,您将冒着启动永不结束循环的风险:

var a = [{a:0}];
var b = goog.object.unsafeClone(a);
a[0].a=22;
console.log(b[0]);//=0
console.log(b instanceof Array);//true

在你的情况下;由于要复制的对象来自JSON字符串,因此不会有循环引用,但可能有更好的方法,因为unsafeClone可能比goog.json.parse

...
if (request.isSuccess()) {
    targetVocab = request.getResponseText();
    setVocab();
}
...
var setVocab = function() {
  vocab = goog.json.parse(targetVocab)['targetVocab'];
}    
...