اشیا (Objects)
آشنایی با Object، ایجاد اشیا، ویژگیها و متدها، دسترسی و تغییر ویژگیها، Getters و Setters، Object Destructuring و Spread، متدهای Object.keys و values و entries و assign و freeze و seal و create، Property Descriptor و مالکیت ویژگیها.
آشنایی با Object
شیء (Object) مهمترین ساختار دادهای جاوا اسکریپت است. یک شیء مجموعهای از ویژگیها (Properties) است که هر کدام یک کلید (نام) و یک مقدار دارند. تقریباً همه چیز در جاوا اسکریپت — آرایهها، توابع، تاریخها — از نوع شیء است.
const person = {
name: "علی",
age: 25,
};
console.log(typeof person); // "object"
console.log(person.name); // "علی"
ایجاد اشیا
سه روش رایج برای ساخت شیء:
// 1. Object Literal (رایجترین روش):
const student = {
firstName: "سارا",
lastName: "احمدی",
grade: 12,
};
// 2. سازنده Object:
const car = new Object();
car.brand = "پراید";
car.year = 1402;
// 3. Object.create — با یک نمونهاولیه مشخص:
const animal = Object.create(null); // بدون نمونهاولیه
animal.name = "شیر";
const base = { greet() { return "سلام"; } };
const cat = Object.create(base); // cat از base ارث میبرد
cat.name = "گربه";
console.log(cat.greet()); // "سلام"
ویژگیهای اشیا
کلید ویژگی همیشه رشته (یا Symbol) است و مقدار میتواند هر نوعی باشد — حتی تابع:
const user = {
"user name": "رضا", // کلید با فاصله — نیازمند کوتیشن
age: 30,
"سطح": "حرفهای", // کلید فارسی هم مجاز است
};
console.log(user["user name"]); // "رضا"
console.log(user["سطح"]); // "حرفهای"
// کلید محاسبهشده (Computed):
const key = "city";
const obj = { [key]: "تهران" };
console.log(obj.city); // "تهران"
const obj = { name, age };متدهای اشیا
وقتی مقدار یک ویژگی تابع باشد، به آن متد میگویند:
const calculator = {
x: 0,
y: 0,
// متد کامل:
sum: function (a, b) {
return a + b;
},
// روش کوتاه (Method Shorthand):
multiply(a, b) {
return a * b;
},
// Arrow Function بهعنوان متد (this ندارد — با احتیاط):
power: (a, b) => a ** b,
};
console.log(calculator.sum(3, 4)); // 7
console.log(calculator.multiply(3, 4)); // 12
console.log(calculator.power(2, 8)); // 256
دسترسی به ویژگیها
دو روش برای خواندن ویژگیها وجود دارد — نقطه و براکت:
const book = { title: "شازده کوچولو", pages: 120 };
// 1. نماد نقطه (Dot Notation):
console.log(book.title); // "شازده کوچولو"
// 2. نماد براکت (Bracket Notation):
console.log(book["pages"]); // 120
// براکت برای کلیدهای پویا لازم است:
const prop = "title";
console.log(book[prop]); // "شازده کوچولو"
// console.log(book.prop); // undefined — غلط!
افزودن و حذف ویژگیها
اشیا در جاوا اسکریپت پویا هستند و میتوان هر لحظه ویژگی جدید اضافه یا حذف کرد:
const product = { name: "لپتاپ" };
// افزودن:
product.price = 45000000;
product["in-stock"] = true;
// حذف با delete:
delete product["in-stock"];
console.log(product); // { name: "لپتاپ", price: 45000000 }
// بررسی وجود ویژگی:
console.log("price" in product); // true
console.log(product.hasOwnProperty("name")); // true
// ناموجودبودن با مقدار undefined فرق دارد:
product.color = undefined;
console.log("color" in product); // true — ویژگی هست ولی undefined است
Getters و Setters
با get و set میتوانید ویژگیهایی بسازید که هنگام خواندن یا نوشتن، کد اجرا میکنند — مثل دروازهبان:
const account = {
_balance: 0, // قراردادی — خصوصی است
get balance() {
return this._balance + " تومان";
},
set balance(value) {
if (value < 0) {
console.log("مقدار نامعتبر!");
return;
}
this._balance = value;
},
};
account.balance = 500000; // Setter اجرا میشود
console.log(account.balance); // "500000 تومان" — Getter اجرا میشود
account.balance = -100; // "مقدار نامعتبر!"
Object Destructuring
تخریب ساختار یعنی استخراج ویژگیهای شیء مستقیم در متغیرها:
const movie = {
title: "گرگ وال_street",
director: "مارتین اسکورسیزی",
year: 2013,
country: "آمریکا",
};
// استخراج پایه:
const { title, director } = movie;
console.log(title); // "گرگ وال_street"
console.log(director); // "مارتین اسکورسیزی"
// مقدار پیشفرض:
const { year, genre = "درام" } = movie;
console.log(genre); // "درام"
// تغییر نام متغیر:
const { title: movieTitle } = movie;
console.log(movieTitle); // "شغل"
// تودرتو:
const { address: { city } = {} } = { address: { city: "تهران" } };
console.log(city); // "تهران"
Object Spread
عملگر سهنقطه (...) ویژگیهای یک شیء را «باز میکند» و در شیء جدید میریزد:
const defaults = { theme: "light", lang: "fa", fontSize: 14 };
const userPrefs = { theme: "dark", fontSize: 16 };
// ادغام — کلیدهای بعدی، قبلیها را بازنویسی میکنند:
const settings = { ...defaults, ...userPrefs };
console.log(settings);
// { theme: "dark", lang: "fa", fontSize: 16 }
// کپی سطحی (Shallow Copy):
const copy = { ...defaults };
// افزودن/بازنویسی در حین کپی:
const updated = { ...defaults, fontSize: 18 };
console.log(updated.fontSize); // 18
structuredClone() استفاده کنید.Object.keys و values و entries
این سه متد برای پیمایش اشیا بسیار کاربردی هستند:
const scores = { math: 18, physics: 17, chemistry: 19 };
// کلیدها بهصورت آرایه:
console.log(Object.keys(scores)); // ["math", "physics", "chemistry"]
// مقادیر بهصورت آرایه:
console.log(Object.values(scores)); // [18, 17, 19]
// جفتهای [کلید, مقدار]:
console.log(Object.entries(scores));
// [["math", 18], ["physics", 17], ["chemistry", 19]]
// پیمایش امن با for...of:
for (const [subject, score] of Object.entries(scores)) {
console.log(subject + ": " + score);
}
// math: 18, physics: 17, chemistry: 19
Object.assign
این متد چند شیء را در شیء مقصد ادغام میکند و شیء مقصد را برمیگرداند:
const target = { a: 1, b: 2 };
const source1 = { b: 3, c: 4 };
const source2 = { c: 5 };
// همه منابع در target ادغام میشوند (بعدیها غالباند):
Object.assign(target, source1, source2);
console.log(target); // { a: 1, b: 3, c: 5 }
// ساخت شیء جدید با assign:
const merged = Object.assign({}, source1, source2);
console.log(merged); // { b: 3, c: 4, c: 5 } → { b: 3, c: 5 }
{ ...obj1, ...obj2 } معادل خواناتر Object.assign({}, obj1, obj2) است و در کد مدرن ترجیح داده میشود.Object.freeze و Object.seal
برای محافظت از اشیا در برابر تغییر:
// freeze — کاملاً غیرقابل تغییر:
const frozen = Object.freeze({ x: 1 });
frozen.x = 99; // بیاثر (در Strict Mode خطا)
console.log(frozen.x); // 1
// seal — مقدارها قابل تغییر ولی افزودن/حذف ممنوع:
const sealed = Object.seal({ x: 1, y: 2 });
sealed.x = 50; // ✅ مجاز
sealed.z = 3; // ❌ بیاثر
delete sealed.y; // ❌ بیاثر
console.log(sealed); // { x: 50, y: 2 }
// تشخیص وضعیت:
console.log(Object.isFrozen(frozen)); // true
console.log(Object.isSealed(sealed)); // true
Object.create
این متد شیء جدیدی با نمونهاولیه (Prototype) مشخص میسازد — پایه وراثت prototype-based:
const vehicle = {
init(wheels, speed) {
this.wheels = wheels;
this.speed = speed;
return this;
},
describe() {
return this.wheels + " چرخ، سرعت " + this.speed;
},
};
// bike از vehicle ارث میبرد:
const bike = Object.create(vehicle).init(2, 30);
console.log(bike.describe()); // "2 چرخ، سرعت 30"
console.log(Object.getPrototypeOf(bike) === vehicle); // true
Property Descriptor (توصیفگر ویژگی)
هر ویژگی یک توصیفگر پنهان دارد که رفتارش را کنترل میکند:
const obj = {};
Object.defineProperty(obj, "name", {
value: "علی",
writable: false, // قابل نوشتن نیست
enumerable: true, // در حلقهها دیده میشود
configurable: false, // قابل حذف/تنظیم مجدد نیست
});
console.log(obj.name); // "علی"
obj.name = "رضا"; // بیاثر!
console.log(obj.name); // "علی"
// دیدن توصیفگر:
console.log(Object.getOwnPropertyDescriptor(obj, "name"));
// {
// "value": "Ali",
// "writable": false,
// "enumerable": true,
// "configurable": false
// }
// همه توصیفگرها:
console.log(Object.getOwnPropertyDescriptors(obj));
value (مقدار)، writable (قابل نوشتن)، enumerable (قابل شمارش) و configurable (قابل پیکربندی).مالکیت ویژگیها
تفکیک ویژگیهای خود شیء از ویژگیهای نمونهاولیه:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
return "سلام " + this.name;
};
const p = new Person("مریم");
// ویژگیهای خودِ شیء:
console.log(Object.getOwnPropertyNames(p)); // ["name"]
// کل کلیدها (شامل نمونهاولیه):
console.log(Object.keys(p)); // ["name"] — فقط enumerable ها
// بررسی مالکیت:
console.log(p.hasOwnProperty("name")); // true — خودش
console.log(p.hasOwnProperty("greet")); // false — از prototype
// ES2022 — بررسی امن حتی برای ویژگیهای خاص:
console.log(Object.hasOwn(p, "name")); // true
جمعبندی
اشیا قلب جاوا اسکریپت هستند. در این مبحث با ایجاد اشیا (Literal، سازنده و Object.create)، دسترسی نقطه/براکتی، افزودن و حذف، Getters/Setters، Destructuring و Spread، متدهای کلیدی Object و مفاهیم پیشرفته مثل Descriptor و مالکیت ویژگی آشنا شدید. در مباحث بعدی سراغ توابع و سپس وراثت prototype-based میرویم.
این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.