سؤال

هل تتكرر حلقة "for...in" في Javascript عبر جداول التجزئة/العناصر بالترتيب الذي تم الإعلان عنه؟هل هناك متصفح لا يقوم بذلك بالترتيب؟
سيتم الإعلان عن الكائن الذي أرغب في استخدامه مرة واحدة ولن يتم تعديلها أبدًا.

لنفترض أن لدي:

var myObject = { A: "Hello", B: "World" };

وأنا أستخدمها أيضًا في:

for (var item in myObject) alert(item + " : " + myObject[item]);

هل يمكنني أن أتوقع "أ":"مرحبا" تأتي دائما قبل "ب":"العالم" في معظم المتصفحات اللائقة؟

هل كانت مفيدة؟

المحلول

نقلا عن جون ريسيج:

حاليًا جميع المتصفحات الرئيسية حول خصائص كائن ما بالترتيب الذي تم تعريفه به.يقوم Chrome بذلك أيضًا، باستثناء بعض الحالات....] يتم ترك هذا السلوك بشكل صريح غير محدد من خلال مواصفات ECMASCRIPT.في ECMA-262، القسم 12.6.4:

آلية حصر الخواص ...يعتمد على التنفيذ.

ومع ذلك، فإن المواصفات تختلف تمامًا عن التنفيذ.جميع التطبيقات الحديثة لـ ECMAScript تكرار من خلال خصائص الكائن بالترتيب الذي تم تعريفه به.ولهذا السبب، اعتبر فريق Chrome أن هذا خطأ وسيقوم بإصلاحه.

تحترم جميع المتصفحات ترتيب التعريف باستثناء كروم وأوبرا التي تفعل ذلك لكل اسم خاصية غير رقمية.في هذين المستعرضين، يتم سحب الخصائص بالترتيب قبل الخاصية غير الرقمية الأولى (يتعلق هذا بكيفية تنفيذ المصفوفات).الترتيب هو نفسه ل Object.keys أيضًا.

يجب أن يوضح هذا المثال ما يحدث:

var obj = {
  "first":"first",
  "2":"2",
  "34":"34",
  "1":"1",
  "second":"second"
};
for (var i in obj) { console.log(i); };
// Order listed:
// "1"
// "2"
// "34"
// "first"
// "second"

إن الجوانب الفنية لذلك أقل أهمية من حقيقة أن هذا قد يتغير في أي وقت.لا تعتمد على بقاء الأمور على هذا النحو.

باختصار: استخدم المصفوفة إذا كان الترتيب مهمًا بالنسبة لك.

نصائح أخرى

ستنفجر هذه بعد عام..

إنها 2012 والمتصفحات الرئيسية ما زال اختلف:

function lineate(obj){
    var arr = [], i;
    for (i in obj) arr.push([i,obj[i]].join(':'));
    console.log(arr);
}
var obj = { a:1, b:2, c:3, "123":'xyz' };
/* log1 */  lineate(obj);
obj.a = 4;
/* log2 */  lineate(obj);
delete obj.a;
obj.a = 4;
/* log3 */  lineate(obj);

جوهر أو اختبار في المتصفح الحالي

سفاري 5، فايرفوكس 14

["a:1", "b:2", "c:3", "123:xyz"]
["a:4", "b:2", "c:3", "123:xyz"]
["b:2", "c:3", "123:xyz", "a:4"]

كروم 21، أوبرا 12، نود 0.6، فايرفوكس 27

["123:xyz", "a:1", "b:2", "c:3"]
["123:xyz", "a:4", "b:2", "c:3"]
["123:xyz", "b:2", "c:3", "a:4"]

IE9

[123:xyz,a:1,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 

ECMAScript مواصفات اللغة ، قسم 12.6.4 (على الحلقة for .. in):

<اقتباس فقرة>   

واليات تعداد خصائص هو التنفيذ التابع. يتم تعريف ترتيب التعداد من قبل الكائن.

والقسم 4.3.3 (تعريف "كائن"):

<اقتباس فقرة>   

وإنه لجمع نقطية من خصائص كل منها يحتوي على بدائية قيمة، وجوه، أو وظيفة. ويطلق على وظيفة المخزنة في خاصية كائن طريقة.

وانا اعتقد ان هذا يعني أنك غير قادر على الاعتماد على خصائص يتم تعداد في ترتيب متناسقة عبر تطبيقات جافا سكريبت. (سيكون سيئا على غرار أي حال الاعتماد على تفاصيل التنفيذ محددة من لغة).

إذا كنت تريد طلبك محددة، وسوف تحتاج إلى تنفيذ شيء أن يعرف ذلك، مثل مجموعة من المفاتيح التي يمكنك الفرز قبل الوصول إلى الكائن معها.

وعناصر كائن ل/ في تسرد هي الخصائص التي لا يوجد لديك مجموعة العلم DontEnum. وECMAScript، ويعرف أيضا باسم جافا سكريبت، ومعيار يقول صراحة أنه "كائن هو مجموعة غير مرتبة للعقارات" (انظر <لأ href = "http://www.mozilla.org/js/language/E262-3.pdf" يختلط = " noreferrer "> http://www.mozilla.org/js/language/E262-3.pdf القسم 8.6).

وانها لن تكون معايير نحو يتفق (أي آمنة) لتولي كافة تطبيقات الجافا وتعداد من أجل الإعلان.

والتكرار النظام هو أيضا في حيرة فيما يتعلق حذف من الخصائص، ولكن في هذه الحالة مع IE فقط.

var obj = {};
obj.a = 'a';
obj.b = 'b';
obj.c = 'c';

// IE allows the value to be deleted...
delete obj.b;

// ...but remembers the old position if it is added back later
obj.b = 'bb';
for (var p in obj) {
    alert(obj[p]); // in IE, will be a, bb, then c;
                   // not a, c, then bb as for FF/Chrome/Opera/Safari
}

والرغبة في تغيير المواصفات لإصلاح النظام التكرار ويبدو أن تماما رغبة شعبية بين المطورين إذا كانت المناقشة في <لأ href = "http://code.google.com/p/v8/issues/detail؟ معرف = 164 "يختلط =" نوفولو "> http://code.google.com/p/v8/issues/detail؟id=164 أي إشارة.

وفي IE6، ليست مضمونة والنظام.

لا يمكن الوثوق بها والنظام. كل من أوبرا وكروم العودة قائمة الخصائص غير مرتبة.

<script type="text/javascript">
var username = {"14719":"A","648":"B","15185":"C"};

for (var i in username) {
  window.alert(i + ' => ' + username[i]);
}
</script>

والرمز أعلاه يظهر B، A، C في الأوبرا وC، A، B في كروم.

وهذا لا يجيب على السؤال في حد ذاته، لكنه لم يقدم حلا للمشكلة الأساسية.

وعلى افتراض أنه لا يمكن الاعتماد على لالحفاظ عليها، لماذا لا تستخدم مجموعة من الكائنات مع مفتاح وقيمة من الخصائص؟

var myArray = [
    {
        'key'   : 'key1'
        'value' : 0
    },
    {
        'key'   : 'key2',
        'value' : 1
    } // ...
];

والآن، والأمر متروك لكم للتأكد من أن مفاتيح فريدة من نوعها (على افتراض أن هذا هو مهم بالنسبة لك. أيضا كذلك، التغيرات معالجة مباشرة، و(... في ...) يعود الآن مؤشرات باسم ' مفاتيح ".

> console.log(myArray[0].key);
key1

> for (let index in myArray) {console.log(myArray[index].value);}
0
1
رؤية القلم ل(... في ...) معالجة من أجل التي كتبها JDQ ( JDQ ) على CodePen .

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top