javascript - لغة - شرح جافا سكربت بالعربي pdf




كيفية تنفيذ حلقة مستمرة من خلال كائن جافا سكريبت عادي مع الكائنات كأعضاء؟ (12)

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

1. المفاتيح يجب الوصول إليها ،

✔ نهج و Object.keys

let k;
for (k of Object.keys(obj)) {

    /*        k : key
     *   obj[k] : value
     */
}

in النهج

let k;
for (k in obj) {

    /*        k : key
     *   obj[k] : value
     */
}

استخدم هذا مع الحذر ، لأنه يمكن طباعة خصائص prototype'd من obj

✔ نهج ES7

for (const [key, value] of Object.entries(obj)) {

}

ومع ذلك ، في وقت التعديل ، لا أوصي باستخدام طريقة ES7 ، لأن JavaScript تقوم بتهيئة الكثير من المتغيرات داخليًا لإنشاء هذا الإجراء (راجع التعليقات الخاصة بالإثبات). إلا إذا كنت لا تطور تطبيقًا ضخمًا يستحق التحسين ، فلا بأس ، ولكن إذا كان التحسين هو الأولوية لديك ، فعليك التفكير فيه.

II. نحن بحاجة فقط للوصول إلى كل القيم ،

✔ نهج و Object.values

let v;
for (v of Object.values(obj)) {

}

مزيد من الردود حول الاختبارات:

  • التخزين المؤقت Object.keys أو Object.values لا يكاد يذكر

على سبيل المثال،

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • بالنسبة لحالة Object.values ، يبدو أن استخدام a Object.values for loop مع المتغيرات المخزنة مؤقتًا في Firefox يكون أسرع قليلاً من استخدام for...of loop. على الرغم من أن الاختلاف ليس مهمًا ، وأن Chrome قيد التشغيل for...of أسرع من العروة الأصلية ، لذا أوصي باستخدامه for...of عند التعامل مع Object.values في أي من الحالات (الاختبارات الرابعة والسادسة).

  • في فايرفوكس ، تكون الحلقة for...in حلقة بطيئة للغاية ، لذلك عندما نريد تخزين المفتاح أثناء التكرار ، من الأفضل استخدام Object.keys . بالإضافة إلى ذلك ، يعمل Chrome على كلا الهيكلين بسرعة متساوية (الاختبارات الأولى والاخيرة).

يمكنك التحقق من الاختبارات هنا: https://jsperf.com/es7-and-misc-loops

كيف يمكنني تكرار جميع الأعضاء في كائن جافا سكريبت بما في ذلك القيم التي تمثل كائنات.

على سبيل المثال ، كيف يمكنني تكرار هذا (الوصول إلى "your_name" و "your_message" لكل منهما)؟

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}

ECMAScript-2017 ، تم الانتهاء منه قبل شهر ، يقدم Object.values ​​(). الآن يمكنك القيام بذلك:

let v;
for (v of Object.values(validation_messages))
   console.log(v.your_name);   // jimmy billy

أعلم أنه متأخر متأخراً ، لكن الأمر استغرقني دقيقتين لكتابة هذه النسخة المحسنة والمحسنة من أجايلجون:

var key, obj, prop, owns = Object.prototype.hasOwnProperty;

for (key in validation_messages ) {

    if (owns.call(validation_messages, key)) {

        obj = validation_messages[key];

        for (prop in obj ) {

            // using obj.hasOwnProperty might cause you headache if there is
            // obj.hasOwnProperty = function(){return false;}
            // but owns will always work 
            if (owns.call(obj, prop)) {
                console.log(prop, "=", obj[prop]);
            }

        }

    }

}

إذا كنت تستخدم العودية ، يمكنك إرجاع خصائص الكائن لأي عمق

function lookdeep(object){
    var collection= [], index= 0, next, item;
    for(item in object){
        if(object.hasOwnProperty(item)){
            next= object[item];
            if(typeof next== 'object' && next!= null){
                collection[index++]= item +
                ':{ '+ lookdeep(next).join(', ')+'}';
            }
            else collection[index++]= [item+':'+String(next)];
        }
    }
    return collection;
}

//example

var O={
    a:1, b:2, c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
};
var lookdeepSample= 'O={'+ lookdeep(O).join(',\n')+'}';


/*  returned value: (String)
O={
    a:1, 
    b:2, 
    c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
}

*/

باستخدام Underscore.js's _.each :

_.each(validation_messages, function(value, key){
    _.each(value, function(value, key){
        console.log(value);
    });
});

تحت ECMAScript 5 ، يمكنك دمج Object.keys() و Array.prototype.forEach() :

var obj = {
  first: "John",
  last: "Doe"
};

//
//	Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {

  console.log(key, obj[key]);

});


في ES6 ، يمكنك التكرار عبر كائن مثل هذا: (باستخدام وظيفة السهم )

Object.keys(myObj).forEach(key => {
    console.log(key);          // the name of the current key.
    console.log(myObj[key]);   // the value of the current key.
});

jsbin

في ES7 يمكنك استخدام Object.entries بدلاً من Object.keys من خلال كائن كهذا:

Object.entries(myObj).forEach(([key, val]) => {
    console.log(key);          // the name of the current key.
    console.log(val);          // the value of the current key.
});

ما ورد أعلاه سيعمل أيضا على شكل واحد :

Object.keys(myObj).forEach(key => console.log(key, myObj[key]));

jsbin

في حالة رغبتك في التكرار من خلال الكائنات المتداخلة أيضًا ، يمكنك استخدام الدالة العودية (ES6):

const loopNestedObj = (obj) => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === 'object') loopNestedObj(obj[key]);  // recurse.
    else console.log(key, obj[key]);  // or do something with key and val.
  });
};

jsbin

نفس الوظيفة المذكورة أعلاه ، ولكن مع ES7 Object.entries بدلاً من Object.keys :

const loopNestedObj = (obj) => {
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') loopNestedObj(val);  // recurse.
    else console.log(key, val);  // or do something with key and val.
  });
};

إذا كنت في برمجة وظيفية ، يمكنك استخدام Object.keys / Object.entries لتعداد الكائن ، ثم معالجة القيم ثم استخدام reduce() للتحويل مرة أخرى إلى كائن جديد.

const loopNestedObj = (obj) => 
  Object.keys(obj)
    // Use .filter(), .map(), etc. if you need.
    .reduce((newObj, key) => 
      (obj[key] && typeof obj[key] === 'object') ?
        {...newObj, [key]: loopNestedObj(obj[key])} :  // recurse.
        {...newObj, [key]: obj[key]},                  // Define value.
      {});

في ES7 ، يمكنك القيام بما يلي:

for (const [key, value] of Object.entries(obj)) {
  //
}

لم أستطع الحصول على المشاركات المذكورة أعلاه لفعل ما كنت عليه بعد.

بعد التلاعب بالردود الأخرى هنا ، قمت بهذا. إنه قرصان ، لكنه يعمل!

لهذا الكائن:

var myObj = {
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"}
};

... هذا الرمز:

// Get every value in the object into a separate array item ...
function buildArray(p_MainObj, p_Name) {
    var variableList = [];
    var thisVar = "";
    var thisYes = false;
    for (var key in p_MainObj) {
       thisVar = p_Name + "." + key;
       thisYes = false;
       if (p_MainObj.hasOwnProperty(key)) {
          var obj = p_MainObj[key];
          for (var prop in obj) {
            var myregex = /^[0-9]*$/;
            if (myregex.exec(prop) != prop) {
                thisYes = true;
                variableList.push({item:thisVar + "." + prop,value:obj[prop]});
            }
          }
          if ( ! thisYes )
            variableList.push({item:thisVar,value:obj});
       }
    }
    return variableList;
}

// Get the object items into a simple array ...
var objectItems = buildArray(myObj, "myObj");

// Now use them / test them etc... as you need to!
for (var x=0; x < objectItems.length; ++x) {
    console.log(objectItems[x].item + " = " + objectItems[x].value);
}

... ينتج هذا في وحدة التحكم:

myObj.pageURL = BLAH
myObj.emailBox.model = emailAddress
myObj.emailBox.selector = #emailAddress
myObj.passwordBox.model = password
myObj.passwordBox.selector = #password

هنا تأتي النسخة المحسنة والعودية من حل AgileJon ( demo ):

function loopThrough(obj){
  for(var key in obj){
    // skip loop if the property is from prototype
    if(!obj.hasOwnProperty(key)) continue;

    if(typeof obj[key] !== 'object'){
      //your code
      console.log(key+" = "+obj[key]);
    } else {
      loopThrough(obj[key]);
    }
  }
}
loopThrough(validation_messages);

يعمل هذا الحل لجميع أنواع الأعماق المختلفة.


for(var k in validation_messages) {
    var o = validation_messages[k];
    do_something_with(o.your_name);
    do_something_else_with(o.your_msg);
}

for(var key in validation_messages){
    for(var subkey in validation_messages[key]){
        //code here
        //subkey being value, key being 'yourname' / 'yourmsg'
    }
}




javascript