JavaScript Accessor Descriptors
همان طور که می دانید اشیا در جاوا اسکریپت داده هایی هستند که به صورت کلید مقدار در یک collection که نام آن را شئ می نامیم ذخیره می شوند. هر یک از این جفت کلید مقدار ها یک Property می باشند. هر Property یک سری تنظیمات دارد که به آن Descriptor و یا Accessor Descriptors و یا Property Accessor می گوییم . پس می توان گفت اعضای یک شئ در جاوا اسکریپت قابل پیکره بندی می باشد.
پیکره اصلی یک عضو از شئ شامل موارد زیر می باشد:
- Property Name
- Descriptor
- Value
- enumerable
- writable
- configurable
در زمان تعریف یک شئ به صورت Object Literal تنها موارد Property Name , Value مقدار دهی می گردد و سایر موارد به صورت پیش فرض مقدار دهی می گردد. مواردی که تحت عنوان Descriptor در این لیست است تحت عنوان مقادیر Descriptor است که می توان به آن Meta Data نیز گفت.
Object.getOwnPropertyDescriptor
برای دریافت مقادیر Descriptor به ازای هر عضو از یک شئ می توان از متد استاتیک getOwnPropertyDescriptor
استفاده کنیم.
let person = { name: 'Abolfazl', age: 26, } Object.getOwnPropertyDescriptor(person,'name') /* Object { value: "Abolfazl", writable: true, enumerable: true, configurable: true } */
در مثال بالا مقادیر پیش فرض در صورت تعیین عضو در شئ به صورت Object Literal می باشد. مقادیر پیش فرض به صورت زیر است (تمامی موارد مربوط به پیکره بندی true است) :
- writable : true
- enumerable : true
- configurable : true
Property Descriptors (Object.defineProperty)
این یک شئ است که به صورت نهان در Property قرار دارد. این مقدار به صورت شئ می باشد و کلید های value , writable , enumerable , configurable را دارد. برای ایجاد یک شئ و همچنین تعریف Descriptor به ازای آن می توان از متد استاتیک defineProperty استفاده کرد. این متد هم می تواند یک Property جدید تعیین کند و هم می تواند یک Property پیش فرض را مقادیر تنظیمات آن را عوض کند.
value
این مقدار این Property را در خود جای داده است . مقدار پیش فرض در زمان تعریف یک شئ تعیین می شود .
Object.defineProperty(person,'age',{ value: 21, })
writable
مقدار value را می تواند به صورت قابل نوشتن تعیین کند یا خیر . به صورتی که اگر برابر true باشد قابل تعویض خواهد بود و اگر برابر false باشد قابل تغییر نیست.
Object.defineProperty(person,'_secret',{ writable: false, })
enumerable
اگر مقدار آن برابر با true باشد قابل شمارش در statement for...of
و متد استاتیک Object.keys
می باشد. همچنین اگر مقدار آن برابر با false باشد اگر Object را پرینت console بگیریم در خروجی نخواهد بود.
Object.defineProperty(person,'_secret',{ enumerable: false, })
configurable
این مقدار تعیین می کند که شئ مورد نظر قابل پیکره بندی مجدد باشد یا خیر . فرض کنید یک مقدار را برابر با writable : false
قرار بدهیم در سایر بلوک های کد (از این بلوک به بعد) قابل تغییر نخواهد بود.
Object.defineProperty(person,'age',{ configurable: false, })
Object.create
در زمان تعریف یک شئ می توان این مقادیر را به ازای هر Property تعیین کنیم.
let person = Object.create(Object.prototype,{ name: { value: 'Abolfazl', writable: true, enumerable: true, configurable: true}, age: {value: 29, writable: true, enumerable: true, configurable: true}, _secret: {value: 'ingasdggakfadi7854jkf',writable: false,enumerable: false, configurable: false}, }) console.log(person)
Examples
در صورتی که یکی از موارد writable , enumerable , configurable را برابر با false قرار بدهید سایر موارد به صورت پیش فرض برابر با false خواهد شد.
let person = new Object Object.defineProperty(person,'name',{ value: "Abolfazl",writable: false }) Object.getOwnPropertyDescriptor(person,'name') /* Object { value: "Abolfazl", writable: false, enumerable: false, configurable: false } */
همان طور که می دانید در صورتی که مقدار writable را برابر با false قرار بدهیم دیگر این مقدار قابل تغییر نخواهد بود مگر آن که پیکره بندی آن را مجدد تغییر بدهیم. در صورت تغییر این مقدار خطایی نخواهیم داشت اما مقدار هم تغییر نخواهد کرد.
let person = { name: 'abolfazl', age: 21, _secret: 'rm248aj&412jawiwnzqwer124usim', } Object.defineProperty(person,'_secret',{ writable: false, }) person._secret = undefined person.age = 29 console.log(person)
در صورتی که مقدار enumerable در یک شئ به صورت false تعریف شده باشد ، در صورتی که دسترسی مستقیم انجام بدهیم نمایش داده خواهد شد اما در صورتی که در for..in , Object.keys این آیتم قابل شمارش نخواهد بود.
let person = { name: 'Abolfazl', age: 29, job: 'sfs', } Object.defineProperty(person,'_secret',{ value: 'rioq2&95fkqrdxscji2fl124', writable: false, enumerable: false, configurable: true, }) for(let key in person){ console.log(key) } console.log(Object.keys(person)) console.log(person._secret)
دیدگاهتان را بنویسید