【问题标题】:How to pass by reference in ActionScript?如何在 ActionScript 中通过引用传递?
【发布时间】:2013-05-02 20:06:57
【问题描述】:

我正在尝试修改另一个类中的Object。所以我有这样的事情:

MainClass.as

..
var myObject:Object = new Object();
Class2_Instance.get_JSON(myObject);
trace(myObject.id); // output: undefined. whereas it should be 42. see below.
..

Class2.as

public function get_JSON(url:String , the_object:Object) 
{ 
    var request:URLRequest = new URLRequest(url); 
    var variables:URLLoader = new URLLoader(); 
    variables.dataFormat = URLLoaderDataFormat.TEXT; 
    variables.addEventListener(Event.COMPLETE, Complete_Handler_JSON(the_object)); 
    try 
    { 
        variables.load(request); 
    }  
    catch (error:Error) 
    { 
        trace("Unable to load URL: " + error); 
    } 
} 

function Complete_Handler_JSON(the_object:Object):Function 
{
  return function(event:Event):void 
  {  
  var loader:URLLoader = URLLoader(event.target);   
  the_object = JSON.parse(loader.data);     
  trace(the_object.id); //returns 42.
  };
}

所以 JSON 操作在 Class2 中正确执行,并将 .parse() 值分配给 the_object,但我认为 AS 的传递引用逻辑有一些我不理解的地方。因为我期待 MainClass.as 中的 myObject 也会改变。

如何直接修改函数参数(myObject)的值?

谢谢!

【问题讨论】:

  • 对象默认通过引用传递。 the_object 不是 myObject。在 Class2_Method 中创建后尝试返回 the_object。您可能会发现,从长远来看,最好采用其他设计而不是静态方法。
  • @AmyBlankenship 谢谢,今天我在从 CompleteHandler 返回时遇到了一些困难(因为他们等待 URLRequest 完成,我猜“异步”是术语),所以我试图找到一种方法没有回报的。非静态方法是什么意思?而且我认为我应该编辑我的问题以添加实际代码。
  • 我真的很困惑。如果 the_object 不是 myObject,那么它是如何“通过引用”的?在 Adob​​e.com 手册中,它说 myObject 的值会改变,但它不会:/而且我不能从 CompleteHandler 返回。那么如何保存 JSON 数组呢?
  • 因为你在调用 JSON.parse 的时候创建了一个新对象。所以你传入了_oobject,然后覆盖了它。

标签: actionscript-3 oop pass-by-reference


【解决方案1】:

问题在于您的事件处理程序中的这一行:

the_object = JSON.parse(loader.data);

执行此操作的那一刻,您将不再处理传递给方法的对象。您正在为名为@9​​87654323@ 的局部变量分配一个新值。重要的是要了解对象不是通过引用传递的 - 对象引用是通过值传递的。因此,您方法中的the_object参考的副本。当您分配一个新值时,该副本将被不同的引用覆盖。

解决方法是通过引用传递引用——这与C++等语言中双指针的概念有关,也称为双间接。我不确定这在 ActionScript 中是否可行。

更好的解决方案,只需将反序列化的对象作为返回值返回即可。

【讨论】:

  • 哇。这解释了我的问题。非常感谢马特!不幸的是我不能从这个函数返回,因为它是异步运行的,但我会记住那个“双重引用”的东西。谢谢!
  • 啊,在异步场景中,您可以考虑改为返回“promise”类型> en.wikipedia.org/wiki/Futures_and_promises 同样,我不确定 ActionScript 是否支持这一点。
  • 传递的不是对象的值,而是对对象的引用。期望@void 是对引用的引用;)
  • @MattDavey 在 ActionScript 中,您可以通过返回一个“包装器”对象来处理此问题,该对象起初不包含任何内容,但稍后会返回真实对象,并在准备好时分派一个事件。使用集合时,您可以传回一个空集合,并在结果进入时使用结果填充内容。如果您不使用 Flex,则必须扩展集合以便能够在需要时分派事件.
【解决方案2】:

Objects 通过引用传递。

但正如我在您的代码中看到的那样,您正在用在线上的另一个人覆盖the_objectthe_object=JSON.parse(loader.data)

您可以创建一个新变量,然后复制 the_object 中的值:

var json:Object = JSON.parse(loader.data);
for (var k:String in json) {
 the_object[k]=json[k];
}

【讨论】:

  • 谢谢!是的,我现在找到了一个与此非常相似的解决方案。但我习惯于在问题中这样做,在 C# 中,这也是通过引用传递的。它不应该保持我覆盖它的方式吗?我的意思是,显然对象的属性是通过引用传递的,而不是对象本身。为什么?
  • 因为现在它是一个完全不同的对象。调用代码中仍引用旧对象。请注意上面的代码如何将 JSON.parse 创建的 new 对象中的所有属性复制到现有对象中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 2017-01-05
  • 2017-12-04
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
相关资源
最近更新 更多