扩展Array时,访问成员时出现问题

时间:2011-07-07 20:20:24

标签: actionscript-3

我目前正在处理我的同事写的一些代码。以下是对它的简化看法:

人民班:

package model{
    public class People extends Array{ // NOTE: it is not dynamic

        public function toXML():XML {
            var out:XML = <people/>;
            for each(var per:Person in this){
                out.appendChild(per.toXML());
            }
            return out;
        }
    }
}

基本上是一个人员阵列:

package model{
    public class Person {

        public var name:String;
        public var phoneNumber:String;

        public function Person(name:String, phoneNumber:String){
            this.name = name;
            this.phoneNumber = phoneNumber;
        }

        public function toXML():XML {
            var xml:XML = <person/>;
            xml.@name = name;
            xml.@phone = phoneNumber;
            return xml;
        }
    }
}

这基本上是我的同事使用代码的方式:

var people:People = new People();
people.push(new Person("Jake", "902 825-4444"));
people.push(new Person("Bob", "514 444-3333"));
return people.toXML().toXMLString();

注意:他添加了Person对象,但他从不查看People Array中的内容,除了打印XML

快进(人们还知道这意味着什么?)到现在。我现在需要查看People类,并执行以下操作:

var people:People = ... init and fill with Person objects
for(var i:int=0; i<people.length(); i++){
    doSomething(people[i]); // <-- Error thrown here.
}

不幸的是,这引发了这个错误:

ReferenceError: Error #1069: Property 0 not found on model.People and there is no default value.
    at runner::Runner$/newUse()
    at ExtendsArray/start()
    at ExtendsArray/___ExtendsArray_Application1_initialize()
    at flash.events::EventDispatcher/dispatchEventFunction()

我该怎么办?

编辑,旁白:扩展阵列不是我做的这是我们旧模型的一部分。我们正在远离旧模型,因为它充满了这样的垃圾。我只需要从旧模型中获取这些东西,将其转换为新模型。我想从我们的产品中删除这些代码,但这样做的成本可能是不合理的。

5 个答案:

答案 0 :(得分:2)

Array.length是一个getter:它返回一个int。 people.length()与调用3()相同。我测试时不知道它是如何工作的。

看起来你应该更好地实现IList之类的内容并将addItem推入Vector.<Person>。这将保证您只有Person对象。

您应该不应该扩展Array。如果要扩展任何内容,请扩展Proxy(您甚至可以使用带有Vector.<Person>的ProxyArray类示例)。扩展顶级类(Object除外)通常会引起混淆。

如果您确实想要扩展Array,则必须使该类动态化 - 您可以随意分配和删除属性。

答案 1 :(得分:2)

  

我该怎么办?

仅使用类方法访问和设置“数组”中的项目,不要使用特定于Array的语法。和/或使课堂充满活力。


编辑我认为您可以将所有内容保留为,并通过仅为项目访问定义一个附加方法(如果由于某种原因不存在)来避免使您的类动态 。类似的东西:

public functon getItem(index:uint):*
{
    if (index >= length) {
        return null;
    }
    return this.slice(index, index+1)[0]; 
    // this creates a redundant array on the fly, sorry.
}

// usage:

var people:People = ... init and fill with Person objects
for(var i:int=0; i<people.length(); i++){
    doSomething(people.getItem(i));
}

而且我知道这不是它在stackoverwlow上的回答方式,但是......我无法忍住它。 ))

Anything extends Array - 是一种异端邪说。如果我在生产代码中看到这一点,我将立即着手启动“清除不洁”序列。

稍微尝试用谷歌搜索一下这个主题,然后你就会发现,几乎没有人能够从这样的活动中获得活力。

这种憎恶不存在的主要理由(除了它是一种异端)是你不能使用数组访问[],你不能像一个普通的数组实例化它与项目和你无法通过数组语法[]设置项目,并通知您班级中的某些更改。但是 是出生权的数组,因此任何不熟悉该主题的开发人员可能会尝试像普通数组一样使用它,因为它很自然。然后他们可能会在stackoverflow上发布另一个问题。

所以,如果你仍然只使用类方法,那么延伸的重点是什么?什么不使用整齐的聚合/组合或代理方式?

这太棒了,但甚至还有an article on extending Array on adobe.com。他们没有提到的是你可能会马上开始在地狱中燃烧。

答案 2 :(得分:0)

这看起来很有效:

var s:String = "";
for each(var per:Person in people){
    s += per.name + " ";    
}

答案 3 :(得分:0)

People类必须编写为public dynamic class脚本,因为它正在扩展Array类。

来自this Adobe help article:Array的子​​类应该使用dynamic属性,就像Array类一样。否则,您的子类将无法正常运行。

答案 4 :(得分:-1)

你使用了“推”功能,显然创建了一个关联数组。

索引不能调用关联数组。它们也可以不被撤销或更改订单。

您需要使用for..in循环

来访问它们
for (var key:String in people) {
  trace("person : " + (people[key] as person).name);
}

// or as you found out the for each.. in
for each(var person:Person in people){
  trace("person : " + person.name);
}

关联数组的arr.length()函数将始终为0,您可以看到错误。

//Try this example you will see how an array can act like an array as we know it and an object.
var a:Array = [];
a[0] = true;
a.push(true);
a.push(true);
a["foo"] = true;
a.push(true);
a.push(true);
a.bar = true;


trace("for loop\n");
for(var i:int = 0, ilen:int = a.length ; i < ilen ; i++){
    trace(i,a[int(i)]);
}

trace("\nfor...in loop\n");
for(var key:String in a){
    trace(key,a[key]);
}