31 - جاوااسکریپت: Object Literals

در js معمولا بیشتر از یک روش برای انجام یک کار وجود دارد. قبلا دیدیم که میتوانیم یک شیء را با new Object() ایجاد کنیم. برای این کار یک shorthand هم وجود دارد که object literal نام دارد: { }کاملا با new Object() یکسان است.var person = {};console.log(person);در خروجی به ما Object خالی میدهد. { } عملگر نیست، یک shorthand است. موتور js وقتی دارد یک سینتکس را parse میکند و به { میرسد که قسمتی از مثلا if statement نیست، فرض میکنید که ما یک شیء ایجاد کرده ایم.ما میتوانیم شیء را initialize کنیم و property ها و method ها را داخل { } بگذاریم. به کل آن به عنوان یک خط از کد نگاه میشود:var person = { firstname:'Tony', lastname:'Alicea' };در js میتونیم برای خوانایی بیشتر از whitespace (اسپیس و tab) استفاده کنیم و باز هم آنچه نوشته ایم به عنوان یک خط از کد دیده میشود.var person = { firstname : 'Tony', lastname: 'Alicea', address : { street : 'Main 111 St.', city : 'New York', state : 'NY' }}پس میتوانیم یک شیء را داخل هر جایی که میخواهیم drop کنیم و property ها و method های آن را همان جا تعریف کنیم. پس اگر در console بخواهیم person را ببینیم یک Object است. این روش ایجاد شیء خیلی سریعتر است. این روش قدرتمندتر هم هست وقتی به رفتار موتور js با این shorthand نگاه میکنیم: ما میتوانیم یک شیء بسازیم هر جایی که میتوانیم یک متغیر را on the fly تعریف کنیم. مثلا موقع پاس دادن یک پارامتر به یک تابع که آن را on the fly ایجاد میکنیم.مثلا در کد زیر تابع greet در انتظار شیء ای است که property ی firstname را دارد:var Tony= { firstname : 'Tony', lastname: 'Alicea', address : { street : 'Main 111 St.', city : 'New York', state : 'NY' }}function greet(person) { console.log('Hi ' + person.firstname) };greet(Tony);اما میتوانیم به جای greet(Tony) پارامتر را on the fly ایجاد کنیم:greet( { firstname:'Mary', lastname:'Doe' } );وقتی js به { میرسه میفهمه که ما یک شیء جدید همین الان و موقع اجرای کد ایجاد کرده ایم. اگر بگیم greet("Tony"); یعنی رشته "Tony" را موقع اجرا و on the fly ایجاد کرده ایم. پس هر موقع که بخواهیم میتوانیم یک شیء ایجاد کنیم.همچنین میتوانیم متدلوژی ها را ترکیب کنیم. مثلا طبق کد بالا اول Tony را با { } ساختیم و داخل آن firstname و lastname و address را ایجاد کرده ایم. ولی بعدا به جای literal با . به آن prorperty جدید میدهیم:Tony.address2 = { street:'Main 333 St.' };چرا میتوانیم به صورت ترکیبی کار کنیم؟ چون کدی که تایپ میکنیم چیزی نیست که واقعا اجرا میشود و توسط موتور js ترجمه میشود. بنابراین سینتکس object literal یا . یا new Object() یا ... در موتور js کاملا یکسان عمل میکنند. اما معمولا از { } استفاده میشود چون هم قدرتمند و هم ساده است.32 - جاوااسکریپت: Faking Namespacesمخواهیم بدانیم آنچه تا اینجا گفته شد در framework ها چطور استفاده شده است. اینجا در مورد faking namespaces صحبت میکنیم.تعریف nemespace: نگهدارنده متغیرها و تابع ها. برای جدا نگه داشتن متغیر و تابع با اسم یکسان به کار میرود.در js به خاطر طبیعت شیء ها namespace نداریم و نیازی هم نداریم. میتوانیم آن را fake کنیم. مثلا داریم:var greet = 'Hello';var greet = 'Hola';console.log(greet);خروجی Hola میدهد. اگر این دو متغیر در دو فایل js مختلف ایجاد شده بودند، مثلا یکی در کتابخانه greeting انگلیسی و یکی در کتابخانه greeting اسپانیایی، هر دو متغیر greet را در global object ست میکنند روی هم overwrite میشود. namespace در این شرایط کمک میکند چون با namespace یک نگهدارنده برای greeting انگلیسی و یکی برای greeting اسپانیایی داریم. ولی چون در js این namespace را نداریم، این کار را با شیء ها انجام میدهیم. شیء هایی ایجاد میکنیم که نگهدارنده هستند:var english = { };var spanish = { };english.greet = 'Hello';spanish.greet = 'Hola';این اشیاء فقط نگهدارنده هستند و هیچ functionality ندارند تا مطمئن باشیم کد ما روی کدهای دیگر اثری نمیگذارد. متغیرهای greet در کد بالا اثری روی هم ندارند. از این نگهدارنده ها در framework ها و کتابخانه ها زیاد استفاده میشود تا مطمئن شویم namespace colusion (دو اسم یکسان) رخ نمیدهد. این کار را میتوان در چندین سطح انجام داد و میتوانیم چندین سطح شیء نگهدارنده داشته باشیم.اگر در همین کد بنویسیم:english.greeting.greet = 'Hello';خطا میدهد: cannot set property 'greet' of undefined چون اول english.greeting اجرا میشود و مقدار undefined برگردانده میشود. undefined خودش یک شیء نیست و در آن greet وجود ندارد و نمیتوان greet را ساخت. بنابراین:english.greeting = {}; english.greeting.greet = 'Hello';خروجی console.log(english); خواهد بود:Object{ greeting: Object }که داخل greeting هم greet وجود دارد. یا اینکه در کد داشته باشیم:var english = { greeting: { basic:'Hello' } }; در این کد هم undefined نداریم.پس property ها و method هایمان را در یک شیء نگهدارنده قرار میدهیم تا آن را از کدهای دیگر در global object که دیگران نوشته اند یا حتی خودمان نوشته ایم جدا کند. به این کار faking namespace در js گفته میشود. از این در framework ها و کتابخانه ها زیاد استفاده شده است.