javascript - حاجات - مطوية عن خصائص المخلوقات الحية




يتكرر من خلال خصائص الكائن (16)

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

افترض أن لديك كائن JSON مثل:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

الطريقة الخاطئة للتكرار من خلال "الخصائص" الخاصة به:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

قد يفاجأ من رؤية وحدة التحكم تسجيل 0 ، 1 ، وما إلى ذلك عند التكرار من خلال خصائص prop1 و prop2 و prop3_1 . هذه الكائنات هي تسلسل ، وفهارس التسلسل هي خصائص هذا الكائن في Javascript.

أفضل طريقة للتكرار المتكرر من خلال خصائص كائن JSON هي التحقق أولاً من أن هذا الكائن هو تسلسل أم لا:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}
var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    alert(propt + ': ' + obj[propt]);
}

كيف تمثل propt المتغير خصائص الكائن؟ انها ليست طريقة مدمجة ، أو خاصية. ثم لماذا يأتي مع كل خاصية في الكائن؟


أنا هنا تكرار كل عقدة وإنشاء أسماء عقدة ذات مغزى. إذا لاحظت ، exampleOre Array و instanceOf Object تشبه إلى حد كبير نفس الشيء (في طلبي ، أعطي منطقًا مختلفًا على الرغم من ذلك)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

ملاحظة - مستوحاة من إجابة Ondrej Svejdar. لكن هذا الحل لديه أداء أفضل وأقل غموضا


إن إجابة دومينيك مثالية ، فأنا أفضل أن أفعلها بهذه الطريقة ، لأنها أكثر نظافة للقراءة:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}

اعتبارًا من JavaScript 1.8.5 يمكنك استخدام Object.keys(obj) للحصول على صفيف من الخصائص المحددة على الكائن نفسه (تلك التي ترجع true إلى obj.hasOwnProperty(key) ).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

هذا أفضل (وأكثر قابلية للقراءة) من استخدام حلقة for-in.

دعمه على هذه المتصفحات:

  • فايرفوكس (جيكو): 4 (2.0)
  • Chrome: 5
  • Internet Explorer: 9

راجع developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… للحصول على مزيد من المعلومات.


الكائنات في JavaScript هي مجموعات من الخصائص ، وبالتالي يمكن تكرارها في كل عبارة.

يجب أن تفكر في obj باعتبارها مجموعة قيمة رئيسية.


انها ل for...in statement ( MDN ، مواصفات ECMAScript ).

يمكنك قراءتها كـ " FOR كل خاصية في كائن obj ، تعيين كل خاصية إلى متغير PROPT بدوره".


تمثل في ... في حلقة كل خاصية في كائن لأنه فقط مثل حلقة for. قمت بتعريف propt في لـ ... في حلقة بواسطة:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

A for ... في تكرار الحلقات من خلال خصائص لا تعد ولا تحصى لكائن. أي متغير يمكنك تعريفه ، أو وضعه في for ... في حلقة ، يتغير في كل مرة ينتقل إلى الخاصية التالية التي يتكررها. يتكرر المتغير في الحلقة ... في الحلقة خلال المفاتيح ، ولكن قيمة القيمة هي قيمة المفتاح. فمثلا:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

يمكنك رؤية كيف يختلف المتغير عن قيمة المتغير. في المقابل ، ل ... من حلقة يفعل العكس.

آمل أن يساعد هذا.


حلقة for الخاصة بك تتكرر على كافة خصائص كائن obj . يتم تعريف propt في السطر الأول من الحلقة الخاصة بك. وهي سلسلة يمثل اسم خاصية كائن obj . في التكرار الأول للحلقة ، سيكون propt "الاسم".


في الإصدارات القادمة من ES ، يمكنك استخدام Object.entries :

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

أو

Object.entries(obj).forEach(([key, value]) => ...)

إذا أردت فقط التكرار أكثر من القيم ، فاستخدم Object.values:

for (const value of Object.values(obj)) { }

أو

Object.values(obj).forEach(value => ...)

في الوقت الحالي ، يمكنك تحويل كائن JS قياسي إلى كائن قابل للتكرار فقط عن طريق إضافة طريقة Symbol.iterator. يمكنك بعد ذلك استخدام حلقة for و empceess قيمها مباشرة أو حتى يمكن استخدام عامل توزيع على الكائن أيضًا. رائع. دعونا نرى كيف يمكننا أن نجعلها:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);


كنت تريد أساسا أن حلقة عبر كل خاصية في الكائن.

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

لمزيد من التحسين في الإجابة المقبولة ، تجدر الإشارة إلى أنه إذا قمت var object = Object.create(null) الكائن باستخدام var object = Object.create(null) فسيتم object.hasOwnProperty(property) على TypeError. لكي تكون في الجانب الآمن ، ستحتاج إلى الاتصال به من النموذج الأولي كما يلي:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}

مضيفا أيضا بطريقة متكررة:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

الاستعمال:

iterate({ foo: "foo", bar: { foo: "foo"} }); 

يتطلب hasOwnProperty فوق الخصائص هذا الاختيار الإضافي لـ hasOwnProperty :

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

من الضروري أن يحتوي النموذج الأولي للكائن على خصائص إضافية للكائن الذي يعد جزءًا من الكائن تقنيًا. يتم توارث هذه الخصائص الإضافية من فئة الكائن الأساسي ، لكن تظل خصائص object .

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


يمكنك استخدام Lodash. وثائق

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});

Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);




object