2012-04-10 30 views
10

Để lặp qua các thuộc tính của một Object trong AS3 bạn có thể sử dụng for(var i:String in object) như thế này:Điều gì đang xảy ra khi tôi sử dụng (i trong đối tượng) trong AS3?

Object:

var object:Object = { 

    thing: 1, 
    stuff: "hats", 
    another: new Sprite() 

}; 

Loop:

for(var i:String in object) 
{ 
    trace(i + ": " + object[i]); 
} 

Kết quả:

 
stuff: hats 
thing: 1 
another: [object Sprite] 

Thứ tự mà thuộc tính được chọn tuy nhiên có vẻ khác và không bao giờ khớp với bất kỳ thứ gì tôi có thể nghĩ như tên thuộc tính chữ cái, thứ tự chúng được tạo, v.v. thời gian khác nhau ở những nơi khác nhau, thứ tự là hoàn toàn khác nhau.

Có thể truy cập các thuộc tính theo một thứ tự nhất định không? Chuyện gì đang xảy ra ở đây?

+1

Cách tôi nghĩ về một đối tượng như đã tuyên bố ở trên, giống như Bảng băm như được thấy trong một số ngôn ngữ khác, nơi bạn không bao giờ có thể tin tưởng thứ tự do cách nó tự xử lý nội bộ. Bạn có thể tìm thấy ý tưởng chung tại đây: http://en.wikipedia.org/wiki/Hash_table – ToddBFisher

+0

câu hỏi hay. trong khi tôi không biết tại sao lặp lại các thuộc tính đối tượng dường như là ngẫu nhiên, tôi nhớ lại các chủ đề trước đây đang thảo luận các vấn đề tương tự và giải pháp là tạo một từ điển được chuyển tới một mảng được sắp xếp theo khóa hoặc giá trị của từ điển. tôi cũng muốn biết điều gì đang xảy ra ở đây. – TheDarkIn1978

+1

Tôi nghĩ @ToddBFisher có ý tưởng đúng ở đây. Trong C++ điều này về cơ bản sẽ là một "bản đồ không có thứ tự", cụ thể là std :: unordered_map từ chuẩn C++ 11 mới được thực hiện trong bản phát hành TR1. Xem http://en.wikipedia.org/wiki/Unordered_associative_containers_(C%2B%2B) và http://www.cplusplus.com/reference/stl/map/ để biết thêm chi tiết về khái niệm tại nơi làm việc. –

Trả lời

9

Tôi đang đăng câu trả lời này chỉ để khen BoltClock's answer bằng một số thông tin chi tiết bổ sung bằng cách xem trực tiếp mã nguồn trình phát flash. Chúng tôi thực sự có thể thấy mã AVM chuyên cung cấp chức năng này và được viết bằng C++. Chúng ta có thể nhìn thấy bên trong ArrayObject.cpp đoạn mã sau:

// Iterator support - for in, for each 
Atom ArrayObject::nextName(int index) 
{ 
    AvmAssert(index > 0); 

    int denseLength = (int)getDenseLength(); 
    if (index <= denseLength) 
    { 
     AvmCore *core = this->core(); 
     return core->intToAtom(index-1); 
    } 
    else 
    { 
     return ScriptObject::nextName (index - denseLength); 
    } 
} 

Như bạn có thể thấy khi có một tài sản hợp pháp (đối tượng) để trở về, người ta nhìn lên từ lớp ScriptObject, đặc biệt là phương pháp nextName(). Nếu chúng ta xem xét các phương thức đó trong ScriptObject.cpp:

Atom ScriptObject::nextName(int index) 
{ 
    AvmAssert(traits()->needsHashtable()); 
    AvmAssert(index > 0); 

    InlineHashtable *ht = getTable(); 
    if (uint32_t(index)-1 >= ht->getCapacity()/2) 
     return nullStringAtom; 
    const Atom* atoms = ht->getAtoms(); 
    Atom m = ht->removeDontEnumMask(atoms[(index-1)<<1]); 
    if (AvmCore::isNullOrUndefined(m)) 
     return nullStringAtom; 
    return m; 
} 

Chúng ta có thể thấy rằng thực tế, như mọi người đã chỉ ra ở đây rằng VM đang sử dụng bảng băm. Tuy nhiên trong các chức năng này có một chỉ số cụ thể được cung cấp, điều này sẽ gợi ý, ngay từ cái nhìn đầu tiên, rằng phải có một thứ tự cụ thể.

Nếu bạn đào sâu hơn (tôi sẽ không đăng tất cả mã ở đây), có rất nhiều phương thức từ các lớp khác nhau tham gia vào/cho từng chức năng và một trong số đó là phương pháp ScriptObject::nextNameIndex(). toàn bộ bảng băm và chỉ bắt đầu cung cấp các chỉ mục cho các đối tượng hợp lệ trong bảng và tăng chỉ số ban đầu được cung cấp trong đối số, miễn là giá trị tiếp theo trỏ tới một đối tượng hợp lệ. Nếu tôi đúng trong cách giải thích của tôi, đây sẽ là nguyên nhân đằng sau việc tra cứu ngẫu nhiên của bạn và tôi không tin rằng sẽ có bất kỳ cách nào để ép buộc một bản đồ được chuẩn hóa/đặt hàng trong các hoạt động này.

Nguồn
Đối với những người bạn của những người có thể muốn lấy mã nguồn cho phần mã nguồn mở của đèn flash player, bạn có thể lấy nó từ các kho lanh lợi sau đây (bạn có thể tải về một snapshop trong zip như github vì vậy bạn không cần phải cài đặt lanh lợi):

http://hg.mozilla.org/tamarin-central - Đây là "ổn định" hoặc "giải phóng" kho

http://hg.mozilla.org/tamarin-redux - Đây là chi nhánh phát triển. Những thay đổi gần đây nhất cho AVM sẽ được tìm thấy ở đây. Điều này bao gồm hỗ trợ cho Android và như vậy. Adobe vẫn đang cập nhật và mở tìm nguồn cung ứng những phần này của trình phát flash, vì vậy nó là công cụ chính xác và hiện tại.

Trong khi tôi đang ở đó, điều này cũng có thể quan tâm: http://code.google.com/p/redtamarin/. Đó là một phiên bản được phân nhánh (và khá trưởng thành) của AVM và có thể được sử dụng để viết các ActionScript phía máy chủ. Neat công cụ và có một tấn thông tin cung cấp cho cái nhìn sâu sắc vào các hoạt động của AVM vì vậy tôi nghĩ rằng tôi muốn bao gồm nó quá.

+1

Đây là một câu trả lời tuyệt vời, cảm ơn. – Marty

+1

Không sao cả. Tôi sẽ chỉnh sửa và đăng các nguồn nơi mọi người có thể lấy phần nguồn mở của trình phát. –

7

Hành vi này là documented (tôi nhấn mạnh):

Các for..in lặp lặp qua các thuộc tính của một đối tượng, hoặc các yếu tố của một mảng. Ví dụ, bạn có thể sử dụng một vòng lặp for..in để lặp qua các thuộc tính của một đối tượng chung chung (các thuộc tính đối tượng không được giữ trong bất kỳ thứ tự cụ thể, vì vậy tính có thể xuất hiện theo một thứ tự dường như ngẫu nhiên)

Làm thế nào các thuộc tính được lưu trữ và truy xuất dường như là chi tiết triển khai, không được đề cập trong tài liệu. Như ToddBFisher đề cập đến trong một bình luận, mặc dù, một cấu trúc dữ liệu thường được sử dụng để thực hiện mảng kết hợp là hash table. Nó thậm chí còn được đề cập trong this page about associative arrays in AS3 và nếu bạn inspect the AVM code as shown by Ascension Systems, bạn sẽ thấy chính xác việc triển khai đó. Như đã mô tả, không có khái niệm về thứ tự hoặc sắp xếp trong các bảng băm điển hình.

Tôi không tin rằng có một cách để truy cập các thuộc tính theo thứ tự cụ thể trừ khi bạn lưu trữ thứ tự đó bằng cách nào đó.

Các vấn đề liên quan