دسترسی به json در جاوا اسکریپت

چگونه می توانم به اشیا تو در تو ، آرایه ها یا JSON دسترسی داشته باشم؟

سوال:

من یک ساختار داده تو در تو دارم که شامل اشیا و آرایه هاست. چگونه می توانم اطلاعات را استخراج کنم، یعنی به یک مقدار خاص یا چندگانه دسترسی پیدا کنم؟

مثلا:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

چگونه می توانم به name آیتم دوم در items دسترسی داشته باشم؟

پاسخ:

مقدماتی

جاوا اسکریپت فقط یک نوع داده دارد که می تواند چندین مقدار داشته باشد: Object. آرایه شکل خاصی از شی است.

اشیا (ساده) دارای این فرم هستند:

{key: value, key: value, ...}

آرایه ها این فرم را دارند:

[value, value, ...]

هم آرایه ها و هم اشیا یک ساختار key -> valueرا آشکار می کنند. کلید های یک آرایه باید عددی باشند، در حالی که هر رشته ای می تواند به عنوان کلید در اشیا استفاده شود. جفت ‌های کلید-مقدار «ویژگی ‌ها» نیز نامیده می ‌شوند.

با استفاده از علامت نقطه-ویرگول می توان به ویژگی ها دسترسی پیدا کرد:

const value = obj.someProperty;

یا علامت براکت، در صورتی که نام ویژگی، یک نام شناسه معتبر جاوا اسکریپت نباشد، یا نام، مقدار یک متغیر باشد:

// the space is not a valid character in identifier names
const value = obj["some Property"];

// property name as variable
const name = "some Property";
const value = obj[name];

به همین دلیل، عناصر آرایه فقط با استفاده از علامت براکت قابل دسترسی هستند:

const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];

صبر کنید… در مورد JSON چطور؟

JSON درست مانند XML، YAML، CSV و غیره یک نمایش متنی از داده ها است. برای کار با چنین داده‌ هایی، ابتدا باید به انواع داده‌ های جاوا اسکریپت، یعنی آرایه ‌ها و اشیا تبدیل شود (و نحوه کار با آن ‌ها پیش تر توضیح داده شد). نحوه تجزیه JSON در سوال “Parse JSON در جاوا اسکریپت؟” توضیح داده شده است.

مطالب خواندنی بیشتر

نحوه دسترسی به آرایه ها و اشیاء دانش اساسی جاوا اسکریپت است و بنابراین توصیه می شود راهنمای جاوا اسکریپت MDN به خصوص بخش ها را مطالعه کنید.

  • کار با اشیا
  • آرایه ها
  • جاوا اسکریپت فصیح – ساختار های داده

از آنجایی که “self” یک متغیر معمولی است، از قوانین دامنه واژگانی تبعیت می کند و در داخل callback قابل دسترسی است. همچنین این مزیت را دارد که می توانید به “that” مقدار خود callback را بدهید.

دسترسی به ساختارهای داده تو در تو

ساختار داده تو در تو آرایه یا شی ای است که به آرایه ها یا اشیا دیگر اشاره دارد، یعنی مقادیر آن آرایه ها یا اشیا هستند. چنین ساختار هایی را می توان با اعمال متوالی علامت نقطه یا براکت در دسترس قرار داد.

به عنوان مثال:

const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

بیایید فرض کنیم می خواهیم به name آیتم دوم دسترسی داشته باشیم.

در اینجا نحوه انجام این کار به صورت گام به گام آورده شده است:

همانطور که می بینیم data یک شی است، بنابراین می توانیم با استفاده از نماد نقطه به ویژگی های آن دسترسی پیدا کنیم. دسترسی به ویژگی های items به شرح زیر است:

data.items

مقدار یک آرایه است، برای دسترسی به عنصر دوم آن، باید از علامت براکت استفاده کنیم:

data.items[1]

این مقدار یک شی است و ما مجدد از نقطه برای دسترسی به ویژگی های name استفاده می کنیم. بنابراین ما در نهایت داریم:

const item_name = data.items[1].name;

از طرف دیگر، می ‌توانستیم از نماد براکت برای هر یک از ویژگی ‌ها استفاده کنیم، به خصوص اگر نام دارای کاراکتر هایی باشد که آن را برای استفاده از نماد نقطه ‌ای نا معتبر کند:

const item_name = data['items'][1]['name'];

من سعی می کنم به یک ویژگی دسترسی پیدا کنم اما فقط undefined پس می گیرم؟

بیشتر مواقعی که در حال دریافت undefined هستید، شی/آرایه به سادگی، ویژگی با آن نام ندارد.

const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined

از console.log یا console.dir استفاده کنید و ساختار شی / آرایه را بررسی کنید. ویژگی که می ‌خواهید به آن دسترسی پیدا کنید ممکن است در واقع روی یک شی / آرایه تو در تو تعریف شده باشد.

console.log(foo.bar.baz); // 42

اگر نام ویژگی ها پویا باشد و من از قبل آن ها را ندانم چه می شود؟

اگر نام ویژگی ها ناشناخته باشد یا بخواهیم به همه ویژگی های یک شی / عناصر یک آرایه دسترسی داشته باشیم، می توانیم از حلقه for…in [MDN]  برای اشیا و حلقه for [MDN]  برای آرایه ها، برای تکرار روی همه ویژگی ها / عناصر استفاده کنیم.

اشیا

برای تکرار روی تمام ویژگی های data, می توانیم روی شی مانند زیر تکرار کنیم:

for (const prop in data) {
    // `prop` contains the name of each property, i.e. `'code'` or `'items'`
    // consequently, `data[prop]` refers to the value of each property, i.e.
    // either `42` or the array
}

بسته به اینکه شی از کجا آمده است (و کاری که می خواهید انجام دهید)، ممکن است مجبور شوید در هر تکرار آزمایش کنید که آیا این ویژگی واقعاً یک ویژگی شی است یا یک ویژگی ارثی. می توانید این کار را با Object#hasOwnProperty [MDN]  انجام دهید .

به عنوان جایگزین for…in با hasOwnProperty، می توانید از Object.keys [MDN]  برای به دست آوردن آرایه ای از نام های ویژگی استفاده کنید:

Object.keys(data).forEach(function(prop) {
  // `prop` is the property name
  // `data[prop]` is the property value
});

آرایه ها

برای تکرار روی تمام عناصر data.items آرایه، از یک حلقه for  استفاده می کنیم:

for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}

همچنین می‌توان از for…in برای تکرار روی آرایه‌ ها استفاده کرد، اما دلایلی وجود دارد که چرا باید از این کار اجتناب شود: چرا «for(var item in list)» با آرایه‌ها در جاوا اسکریپت عمل بدی در نظر گرفته می‌شود؟ .

با افزایش پشتیبانی مرورگر ها از  ECMAScript 5، روش آرایه forEach [MDN]  نیز جایگزین جالبی می شود:

data.items.forEach(function(value, index, array) {
    // The callback is executed for each element in the array.
    // `value` is the element itself (equivalent to `array[index]`)
    // `index` will be the index of the element in the array
    // `array` is a reference to the array itself (i.e. `data.items` in this case)
});

در محیط ‌هایی که از ES2015 (ES6) پشتیبانی می‌ کنند، می‌ توانید از حلقه  for…of [MDN]نیز استفاده کنید، که نه تنها برای آرایه ‌ها، بلکه برای هر تکراری کار می ‌کند:

for (const item of data.items) {
   // `item` is the array element, **not** the index
}

در هر تکرار، for…ofب ه طور مستقیم عنصر بعدی تکرار پذیر را به ما می دهد، هیچ “شاخصی” برای دسترسی یا استفاده وجود ندارد.

اگر “عمق” ساختار داده برای من ناشناخته باشد چه؟

علاوه بر کلیدهای ناشناخته، “عمق” ساختار داده (یعنی چند شیء تو در تو) ممکن است ناشناخته باشد. نحوه دسترسی به خصوصیات عمیق تو در تو معمولاً به ساختار دقیق داده بستگی دارد.

اما اگر ساختار داده حاوی الگو های تکرار شونده باشد، به عنوان مثال نمایش یک درخت باینری، راه حل معمولا شامل دسترسی بازگشتی به هر سطح از ساختار داده است.

در اینجا یک مثال برای بدست آوردن اولین گره برگ درخت باینری آورده شده است:

function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild); // <- recursive call
    }
    else if (node.rightChild) {
        return getLeaf(node.rightChild); // <- recursive call
    }
    else { // node must be a leaf node
        return node;
    }
}

const first_leaf = getLeaf(root);

یک راه عمومی تر برای دسترسی به یک ساختار داده تو در تو با کلید ها و عمق ناشناخته، آزمایش نوع مقدار و عمل کردن بر اساس آن است.

در اینجا یک مثال آورده شده است که تمام مقادیر اولیه داخل یک ساختار داده تو در تو را به یک آرایه اضافه می کند (با فرض اینکه هیچ توابعی نداشته باشد). اگر با یک شی (یا آرایه) روبرو شویم، به سادگی toArray آن مقدار را دوباره فراخوانی می کنیم (تماس بازگشتی).

function toArray(obj) {
    const result = [];
    for (const prop in obj) {
        const value = obj[prop];
        if (typeof value === 'object') {
            result.push(toArray(value)); // <- recursive call
        }
        else {
            result.push(value);
        }
    }
    return result;
}

یاوران

از آن جایی که ساختار یک شی یا آرایه پیچیده لزوماً واضح نیست، می ‌توانیم مقدار را در هر مرحله بررسی کنیم تا تصمیم بگیریم که چگونه بیشتر حرکت کنیم. console.log [MDN] و console.dir [MDN]  در انجام این کار به ما کمک می کنند. به عنوان مثال (خروجی کنسول کروم):

> console.log(data.items)
 [ Object, Object ]

در اینجا می بینیم که data.items آرایه ای با دو عنصر است که هر دو شی هستند. در کنسول کروم، اشیا حتی می توانند فوراً گسترش یافته و بازرسی شوند.

> console.log(data.items[1])
  Object
     id: 2
     name: "bar"
     __proto__: Object

این به ما می گوید که data.items[1] یک شی است، و پس از گسترش آن می بینیم که دارای سه ویژگی id، name و __proto__ است. مورد دوم یک ویژگی داخلی می باشد که برای زنجیره نمونه اولیه شی مورد استفاده قرار می گیرد. با این حال، زنجیره اولیه و وراثت خارج از محدوده این پاسخ است.

سخن پایانی

برای یادگیری جاوا اسکریپت به صورت کاملا پروژه محور و عملی می توانید از مسیر کارآموزی فرانت اند استفاده کنید.

پاسخ‌ها

آدرس ایمیل شما منتشر نخواهد شد.

پل ورود به بازار تکنولوژی

مشاوره رایگان انتخاب مسیر

با کمک مشاورهای رستاوا آکادمی مسیر کارآموزی مناسب برای خودت رو برای ورود به بازار کار تکنولوژی انتخاب کن

توسعه فردی برای حرفه‌ای شدن

منتورهای رستاوا و دوره‌های ما شما رو برای کارآموزی و در نهایت جذب و استخدام آماده میکنن

مدرک بین المللی و استانداردهای جهانی

یادگیری با استاندار های بین المللی و دریافت مدرک از Credx Academy کانادا

اگر در مسیرهای کارآموزی ما پذیرش بگیری موقعیت‌های کارآموزی و استخدام در پروژه‌ها و شرکت های بین المللی از طریق مجموعه رستاوا به روت باز می شه.

۲ هفته رایگان

همین حالا با منتورها

ارتباط آنی بگیر!