函数和手表内部的JS引用

JS reference inside function and watch

本文关键字:JS 引用 内部 手表 函数      更新时间:2023-09-26

我的以下代码有问题。我不明白它有什么问题。

function some(){
 for (var i=0;i<....;i++)
 {
   var oneObject;
   ...some logic where this object is set
   oneObject.watch(property,function(id, oldval, newval){
       globalFunction(oneObject,id,newval);
       return newval;
   });
 }
}

例如,如果我有三个周期并设置三个不同的对象,我会得到以下结果。设置了三个不同的对象(例如oneObject can be equal some={},some.foo={}, some.boo={})。它们中的每一个都有自己的监视处理程序(我更改对象并调用处理程序)。问题在于,当 globalFunction 被调用时,作为参数传递的 oneObject 总是等于 for 循环的最后一个对象。

我不明白为什么它就像每个新循环一样,我使用 var 重新声明 oneObject 变量。 请解释一下。

编辑
我也尝试过:

function some(){
 for (var i=0;i<....;i++)
 {
   var oneObject;
   ...some logic where this object is set
   oneObject.watch(property,function(id, oldval, newval){
     (function(obj) {
        globalFunction(obj,id,newval);
      }(oneObject))
    return newval;
   });
 }
}

由于oneObject引用对象,因此更改它也会更改对该对象的其他引用。你可以用闭包来解决这个问题。

(function(obj) {
  globalFunction(obj,id,newval);
}(oneObject))
这样,每次您调用globalFunction时,它都会收到唯一的oneObject副本。

您需要为对oneObject的整个引用创建一个闭包:

(function(obj) {
  obj.watch(property,function(id, oldval, newval){
    globalFunction(obj,id,newval);
    return newval;
 });
}(oneObject));

(我很好奇该return在回调中应该做什么,但这是一个单独的问题。

从您提供的抽象代码中很难分辨出来,但这看起来像是使用异步事件循环回调(即 watch 中的函数)引起的问题。在这种情况下通常会发生什么:主循环设置回调。值更改,触发正在侦听的事件(即watch)。回调在事件循环中排队,这与主执行循环不同。回调直到下一个打开循环才会被触发,这可能意味着主循环在此期间一直在执行,从而进一步更改了值。

这里有点难以解释,但这里有一个精彩视频的链接,它将引导您了解可能发生的事情的细节:https://www.youtube.com/watch?v=8aGhZQkoFbQ

我不认为oneObject存在于范围之外。 您可以尝试使用 oneObject 数组,这样您的 oneObject 变量就不会在每次迭代时重新分配。在 for 循环中声明变量往往是不稳定的。