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

Variable loses value when referenced a second time

本文关键字:引用 第二次 变量      更新时间:2023-09-26

我有一些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,而不以这种方式连接两个?

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

我刚刚意识到的第二件事是:你应该写两个函数——一个set函数和一个GET函数——这样就不会再拼接了。

例如

 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
}

});

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

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

你要找的是克隆你的对象,我可以在闭包库中找到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'];
}    
...