اشیاء در جاوا اسکریپت تقریباً به تمام جنبه های زبان نفوذ می کنند. بنابراین ما باید قبل از هر کار دیگری باید انها را خوب درک کنیم .یک object را می توان با براکت هایی به شکل {…} با لیست دلخواه از ویژگی ها ایجاد کرد. یک ویژگی یک جفت “key: value” است، جایی که در آن key
یک رشته است (همچنین“property name”نامیده می شود)، و value
می تواند هر چیزی باشد.
ما می توانیم یک object را به عنوان یک کابینت با پرونده های امضا گردیده تصور کنیم.هر قطعه داده در فایل خود توسط کلید ذخیره میگردد.که جستوجوی یک فایل را به وسیله نام آن و یا عملیات افزودن/حذف آن را برای ما راحتتر می کند.
یک شی خالی (“کابینت خالی”) را می توانیم با استفاده از یکی از دو سینتکس زیر ایجاد کنیم:
let user = new Object(); // "object constructor" syntax let user = {}; // "object literal" syntax
Literals and properties
ما میتوانیم برخی از ویژگیها را بهعنوان جفتهای «key: value» در {…} قرار دهیم:
let user = { // an object name: "John", // by key "name" store value "John" age: 30 // by key "age" store value 30 };
یک ویژگی دارای یک کلید (که به آن ب“name” یا “identifier” نیز می گوییم) قبل از دو نقطه “:” و یک مقدار در سمت راست آن است.
در شی user
دو ویژگی وجود دارد.
- اولین ویژگی که نام “name” و مقدار “John” را دارد.
- دومین ویژگی که نام “age” و مقدار 30 را دارد.
در نتیجه شی کاربر به دست آمده را می توانیم به عنوان یک کابینت با دو فایل امضا شده با برچسب “نام” و “سن” تصور کنیم. که ما می توانیم در هر زمان عملیات خواندن و یا حذف و اضافه کردن فایل را اجرا نماییم. برای دسترسی به مقادیر پراپرتی ها ما میتوانیم از نوتیشن “.” استفاده نماییم.
// get property values of the object: alert( user.name ); // John alert( user.age ); // 30
مقادیر میتوانند از هر نوعی باشند.حال میخواهیم یک مقدار بولیین به شی خودمان اضافه نماییم.
user.isAdmin = true;
برای حذف یک ویژگی می توانیم از عملگر delete
استفاده نماییم.
delete user.age;
ما میتوانیم برای پراپرتیها از نامی استفاده نماییم که شامل چند قسمت باشد که در این صورت آنها باید داخل دابل کوتیشن قرار دهیم.
let user = { name: "John", age: 30, "likes birds": true // multiword property name must be quoted };
آخرین ویژگی در لیست ممکن است با کاما به پایان برسد:
let user = { name: "John", age: 30, }
که به آن کاما “trailing”یا “hanging” نیز میگویند.که با اینکار با توجه به اینکه کلیه خطوط یکسان میشونددر نتیجه عملیات حذف/درج و حرکت را برای ما اسان میکند.
Square brackets
در قسمت های بالا اعلام کردیم برای دسترسی به مقادیر objct از نوتیشن دات استفاده میکنیم،ولی این مورد برای نام پراپرتی هایی که از چندین کلمه تشکیل میباند کار نمیکند.
// this would give a syntax error user.likes birds = true
جاوا اسکریپت این را نمی فهمد و فکر میکند که ما user.likes
را آدرسدهی میکنیم، و از اجایی که چنین چیزی وجود ندارد، یک خطای نحوی میدهد. نقطه نیاز دارد که کلید یک شناسه متغیر معتبر باشد. این بدان معناست که: فاقد فاصله است، با یک رقم شروع نمی شود و شامل کاراکترهای خاصی نمی شود. ($ و _ مجاز هستند).
یک جایگزینی” square bracket notation ” وجود دارد که با هر رشتهای کار میکند:
let user = {}; // set user["likes birds"] = true; // get alert(user["likes birds"]); // true // delete delete user["likes birds"];
حالا همه چی اکی شد.فقط توجه کنید حتما نام داخل کوتیشن قرار بگیره.
در اینجا، متغیر key
ممکن است در زمان اجرا محاسبه شود یا به ورودی کاربر بستگی داشته باشد. و سپس از آن برای دسترسی به پراپرتی ها استفاده می کنیم. که این مورد به ما انعطاف زیادی می دهد.
let user = { name: "John", age: 30 }; let key = prompt("What do you want to know about the user?", "name"); // access by variable alert( user[key] ); // John (if enter "name")
در این گونه روش ها ما نمیتوانیم از نوتیشن دات استفاده نماییم.
let user = { name: "John", age: 30 }; let key = "name"; alert( user.key ) // undefined
Computed properties
در زمان ایجاد یک شی ما از براکت ها میتوانیم در ابجکت لیترال ها نیز استفاده نماییم.که به انها ” computed properties” میگویند.
.برای مثال:
let fruit = prompt("Which fruit to buy?", "apple"); let bag = { [fruit]: 5, // the name of the property is taken from the variable fruit }; alert( bag.apple ); // 5 if fruit="apple"
معنی ویژگی محاسبه شده سادست: [fruit]
به این معنی میباشد که نام پراپرتی باید از fruit
گرفته شود.
براکت ها بسیار قوی تر از نوتیشن دات هستند. آنها هر گونه نام و متغیری را مجاز می دانند. اما نوشتن آنها دست و پا گیرتر است. بنابراین در مواقعی که نام اشیاء ساده است، از نوتیشن دات استفاده میکنیم. و اگر به چیز پیچیدهتری نیاز داشتیم، آنگاه از براکت ها استفاده مینماییم.
Property value shorthand
در کد های واقعی ما اغلب از متغیرهای موجود به عنوان مقادیر برای نام ویژگی ها استفاده می کنیم.
برای مثال:
function makeUser(name, age) { return { name: name, age: age, // ...other properties }; } let user = makeUser("John", 30); alert(user.name); // John
در مثال بالا، ویژگی ها با نام متغیرها یکسان هستند.استفاده از این روش بسیار رایج می باشد.که برای این روش نیز خاصیت خاصی برای کوتاه کردن کدها وجود دارد.که ما میتوانیم بجای name:name
فقط از name
استفاده نماییم.
function makeUser(name, age) { return { name, // same as name: name age, // same as age: age // ... }; }
همچنین ما می توانیم از هر دو ویژگی معمولی و کوتاه در یک شی استفاده کنیم:
let user = { name, // same as name:name age: 30 };
Property names limitations
در بخش های قبل خواندیم که یک متغییر نمیتواند برا خود نامی داشته باشد که آن نام جزء کلمات رزو شده مانن “for”, “let”, “return” و …باشد.اما برای یک ویژگی شی، چنین محدودیتی وجود ندارد:
// these properties are all right let obj = { for: 1, let: 2, return: 3 }; alert( obj.for + obj.let + obj.return ); // 6
به طور خلاصه بهتون بگم که نام پراپرتی ها هیچ محدودیتی ندارند.و همه انها به طور خودکار به رشته تبدیل می گردند.
به عنوان مثال، عدد 0 هنگامی که به عنوان کلید ویژگی استفاده می شود، تبدیل به یک رشته “0” می شود:
let obj = { 0: "test" // same as "0": "test" }; // both alerts access the same property (the number 0 is converted to string "0") alert( obj["0"] ); // test alert( obj[0] ); // test (same property)
یک gotcha کوچک با ویژگی خاصی به نام __proto__ وجود دارد. ما نمی توانیم آن را روی یک مقدار غیر شی تنظیم کنیم:
let obj = {}; obj.__proto__ = 5; // assign a number alert(obj.__proto__); // [object Object] - the value is an object, didn't work as intended
Property existence test, “in” operator
یکی از ویژگی های قابل توجه اشیاء در جاوا اسکریپت، در مقایسه با بسیاری از زبان های دیگر، این است که امکان دسترسی به هر ویژگی وجود دارد. حتی اگر وجود نداشته باشد نیز هیچ خطایی وجود نخواهد داشت!
let user = {}; alert( user.noSuchProperty === undefined ); // true means "no such property"
یک اپراتور ویژه برای این موضوع وجود دارد که ان را با نام "in"
میشناسیم.که سینتکس آن به شکل زیر میباشد.
"key" in object
برای مثال:
let user = { name: "John", age: 30 }; alert( "age" in user ); // true, user.age exists alert( "blabla" in user ); // false, user.blabla doesn't exist
توجه داشته باشید که در سمت چت in
باید نام پراپرتی قرارگیرد و معمولا داخا کوتیشن نوشته میشوند.حالا اگر کوتیشن ها را حذف کنیم به این معناست که ما داریم از یک متغیر استفاده میکنیم. برای مثال:
let user = { age: 30 }; let key = "age"; alert( key in user ); // true, property "age" exists
حالا سوالی که ممکنه پیش بیاد اینه که چرا اپراتور in
وجود داره؟ برای مقایسه مگه استفاده از undefined
کافی نیست؟
in
به درستی کار میکنه. برای مثال زمانی که یک ویژگی شی وجود داشته باشد ولی به صورت undefined ذخیره شده باشد.let obj = { test: undefined }; alert( obj.test ); // it's undefined, so - no such property? alert( "test" in obj ); // true, the property does exist!
در کد بالا، ویژگی obj.test از نظر فنی وجود دارد. بنابراین عملگر in درست کار می کند.چنین چیزهایی به ندرت اتفاق میافتد، زیرا مقدار تعریف نشده نباید به صراحت اختصاص یابد. ما بیشتر از null برای مقادیر “unknown” یا “empty” استفاده می کنیم.
The “for…in” loop
برای حرکت روی تمام کلیدهای یک شی، شکل خاصی از حلقه وجود دارد: for..in
این یک چیز کاملاً متفاوت با ساختار(;;)
for است که قبلاً خواندیم.که سینتکس آن به شکل زیر میباشد.
for (key in object) { // executes the body for each key among object properties }
به عنوان مثال، بیایید تمام ویژگی های user
را خروجی بگیریم:
let user = { name: "John", age: 30, isAdmin: true }; for (let key in user) { // keys alert( key ); // name, age, isAdmin // values for the keys alert( user[key] ); // John, 30, true }
توجه داشته باشید که تمام ساختارهای “for” به ما اجازه می دهند که متغیر حلقه را در داخل حلقه اعلام کنیم، مانند let key در اینجا.همچنین، میتوانیم به جای key
از نام متغیر دیگری در اینجا استفاده کنیم. به عنوان مثال، "for (let prop in obj)"
نیز به طور گسترده استفاده می شود.
Ordered like an object
آیا اشیاء در جاوا اسکریپت به صورت مرتب میباشد؟ به عبارت دیگر، اگر روی یک شی حلقه بزنیم، آیا همه ویژگی ها را به همان ترتیبی که اضافه شده اند به دست می آوریم؟ آیا می توانیم به این تکیه کنیم؟
به عنوان مثال، بیایید یک شی را با کدهای تلفن در نظر بگیریم:
let codes = { "49": "Germany", "41": "Switzerland", "44": "Great Britain", // .., "1": "USA" }; for (let code in codes) { alert(code); // 1, 41, 44, 49 }
- USA (1) اول میشود.
- سپس Switzerland (41) و غیره
کدهای تلفن به ترتیب صعودی مرتب میشوند، زیرا اعداد صحیح هستند. بنابراین ما 1، 41، 44، 49 را می بینیم.
از طرف دیگر اگر، اگر کلیدها غیر صحیح باشند، به ترتیب ایجاد فهرست می شوند.به عنوان مثال:
let user = { name: "John", surname: "Smith" }; user.age = 25; // add one more // non-integer properties are listed in the creation order for (let prop in user) { alert( prop ); // name, surname, age }
بنابراین، برای رفع مشکل کدهای تلفن، میتوانیم با غیر صحیح کردن کدها «تقلب» کنیم. اضافه کردن علامت پلاس "+"
قبل از هر کد کافی است.
let codes = { "+49": "Germany", "+41": "Switzerland", "+44": "Great Britain", // .., "+1": "USA" }; for (let code in codes) { alert( +code ); // 49, 41, 44, 1 }
حالا همانطور که میخواستیم کار میکنه.
دوستان گرامی به پایان جلسه اشیاء در جاوا اسکریپت رسیدیم امیداواریم این مقاله برای شما مفید باشد.
سایر مقالات
ممنون از مقالتون نکات خوبی یاد گرفتم
سلام خواهش میکنم .
لطف دارید