تعداد بازدید: 447

Obeject Data Structure in JavaScript

هر زبان برنامه نویسی از دو ساختار اصلی تشکیل شده است . بخش اول (Data Structure) ساختمان های داده آن و بخش دوم لیست عملیات های آن (Statements) . ممکن است هر قسمت از یک ساختمان داده رفتاری متفاوت در زبان دیگر داشته باشد.

Object or Primitive

در جاوا اسکریپت مفاهیم یا شئ هستند و یا داده اولیه (Object or Primitive value) به این شکل که داده هایی که متد و ویژگی (Methods and Properties) نداشته باشند جزو داده های اولیه هستند و بقیه داده ها که متد و ویژگی دارند شئ هستند. داده های اولیه در جاوا اسکریپت :

  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • bigint

این ساختمان های داده در جاوا اسکریپت مقادیر آن ها قابل تغییر نیست مثل Array , Object و ما وقتی مقدار 54 را تعریفن می کنیم مقدار نهایی همین است . در صورتی که این مقادیر در const تعریف گردند قابل تغییر نمی باشند.

همه چیز در جاوا اسکریپت شئ است :

  • Boolean()
  • Number()
  • String()
  • Function()
  • Object()
  • Array()

تمامی موارد بالا اگر با کلمه کلیدی new تعریف گردند به صورت شئ عمل خواهند کرد. نوع داده Boolean, Number , String به صورت primitive نیز قابل تعریف هستند. برای تعریف این نوع داده ها به صورت شئ باید از کلمه کلیدی new استفاده کنیم.

اشیا در جاوا اسکریپت بسیار زیاد می باشند و هر کدام یک مبحث باشند (Promise , Error , …) ولی یک سری اشیا اولیه در جاوا اسکریپت داریم. تمام مقادیر جاوا اسکریپت، به جز مقادیر اولیه (Primitive value like number , string , undefined , boolean , null)، اشیا هستند. هر شئ که با کلید new ساخته شود (new String , new Number , new Boolean) در زمانی که با کلمه new  صدا زده می شوند شئ هستند و در صورتی که به صورت ساده تعریف شده باشند جزو Primitive value ها هستند.

Date , Math , Regular expression , Functions , Array , Objects همیشه یک شئ هستند و همچنین این مورد را می توان از رفتار آن ها نیز فهمید (به این شکل که یک سری متد و یک سری ویژگی دارند)

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

Object

ساختمان داده اشیا در جاوا اسکریپت برای نگهداری به صورت کلید مقدار در برای ساخت موجودیت های پیشرفته تر کاربرد دارد. تقریبا همه اشیا در جاوا اسکریپت از موجودیت Object ساخته شده اند . اشیا در جاوا اسکریپت بسیار نزدیک به ماهیت Associative arrays  در زبان پی اچ پی است.

هر متغیر می تواند یک یا چند مقدار بگیرد. اگر قرار بر نگهداری یک collection از داده ها در یک متغیر داشتیم از ساختار Array , Object استفاده می کنیم. برای تعریف کردن اشیا از ساختار کلید : مقدار ("key":"value") استفاده می کنیم دقت داشته باشید هم کلید و هم مقدار در میان “” قرار گرفته اند و همچنین بهتر است بین : فاصله اضافی نداشته باشیم این یک Best Practice است.

اشیا نیز در یک متغیر تعریف می شوند تا به آن دسترسی داشته باشیم (در هارددیسک). در جاوا اسکریپت به دو روش زیر می توان شئ را تعریف کرد :

  • به صورت عادی با {}
  • با استفاده از کلمه کلیدی new Object
  • با استفاده از متد Object.create
  • به وسیله Object Constructor به طور مثال new String() , new Number()
const person = {
  firstName: "John",
  lastName: "Doe",
  age: 50,
  eyeColor: "blue"
};
//-------------------------type 2
const person = {};
person.firstName = "John";
person.lastName = "Doe";
person.age = 50;
person.eyeColor = "blue";
//-------------------------type 3
const person = new Object();
person.firstName = "John";
person.lastName = "Doe";
person.age = 50;
person.eyeColor = "blue";

نکته مهم Best Practice : بهتر است به عنوان یک عادت خوب اشیا و آرایه ها را در const تعریف کنیم. به این دو ماهیت ساختمان داده های پیشرفته در جاوا اسکریپت می گوییم و const رفتار خاص تری با موجودیت های برگرفته از این ساختمان داده دارد . (اعضای آن قابل ویرایش و حذف هستند ولی کل متغیر قابل ReAssign نیست )

در داخل اشیا ما می توانیم هر یک از ساختمان داده های String , number , null , Nan , Undefined , Function , Array را تعریف کنیم. پس اگر اسم Json Array را شنیدید بدانید که در آن اشیا است که داخل آن آرایه تعریف شده است.

var person = {
"name":"John",
"age":30,
"cars":["Ford", "BMW", "Fiat"]
}

برای تعریف یک شئ می توانید از ساختار زیر استفاده کنید( کلیدها در میان "" قرار بگیرند در صورتی که در کلید ما از کاراکتر – استفاده کنیم.)  و اگر به صورت رشته ساده باشند می توان به صورت عادی کلید ها را تعریف کرد.

const person = {
   name: 'ali',
   famil: 'alavi',
   job: 'sfs',
   "education-1": "elementry",
}

در ES6 می توان به صورت زیر هم با این گونه کلید ها برخورد کرد:

const person = {
    name: 'ali',
    famil: 'alavi',
    job: 'sfs',
    ["education-1"]: "elementry"
}

Access , Update , Delete in Object

برای دسترسی به یک المان در یک object هم می توان از روش object استفاده کرد و هم می توان مثل یک Array رفتار کرد هم می توان به صورت ترکیبی از دو روش استفاده کرد.

به طور مثال برای آخرین شئ تعریف شده در بالا person Object :

person.name  //"John"
person["name"]  //"John"
person.car[0]  //"Ford"

به همان روش که به اعضای یک شی یا آرایه دسترسی داریم می توانیم مقدار آن را بروزرسانی کنیم

person.name="jafar" 
person["name"]="jafar" 
person.car[0]="peykan"

برای افزودن یک متغیر به عنوان یک عضو از یک شئ می توان از ساختار زیر استفاده کرد:

var name='ali'
var person = {
    name,
    famil: 'alavi',
    job: 'sfs',
}
person //Object { name: "ali", famil: "alavi", job: "sfs" }

همچنین می توان با همین syntax یک تابع را نیز به یک شئ‌ افزود . به این نوع syntax ها shorthand می گوییم که زیبا تر خوانا تر و سریع تر نوشته می شود . حالت پیش فرض را longhand می گوییم .می توانید مثال های زیادی از shorthand ها در جاوا اسکریپت ببینید.

const person = {
    name: 'ali',
    getName(){
        return this.name
    }
}

برای تعریف یک عضو به یک شئ به صورت ثابت و بدون تغییر (read-only property) از ساختار Object.defineProperty استفاده کرد.

let person={}
Object.defineProperty(person,'id',{value:0922229174,writable:false})
person.id //922229174
person.id = 'hello'
person.id //922229174

در ساختار بالا زمانی که property با کلید id را به صورت شخصی تعریف کردیم و مقدار دهی مجدد کردیم مقدار جدید ست نشد.

برای حذف یک عضو از یک شئ لازم است از عبارت delete thisIsObject[key] یا delete thisIsObject.cow استفاده کنیم. سه روش مرسوم برای حذف:

//-----------------------------Type1
delete person["name"];
//-----------------------------Type2
delete person.name;

Loop throw an Objects

برای پیمایش میان اشیا ما از statements های جاوا اسکریپت استفاده می کنیم . دو statement معروف برای پیمایش for...in است .

for (var key in person) {
    console.log(key + " is equal to " + person.key)
}

راه حل دوم استفاده ترکیبی از Object.entries و for...of است که در لیست static methods آن را بررسی می کنیم.

const object1 = {
  a: 'somestring',
  b: 42
};
for (const [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}
// expected output:
// "a: somestring"
// "b: 42"

راه حل سوم استفاده ترکیبی از Object.entries , Desctructuring می باشد به همراه map :

let person = {
  name: 'Abolfazl',
  age: 29,
  job: 'sfs'
}

Object.entries(person).map( ([key,value]) => {
  console.log(key,value)
})

نکته مهم این است که به صورت عادی امکان استفاده از for…of برای پیمایش Object وجود ندارد.

Static Methods

تمام اشیا که ما می سازیم گونه ای از شئ Object است.

Method Description
Object.assign(target,…source) همان طور که از نام آن معلوم است متغیر های source را در متغیر target قرار می دهد. کاربرد آن برای کپی یک متغیر در متغیر دیگر یا تقریبا ادغام متغیر هاست.

Object.assign({"name":"ali","famil":"rangin"},{"name":"ahmad","famil":"alavi"}) 
// { name: "ahmad", famil: "alavi" } 
Object.assign(
    {"name":"ali","famil":"rangin"},
    {"name":"ahmad","famil":"alavi"},
    {"name":"jafar","famil":"haghi"}
) 
// { name: "jafar", famil: "haghi" } 
/*---------------------------------------*/ 
const target = { a: 1, b: 2 }; 
const source = { b: 4, c: 5 }; 
const returnedTarget = Object.assign(target, source);
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1); //{ "a": 0, "b": { "c": 0}}

معادل ES6 در این مثال برابر است با syntax {...{} , ...{}}

var concat = {...{a:1,b:4},...{b:5,c:10}} //Object { a: 1, b: 5, c: 10 }
Object.create(object) این برای ساختن یک شئ از روی یک شئ دیگر است .

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};
const me = Object.create(person);
me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

کاربرد دیگر این تابع این است که یک شی به عنوان یک Resource از روی آن می سازیم .

const HttpRequest = {
    #attributes
    #actions
}
let requestUpdate = Object.create(HttpRequest)  // request update
let requestCreate = Object.create(HttpRequest)  // request create
Object.entries(object) این تابع به صورت یک آرایه هم کلید و هم مقدار را بر می گرداند.

var person = {
   "name":"Abolfazl",
   "famil":"sabagh"
}
console.log(Object.entries(person)
Array [
   0: Array [ "name", "Abolfazl" ]
   1: Array [ "famil", "sabagh" ]
]
Object.freeze(object) این تابع شی را به شکلی فریز می کنند تا قابل ویرایش نباشد.(نه بروزرسانی نه حذف )

const obj = {
  prop: 42
};
Object.freeze(obj);
obj.prop = 33;
// Throws an error in strict mode
console.log(obj.prop);
// expected output: 42
Object.keys(object) لیست کلید ها را برمی گرداند.

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
Object.value(object) لیست مقادیر را بر می گرداند.

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]
Object.defineProperty()

Arguments:

  • Object
  • Property
  • Meta Data
برای تعریف یک Property با پارامتر هایی کمی پیشرفته تر قابل تعیین می باشد.

'use strict';
 let obj = {};
 Object.defineProperty(obj, "x", {value:0, writable:false});

Meta Data :

  • value : برابر مقدار property است.
  • enumerable : اگر برابر true باشد شئ قابل پیمایش می باشد.
  • writable : اگر برابر true باشد قابل مقدار دهیم مجدد است و اگر برابر false باشد به صورت فقط خواندنی تعریف شده است.
  • configurable : اگر برابر false باشد قابل حذف نمی باشد property مورد نظر .

متدهای بالا بخشی از توابعی بود که روی اشیا پیاده سازی برای اهداف خاص پیاده سازی می کردیم. این متد ها برای کار با اشیا در ES5 تعریف شده اند.

Object Inheritance (__proto__)

با استفاده از ویژگی __proto__ می توان یک شئ از دیگری ارث بری کند.

var person = {
    firstName: 'ali',
    lastName: 'alavi',
    getName(){
        return `${this.firstName} ${this.lastName}`
    }
} 

var student = {
    grade: 15,
    __proto__: person
} 

student.getName()

Object Resource

این یک روش برای ساخت یک سری اشیا مشابه بدون استفاده از کلاس است . به طور مثال شما می خواهید یک شئ داشته باشید و در عملیات های مختلف (مراحل مختلف یا Event ها) جاواسکریپتی یک سری تغییرات در شئ ایجاد و در نهایت به سرور ارسال کنید.

فرض کنید یک شمارنده ساده داریم که لازم است در هر مرحله یکی بسازیم و به ازای هر Event یک عدد به این شمارنده اضافه کنیم (مثلا فرض کنید یک صلوات شمار به ازای ذکر های مختلف) بدون استفاده از کلاس به روش زیر عمل می کنید.

const counterResource = {
    "count":0,
    "init":function(start){
        this.count = start
    },
    increase:function(){
        this.count++
    }
}

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

let counterOne = Object.create(CounterResource)
counterOne.init(0);
counterOne.increase();
counterOne.increase();
console.log(counterOne.count);

می توان به ازای تعداد مشخص از شمارنده ها بسازیم با همین قالب و از آن ها در سیستم استفاده کنیم. یک حافظه مشخص در RAM به ازای هر شمارنده است .

Object Constructor

object ها در جاوا اسکریپت ساختمان داده مناسبی برای ساخت اشیا مورد نظر برای ما هستند . همان طور که می دانیم توابع در جاوا اسکریپت هم شئ هستند و ا گر با کلمه کلیدی new تعریف شوند می توان با آن ها به صورت شئ برخورد کرد. همان شمارنده قبل را با استفاده از Object Constructor تعریف می کنیم.

function Counter(counter){
  this.counter = counter
  this.increase = function(){
    this.counter++
  }
  this.getCounter = function(){
    return this.counter
  }
} 

var counter1 = new Counter(0)
counter1.increase()
counter1.increase()
counter1.getCounter() //2

Prototype

تمامی اشیا در جاوا اسکریپت از prototype ارث بری می شوند (Object.prototype , String.prototype, Number.prototype , Date.prototype) حال می توان با استفاده از prototype یک سری متد یا ویژگی به Function Constructor افزود.

Counter.prototype.reset = function(){
    this.counter = 0
}

var c = new Counter(0)
c.increase()
c.increase()
c.getCounter() //2
c.reset()
c.getCounter() //0

در ES5 ما به جای استفاده از Class از ساختار Function Constructor استفاده می کردیم که نوع پیشرفته تری از Object است (در حقیقت یک نوع Object است که constructor دارد). در تعریف Function Constructor بهتر از upper case naming convention استفاده کنید.

مطالب مشابه

Window Object Methods

در محیط اجرای مرورگر یک سری متد های پیش فرض برای یک سری عملیات های عمومی تر از متدهای ساختمان داده های موجود primitive...

Window Object Properties

شئ جاری در Browser Environment یک سری اطلاعات در قالب یک سری ساختمان داده در رابطه با اطلاعات صفحه وب فعلی از قبیل...

JavaScript Accessor Descriptors

همان طور که می دانید اشیا در جاوا اسکریپت داده هایی هستند که به صورت کلید مقدار در یک collection که نام آن را شئ می...

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

۰ دیدگاه برای Obeject Data Structure in JavaScript

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *