<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های pazirehsarafraz</title>
        <link>https://virgool.io/feed/@pazirehsarafraz</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-07 18:16:11</pubDate>
        <image>
            <url>https://static.virgool.io/images/default-avatar.jpg</url>
            <title>pazirehsarafraz</title>
            <link>https://virgool.io/@pazirehsarafraz</link>
        </image>

                    <item>
                <title>70 - جاوااسکریپت: بررسی کدهای jQuery، بخش اول</title>
                <link>https://virgool.io/@pazirehsarafraz/70-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%DA%A9%D8%AF%D9%87%D8%A7%DB%8C-jquery-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-tomwvoybt8s7</link>
                <description>میخواهیم ساختار و استایل این source code را بررسی کنیم. نمیخواهیم بررسی کنیم که هر ویژگی چطور پیاده سازی شده، میخواهیم سعی کنیم کد را بخوانیم و بفهمیم چگونه ساختاربندی شده است. کتابخانه jQuery هیچ ویژگی ای به بروزر اضافه نمیکند، فقط یک کتابخانه است. تنها کاری که میکند این است که تایپ سینتکسی کدها را راحت تر میکند و همچنین مسائل مربوط به بروزرها را برای ما هندل میکند. بروزرها با هم متفاوت هستند و هسته های مختلفی دارند. ما دیگر نگران این مسئله نیستیم، آن کدی که میخواهیم را مینویسیم و کدهای داخل کتابخانه jQuery این مسئله را هندل میکنند. این کتابخانه به ما اجازه دستکاری DOM را میدهد. DOM همان document object modelling داخل بروزر است و از موتور js مجزا است. چیزی است که به بروزر اجازه میدهد تا به html نگاه کند و تصمیم بگیرد چگونه آن را render کند و در صفحه نمایش دهد. js به DOM دسترسی دارد و میتواند آن را تغییر دهد. میتواند با دستکاری DOM در حافظه، ساختار صفحه html را بعد از لود شدن دستکاری کند. DOM ساختاری شبیه به درخت دارد که html را در خود قرار داده است. js نگاه کردن به DOM را راحت میکند تا المنت ها را در صفحه مان پیدا کنیم و آنها را دستکاری کنیم.اسم این کتابخانه در کد $ یا jQuery است. مثلا کد html زیر را داریم:&lt;div id=&#x27;main&#x27; class=&#x27;container&#x27;&gt;&lt;h1&gt;People&lt;/h1&gt;&lt;ul class=&#x27;people&#x27;&gt;&lt;li&gt;John Doe&lt;/li&gt;&lt;li&gt;Jane Doe&lt;/li&gt;&lt;li&gt;Jim Doe&lt;/li&gt;&lt;/ul&gt;&lt;script src=&#x27;jquery-1.11.2.js&#x27;&gt;&lt;script src=&#x27;app.js&#x27;&gt;کد js خودمان را در app.js مینویسیم. کتابخانه jQuery دو نسخه دارد. نسخه دوم در بروزرهای خیلی قدیمی ساپورت نمیشود. اما ساختار کدها یکسان است. کل html به صورت ساختار درختی در حافظه داخل بروزر ذخیره شده است و js به همه آن دسترسی دارد. اگر در app.js بنویسیم:var q = $(&#x27;ul.people li&#x27;);console.log(q);همه li هایی که داخل ul ها با کلاس people هستند را داخل درخت انتخاب میکند. خروجی کد بالا:jQuery.fn.init[3]یک شیء با نوع jQuery برگردانده که یک آرایه است. هر عضو از این آرایه یک المنت از DOM است. یک المنت استاندارد از بروزر است.در همین خروجی در قسمت __proto__ داریم: __proto__:jQuery[0]این یک شیء jQuery است که داخل آن متدهای خیلی زیادی وجود دارد. قبلا گفته شده بود که بهتر است متدها را در prototype قرار دهیم تا در فضای حافظه صرفه جویی کنیم.میخواهیم بدانیم jQuery.fn.init یعنی چه. همان طور که در  کد مشاهده میکنید از عملگر new استفاده نشده است:var q = $(&#x27;ul.people li&#x27;);میخواهیم بدانیم این کد چگونه کار میکند. کد minify نشده jQuery حدود 10 هزار خط کد است که پر از کامنت است. اولین خط کد این کتابخانه:(function(global, factory) { ... این یک IIFE است. از تریک پرانتز استفاده کرده است تا syntax parser بداند این یک function expression است. همه کدها را در یک تابع wrap کرده است. این تابع دو پارامتر میگیرد. میخواهد بداند که global object چی هست. در خط اول کد داخل این تابع یک ماژول را چک میکند:if (typeof module===&#x27;object&#x27; &amp;&amp; typeof module.exports===&#x27;object&#x27;) { ... }در مورد این خط کد توضیح داده که برای commonJS یا commonJs-like environment ها یا Node.js استفاده میشه. در واقع داره چک میکنه که jQuery در چه environment ای هست تا بفهمد global object چی هست. این تابع در آخر تعریف ش invoke شده است:(function(global, factory) {...return factory(w);...}(typeof window!==&#x27;undefined&#x27; ? window : this, function(window, noGlobal){...})یعنی برای پاس دادن پارامتر global چک میکند که آیا شیء window وجود دارد یا نه. پس اگر داخل یک بروزر باشیم global object همان window است، در غیر این صورت this را برمیگرداند (مثلا ممکن است node.js باشد).پارامتر دوم که پاس داده میشود factory است که آخر همین تابع برگردانده میشود. موقع فراخوانی تابع، این پارامتر خودش به صورت یک تابع پاس داده شده است. پس تابع اول تابعی است که دارد چک میکند که jQuery کجا قرار گرفته است و تابع factory پاس داده شده کد اصلی jQuery است. در پاس دادن پارامتر factory یک function expression دیگر داریم که window و noGlobal را میگیرد. شیء window را وقتی تابع factory فراخوانی میشود (return factory(w)) میگیریم. کد function(window, noGlobal) به عنوان factory پاس داده میشود و factory داخل کد invoke میشود. وقتی که function(window, noGlobal) فراخوانی میشود چه اتفاقی می افتد؟ در یک execution context جدید یک سری متغیر ست میشوند. در واقع وقتی factory آخر تابع invoke میشود یک execution context جدید داریم. یکی از متغیرهای مهمی که ست میشود jQuery است که یک تابع است:var jQuery = function (selector, context){ return new jQuery.fn.init(selector, context); };پارامتر selector همان رشته ای است که به jQuery میدهیم تا بفهمد چه المنتی از html را پاس داده ایم. همان طور که دیده میشود داخل تعریف jQuery کد زیادی نداریم. وقتی شیء jQuery را در کد زیر ایجاد کردیم:var q = $(&#x27;ul.people li&#x27;);به ما jQuery.fn.init[3] را برگرداند. چون تابع jQuery یک function constructor نیست. به همین دلیل در خط کد بالا نیازی نبود از عملگر new استفاده کنیم. چون تعریف jQuery یک تابع است که یک شیء را برمیگرداند. شیء را با فراخوانی یک function constructor برمیگرداند (new jQuery.fn.init(selector, context)). پس دیگر نیازی نیست موقع استفاده از jQuery ما خودمان همیشه از کلمه کلیدی new استفاده کنیم.jQuery.fn = jQuery.prototype = { ... };مقدار jQuery.fn را برابر با Query.prototype قرار داده یعنی by reference است. پس fn به همان قسمت از حافظه اشاره میکند که ویژگی prototype تابع jQuery در آن قرار دارد. همه تابع ها ویژگی .prototype دارند که وقتی به عنوان function constructor استفاده شوند از آن ویژگی استفاده میشود. اگر به عنوان function constructor هم استفاده نکنیم، همچنان این ویژگی را داریم که خالی است. پس از این شیء خالی استفاده کردیم. با توجه به خط کد بالا نیازی نیست که هر بار prototype را تایپ کنیم و میتوانیم به جای آن از fn استفاده کنیم. پس fn همان prototype تابع است که با یک شیء جدید مجددا نوشته میشود (= { ... }). حال میخواهیم بدانیم داخل jQuery.fn چه داریم. داخل آن ویژگی های زیادی داریم، از جمله each و map که از callback استفاده میکنند:each: function(callback, args) { return jQuery.each(this, callaback, args); },map: function(callback) { return this.pushStack(jQuery.map(this, function(elem, i){ return callback.call(elem, i, elem); })); }در این دو یک callback را به یک تابع پاس داده ایم. برای مثال در map از callback.call استفاده کرده ایم. یعنی داریم تابعی که به map پاس داده شده است را invoke میکنیم.بعد از تمام شدن قطعه کد jQuery.fn = jQuery.prototype = { ... }; داریم:jQuery.extend =  jQuery.fn.extend = function() {};یعنی به یک تابع دو تا اسم داده شده است و by reference است. در بخش های قبل در مورد extend در underscore توضیح داده شد.jQuery.extend =  jQuery.fn.extend = function() {var src, copyIsArray, copy, name, options, clone, target=arguments[0]||{}, i=1, length=arguments.length, deep=false;if (typeof target === &#x27;boolean&#x27;) { deep=target;  target=arguments[i]||{};  i++; }if (typeof target !== &#x27;object&#x27; &amp;&amp; !jQuery.isFunction(target)) { target={} }if (i ===  length) { target=this;  i--; }for ( ; i&lt;length; i++) {   if ((options=arguments[i]) != null) {      for (name in options) {         src=target[name];         copy=options[name];           if(target===copy){continue;}         if(...){ ... target[name]=jQuery.extend(deep, clone, copy); }          else if(copy!==undefined) { target[name]=copy; }      }   return target;};}};در این کد چیزها را به یک شیء اضافه میکند. ویژگی ها و متدهای یک شیء را میگیرد و به شیء دیگری اضافه میکند. قسمت length=arguments.length یعنی میتوانیم به هر تعداد شیء که میخواهیم داشته باشیم، چون حلقه for ( ; i&lt;length; i++) را داریم. در اولین خط کد این حلقه دسته ای از شیء ها را پاس میدهیم:options=arguments[i]برای اگر 3 شیء داشته باشیم، length برابر با 3 است. سپس در حلقه for (name in options) از reflection استفاده میکنیم و همه ویژگی ها و متدها را بررسی میکنیم. یک src و یک copy داریم. همه ویژگی ها و متدهای یک شیء را به شیء دیگری اضافه میکند. همان طور که در کد target=arguments[0]||{} مشاهده میشود target آرگومان اول مان است. پس اولین پارامتری که به extend پاس میدهیم همان چیزی است که میخواهیم extend کنیم و همان شیئی است که میخواهیم در نهایت داشته باشیم. پس طبق src=target[name]; یعنی src جایی است که ویژگی ها و متدها در آن کپی میشوند. در خط کد target[name]=jQuery.extend(deep, clone, copy);دوباره از extend استفاده کرده ایم برای اینکه شیء ها میتوانند خودشان شامل شیء دیگری باشند و میخواهیم مطمئن شویم که همه ویژگی ها و متدها حتی sub-object ها هم به target اضافه شده اند.در ادامه کد میبینیم:jQuery.extend({...});یعنی دارد ویژگی ها و متدهایی را به شیء jQuery اضافه میکند و اولین آگورمان آن target است.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Fri, 24 May 2019 11:44:52 +0430</pubDate>
            </item>
                    <item>
                <title>۶۷ - جاوااسکریپت: Strict Mode</title>
                <link>https://virgool.io/@pazirehsarafraz/%DB%B6%DB%B7-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-strict-mode-wlhzeylwzw3p</link>
                <description>دیدیم که js در مورد چیزها خیلی لیبرال و انعطاف پذیر است. روشی وجود دارد تا به موتور js بگوییم که میخواهیم کدها رار سختگیرانه تر بررسی کند. strict mode میتواند به ما در جلوگیری از خطا در یک سری شرایط خاص کمک کند. فرض کنید متغیری را تعریف کرده ایم ولی موقع مقداردهی در تایپ اشتباه میکنیم:var person;persom = { };console.log(persom);خروجی کد بالا Object() است. این شیء به global object یا همان window اضافه شده. متغیر person هم همین طور. اگر در کنسول بنویسیم window.person مقدار undefined را برمیگرداند. این مسئله میتواند باعث مشکلات زیادی شود. js یک ویژگی دارد. میتوانیم به js بگوییم تا سختگیرتر باشد و قانون های بیشتری را پیاده سازی کند. برای این کار به اول کد خط زیر را اضافه میکنیم:&quot;use strict&quot;;یکی از پرکاربردترین مفاهیم در strict mode این است که حتما باید اول متغیر با var تعریف شود و بعد تنظیم شود. در این حالت اگر از کد اجرا بگیریم خطا میدهد:persom is not definedعبارت &quot;use strict&quot; باید بالای همه خط کدها یا بالای یک تابع قرار بگیرد، چوان میتوانی فقط یک تابع را strict کنیم. بخصوص یک execution context جدید میتواند از strict mode استفاده کند، نه بقیه فایل و global execution context. function logNewPerson() {&quot;use strict&quot;;var person2;persom2 = { };console.log(persom2);}var person;persom = { };console.log(persom);logNewPerson();با اجرای کد بالا میشود:Object { }Uncaught ReferenceError: persom2 is not definedیعنی قسمت global چون strict نبوده مشکلی نداشته. شاید این سوال پیش بیاید که چرا همیشه از اول از strict mode استفاده نکردیم. چونا این یک ویژگی اضافی است و همه موتورهای js این ویژگی را مثل هم پیاده سازی نکرده اند. پس این چیزی نیست که بتوانیم ۱۰۰٪ به آن متکی باشیم. اگر چند فایل js داشته باشیم و بخواهیم آنها را یکی و minify کنیم تا فقط یک بار دانلود شود، اگر فایل اول از &quot;use strict&quot;; استفاده کرده باشد، روی همه کدها اعمال میشود و اگر همه فایل های دیگر js قوانین strict را رعایت نکرده باشند به مشکل میخوریم.در سایت mozilla developer network در قسمت strict mode درباره چگونگی پیاده سازی strict mode در firefox توضیح داده شده.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sun, 28 Apr 2019 13:49:56 +0430</pubDate>
            </item>
                    <item>
                <title>66 -  جاوااسکریپت: typeof,  instanceof</title>
                <link>https://virgool.io/@pazirehsarafraz/66-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-typeof-instanceof-zpd4xxs4kwdf</link>
                <description>دیدیم که js یک زبان dynamic typing است، که به ما اجازه میدهد کارهای جالب و گاهی خطرناک انجام دهیم. اگر یک متغیر داشته باشیم و بخواهیم بدانیم نوع آن چیست چه کنیم؟ عملگر typeof به ما میگوید که متغیر از چه نوعی است.var a = 3;console.log(typeof a);خروجی این کد number است. حرف اول number کوچک است. چون از function constructor استفاده نکرده ایم (بهتر است استفاده نکنیم).var b = &#x27;Hello&#x27;;console.log(typeof b);خروجی کد بالا string است.var c = { };console.log(typeof c);خروجی کد بالا object است که با حرف کوچک شروع میشود. این خروجی فقط یک رشته است.var d = [ ];console.log(typeof d);console.log(Object.prototype.toString.call(d));همان طور که میدانیم آرایه ها شیء هستند. بنابراین خروجی typeof آن برابر با object است. این خروجی خیلی به درد نمیخورد. برای این مسئله چند راه حل وجود دارد. یکی از این راه حل ها استفاده از مفهوم prototype و مفهوم call است. اگر از کد:console.log(d.toString());استفاده کنیم، خروجی یک رشته خالی است. در کنسول هیچی نمیبینیم، یک رشته خالی است. چون سعی کرده که متن داخل آرایه را بگیرد و به رشته تبدیل کند. در شیء پایه Object یک ویژگی toString در prototype ش وجود دارد. به جای اینکه با Object.prototype.toString کار کنیم از call استفاده میکنیم تا تابع را فراخوانی کند و به آن بگوید که متغیر this به کجا اشاره میکند. چون toString از متغیر this استفاده میکنید تا خروجی خود را تولید کند. با چنین کدی خروجی [object Array] خواهد بود.function Person(name) { this.name = name; }var e = new Person(&#x27;Jane&#x27;);console.log(typeof e);اینجا یک function constructor داریم که با حرف بزرگ شروع شده و چیزی return نمیکند. خروجی کد بالا هم object است.console.log(e instanceof Person);کلمه کلیدی instanceof به ما میگوید که آیا شیء در prototype chain هست یا نه. پس خروجی کد بالا true است..console.log(typeof undefined);خروجی کد بالا undefined است.console.log(typeof null);خروجی کد بالا object است که یک باگ در js است. چون کدها و کتابخانه های زیادی بر این اساس نوشته شده است هیچ وقت این باگ را درست نکردند. حل این باگ خیلی زمانبر خواهد بود.پس عملگر typeof یک پارامتر را میگیرد. یک تابع است و یک رشته برمیگرداند. instanceof موقع کار کردن با object chain به کار میرود. بررسی میکند که آیا شیء در prototype chain شیئی هست یا نه.var z = function() { };console.log(typeof z);خروجی این کد function است. تابع ها در js شیء هستند. پس به علت first class function متغیر z یک شیء است. </description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sun, 28 Apr 2019 10:45:15 +0430</pubDate>
            </item>
                    <item>
                <title>65 - جاوااسکریپت: Initialization</title>
                <link>https://virgool.io/@pazirehsarafraz/65-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-initialization-ecyl7e5ysrab</link>
                <description>قبلا گفته شد که چطور میتوانیم از object literal ها و array literal ها و function expression استفاده کنیم. برای استفاده از این روش ها نیاز به مقداردهی اولیه شیء داریم. مثلا یک آرایه را به array literal تعریف میکنیم و آیتم اول را شیء  میگذاریم:var people = [{   // the &#x27;john&#x27; object   firstname: &#x27;John&#x27;,   lastname: &#x27;Doe&#x27;,   addresses: [&#x27;111 Main St&#x27;, &#x27;222 Main St&#x27;]},{   // the &#x27;jane&#x27; object   firstname: &#x27;Jane&#x27;,   lastname: &#x27;Doe&#x27;,   addresses: [&#x27;333 Main St&#x27;, &#x27;444 Fifth St&#x27;],   greet: function() { return &#x27;hello&#x27;; }}];همان طور که مشاهده میشود کد آرایه خیلی بزرگ شده ولی این روش خیلی تمیزی برای مقداردهی اولیه داده ها است. همچنین این روش برای prototype هم خیلی مناسب است. مثلا موقعی که در حال ایجاد برنامه ای هستیم که هنوز به سرور یا api وصل نشده، میتوانیم به شکل کد بالا داده ها را مقداردهی اولیه کنیم تا در interface به کار روند و ببینم کد چطور شده و وقتی داده اصلی آماده شد، از طریق json و api داده های اصلی را به آن بدهیم.در چنین کدهایی که initialization زیادی داریم معمولا کاما فراموش میشود یا به جای : اشتباها از = استفاده میشود و خطا میدهد: unexpected. مثلا unexpected token. اگر همین آرایه people بالا را در کنسول ببینیم خروجی میشود:[Object, Object]مثلا اگر در کنسول بگوییم people[1].greet() خروجی hello را برمیگرداند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sun, 28 Apr 2019 10:41:23 +0430</pubDate>
            </item>
                    <item>
                <title>63 - جاوااسکریپت: Object.create and Pure Prototypal Inheritance</title>
                <link>https://virgool.io/@pazirehsarafraz/63-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-objectcreate-and-pure-prototypal-inheritance-re2jseutneif</link>
                <description>با استفاده از function constructor شیء ایجاد کردیم. اما همان طور که گفته شد function constructor برای تقلید از سایر زبانها که prototype inheritance را پیاده سازی نمیکنند طراحی شده. سایر زبانها از کلاس استفاده میکنند. کلاس تعیین میکند که شیء باید چه شکلی باشد، سپس با کلمه کلیدی new شیء ایجاد میشود. این چیزی است که function constructor سعی میکند تقلید کند. اما بسیاری معتقدند که بهتر است فقط روی آنچه js روی prototype inheritance انجام میدهد تمرکز کرد و کاری با classical inheritance نداشت. پس میخواهیم از روشی برای ایجاد شیء استفاده کنیم که از زبان های دیگر تقلید نمیشود. همه بروزرهای مدرن آن را دارند: Object.creat.var person = {firstname: &#x27;Default&#x27;,lastname: &#x27;Default&#x27;,greet: function() { return &#x27;Hi &#x27;+this.firstname; }};اگر داخل تابع greet از this استفاده نکنیم، داخل خود تابع greet دنبال firstname میگردد و چون آن را پیدا نمیکند داخل global میگردد و پیدایش نمیکند. چون firstname داخل person نوشته شده. شیء person یک execution context جدید درست نمیکند. شیء person را ایجاد کردیم. حالا میخواهیم شیء دیگری به روش دیگر ایجاد کنیم و prototype آن را تعیین کنیم:var john = Object.create(person);console.log(john);شیء Object شیء پایه در js است. شیئی را که میخواهیم از آن شیء جدید ایجاد کنیم به create پاس دادیم. تابع create در موتور js م built-in است. خروجی کد بالا:Object { firstname:&#x27;Default&#x27;, lastname:&#x27;Default&#x27;, greet:function }این شیء کاملا خالی است و prototype آن شیء person است که firstname و متد greet و lastname را دارد. برای اینکه روی مقادیر Default که در prototype است overwrite کنیم:john.firstname = &#x27;John&#x27;;john.lastname = &#x27;Doe&#x27;;با همون اسم ویژگی ها، به شیء جدید john ویژگی اضافه میکنیم تا وقتی موتور js میخواهد در prototype chain حرکت کند، مقدار ویژگی ها را داخل خود john ببیند و پایین نرود. در این حالت خروجی میشود:Object { firstname:&#x27;John&#x27;, lastname:&#x27;Doe&#x27;, greet:function }و همچنان prototype مان person (با مقادیر Default) است. یعنی میتوانیم john.greet() را بنویسیم تا خروجی Hi John را بدهد. این روش ساخت شیء pure prototypal inheritance است و هیچ مفهوم دیگری در ساخت شیء استفاده نشده است. اول یک شیء میسازیم، سپس از آن یک شیء جدید create میکنیم به طوری که به شیء اول به عنوان prototype ش اشاره دارد. اگر میخواهیم یک شیء جدید را تعریف کنیم آن را create میکنیم. میتوانیم روی متدها و ویژگی ها overwrite کنیم. این روش ساخت شیء بسیار ساده است.این روش جدید است و در بروزرهای جدید ساپورت میشود. اما اگر نیاز باشد برای بروزرهای قدیمی که موتور js این را ساپورت نمیکند کار کنیم چه؟ میتوانیم از polyfill استفاده کنیم.تعریف polyfill: کدی است که ویژگی را که احتمالا موتور ندارد اضافه میکند. معمولا از موتورهای مختلفی استفاده میکنیم، چون بروزرهای مختلف موتورهای مختلف دارند. میتوانیم کدهایی داشته باشیم که چک کنند آیا موتور یک ویژگی را دارد یا نه. اگر ندارد کدی مینویسیم که همان کار را در بروزرهای جدید انجام میدهد. یعنی گپ بین موتورهای قدیمی و جدید را پر میکنیم.برای مثال در کد بالا که از create استفاده کرده ایم، در بروزرهای قدیمی ساپورت نمیشود. کد polyfill ای به اول کد اضافه میکنیم تا این مشکل را برطرف کند:// polyfillif (!Object.create) {Object.create = function(o) {if (arguments.length&gt;1) { throw new Error(&#x27;Object.create implementation&#x27; + &#x27; only accepts the first parameter&#x27;); }function F() { };F.prototype = o;return new F();};}در این کد ابتدا چک میکنیم که آیا Object.create وجود دارد یا نه. اگر وجود نداشته باشد undefined را برمیگرداند و اگر وجود داشته باشد کل if را skip میکند. اگر وجود نداشته باشد طبق اولین خط کد این متد را به global object اضافه میکند چون شیء پایه Object در global object است. در کد polyfill ابتدا یک تابع خالی ایجاد میشود و سپس prototype (ویژگی که در function constructor داشتیم) آن تنظیم میشود. پس در این کد new یک شیء ایجاد میکند و تابع F() را که خالی است فراخوانی میکند و prototype این شیء خالی را برابر با آنچه پاس داده ایم قرار میدهد. این دقیقا همان چیزی است که Object.create انجام میدهد: یک شیء به آن میدهیم و این شیء prototype شیء جدید خالی میشود.موقع استفاده از Object.create یک شیء ایجاد کردیم که اساس شیء های دیگر را تشکیل میدهد (person). با Object.create یک شیء دیگر از آن میسازیم و میتوانیم ویژگی هایش را overwrite یا hide کنیم. این کار pure prototypal inheritance است. پس میتوانیم prototype را on the fly تغییر دهیم. میتوانیم در هر قسمت از برنامه، بسته به آنچه نیاز داریم ویژگی هایی اضافه کنیم.64 - جاوااسکریپت: ES6 and Classesنسخه بعدی جاوا اسکریپت یعنی es 2015 یا ES6 یک مفوم جدید ارائه داده است. این مفهوم روش دیگری برای ایجاد شیء و تنظیم کردن prototype است. کلاس ها در زبان های برنامه نویسی دیگر خیلی رایج هستند. آنها روش تعریف شیء هستند. یعنی متدها و ویژگی هایش چطور باید باشند. در js کلاس نداریم. با این حال در ES6 به نحو متفاوتی کلاس داریم. کلاس js یک شیء را نشان میدهد. داخل آن یک constructor داریم که شبیه به constructor function ها عمل میکند. میتوانیم مقادیرش را از قبل تنظیم کنیم. بنابراین وقتی با new یک شیء از این کلاس ایجاد میکنیم، میتوانیم firstname و lastname را به آن پاس دهیم و کلمه this به شیء جدید ایجاد شده اشاره میکنید.class Person {constructor(firstname, lastname){   this.firstname = firstname;   this.lastname = lastname;}greet(){   return &#x27;hi &#x27; + firstname;}}var john = new Person(&#x27;John&#x27;, &#x27;Doe&#x27;);اما مشکلی وجود دارد. برنامه نویس هایی که از زبان های دیگر وارد js شده اند وقتی class را در js میبینند فکر میکنند مانند کلاسی است که در زبان های دیگر استفاده میکردند. اما در زبان های دیگر کلاس شیء نیست، فقط یک تعریف است. مثل template است و میگوید که شیء ها باید چه شکلی باشند. ولی تا زمانی که از new استفاده نکرده باشیم، شیء ندارم. اما در js با اینکه از کلمه کلیدی class استفاده میکند، باز هم یک شیء است. یعنی در مثال بالا class Person یک شیء است. به همین دلیل ممکن است برنامه نویس هایی که از زبان های دیگر آمده اند مثل همان زبان ها شروع به طراحی ساختار شیء کنند. همچنین ممکن است در استفاده از کلمه new هم مشکل پیش بیاید، گرچه چون از کلمه class استفاده شده احتمال اشتباه نسبت به function constructor کمتر است. توصیه میشود که به دنبال تقلید سایر زبان های برنامه نویسی نباشیم و از prototypal inheritance استفاده کنیم.موقع استفاده از class برای تعیین prototype چه کنیم؟ مثلا میخواهیم یک InformalPerson درست کنیم که Person برای آن prototype باشد. برای این کار از کلمه کلیدی extends استفاده میکینم. در واقع همان ویژگی __proto__ در کروم است:class InformalPerson extends Person {constructor(firstname, lastname) { super(firstname, lastname); }greet() { return &#x27;Yo &#x27;+firstname; }}در constructor میتوانیم از کلمه کلیدی super استفاده کنیم تا constructor شیء prototype را فراخوانی کند. پس میتوانیم مقادیر اولیه را تا پایین زنجیره پاس دهیم. همچنین مثل مثال بالا میتوانیم متد greet را overwrite کنیم. این روشی است که دارد برای ساخت شیء و تعیین prototype به js وارد میشود. فقط یک سینتکس جدید است، در پشت صحنه همه مثل هم عمل میکنند.تعریف syntactic sugar: یک روش تایپ متفاوت که آنچه پشت صحنه انجام میشود را تغییر نمیدهد.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sun, 28 Apr 2019 09:23:40 +0430</pubDate>
            </item>
                    <item>
                <title>60 - جاوااسکریپت: Built-In Function Constructors</title>
                <link>https://virgool.io/@pazirehsarafraz/60-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-built-in-function-constructors-x8etfg7ydb58</link>
                <description>در معماری جاوااسکریپت built-in function constructor وجود دارد. یعنی تابع ها و prototype هایی وجود دارند. اگر در گوگل کروم قسمت کنسول بنویسیم:var a = new Number(3);یا حتی var a = new Number(&quot;3&quot;); تا &quot;3&quot; را به عدد تبدیل کند. پس Number ای که استفاده کردیم یک function constructor است. میبینیم که خود js هم حرف اول آن را بزرگ انتخاب کرده. اگر بعد از خط بالا در کنسول مقدار a را ببینیم:Number { [[PrimitiveValue]]: 3 }توجه داشته باشید که a یک عدد نیست، primitive نیست. بلکه یک شیء است. چون function constructor شیء ایجاد میکند. یک مقدار primitive را داخل آن قرار داده. اگر در کنسول بنویسیم Number.prototype. به ما متدهایی را پیشنهاد میدهد، مثل toPrecision یا toFixed. پس مثلا میتوانیم بنویسیم a.toFixed(2) که خروجی 3.00 را برمیگرداند.اگر در کنسول بنویسیم:var a = new String(&quot;John&quot;);تابع String هم یک function constructor است. a هم به متدهای زیادی دسترسی دارد. این متدها داخل خود a نیستند اما در String.prototype هستند. مثلا اگر بنویسیم String.prototype.indexOf(&quot;o&quot;); مقدار -1 را برمیگرداند. وقتی مینویسیم a.indexOf(&quot;o&quot;); خروجی 1 را برمیگرداند. یعنی a یک String و یک primitive نیست، یک شیء است. اگر a را در کنسول بزنیم خروجی میشود:String { 0:&#x27;J&#x27;, 1:&#x27;o&#x27;, 2:&#x27;h&#x27;, 3:&#x27;n&#x27;, length:4, isLengthGreaterThan:function, [[PrimitiveValue]]:&#x27;John&#x27; }پس با استفاده از String و Number یک شیء ایجاد کردیم، نه یک primitive. در برخی مواقع js متوجه میشود که ما میخواهیم به چیزی به عنوان یک شیء نگاه کنیم، نه primitive. بنابراین میتوانیم مثلا بنویسیم &quot;John&quot;.length که خروجی 4 را میدهد. یعنی &quot;John&quot; که primitive بوده، توسط js در شیء String بسته شده تا به length دسترسی داشته باشیم. همین اتفاق برای کد زیر وقتی از .length استفاده میکند هم می افتد:new String(&quot;John&quot;);در چنین مواردی که موتور js یک primitive را به صورت یک شیء wrap میکند، میتوانیم از ویژگی و متدهای مورد نیاز استفاده کنیم. اما هر موقع که کلمه new را در کد ببینیم:var a = new Date(&quot;3/1/2015&#x27;);خروجی کنسول برای a خواهد بود:Sun Mar 01 2015 00:00:00 GMT-0500 (Eastern Standard Time)پس a یک شیء است. پس اگر بعد از a نقطه بگذاریم ویژگی های زیادی را که js تامین کرده در اختیار داریم. اما این ویژگی و متدها واقعا کجا قرار دارند؟ آنها در Date.prototype قرار دارند. پس وقتی از این function constructor ها استفاده میکنیم داریم یک شیء ایجاد میکنیم. این مسئله میتواند خیلی پرکاربرد باشد، بخصوص وقتی میخواهیم ویژگی ها یا متدهای دیگری هم به کتابخانه ها یا framework ها یا خود primitive ها اضافه کنیم. مثلا میخواهیم در js یک ویژگی به همه string ها اضافه کنیم. متدها و ویژگی هایی که الان برای رشته ها قابل دسترس هستند، در prototype آن قرار دارند. همان طور که گفته شد عبارت String.prototype نشان دهنده جایی است که همه شیء های رشته به عنوان prototype شان به آن اشاره میکنند.String.prototype.isLenghtGreaterThan = function(limit) {return this.length &gt; limit;}console.log(“john”.isLengthGreaterThan(3));در کد بالا اگر یک رشته باشیم، this به آن شیء رشته اشاره میکند. خروجی true میشود. در این کد “john” که یک رشته primitive است به صورت اتوماتیک به شیء string که با تابع String.prototype ایجاد میشود تبدیل شد. ما متد isLengthGreaterThan را به prototype اضافه کردیم. بنابراین همه رشته ها به این متد دسترسی دارن. این قدرت prototype و وراثت است. بسیاری از کتابخانه ها و framework ها برای اضافه کردن ویژگی ها و utility ها از این تکنیک استفاده میکنند. اما باید مراقب باشیم که روی یک ویژگی یا متد موجود overwrite نکنیم. پس میتوانیم با فهم function constructor ها و ویژگی prototype آن به طور موثری روی زبان تاثیر بگذاریم. کد بالا به علت اینکه “john” به طور خودکار به شیء تبدیل شد کار کرد. آیا میتوانیم همین کار را با اعداد هم انجام دهیم؟کلمه Number یک built-in function constructor است. یعنی فقط یک تابع است و همراه با new استفاده میشود. اگر روی ویژگی prototype آن تاثیر بگذاریم، روی همه اشیائی که با Number constructor ایجاد شده اند تاثیر میگذاریم:Number.prototype.isPositive = function() { return this&gt;0; }اگر در خروجی کد بالا در کنسول بزنیم:3.isPositive()خطا میدهد: unexpected token ILLEGAL. چون js نمیتواند به صورت خودکار عدد را به شیء تبدیل کند. اما اگر در کنسول بنویسیم:var a =  new Number(3);a.isPositive()خروجی true برمیگرداند. بنابراین میتوانیم به آسانی به built-in function constructor ها توانایی هایی را اضافه کنیم. بخصوص به آنها که آرایه یا رشته هستند. اما اگر بخواهیم با مقادیر primitive در کنار مقادیری که با این function constructor ها ایجاد شده کار کنیم کمی مشکل داریم. مثلا در کد بالا Number(3) شبیه به یک عدد است، اما عدد نیست. یک شیء است. پس در حالت کلی برای انواع primitive از built-in function constructor ها استفاده نمیکنیم، مگر اینکه مجبور شویم.61 – جاوااسکریپت: خطرات استفاده از Built-In Function Constructorsفرض کنید در کنسول مینویسیم:var a = 3;var b = new Number(3);a == bخروجی کد بالاtrue  است چون عملگر == نوع ها را coerce میکند. تلاش میکند که نوع دو پارامترش را یکسان کند. اما اگر از a===b استفاده کنیم، خروجی false میشود. چون a یک primitive است و b یک شیء است. بنابراین موقع استفاده از built-in function constructor ها برای ایجاد primitive ها، واقعا یک primitive درست نمیکنیم و ممکن است موقع مقایسه مشکلاتی پیش آید. پس در حالت کلی بهتر است از built-in function constructor ها استفاده نکنیم، میتوانیم از literal ها یا مقدار واقعی primitive (مثلا 3 خالی) استفاده کنیم.یک کتابخانه خیلی خوب به اسم moment.js داریم. میتوانیم به سایت momentjs.com برویم. در این کتابخانه تابع های زیادی برای کار کردن و فرمت بندی و محاسبه تاریخ وجود دارد. اگر در برنامه از تاریخ زیاد استفاده میکنیم، توصیه میشود به جای کار کردن با built-in js Date constructor از این کتابخانه استفاده کنید. تابع های این کتابخانه برخی از مشکلات استفاده از built-in function constructor را حل کرده است.میتوانیم از built-in function constructor ها برای coercion استفاده کنیم:var c = Number(&quot;3&quot;);در این مثال از Number به عنوان یک تابع معمولی استفاده کرده ایم چون از new استفاده ای نشده. اگر قبل از آن new میگذاشتیم، یک شیء به ما برگردانده میشد.62 - جاوااسکریپت: Arrays and for inدر بخش reflection و extend روی همه ویژگی ها و همه متدهای یک شیء حلقه زدیم. همان طور که میدانیم آرایه ها شیء هستند و میتوانیم همین کار را برای آرایه ها هم انجام دهیم.var arr = [&#x27;John&#x27;, &#x27;Jane&#x27;, &#x27;Jim&#x27;];for (var prop in arr) {console.log(prop + &#x27;:  &#x27; + arr[prop]);}خروجی میشود:0: John1: Jane2: Jimآرایه ها در js نسبت به سایر زبانها کمی متفاوت هستند. 0 و 1 و 2 در واقع اسم ویژگی هستند، به همین دلیل میتوانیم با [ ] آن ویژگی را بگیریم. در حقیقت آرایه ها شیء هستند و هر آیتم یک name/value است. هر آیتم یک ویژگی جدید است. در واقع داریم به آرایه ویژگی اضافه میکنیم. بنابراین اگر جای دیگری ویژگی به آرایه ها اضافه کرده باشیم مشکل پیش می آید. مثلا ابتدای کد بالا بنویسیم:Array.prototype.myCustomFeature = &#x27;cool&#x27;;این خط کد ویژگی myCustomFeature را به Array.prototype اضافه میکند. اگر خط بالا را اول کد اضافه کرده و خروجی بگیریم:0: John1: Jane2: JimmyCustomFeature: coolیعنی وقتی از for in استفاده میکنیم، یک ویژگی دیگر هم در آرایه داریم. بنابراین در مورد آرایه ها از for in استفاده نمیکنیم و از حلقه for استاندارد استفاده میکنیم:for (var i=0; i&lt;arr.length; i++) { ... }</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sat, 27 Apr 2019 21:34:15 +0430</pubDate>
            </item>
                    <item>
                <title>57 - جاوااسکریپت: Function Constructors</title>
                <link>https://virgool.io/@pazirehsarafraz/57-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-function-constructors-snofags0ckdg</link>
                <description>میخواهیم به طور عمیقتر در مورد ایجاد شیء صحبت کنیم. قبلا روش object literal syntax را برای ایجاد شیء دیدیم. اما روش های دیگری هم هستند، بخصوص وقتی میخواهیم برای شیء prototype هم تعیین کنیم. از روش های ساخت شیء function constructor و new است. مثل الان که بین گوگل و اپل رقابت تکنولوژی هست، در گذشته هم بین تکنولوژی ها و زبان های برنامه نویسی مثل netscape و مایکروسافت و oracleSon رقابت وجود داشت. زبان js برای استفاده در بروزر نوشته شده بود. ابتدا به این منظور ساخته نشد ولی به تدریج با همین منظور استفاده میشد. اسم آن را جاوااسکریپت گذاشتند تا برنامه نویس های جاوا را جذب کنند، چون برنامه نویس های جاوا خیلی زیاد بودند و اگر برنامه نویس ها از زبانی استفاده نکنند، آن زبان از بین میرود. بنابراین شرکت اسم زبان را جاوااسکریپت گذاشت تا برنامه نویس های جاوا را جذب کند. مثل زمانی که مایکروسافت زبان بروزر را با اسم VBScript منتشر کرد. آن موقع VB خیلی محبوب بود. اسم جاوااسکریپت مثل جاوا هست و کمی شبیه آن است ولی در واقع هیچ شباهتی با آن ندارد. یکی از موارد بازاریابی که در جاوااسکریپت آورده شده خط کد زیر است:var john = new Person();برنامه نویسان جاوا به شکل بالا شیء ایجاد میکردند و از کلمه کلیدی new و چیزی به اسم کلاس استفاده میکردند. در جاوا کلاس یک شیء نیست، یک  شیء را تعریف میکند. از کلمه new برای ایجاد شیء از آن کلاس استفاده میشود. در جاوااسکریپت کلاس نداریم. در نسخه بعدی جاوااسکریپت کلمه کلیدی class دارد به آن اضافه میشود، اما باز هم کلاس در جاوااسکریپت مثل کلاس در جاوا یا c# وجود ندارد. در جاوااسکریپت هم مثل جاوا با کلمه new میتوانیم شیء درست کنیم. اما در جاوااسکریپت لزومی به استفاده از new برای ایجاد شیء نداریم. وقتی برنامه نویسان جاوا به جاوااسکریپت نگاه میکنند میگویند جاوااسکریپت شبیه جاوا است پس از آن استفاده میکنیم. ولی در واقع این طور نیست. روشی که برای ایجاد شیء در جاوااسکریپت وجود دارد روش بدی نیست ولی مشکلاتی دارد. البته روش های جدیدی برای ایجاد شیء به جاوااسکریپت اضافه میشوند.function Person() {this.firstname = &#x27;John&#x27;;this.lastname = &#x27;Doe&#x27;;}var john = new Person();console.log(john);پس ما فقط با نوشتن Person() آن را فراخوانی نکرده ایم. قبل از آن new گذاشته ایم. خروجی میشود:Person { firsname:&#x27;John&#x27;, lastname:&#x27;Doe&#x27; }آنچه میخواهیم در این بخش درباره اش صحبت کنیم، روش های مختلف ایجاد کردن شیء است. نمیخواهیم شیءها یا نحوه عملکردشان را تغییر دهیم. فقط میخواهیم از ویژگی های زبان js برای ساخت اشیاء استفاده کنیم. برای ساخت شیء آن را ایجاد میکنیم و به آن ویژگی و متد میدهیم و prototype ش را تنظیم میکنیم. در بخش قبل prototype را با روش نادرستی تغییر دادیم، فقط برای اینکه عملکرد آن نشان داده شود.کلمه کلیدی new برای شبیه کردن js به زبان برنامه نویسی رایج بود. این کلمه کلیدی در واقع یک عملگر است. وقتی کلمه new در کد آورده میشود، فورا یک شیء خالی ایجاد میشود. چیزی مثل کد زیر:var a = { };سپس تابع Person() فراخوانی میشود. با فراخوانی تابع execution context با متغیر this ایجاد میشود. زمانی که از کلمه کلیدی new استفاده میکنیم، آنچه this به آن اشاره میکند را تغییر میدهیم. متغیر this به آن شیء خالی اشاره میکند. پس وقتی داخل کد Person() م firstname و lastname را تعریف کرده ایم، یعنی این دو ویژگی را به شیء خالی اضافه کرده ایم. تا زمانی که تابع Person() مقداری را return نکند موتور js شیئی را که با عملگر new ایجاد شده برمیگرداند. پس یک شیء جدید ایجاد میشود، سپس تابع فراخوانی میشود و this به شیء خالی اشاره میکند و  کارهایی که با متغیر this انجام میشوند مربوط به شیء خالی هستند و این شیء جدید برگردانده میشود. مثلا اگر در انتهای کد Person() خط کد زیر را اضافه کنیم:console.log(&#x27;This function is invoked&#x27;);خروجی میشود:This function is invokedPerson { firstname:&#x27;John&#x27;, lastname:&#x27;Doe&#x27; }این نشان میدهد که تابع Person() فراخوانی شده است. اگر به ابتدای کد تابع Person() اضافه کنیم:console.log(this);خروجی Person { }  یعنی یک شیء خالی خواهد بود. اما اگر کد تابع Person() را به صورت زیر تغییر دهیم:function Person() {this.firstname = &#x27;John&#x27;;this.lastname = &#x27;Doe&#x27;;return { greeting: &#x27;i got in the way&#x27; };}var john = new Person();console.log(john);خروجی به صورت زیر میشود:Object { greeting:&#x27;i got in the way&#x27; }اما اگر داخل کد تابع return نداشته باشیم، موتور js  میگوید که شما با عملگر new تابع را فراخوانی کرده اید، پس چیزی که برگردانده میشود یک شیء است که this به آن اشاره میکند، قبل از اینکه تابع شروع به اجرا کند و execution context ایجاد شود. پس توانستیم یک شیء را با استفاده از یک تابع بسازیم. به چنین تابعی که برای ساخت شیء از آن استفاده میکنیم function constructor میگوییم.اگر بخواهیم شیء های بیشتری با ویژگی ها و متدهای یکسان ایجاد کنیم چه اتفاقی می افتد؟ مثلا به انتهای کد فوق اضافه کنیم:var jane = new Person();console.log(jane);در خروجی میبینیم که مقدار john و jane هر دو به صورت زیر است:Person { firstname:&#x27;John&#x27;, lastname:&#x27;Doe&#x27; }دو تا شیء مجزا ایجاد میشوند ولی مقدار firstname و lastname ثابت مانده. وقتی قبل از یک تابع عملگر new را میگذاریم کلمه کلیدی this را به یک شیء جدید اشاره میدهد و اگر در تابع چیزی return نشود، به جای برگرداندن undefined، آن شیء خالی برگردانده میشود. پس اگر بخواهیم که firstname و lastname هر آنچه میخواهیم باشد، از پارامتر استفاده میکنیم:function Person(firstname, lastname) {this.firsname = firstname;this.lastname = lastname;}var john = new Person(&#x27;John&#x27;, &#x27;Doe&#x27;);console.log(john);var jane = new Person(&#x27;Jane&#x27;, &#x27;Doe&#x27;);console.log(jane);پس معمولا مثلا کد بالا در function constructor ها از پاس دادن مقادیر پیش فرض استفاده میشود. خروجی کد بالا:Person { firsname:&#x27;John&#x27;, lastname:&#x27;Doe&#x27; }Person { firsname:&#x27;Jane&#x27;, lastname:&#x27;Doe&#x27; }تعریف function constructor: یک تابع معمولی که برای ساخت شیءها استفاده میشود. وقتی کلمه new را قبل از فراخوانی تابع قرار میدهیم، در آن تابع this به شیء جدید اشاره میکند و آن شیء به طور خودکار از تابع برگردانده میشود.پس توانستیم متدها و ویژگی ها را با function constructor ایجاد کنیم. اما در مورد prototype چه؟ 58 - جاوااسکریپت: Function Constructors and .prototypeوقتی از function constructor استفاده میکنیم، خودش prototype را برای ما تنظیم میکند. مثلا در همان کد بخش قبل اگر در گوگل کروم در کنسول بنویسیم:john.__proto__خروجی Person { } خواهد بود، یک شیء خاص Person که خالی است. همان طور که قبلا گفته شد هر زمان که یک شیء تابع ایجاد میکنیم، یک سری ویژگی خاص (مثل NAME و CODE) خواهد داشت. یک ویژگی دیگر هم هست که همه تابع ها دارند و موقع function constructor باید از آن استفاده کنیم. همه تابع ها ویژگی prototype را دارند که شیء Empty است. اگر از تابع به عنوان یک function constructor استفاده کنیم، هیچ وقت از این ویژگی استفاده نمیشود. اما اگر از عملگر new موقع فراخوانی تابع استفاده کنیم،  از این ویژگی استفاده میشود. بنابراین از ویژگی prototype فقط زمانی که از تابع به عنوان یک function constructor استفاده میکنیم استفاده میشود. وقتی از .prototype استفاده میکنیم، به نظر میرسد که داریم prototype شیء را تنظیم میکنیم، اما همان طور که قبلا گفته شد با .__proto__ میتوانیم این کار را انجام دهیم. ویژگی prototype در تابع prototype آن تابع نیست، بلکه prototype هر شیئی است که با این تابع ساخته میشود. همان طور که گفته شد همه تابع ها این ویژگی را دارند:function Person(firstname, lastname) {this.firsname = firstname;this.lastname = lastname;}Person.prototype.getFullName = function() { return this.firstname+&#x27;  &#x27;+this.lastname; };var john = new Person(&#x27;John&#x27;, &#x27;Doe&#x27;);console.log(john);var jane = new Person(&#x27;Jane&#x27;, &#x27;Doe&#x27;);console.log(jane);قبلا گفته شده بود که اگر شیئی ویژگی یا متدی را نداشته باشد در prototype chain پیش میرود. وقتی از کلمه کلیدی new استفاده میکنیم، یک شیء خالی ایجاد میشود و prototype آن شیء خالی برابر با Person.prototype قرار داده میشود. بنابراین در مثال بالا john و jane هر دو به متد getFullName که در prototype شان است دسترسی دارند. خروجی کد بالا میشود:Person { firstname:&#x27;John&#x27;, lastame:&#x27;Doe&#x27;, getFullName:function }Person { firstname:&#x27;Jane&#x27;, lastame:&#x27;Doe&#x27;, getFullName:function }همچنین میتوانیم بعدا چیزی را on the fly به prototype اضافه کنیم. مثلا در آخر کد بالا بنویسیم:Person.prototype.getFormalFullName = function() { return this.lastname+&#x27;,  &#x27;+this.firstname; };بعد از این کد میتوانیم از کد john.getFormalFullName() استفاده کنیم. بنابراین میتوانیم با استفاده از ویژگی prototye برای همه شیءهایی که با function constructor ساخته ایم، بعدا هم ویژگی هایی اضافه کنیم. یعنی اگر هزار شیء با استفاده از new از تابع Person ساخت باشیم، میتوانیم یک باره به همه آنها ویژگی یا متدی را اضافه کنیم. حتی بعد از اینکه این شیءها ساخته شده باشند. معمولا این طور است که ویژگی ها داخل function constructor ایجاد میشوند، چون معمولا مقادیر مختلفی دارند اما متدها در ویژگی prototype ایجاد میشوند. چرا متد getFullName را داخل تابع Person تعریف نکردیم؟ میتوانیم چنین کاری را انجام دهیم اما مشکلی ایجاد میشود: تابع ها در js شیء هستند. آنها حافظه ای را اشغال میکنند. هر چیزی که به آنها اضافه میکنیم فضایی میگیرد. بنابراین اگر مثلا متد getFullName را داخل آن بگذاریم، یعنی هر شیئی که با آن ساخته میشود یک کپی از getFullName برای خودش خواهد داشت. اما اگر این متد را به prototype اضافه کنیم، حتی اگر هزار شیء از تابع ساخته شوند فقط یک بار این تابع را خواهیم داشت. بنابراین برای کارآمدی بیشتر بهتر است که متدها را داخل prototype قرار دهیم. برای ویژگی ها این کار را نمیکنیم چون هر شیئی که ساخته میشود مقدار خودش را دارد.روشی که در این بخش گفته شد یکی از روش های معتبر برای ایجاد شیء و تنظیم prototype آنها بود.59 - جاوااسکریپت: new and functionsهمان طور که گفته شد مثلا در کد new Person() تابع Person() فراخوانی میشود. کلمه new باعث برخی تغییرات میشود ولی در نهایت تابع Person() همچنان یک تابع است. مشکل وقتی ایجاد میشود که فراموش کنیم از کلمه کلیدی new قبل از آن استفاده کنیم:var john = Person(&#x27;John&#x27;, &#x27;Doe&#x27;);در این کد تابع Person() اجرا میشود. موتور js نمیداند که من میخواهم تابع را اجرا کنم یا با new آن را فراخوانی کنم. چون داخل کد تابع Person() مقداری return نمیشود، خودش مقدار undefined را برمیگرداند. بنابراین شیء john برابر با undefined خواهد شد. پس موقع استفاده از این روش باید حواسمان به استفاده صحیح از کلمه new باشد.اسم هر تابعی را که میخواهیم یک function constructor باشد، با حرف بزرگ شروع میکنیم. اگر موقع اجرای برنامه با خطاهایی مواجه شدیم، میتوانیم کدمان را چک کنیم تا اگر جایی تابعی با حرف بزرگ به اشتباه بدون new فرخوانی شده، آن را اصلاح کنیم. این فقط یک قرارداد است. برخی برنامه ها هستند که میتوانند در این مورد به ما کمک کنند، به آنها linter گفته میشود. پیشنهاد میشود که اگر میخواهیم از function constructor استفاده کنیم، حتما حرف اول را بزرگ بنویسیم. برای ایجاد شیءها به غیر از روشی که گفته شد، روش های دیگری هم دارند به js اضافه میشوند و این روش کم کم (نه به طور کامل) کنار میرود.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Fri, 26 Apr 2019 22:01:56 +0430</pubDate>
            </item>
                    <item>
                <title>55 - جاوااسکریپت: همه چیز Object یا primitive است.</title>
                <link>https://virgool.io/@pazirehsarafraz/55-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%87%D9%85%D9%87-%DA%86%DB%8C%D8%B2-object-%DB%8C%D8%A7-primitive-%D8%A7%D8%B3%D8%AA-panlu61hfb3g</link>
                <description>در js هر چیزی که primitive نباشد یعنی تابع ها، آرایه ها، شیءها، همه یک prototype دارند، به غیر از یک چیز: شیء پایه در js. var a = { };var b = function() { };var c = [ ];اگر در گوگل کروم این کد را اجرا کنیم و در کنسول بنویسیم:a.__proto__خروجی Object{} را به ما برمیگرداند. این شیء پایه در js است. همیشه پایین ترین سطح زنجیره prototype است. پس اگر در کنسول بزنیم a.__proto__. یک سری متد به ما پیشنهاد میدهد، مثل toString. یعنی همه شیء ها به متد toString دسترسی دارند. اگر در کنسول بنویسیم:b.__proto__به ما خروجی function Empty(){} را برمیگرداند. این تابع prototype همه تابع ها است. اگر در همان کنسول بزنیم b.__proto__. متدهایی را پیشنهاد میدهد، مثل apply و bind و call. پس به همین دلیل است که همه تابع ها به این متدها دسترسی دارند. اگر در کنسول بنویسیم:c.__proto__به ما خروجی [ ] را میدهد. اگر در کنسول بزنیم c.__proto__. متدهای کاربردی پیشنهاد میدهد مثل indexOf و length و push. پس همه آرایه ها در js به چنین متدهایی دسترسی دارند. چون js خودش prototype را برای ما تنظیم میکند. اگر در کنسول بنویسیم:b.__proto__.__proto__c.__proto__.__proto__برای هر دو خروجی Object{} را برمیگرداند. این شیء یک شیء built-in و هسته ای است و دیگر خودش prototype ندارد. پس به این روش است که میتوانیم به ویژگی ها یا متدهای شیءهای دیگر دسترسی داشته باشیم.56 - جاوااسکریپت: Reflection and Extendدر کتابخانه ها و framework ها از ویژگی extend خیلی استفاده میشود. extend کردن به دلیل reflection امکان پذیر است.تعریف reflection: یک شیء میتواند به خودش نگاه کند، ویژگی ها و متدهایش را لیست کند و آنها را تغییر دهد. پس شیء در js این توانایی را دارد که به ویژگی و متدهای خودش نگاه کند و میتواند از این ویژگی برای extend استفاده کند.میخواهیم مثالی از reflection بزنیم و در آن از for in استفاده میکنیم. عبارت for in مثل foreach است. حلقه for in روی همه عضوهای شیء میچرخد. مثل این است که روی همه آیتم های یک آرایه حرکت کنیم. مقدار prop در هر تکرار برابر با همان عضو شیء خواهد بود. همان طور که گفته شد برای دسترسی به یک مقدار یک عضو میتوانیم به جای استفاده از . از [ ] استفاده کنیم تا به جای اسم عضو به آن متغیر بدهیم:var person = {firstname: &#x27;Default&#x27;,lastname: &#x27;Default&#x27;,getFullName: function() { return this.firstname+&#x27;  &#x27;+this.lastname; }};var john = {firstname: &#x27;John&#x27;,lastname: &#x27;Doe&#x27;};//dont do this EVER!john.__proto__ = person;for (var prop in john){console.log(prop + &#x27;: &#x27; + john[prop]);}پس این حلقه روی همه ویژگی ها و متدهای john میچرخد. خروجی میشود:firstname: Johnlastname: DoegetFullName: function() { return this.firsname+&#x27;  &#x27;+this.lastname; }همان طور که میدانیم getFullName در prototype قرار دارد. یعنی حلقه for in به همه ویژگی ها و متدها، نه فقط داخل خود شیء بلکه داخل prototype ش هم دسترسی دارد. اما اگر بخواهیم فقط موارد داخل خود شیء را بررسی کنیم چه کنیم؟for (var prop in john){if (john.hasOwnProperty(&#x27;prop&#x27;)) {   console.log(prop + &#x27;: &#x27; + john[prop]);   }}متد hasOwnProperty در شیء پایه Object() وجود دارد، در john یا person نیست ولی میتوانیم در john به آن دسترسی داشته باشیم. یک رشته میگیرد و میگوید که آیا شیء واقعا ویژگی به اسم این رشته دارد یا نه. اگر این اسم داخل خود شیء نباشد false برمیگرداند. پس با این تغییر خروجی کد میشود:firstname: Johnlastname: Doeپس توانستیم reflect کنیم در شیء john. یعنی به ویژگی هایش نگاه کنیم. توانستیم به metadata ویژگی های آن نگاه کنیم. میتوانیم آنها را لیست کنیم تا تغییر دهیم. با استفاده از این مفهوم ایده ای پیاده سازی شده که خیلی پرکاربرد است. در واقع ترکیبی است از inheritance و prototype. ولی در js م built-in نیست. بنابراین بسیاری از framework ها و کتابخانه ها خودشان آن را ساخته اند چون خیلی مفید است. میخواهیم از کتابخانه underscore استفاده کنیم. اگر در ادامه کد بالا داشته باشیم:var jane = {address: &#x27;111 Main St&#x27;,getFormalFullName: function() { return this.lastname+&#x27;,  &#x27;+this.firstname; }};var jim = {getFirstName: function(){ return firstname; }};برای این دو شیء جدید prototype را تغییر ندادیم. آنچه میتوانیم مثلا با کتابخانه underscore انجام دهیم به صورت زیر است:_.extend(john, jane, jim);میخواهیم john را به شیءهای دیگری extend کنیم. این خط کد این شیءها را ترکیب میکند. همه ویژگی ها و متدهای jane و jim (ممکن است خیلی بیشتر از دو تا باشد) را میگیرد و آنها را به طور مستقیم به john اضافه میکند. میتوانستیم این کار را خودمان هم به طور دستی انجام دهیم. خروجی console.log(john); خواهد بود:firstname: Johnlastname: DoeObject { firstnam:&#x27;John&#x27;, lastname:&#x27;Doe&#x27;, address:&#x27;111 Main St&#x27;, getFormalFullName:function, getFirstName:function... }یعنی firstname و lastname را از خودش دارد، address و getFormalFullName را از jane و getFirstName را از jim گرفته. همچنین prototype ش هم همان person است که در آن getFullName را داریم. پس این مسئله خیلی با prototype chain متفاوت است. این کار به صورت فیزیکی و واقعا ویژگی ها را داخل شیء john قرار میدهد. آنها را ترکیب کرده ایم. حال میخواهیم ببینیم چطور این کار انجام گرفته. پس سراغ underscore میرویم. در کد آن extend را سرچ میکنیم:_.extend = createAssigner(_.allKeys);پس باید دنبال تابع createAssigner بگردیم:var createAssigner = function(keysFunc, undefinedOnly) {return function(obj){   var length = arguments.length;   if (length&lt;2 || obj==null) return obj;   for (var index=1; index&lt;length; index++) {         var source=arguments[index], keys=keysFunc(source), l=keysLength;         for (var i=0; i&lt;l; i++) {            var key = keys[i];            if (!indefinedOnly || obj[key]===void 0) obj[key] = source[key];         }   }   return obj;};};تابع createAssigner تعداد keys میگیرد و یک تابع برمیگرداند. یعنی یک closure ایجاد میکند. پس در واقع وقتی extend را فراخوانی میکنیم، تابعی که اجرا میشود تابعی است که بعد از return اصلی نوشته شده. این تابعی که اجرا میشود به تابع های دیگر با closure دسترسی دارد. همان طور که میدانیم arguments همه ویژگی هایی هستند که پاس داده میشوند. اگر length کمتر از 2 بود فقط obj که به آن پاس داده ایم را برگردان. یعنی اگر در کدی که خودمان زده ایم، فقط بنویسیم:_.extend(john);مقدار length برابر با 1 است و خود john را برمیگرداند. چون چیزی به extend نداده ایم تا به john اضافه کند.در حلقه for index هم length تعداد پارامترهایی که به extend پاس داده ایم را نشان میدهد. پس اگر مثلا تعداد آنها 2 باشد باید با index برابر با 1 شروع کنیم تا اولین پارامتر را skip کند (میدانیم که آرایه ها 0-based هستند). پس john را skip کرده و سراغ پارامتر بعدی میرود. میدانیم که میتوان در قسمت function(obj) پارامترهای دیگری را هم اضافه کنیم و نیازی نیست که حتما اینجا آنها را لیست کنیم، چون با کلمه کلیدی arguments در دسترس هستند. پس این حلقه روی پارامترهای jane و jim اجرا میشود.خط کد source=arguments[index] ابتدا jane را برمیگرداند. keys در واقع همان اسم ویژگی ها است. پس اسم همه name/value ها را برای jane برمیدارد. خط کد l=keys.length تعداد ویژگی ها و متدهای jane را داخل l میریزد. در این مثال jane دو عضو دارد، پس مقدار l برابر با 2 میشود. سپس یک حلقه روی آنها حرکت میکند: هر ویژگی یا متد را میگیرد و دوباره چک میکند که حتما آنجا باشد (!undefinedOnly) و سپس obj ای که داشتیم (در این مثال john) را بروزرسانی میکند و برای آن ویژگی یا متدی با همان اسم obj[key] ایجاد میکند. پس اینجا reflection دارد انجام میشود. چون دارد به ویژگی و متدهایش نگاه میکند و دارد آنها را برای شیء john تنظیم میکند. پس حلقه اول روی شیءهایی که به عنوان source و پارامتر داده ایم میچرخد و حلقه دوم روی ویژگی ها و متدهای هر کدام از آنها میچرخد.پس دیدیم که چقدر reflection بخصوص در extend مفید است. ویژگی extend خیلی استفاده میشود و باعث میشود برای فشرده سازی شیء ها همیشه به prototype chain نیاز نداشته باشیم. با مطالعه کد underscore و فهم آن میتوانیم خودمان چنین کدی را نوشته و از آن در کتابخانه شخصی خودمان استفاده کنیم. البته در نسخه جدید js چیزی به اسم extends وجود دارد ولی این ویژگی prototype را تنظیم میکند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Thu, 25 Apr 2019 13:21:03 +0430</pubDate>
            </item>
                    <item>
                <title>53 – جاوااسکریپت: Classical and Prototypal Inheritance</title>
                <link>https://virgool.io/@pazirehsarafraz/53-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-classical-and-prototypal-inheritance-sz3m0pgpy4ro</link>
                <description>  وقتی در این قسمت در مورد object-oriented js صحبت میکنیم، تمرکزمان روی ایجاد شیء ها است.تعریف وراثت (Inheritance): یک شیء به ویژگی ها و متدهای شیء دیگر دسترسی داشته باشد. وقتی در مورد js صحبت میکنیم، ایده اصلی وراثت با زبان های برنامه نویسی دیگر متفاوت است. منظور از وراثت classical آن وراثتی است که معروف است و در c# و جاوا وجود دارد. روشی است برای به اشتراک گذاشتن ویژگی ها و متدها. اینجا نمیگوییم که این نوع وراثت بد است اما اشتباه است فکر کنیم که فقط این نوع وراثت وجود دارد و معایبی ندارد. این روش خیلی سخاوتمندانه و باز است و تعداد خیلی زیادی ارتباط بین اشیاء ایجاد میشود. ممکن است خیلی سخت باشد که بفهمیم چگونه یکی روی دیگری تاثیر میگذارد. ممکن است چیزی را جایی تغییر دهیم و ببینیم چیز دیگری جایی دیگر تغییر کرده. در این نوع وراثت از کلمات friend و protected و private و interface استفاده میشود.وراثت prototypal خیلی ساده تر، منعطف تر و extensible تر است و فهم آن خیلی راحت است. این نوع وراثت هم عالی و بدون نقص نیست اما باید بدانیم وقتی که در js در مورد وراثت صحبت میکنیم، تفاوت هایی با زبان های دیگر برنامه نویسی دارد. باید این موضوع توجه داشته باشیم که منظور از وراثت دسترسی یک شیء به ویژگی ها و متدهای شیء دیگری است. در js این کار با prototype انجام میشود.54 – جاوااسکریپت: Understanding the Prototypeمفهوم prototype: فرض کنید در حافظه یک شیء به اسم obj داریم. همان طور که میدانیم شیء ها میتوانند ویژگی و متد داشته باشند. مثلا prop1 را داریم که میتوانیم با obj.prop1 به آن دسترسی داشته باشیم. همچنین دیدیم که موتور js ویژگی ها و متدهای پنهانی هم میدهد. ویژگی ها یا متدهایی که معمولا به طور مستقیم با آنها کار نمیکنیم. در js همه اشیاء (از جمله تابع ها) یک ویژگی به اسم prototype دارند. این ویژگی یک رفرنس به یک شیء جدید به اسم proto است. خودش یک شیء است و میتوانیم از خودش هم استفاده کنیم. پس همین شیء proto هم ویژگی هایی دارد، مثلا prop2. اگر بگوییم obj.prop2 عملگر . در خود obj دنبال ویژگی prop2 میگردد و وقتی آن را پیدا نمیکند، سراغ prototype میرود و آنجا دنبال ویژگی prop2 میگردد. یعنی به prop2 به چشم ویژگی خودش نگاه میکند، ولی در واقع این ویژگی مربوط به prototype ش است. این ویژگی proto خودش هم میتواند یک ویژگی proto داشته باشد و به شیء دیگری اشاره کند. هر شیء میتواند proto خودش را داشته باشد. ممکن است این proto دوم ویژگی prop3 را داشته باشد. پس وقتی بگوییم obj.prop3 چون داخل obj آن را پیدا نمیکند به proto آن میرود، در آنجا هم prop3 را پیدا نمیکند پس به proto بعدی میرود و وقتی پیدایش کرد آن را برمیگرداند. مثل این است که prop3 داخل خود obj اصلی باشد ولی در اصلی در prototype chain پیش رفته ایم تا پیدایش کرده ایم. نباید این را با scope chain اشتباه بگیریم. Scope chain در مورد جایی است که نگاه میکنیم تا به مقدار متغیر دسترسی داشته باشیم. اما prototype chain در مورد پیدا کردن ویژگی یا متد در رشته ای از اشیائی است که به خاطر ویژگی proto به هم متصل هستند. این مسئله از نظر ما پنهان است. یعنی نیازی نیست بگوییم obj.proto.proto.prop3 و میتوانیم فقط بگوییم obj.prop3. موتور js خودش در prototype chain جستجو میکند.میتوانیم یک obj2 هم داشته باشیم که prototype ش همان prototype م obj باشد. پس میتوانیم داشته باشیم obj2.prop2 و همان ویژگی را برمیگرداند که برای obj.prop2 برگردانده بود. یعنی یک ویژگی به اشتراک گذاشته شده است.var person = {firstname: ‘Default’,lastname: ‘Default’,getFullName: function(){return this.firstname+’ ‘+this.lastname}};var john = {firstname: ‘John’,lastname: ‘Doe’};کاری که اینجا میخواهیم انجام دهیم برای یادگیری مهفوم prototype است و هیچ وقت نباید انجامش دهیم. بروزرهای مدرن راهی فراهم کرده اند تا به طور مستقیم به prototype دسترسی داشته باشیم. اما ما نباید از آن استفاده کنیم و تغییرش دهیم. چون در performance مشکلاتی پیش می آید و باعث کند شدن برنامه میشود.// don’t do this EVER!john.__proto__ = person;console.log(john.getFullName());همان طور که گفتیم همه اشیاء رفرنسی به شیء دیگری دارند که prototype نام دارد. در بسیاری از بروزرهای مدرن میتوانیم این کار را انجام دهیم. از __ قبل و بعد از proto استفاده شده تا مطمئن باشید هیچ وقت به طور اتفاقی از آن استفاده نکرده اید. اکنون john از person به ارث میبرد. یعنی اگر بخواهم در john به ویژگی یا متدی دسترسی داشته باشم که در john وجود ندارد، سراغ person میرود تا پیدایش کند. اگر در person هم نباشد سراغ proto مربوط به person میرود. خروجی کد بالا John Doe میشود. زمانی که تابع getFullName فراخوانی میشود، execution context ای که this را ایجاد میکند، میداند که در مورد چه شیئی صحبت میکنیم. پس this به person اشاره نمیکند، به john اشاره میکند، جایی که صدا زده شده. اگر در کنسول john.firstname را ببینیم مقدار John برگردانده میشود. چرا مقدار Default برگردانده نمیشود؟ چون اول خود john را چک میکند و اگر پیدایش کند دیگر سراغ prototype chain نمیرود. بنابراین firstname در john باعث میشود که firstname در prototype پنهان شود. این به دلیل این است که موتور js جستجو را از بالای زنجیره شروع میکند و هر موقع که پیدا شد جستجو متوقف میشود.var jane = {firstname: ‘Jane’}jane.__proto__ = person;console.log(jane.getFullName());پس proto هر دو شیء john و jane به یک جا از حافظه اشاره میکند. هر موقع که بخواهیم به متغیری دسترسی داشته باشیم prototype chain جستجو میشود. در این حالت this به jane اشاره میکند. پس در شیء jane دنبال firstname و lastname میگردد. jane فقط firstname را دارد. وقتی در jane دنبال lastname میگردد، آن را پیدا نمیکند و به prototype آن یعنی person نگاه میکند. خروجی Jane Default است.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Thu, 25 Apr 2019 10:21:03 +0430</pubDate>
            </item>
                    <item>
                <title>51 – جاوااسکریپت: Functional Programming</title>
                <link>https://virgool.io/@pazirehsarafraz/51-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-functional-programming-czubch9xetzn</link>
                <description>داشتن ویژگی first class function در زبان برنامه نویسی جاوااسکریپت باعث میشود که بتوانیم برنامه نویسی تابعگرا را در آن استفاده کنیم، یعنی فکر کردن و کد زدن مان بر اساس تابع ها باشد. این روش را نمیتوانیم به راحتی در زبان های برنامه نویسی دیگری که ویژگی first class function ندارند انجام دهیم. var arr1 = [1, 2, 3];console.log(arr1);فرض کنید میخواهیم یک آرایه دیگر از روی آرایه arr1 ایجاد کنیم.var arr2 = [ ];for (var i=0; i&lt;arr1.lenght; i++) {arr2.push(arr1[i]*2);}console.log(arr2);خروجی کد بالا:[1, 2, 3][2, 4, 6]برای این کار کد زیادی زده ایم. به عنوان یک برنامه نویس همیشه دنبال این هستیم که آنچه تایپ کرده ایم کمترین حالت باشد و کمترین تکرار را داشته باشیم. بنابراین از تابع ها استفاده میکنیم. در زبان های برنامه نویسی که تابع ها first class نیستند محدودیت هایی در مورد مقدار چیزی که میتوان در تابع قرار داد وجود دارد. اما با first class function میتوانیم کار متفاوتی انجام دهیم. فرض کنید تابعی داریم که یک آرایه و یک تابع را میگیرد. چون با first class function کار میکنیم میتوانیم تابع را به عنوان پارامتر به تابع پاس دهیم:function mapForEach(arr, fn) {var newArr = [ ];for (int i=0; i&lt;arr.length; i++){newArr.push( fn(arr[i]) );}return newArr;}var arr1 = [1, 2, 3];console.log(arr1);var arr2 = mapForEach(arr1, function(item){return item*2;});console.log(arr2);کلمه map یعنی یک آرایه گرفتیم، کاری با آن انجام داده ایم (اینجا ضربدر 2 کرده ایم) و یک آرایه جدید از آن گرفته ایم. چیزی که داخل push نوشته ایم جایی است که از functional programming استفاده کرده ایم. خروجی کد بالا:[1, 2, 3][2, 4, 6]در این کد کل حلقه for را که آرایه جدید ایجاد میکرد در یک تابع سگمنت کردیم. سپس موقع فراخوانی، آن کار را به هر آیتم آرایه دادیم. این روش بسیار قدرتمند است. میتوانم از آن تابع یک بار دیگر هم استفاده کنم:var arr3 = mapForEach(arr1, function(item){return item&gt;2;});console.log(arr3);خروجی این قسمت میشود:[false, false, true]پس توانستیم به راحتی و با پاس دادن یک تابع، از تابع mapForEach کاملا به صورت متفاوتی دوباره استفاده کنیم. این یک مثال کلاسیک از functional programming و استفاده از فواید first class function است.حالا میخواهیم از تابع mapForEach استفاده کنیم تا چک کنیم آیا چیزی از آستانه ای گذشته یا نه. یعنی در مثال بالا به جای مقدار 2 در item&gt;2 یک آستانه به آن بدهیم تا قابل استفاده مجدد باشد:var checkPastLimit = function(limiter, item) { return item&gt;limiter };مشکلی که اینجا داریم این است که تابع checkPastLimit دو پارامتر میگیرد ولی در کدی که بالا زده شد، تابع fn فقط یک ورودی میگیرد. باید طوری از تابع استفاده کنیم که یک پارامتر آن از قبل ست شده باشد. برای این کار میتوانیم از bind استفاده کنیم:var arr4 = mapForEach(arr1, checkPastLimit.bind(this, 2));پس on the fly یک کپی از تابع checkPastLimit ایجاد کردیم و 2 را به عنوان limiter به آن دادیم. اگر در کنسول arr4 را ببینیم، خروجی [false, false, true] میشود. شاید به نظر برسد که استفاده از bind به صورت همیشگی کمی آزار دهنده است، بهتر است همیشه فقط limiter را به عنوان تنها پارامتر پاس دهیم. چطور میتوانیم این کار را بکنیم و چنین تابعی ایجاد کنیم که فقط limiter را به عنوان ورودی میگیرد؟var checkPastLimitSimplified = function(limiter) {return function(limiter, item) { return item&gt;limiter }.bind(this, limiter);};در تابع checkPastLimitSimplified باید مقدار اولیه اولین پارامتر را از قبل ست کنیم. برای همین در ادامه از bind استفاده کرده ایم. در این کد تابع داریم که پارامتر limiter را میگیرد و یک تابع برمیگرداند. از bind هم برای ست کردن limiter استفاده کردیم. پس زمانی که checkPastLimitSimplified را اجرا میکنیم مثل حالت بالاتر که از bind استفاده کرده بودیم عمل میکند. در کد بالا یک پارامتر limiter خط اول تکه کد داریم و یک پارامتر limiter خط دوم کد داریم. پارامتر limiter در خط اول به limiter خط دوم پاس داده میشود. پس برای استفاده از این قطعه کد:var arr5 = mapForEach(arr1, checkPastLimitSimplified(2));خروجی آن [false, false, true] است.نباید فقط برای سگمنت کردن و ساده کردن کدنویسی از تابع ها استفاده کنیم. باید این طور فکر کنیم که چگونه به تابع هایمان تابع دهیم و تابع برگردانیم. دقت داشته باشیم که همه تابع ها بخصوص تابع های کوچکی که به هم پاس میدهیم، نباید داده ای را mutate کنند. پس همیشه بهتر است که داده ها را در بالاترین سطح ممکن زنجیره تابع ها mutate کنیم. Functional programming یک درس مجزا است. اینجا فقط خواستیم این ایده را در js معرفی کنیم. چون first class function و funcationa programming در js باعث میشود که js به سطح بالاتری برسد. میتوانیم علاوه بر کدنویسی مثل کدنویسی با زبان جاوا یا php از این ویژگی در js استفاده های زیادی داشته باشیم.52 – جاوااسکریپت: Functional Programmingکتابخانه underscore.js کتابخانه خیلی معروفی در js است که به ما کمک میکند با آرایه ها و مجموعه ای شیء ها کار کنیم. علاوه بر مفید بودن، یک نکته خیلی خوب در مورد این کتابخانه این است که تلاش کرده نشان دهد چگونه پیاده سازی شده است. کدهای خیلی زیادی به صورت کتابخانه و framework وجود دارند و به صورت رایگان در دسترس هستند و source code آنها عالی است. میتوانیم source code آنها را بخوانیم و چیزهای زیادی یاد بگیریم. با خواندن کدهای خیلی خوب در js میتوانیم خودمان هم خیلی خوب کد بزنیم. کتابخانه underscore.js دو نسخه دارد: development و produnction. نسخه development کامنتهای بیشتری دارد. پس برای مطالعه از آن استفاده میکنیم. همچنین میتوانیم قسمت Annotated Source را دانلود کنیم که در آن کامنتها در ستونهایی کنار کد قرار گرفته اند و میتوانیم آن را بخوانیم یا در آن کد بزنیم. در این کتابخانه از مفاهیم functional programming خیلی استفاده شده است. در این کتابخانه معمولا اسم تابع هایی که به هم پاس داده شده اند predicate یا iteratee است.کتابخانه دیگری هم به اسم lodash هست. از بیرون خیلی مشابه کتابخانه قبلی است اما ویژگی های اضافی دیگری را هم پیاده سازی کرده و برخی از utility ها را دوباره نوشته و سریعتر اجرا میشود. به همین دلیل برخی ترجیح میدهند از lodash استفاده کنند. میخواهیم از underscore استفاده کنیم. فایل کتابخانه آن را دانلود میکنیم. داخل آن با (function(){شروع شده است. یعنی کل کد در یک IIFE م wrap شده است تا کدهای داخل این کتابخانه با کدهای دیگر در پروژه تصادمی نداشته باشد. فایل کتابخانه را قبل از فایل js خودمان اتچ میکنیم. پس اول کل کد داخل IIFE کتابخانه اجرا میشود و سپس کد global ای که خودمان نوشته ایم. در کتابخانه underscore شیئی به نام _ داریم.// underscorevar arr6 = _.map(arr1, function(item){return item*3});console.log(arr6);کدی که در underscore نوشته شده بهتر است چون سناریوهای بیشتری را شامل میشود. خروجی کد بالا [3, 6, 9] خواهد بود. شیء _ در global قرار گرفته و همه جا قابل دسترس است.var arr7 = _.filter([2,4,5,6,7], function(item){return item%2===0;});console.log(arr7);خروجی [2, 4, 6] میشود. در underscore متدهای خیلی زیادی وجود دارد. خواندن این کتابخانه به ما کمک میکند تا از ایده ها و مفاهیمی که تا کنون آموخته ایم در کد خودمان استفاده کنیم.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Tue, 23 Apr 2019 11:54:44 +0430</pubDate>
            </item>
                    <item>
                <title>50 – جاوااسکریپت: call, apply, bind</title>
                <link>https://virgool.io/@pazirehsarafraz/50-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-call-apply-bind-y9sr42nmqp3t</link>
                <description> در execution context یک variable environment و یک outer environment reference و یک متغیر this داریم. همان طور که قبلا گفته شد متغیر this در شرایطی به global object اشاره میکند و در شرایطی به شیئی که تابع را دربر دارد (اگر تابع متدی از آن شیء باشد) اشاره میکند. خیلی خوب است اگر بتوانیم موقع ایجاد execution context روی this کنترل داشته باشیم. js این امکان را به ما میدهد و به همین دلیل call و apply و bind رایج هستند. میتوانستیم در این مورد قبلا صحبت کنیم، همان موقع که در مورد متغیر this توضیحاتی داشتیم. اما برای فهم عمیقتر آن نیاز بود در مورد first class function بدانیم. همان طور که میدانیم تابع ها نوع خاصی از شیء هستند. تابع یک ویژگی پنهان اختیاری NAME دارد. یک ویژگی CODE دارد که invocable است. همه تابع ها در js همچنین به یک سری ویژگی و یک سری متد دسترسی دارند. چون تابع یک شیء است و میتواند ویژگی ها و متدهایی داشته باشد. همه تابع ها به متدهای call() و apply() و bind() دسترسی دارند. این سه متد با متغیر this کار میکنند.var person = {firstname: ‘John’,lastname: ‘Doe’,getFullName: function() {var fullName=this.firstname+’ ‘+this.lastname; return fullName;}};در متد از this استفاده کرده ایم. چون این یک متد در شیء است، وقتی این تابع اجرا میشود this به کل شیء نگهدارنده متد اشاره میکند. حال فرض کنید تابعی داریم که خارج از این شیء است:var logName = function(lang1, lang2) { console.log(‘Logged: ‘+this.getFullName()); };logName();میدانیم که در کد بالا this.getFullName() خطا میدهد: undefined is not a function. چون this در این قسمت به global object اشاره میکند. این تابع متد شیء person نیست. در global object متد getFullName را نداریم و undefined است و این خطا را به ما میدهد. میخواهیم روی مقدار this کنترل داشته باشیم. پس قبل از فراخوانی logName(); یک تابع دیگر تعریف میکنیم:var logPersonName = logName.bind(person);همه تابع ها در js به سه متد گفته شده (از جمله bind) دسترسی دارند. توجه داشته باشید که در کد بالا تابع logName را با پرانتز فراخوانی نکرده ایم چون تابع مقداری را برمیگرداند. ولی ما اینجا میخواهیم به تابع به عنوان یک شیء نگاه کنیم و متد bind را برای آن شیء فراخوانی کنیم. (logName یک شیء تابع است و همه تابع ها این متد را دارند) میتوانیم به تابع bind هر شیئی که میخواهیم را پاس دهیم تا وقتی تابع اجرا میشود متغیر this به همان شیء پاس داده شده اشاره کند. تابع bind یک تابع جدید را برمیگرداند. در واقع یک کپی از logName در یک تابع شیء جدید ایجاد میکند. بنابراین هر موقع که اجرا میشود و execution context آن ایجاد میشود، موتور js میبیند که این شیء با bind ایجاد شده، پس مقدار متغیر this را برابر با person قرار میدهد. در واقع با این کار روی تصمیم موتور js تاثیر میگذاریم. بنابراین اگر به جای فراخوانی logName();، تابع logPersonName(); را فراخوانی کنیم خروجی میشود:Logged: John Doeمیتوانیم این کار را به صورت زیر و on the fly هم انجام دهیم:var logName = function(lang1, lang2) { console.log(‘Logged: ‘+this.getFullName()); }.bind(person);logName();در این حالت مقدار logName به یک کپی از تابع اشاره میکند که on the fly ایجاد شده که به person م bind شده است. بنابراین bind یک کپی از تابع ایجاد میکند که this به هر شیئی که به آن by reference پاس دهیم اشاره میکند.var logName = function(lang1, lang2) {console.log(‘Logged: ‘+this.getFullName());console.log(‘Arguments: ‘+lang1+’ ‘+lang2);};var logPersonName = logName.bind(person);logPersonName(‘en’);اگر کد با به صورت بالا کمی تغییر دهیم، باز هم یک کپی از تابع داریم. پس یک آرگومان گرفته و مقدار this در کد بالا همان person خواهد بود. خروجی میشود:Logged: John DoeArguments: en undefinedاگر در مثال بالا از عبارت logName.call استفاده کنیم، تابع فراخوانی میشود. این کار را میتوانیم با پرانتز خالی هم انجام دهیم. اما استفاده از متد call به ما این امکان را میدهد تا مقدار متغیر this را تعیین کنیم. اولین پارامتری که به call پاس میدهیم برای تعیین مقدار this است. سپس میتوانیم پارامترها را به آن پاس دهیم:logName.call(person, ‘en’, ‘es’);پس متد bind یک کپی از تابع ایجاد میکند ولی متد call آن را اجرا میکند. خروجی کد بالا:Logged: John DoeArguments: en esمتد bind خودش تابع را اجرا نمیکند.متد apply هم به غیر از یک مورد دقیقا مثل call عمل میکند. اگر بخواهیم متغیرها را به صورتlogName.apply(person, ‘en’, ‘es’);به تابع apply پاس دهیم، به ما خطا میدهد: Function.prototype.apply: Arguments list has wrong typeچون تابع apply آرایه ای از پارامترها را میخواهد:logName.apply(person, [‘en’, ‘es’]);خروجی این کد:Logged: John DoeArguments: en esآرایه میتواند مفیدتر باشد، بخصوص در مواردی که از ریاضیات استفاده میکنیم. مثلا موقعی که میخواهیم چندین عدد را با هم جمع کنیم، تعداد اعداد میتواند هر عددی باشد. بنابراین دو آپشن call و apply را داریم و بسته به چگونگی کد زدنمان از یکی استفاده میکنیم.اینجا هم میتوانیم از این متدها on the fly استفاده کنیم. میتوانیم از تریک گذاشتن پرانتز قبل از اسم تابع استفاده کنیم تا به syntax parser بگوییم این خط کد یک function statement نیست و یک function expression است. و به جای اینکه با () آن را فورا فراخوانی کنیم، میتوانیم با apply یا call آن را فراخوانی کنیم:(function(lang1, lang2) {console.log(‘Logged: ‘+this.getFullName());console.log(‘Arguments: ‘+lang1+’ ‘+lang2);}).apply(person, [‘en’, ‘es’]);پس یک تابع on the fly ایجاد کردیم و با apply آن را فراخوانی کردیم. خروجی این کد:Logged: John DoeArguments: en esسوالی که ممکن است پیش بیاید این است که آیا واقعا از چنین چیزهایی استفاده میشود؟ به مثالهای زیر توجه کنید. مثلا یک شیء دیگر به اسم person2 داریم که خیلی شبیه به شیء اول person است و فقط متد را ندارد:// function borrowingvar person2 = {firstname: ‘Jane’,lastname: ‘Doe’};میخواهیم با استفاده از call یا apply یک function borrowing داشته باشیم.در شیء اول متد getFullName را داریم. چون این متد یک تابع است پس متد apply را میتوانیم برای آن صدا کنیم. ولی مقدار this را برابر با person2 میگذاریم:person.getFullName.apply(person2);بنابراین متد getFullName داخل شیء اول person را فراخوانی کردیم ولی داخل آن this به شیء دوم person2 اشاره میکند. بنابراین اگر کد بالا را در کنسول اجرا بگیریم، خروجی:Jane Doeآنچه انجام دادیم، قرض کردن یک تابع است. میخواهیم از متدی در یک شیء برای شیء دیگری استفاده کنیم و با استفاده از apply آن را قرض گرفتیم. میتوانیم این کار را با call هم انجام دهیم. این دو شیء اسم ویژگی هایشان یکی بود تا تابع بتواند در شیء دوم هم اجرا شود.یک مثال دیگر استفاده از این سه متد به صورت زیر است. اینجا از متد bind استفاده میکنیم. این متد یک کپی از تابع ایجاد میکند و اگر به آن پارامترهایی را پاس دهیم میتواند جالبتر هم باشد. موقع استفاده از call و apply با پاس دادن پارامتر فقط آنها را پاس داده ایم، اما وقتی که bind یک کپی از تابع ایجاد کرد، اگر به آن پارامترهایی پاس دهیم چه اتفاقی می افتد؟// function curryingfunction multiply(a, b) { return a*b; }var multipleByTwo = multiply.bind(this, 2);multipleByTwo(3);یک تابع جدید که یک کپی از تابع multiply است ایجاد کردیم. اینجا برایمان مهم نیست که this به کجا اشاره میکند، فقط به bind یک مقدار پارامتر میدهیم. همان طور که گفته شد، متد bind تابع را اجرا نمیکند، پس دادن پارامتر 2 به چه معناست؟ دادن پارامتر به bind باعث میشود که وقتی کپی از تابع ایجاد شد مقدار پارامتر اول آن برابر با 2 باشد. مثلا این است که کد زیر را داشته باشیم:function multipleByTwo(b) { var a=2; return a*b; }موقع فراخوانی multipleByTwo فقط پارامتر دوم را به آن پاس داده ایم. اگر آن را در کنسول اجرا بگیریم خروجی 6 را میدهد. اگر موقع ایجاد تابع multipleByTwo هر دو پارامتر را به آن پاس دهیم، داریم به a و b به صورت همیشگی مقدار ثابت میدهیم.var multipleByTwo = multiply.bind(this, 2, 2);multipleByTwo(3);با اینکه موقع فراخوانی تابع multipleByTwo به آن پارامتر 3 را پاس داده ایم، ولی مقدار 4 خروجی آن خواهد بود، چون موقع ساخت تابع multipleByTwo هر دو پارامتر را برایش انتخاب کرده ایم. اگر موقع ایجاد این تابع هیچ پارامتری به آن پس ندهیم:var multipleByTwo = multiply.bind(this);multipleByTwo(5, 2);موقع اجرا نیاز است که هر دو پارامتر به آن داده شود. در این مثال خروجی 10 میشود.بنابراین یک تابع داریم. سپس یک تابع جدید با برخی مقادیر پیش فرض از آن ایجاد میکنیم. به این کار currying گفته میشود.تعریف function currying: ایجاد یک کپی از یک تابع با چند پارامتر ست شده. در مواردی که از ریاضیات استفاده میشود خیلی کاربرد دارد. پس اگر بخواهیم یک کتابخانه درست کنیم که محاسبات ریاضی زیادی را شامل میشود، میتوانیم از تابع های fundamental استفاده کنیم و سپس با bind کردن آنها تابع هایی را با مقادیر پیش فرض ایجاد کنیم.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Mon, 22 Apr 2019 15:32:02 +0430</pubDate>
            </item>
                    <item>
                <title>48 – جاوااسکریپت: Function Factories</title>
                <link>https://virgool.io/@pazirehsarafraz/48-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-function-factories-dztypmbdvwhs</link>
                <description>در این بخش در مورد استفاده از فواید closure برای ایجاد الگوهایی که بدون closure غیرممکن است صحبت میکنیم: function factories. تا به حال دیدم که چگونه میتوانیم از ویژگی های زبان js استفاده کنیم تا به تابع اجازه دهیم در شرایط مختلفی با مقادیر پیش فرض مختلف فراخوانی شود. در این مورد در بخش function overloading صحبت شد. اینجا میخواهیم در مورد الگوهای قوی تر و منعطف تری صحبت کنیم که از closure استفاده میکنند. یک factory یعنی تابعی که چیزهایی را برای ما ایجاد یا return میکند. در مثال زیر تابع makeGreeting تابعی را return میکند. میتوانیم در قسمت return به تابع اسم greet را هم بدهیم ولی نیازی نیست:function makeGreeting(language) {return function(firstname, lastname) {if (language==’en’) { console.log(‘Hello’+’ ‘+firstname+’ ‘+lastname); }if (language==’es’) { console.log(‘Hola’+’ ‘+firstname+’ ‘+lastname); }}}var greetEnglish = makeGreeting(‘en’);var greetSpanish = makeGreeting(‘es’);تفاوت این تابع با تابع مشابهی که قبلا گفته شد این است که به جای پاس دادن پارامتر language به تابع return شده، این پارامتر را به تابع بیرونی پاس داده ایم. پس language در closure میماند و زمانی که تابع return شده را اجرا میکنیم، مقدار language را با scope chain پیدا میکند حتی اگر اجرای تابع makeGreeting تمام شده باشد. وقتی کد بالا اجرا میشود و makeGreeting اجرا میشود، یک تابع را برمیگرداند که outer reference آن مقدار language را به ما نشان میدهد. دفعه دوم که makeGreeting اجرا میشود یک execution context دیگه ایجاد میشه که داخل آن مقدار language چیز دیگه ای هست. پس با اینکه از نظر lexical این دو تابع در یک جا نوشته شده اند، به دو جای مختلف از حافظه اشاره میکنند، چون در دو execution context مختلف ایجاد شده اند. پس greetEnglish یک شیء تابع است که closure آن به language=’en’ اشاره میکند و greetSpanish یک شیء تابع است که closure آن به یک execution context دیگر اشاره میکند و در آن language=’es’ است.بنابراین با اینکه یک تابع makeGreeting داریم، هر بار که اجرا میشود یک execution context جدید و حافظه جدید ایجاد میکند. پس اگر در انتهای کد اضافه کنیم:greetEnglish(‘John’, ‘Doe’);greetSpanish(‘John’, ‘Doe’);خروجی میشود:Hello John DoeHola John Doeتابع makeGreeting به عنوان یک function factory عمل میکند. در آن از خصوصیات closure ها برای ست کردن مقدار پارامتر در تابعی که return میکند استفاده کردیم. سپس تابع greetEnglish را که همیشه از مقدار ‘en’ استفاده میکند تعریف کردیم. اما موقع فراخوانی تابع greetEnglish دیگر به مقدار ‘en’ به طور مستقیم دسترسی نداریم. میتوانیم این کد را از دید دیگری بررسی کنیم:وقتی اجرای کد شروع میشود global execution context را داریم که در آن متغیرهای greetEnglish و greetSpanish و تابع makeGreeting() قرار دارد. وقتی به خط کد var greetEnglish = makeGreeting(‘en’); میرسیم برای تابع makeGreeting یک execution context ایجاد میشود که در آن language=’en’ پاس داده میشود. سپس یک تابع را برمیگرداند که در greetEnglish ذخیره میشود و execution contex آن حذف میشود ولی حافظه آن هنوز در دسترس است. سپس در خط کد var greetSpanish = makeGreeting(‘es’); تابع makeGreeting دوباره فراخوانی میشود و execution context ایجاد میشود که در آن language=’es’ است. دوباره تابعی برگردانده شده و تمام میشود و execution context حذف میشود. پس الان در حافظه دو جای مختلف داریم که مقدار language در آنها هست و قبلا در execution context ای بوده اند. پس وقتی به خط کد greetEnglish(‘John’, ‘Doe’); میرسیم، تابعی که return شده بود را فراخوانی میکنیم و یک execution context جدید ایجاد میشود که در حافظه آن firsname=’John’ و lastname=’Doe’ قرار دارد. موتور js میداند که outer reference این تابع به اولین اجرای تابع پدر برمیگردد، به جایی که در آن ایجاد شده است. موقع اجرای خط کد greetSpanish(‘John’, ‘Doe’); هم به همین ترتیب است. این تابع در دومین بار فراخوانی ایجاد شده، پس outer reference آن به دومین execution context برمیگردد و closure خودش را دارد.پس هر بار که تابعی اجرا میشود execution context مجزایی ایجاد میشود و هر تابعی که در آن ایجاد میشود به همان execution context اشاره میکند.این کد کار فراخوانی تابع را خیلی راحت کرده است. چون دیگر نیازی نیست که هر بار یک پارامتر یکسان را به تابع پاس دهیم. فقط با استفاده از closure ها تابع جدیدی ایجاد کردیم که پارامترهایی را به صورت پیش فرض دارد. پس تابعی که return شده به مقدار language در همان لحظه که تولید شده دسترسی دارد.49 – جاوااسکریپت: Closures, Callbacksوقتی داریم از تابعی مثل setTimeout یا jQuery event استفاده میکنیم، داریم تمام مدت از closure ها استفاده میکنیم. Function sayHiLater() {var greeting = ‘Hi’;setTimeout(function(){ console.log(greeting); }, 3000);}sayHiLater();تابع setTimeout یک تابع built-in در js است. وقتی بخواهیم چیزی بعد از مدتی اتفاق بیفتد از آن استفاده میکنیم. این تابع یک تابع میگیرد که چیزی که قرار است اتفاق بیفتد را تعیین میکند و همچنین مدت زمانی را که باید صبر کند میگیرد. این کد بعد از 3 ثانیه خروجی Hi را میدهد. تابع setTimeout به خارج از بروزر میرود و صبر میکند تا event اتفاق بیفتد (3 ثانیه بگذرد). سپس تمام میشود. سپس موتور js جستجو میکند که آیا تابع دیگری در حال listening هست یا نه. تابع function(){console.log(greeting);} را پیدا میکند و آن را اجرا میکند. اما مقدار متغیر greeting داخل این تابع وجود ندارد و sayHiLater هم تمام شده ولی چون در scope chian مان closure داریم، بعد از این 3 ثانیه هنوز به greeting دسترسی داریم. اجرای تابع sayHiLater فقط چند میلی ثانیه طول میکشد ولی حتی بعد از چندین ثانیه هنوز به مقدار greeting دسترسی داریم. پس در این مثال از closure و function expression استفاده کردیم.در jQuery هم همین طور است. برای مثال در کد زیر:// jQuery uses function expressions and first-class functions$(“button”).click(function(){});این click یک تابع است که یک تابع دیگر را میپذیرد تا وقتی event اتفاق افتاد آن را اجرا کند. پس در اینجا از first class function استفاده کرده ایم. یعنی تابع را به عنوان یک پارامتر پاس داده ایم. از function expression استفاده کرده ایم تا تابع مان را تعریف کنیم.زمانی که از jQuery یا js استفاده میکنیم از فواید first class function و closure ها استفاده میکنیم. تابع هایی مثل function(){ console.log(greeting); } که بعد از اجرای تابعی، کاری انجام میدهند و به تابع اول پاس داده میشوند callback نام دارند. تابع callback را به تابعی میدهیم تا وقتی کارش تمام شد، آن را اجرا کند.تعریف تابع callback: تابعی که به یک تابع دیگر داده میشود، تا بعد از تمام شدن تابع دیگر اجرا شود.function tellMeWhenDone(callback){var a = 1000; // some codes here to docallback();}tellMeWhenDone(function(){ console.log(‘I am done’); });tellMeWhenDone(function(){ alert&#40;‘I am done’&#41;; });در مثال بالا یک تابع را به tellMeWhenDone پاس میدهیم تا وقتی تابع tellMeWhenDone را اجرا کردیم، خودش آن را فراخوانی کند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Mon, 22 Apr 2019 15:27:58 +0430</pubDate>
            </item>
                    <item>
                <title>46 - جاوااسکریپت: Closure</title>
                <link>https://virgool.io/@pazirehsarafraz/46-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-closure-agyes41bzk1e</link>
                <description>موضوع closure در js مطرح شده و فهم آن دشوار است. تمام آنچه تا اینجا گفته شد برای درک چگونگی اتفاق افتادن چیزها، درک first class function، درک execution stack و execution context برای فهم closure در js لازم است. ابتدا میخواهیم قدرت closure را نشان دهیم. اینجا به جای اینکه داخل تابع کاری کنیم، تابعی را با استفاده از function expression برمیگردانیم و میخواهیم از فواید scope chain استفاده کنیم:function greet(whattosay) {   return function(name) { console.log(whattosay+&#x27;  &#x27;+name); }}greet(&#x27;Hi&#x27;)(&#x27;Tony&#x27;);یک تابع greet داریم که یک تابع برمیگرداند. بنابراین زمانی که greet را فراخوانی کنیم، یک تابع به ما برگردانده میشود که میتوانیم دوباره آن را invoke کنیم. کد بالا خروجی Hi Tony را میدهد. اما یک چیز غیرمعمول در حال انجام است. برای اینکه بفهمیم چگونه غیرمعمول است، کمی متفاوت کد میزنیم و یک متغیر را برابر با نتیجه تابع قرار میدهیم:function greet(whattosay) {   return function(name) { console.log(whattosay+&#x27;  &#x27;+name); }}var sayHi = greet(&#x27;Hi&#x27;);sayHi(&#x27;Tony&#x27;);بنابراین متغیر sayHi برابر با تابعی است که تابع greet برمیگرداند. خروجی کد بالا Hi Tony میشود. اما چگونه تابع sayHi هنوز متغیر whattosay را میشناسد. متغیر whattosay وقتی greet(&#x27;Hi&#x27;) را صدا زدیم ایجاد شده و وقتی کار این تابع تمام میشود، execution context آن از استک pop میشود. اما وقتی بعد از آن sayHi(&#x27;Tony&#x27;) را فراخوانی میکنیم، همچنان مقدار صحیح متغیر whattosay را دارد. چگونه این اتفاق افتاده است؟ دلیل آن closure است.این مسئله غیرمعمول به نظر میرسد چون تابع greet تمام میشود و وقتی تابعی که برگردانده شده را invoke میکنیم، اینطور به نظر میرسد که تابع greet همچنان جایی هست چون متغیر whattosay هنوز وجود دارد. آنچه اتفاق می افتد این است که وقتی کد شروع میشود global execution context را داریم. وقتی به خط var sayHi = greet(&#x27;Hi&#x27;); میرسیم، تابع greet مان invoke میشود و یک execution context جدید ایجاد میشود و متغیری که به آن پاس داده شده است یعنی whattosay در variable environment آن قرار میگیرد. این تابع یک تابع جدید را برمیگرداند. یعنی تابع را on the fly ایجاد میکند و آن را برمیگرداند. پس از return کردن، execution context از استک pop میشود. قبلا گفته شد که هر execution context برای متغیرها و تابع هایی که داخلش ایجاد میشوند فضای خودش را در حافظه دارد. وقتی execution context از بین میرود، برای آن فضای حافظه چه اتفاقی می افتد؟در شرایط نرمال، موتور js با فرایند garbage collection این فضا را خالی میکند. اما در لحظه ای که execution context تمام میشود، این فضای حافظه هنوز آنجا هست. execution context رفته ولی این فضا جایی در حافظه است. پس به global execution context میرویم و سپس تابع sayHi(&#x27;Tony&#x27;) را invoke میکنیم. این یک تابع anonymous است چون به تابع اسمی نداده ایم. execution context جدید ایجاد میشود و متغیر name به آن پاس داده میشود و داخل حافظه آن قرار میگیرد. اما وقتی به خط console.log(whattosay+&#x27;  &#x27;+name); از کد میرسیم و این کد invoke میشود، موتور js متغیر whattosay را میبیند. پس در scope chain پیش میرود. یعنی به جایی که تابع در آن ایجاد شده میرود. گرچه execution context مربوط به تابع greet از بین رفته و از استک pop شده، execution context مربوط به sayHi هنوز reference به متغیرها و فضای حافظه outer environment دارد. یعنی اگرچه تابع greet در واقع تمام شده اما همه تابع های ایجاد شده داخل آن وقتی فراخوانی میشوند، هنوز reference به فضای حافظه execution context تابع greet دارند. تابع greet رفته ولی حافظه آن execution context از بین نرفته. موتور js این اطمینان را میدهد که تابع من همچنان میتواند از scope chain پایین رود حتی اگر هنوز در execution stack نباشد. در این حالت میگوییم که execution context با outer variable هایش (متغیرهایی که در حالت نرمال به آنها reference دارد) closed-in است، حتی اگر آن execution context ها از بین رفته باشند. این پدیده یعنی close-in بودن همه متغیرهایی که فرض میشود به هم دسترسی دارند closure نام دارد. این پدیده چیزی نیست که ما ایجاد یا تایپ کنیم یا ما به موتور js بگوییم انجام دهد. closure یک ویژگی زبان برنامه نویسی js است. مهم نیست کی یک تابع را فراخوانی میکنیم. نیازی نیست نگران این باشیم که آیا outer environment آن هنوز در حال اجرا هست یا نه. موتور js همیشه این اطمینان را میدهد که هر تابعی را اجرا کنیم به متغیرهایی که فرض میکند دسترسی دارد، واقعا دسترسی داشته باشد. این یک ویژگی زبان است و بسیار مهم و قدرتمند است و بسیار از آن استفاده میکنیم. به ما اجازه میدهد که از الگوهای جالب زیادی در کد استفاده کنیم. درک اینکه چه اتفاقاتی می افتد به ما در ساده تر کردن درک closure ها کمک میکند. closure ها ویژگی هستند که ما را مطمئن میکنند وقتی یک تابع را اجرا میکنیم، همان طور که باید کار میکند و به outer variable هایش دسترسی دارد. مهم نیست که اجرای تابع دیگر تمام شده یا نه. بنابراین وقتی میگوییم که یک closure ایجاد کرده ایم، در واقع js آن را ایجاد کرده است و ما فقط از آن فایده میبریم.47 - جاوااسکریپت: Understanding Closuresاگر کلمه closure را سرچ در اینترنت کنیم، به مثال زیر میرسیم:function buildFunctions() {var arr = [ ];for (var i=0; i&lt;3; i++) {arr.push( function() {console.log(i);} );}return arr;}var fs = buildFunctions();fs[0]();fs[1]();fs[2]();داخل آرایه تابع اضافه میکنیم. آرایه میتواند شامل هر چیزی باشد. داخل آرایه سه تا تابع قرار دادیم. این آرایه را در متغیر fs ریختیم. در این قسمت از کد که arr.push(function() {console.log(i);}); را نوشتیم در حال invoke کردن تابع نیستیم و فقط آن را ایجاد میکنیم. تابع ها در قسمت fs[0](); فراخوانی میشوند. وقتی به این کد نگاه میکنیم احتمالا انتظار داریم که خروجی 0 و 1 و 2 باشد. اما خروجی 3 و 3 و 3 میشود. چرا هر بار که دنبال i در outer reference رفته 3 را پیدا کرده؟وقتی این کد اجرا میشود global execution context پایین execution stack ایجاد میشود. داخل آن buildFunctions() و fs قرار دارد. وقتی به خط var fs = buildFunctions(); میرسیم، یک execution context ایجاد میشود که داخل آن دو متغیر arr و i وجود دارد. وقتی به خط کد return arr; میرسیم مقدار این متغیرها چند است؟ وقتی حلقه for اجرا میشود، مقدار i اول صفر است و یک تابع در آرایه push میکند. اما در این مرحله کد console.log(i); اجرا نمیشود. در مورد function expression صحبت کردیم. آنچه در اینجا اتفاق می افتد این است که فقط یک شیء جدید ایجاد میشود و کد داخل آن یعنی console.log(i); در ویژگی CODE آن قرار میگیرد ولی این کد اجرا نمیشود. سپس مقدار i برابر با یک میشود و ... تا اینکه مقدار i برابر با 3 شده و از حلقه خارج میشود. بنابراین وقتی به خط کد return arr; میرسیم، در حافظه execution context مقدار i برابر با 3 است و داخل arr مان سه تابع anonymous داریم. سپس به global execution context برمیگردیم و buidFuncions execution context از استک pop میشود ولی حافظه آن در دسترس باقی میماند. پس زمانی که به خط کد fs[0](); میرسیم، کد داخل CODE که console.log(i); است اجرا میشود و execution context آن ایجاد میشود و چون هیچ متغیر i ای داخل آن نیست، در scope chain پایین میرود. این تابع داخل تابع buildFuncions ایجاد شده است. پس به حافظه ای که قبلا در buildFunctions execution context بوده اشاره میکند. مقدار i در آن برابر با 3 است. پس 3 را چاپ میکند. اجرا تمام میشود و execution context مربوط به آن pop میشود و سراغ خط کد بعدی یعنی fs[1](); میرود و execution context جدید برای آن ایجاد میشود. این تابع هم outer environment reference مشابه قبلی دارد چون در همان جای تابع قبلی ایجاد شده است. پس در این حالت هم مقدار i برابر با 3 میشود. برای خط کد fs[2](); هم به همین ترتیب است. هر سه این تابع ها در تابع buildFunction ایجاد شده اند، یعنی پدر آنها یکسان است. وقتی از سه فرزند سن پدرشان را بپرسیم، سن پدر را وقتی که به دنیا آمده اند نمیگویند، سن الان او را میگویند. اینجا هم سه تابع داریم که بعدا اجرا میشوند. مقدار الان متغیر را به ما میدهند، نه مقداری که موقع ایجاد شدن داشته. بنابراین خروجی برای هر سه تابع یکسان است. پس باید توجه داشته باشیم که خط کد console.log(i); همان جا که تایپ شده اجرا نمیشود، وقتی تابع invoke میشود اجرا میشود.دیدیم که وقتی fs[0](); را اجرا میکنیم هنوز به outer variable ها دسترسی دارد. این متغیرها free variable نام دارند یعنی متغیری که خارج از تابع است ولی به آن دسترسی داریم. حال اگر نخواهیم کدی که نوشته ایم به شکلی که توضیح داده شد کار کند چه کنیم؟ یعنی میخواهیم که خروجی 0 و 1 و 2 باشد. برای این کار چند روش وجود دارد. در نسخه جدید جاوااسکریپت یعنی es6 متغیر let را داریم:function buildFunctions2() {var arr = [ ];for (var i=0; i&lt;3; i++) {let j = i;arr.push( function() {console.log(j);} );}return arr;}var fs2 = buildFunctions2();fs2[0]();fs2[1]();fs2[2]();متغیر let در بلاک scope مربوط به for میشود. بنابراین هر موقع که حلقه for اجرا میشود، j یک متغیر جدید در حافظه میشود و وقتی تابع function() {console.log(j);} فراخوانی میشود، هر دفعه به یک جای متفاوت داخل آن حافظه اشاره میکند. در واقع subsegment است. پس با functionality جدید js میتوانیم کد را به صورت بالا بنویسیم. اما اگر بخواهیم با es5 این کار را انجام دهیم چه کنیم؟ برای preserve کردن مقدار متغیر i برای تابع function() {console.log(j);}، به یک execution context مجزا برای هر تابعی که در آرایه push میکنیم نیاز داریم. یعنی به یک parent scope نیاز داریم که مقدار فعلی i را در حلقه for نگه دارد. تنها راه برای داشتن یک execution context این است که تابع را اجرا کنیم. پس نیاز هست تابع function() {console.log(j);} را on the fly اجرا کنیم: IIFE:function buildFunctions() {var arr = [ ];for (var i=0; i&lt;3; i++) {arr.push( (function(j){ return function(){console.log(j);} }(i)); );}return arr;}var fs = buildFunctions();fs[0]();fs[1]();fs[2]();در کد بالا هر دفعه که حلقه for اجرا میشود تابع function(j){ return function(){console.log(j);} } اجرا میشود. اگر در حلقه مقدار i برابر با صفر باشد، صفر به تابع پاس داده میشود و هر بار که در حلقه این تابع اجرا میشود، execution context مجزا دارد و j در هر سه execution context ذخیره میشود. پس در یکی مقدار j برابر با 0 و در یکی برابر با 1 و در یکی برابر با 2 است. حتی زمانی که این execution context ها از بین میروند، به خاطر closure مقدار j در هر کدام از آنها قابل دسترس است.چرا در کد بالا به جای function(j){ return function(){console.log(j);} } فقط ننوشتیم function(j){ console.log(j); }؟ چون push میخواهد نتیجه تابع را در آرایه push کند. اجرای تابعی که نوشته ایم، یک تابع برمیگرداند. اگر فقط console.log(j); را مینوشتیم خروجی تابع برگردانده نمیشد. وقتی قسمت کد function(){console.log(j);} اجرا میشود و دنبال مقدار j میگردد نیازی نیست تا حلقه for بیرون رود، فقط به execution context مربوط به تابع function(j){ return function(){console.log(j);} } میرود. مقدار j همان موقع که در حلقه اجرا میشود ذخیره میشود. این مثالی از استفاده از فواید closure بود. این مسائل به خاطر ویژگی ها first class function و closure ها هستند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Mon, 22 Apr 2019 15:24:29 +0430</pubDate>
            </item>
                    <item>
                <title>44 - جاوااسکریپت: Immediately Invoked Functions Expressions</title>
                <link>https://virgool.io/@pazirehsarafraz/44-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-immediately-invoked-functions-expressions-ktrysgjc8sbn</link>
                <description>تفاوت بین function statement و function expression را دیدیم. function statement به عنوان یک statement جدید دیده میشود که کلمه function اولین کلمه آن است:// function statementfunction greet (name) {   console.log(&#x27;Hello &#x27;+name);   }greet(&#x27;John&#x27;);جاوااسکریپت این کد را میبیند و آن را در حافظه قرار میدهد ولی وقتی به این خط کد میرسد در واقع چیزی اجرا نمیکند و برای اجرای آن باید تابع را invoke کنیم. اما میتوانیم از function expression برای ست کردن یک متغیر مساوی با آن استفاده کنیم و یک تابع anonymous داشته باشیم:// using a function expressionvar greetFunc = function(name) {   console.log(&#x27;Hello &#x27;+name);   };greetFunc(&#x27;John&#x27;);در کد بالا قسمت function(name) {console.log(&#x27;Hello &#x27;+name);} یک expression است و ابتدا در حافظه قرار نمیگیرد. موقع اجرا وقتی به این خط از کد میرسد، این شیء تابع را on the fly ایجاد میکند. در این کد قسمت function(name) {console.log(&#x27;Hello &#x27;+name);}  به نوعی function literal است و داریم on the fly تابع میسازیم. یک کار خاص که میتونیم با تابع ها انجام دهیم و آنها را یک شیء بخصوص کرده این است که یک ویژگی CODE دارند و میتوانیم آن را invoke کنیم. میتوانیم تابع را on the fly م invoke کنیم. یعنی میتوانیم در کد بالا به جای فراخوانی greetFunc بعد از تعریف تابع، میتوانیم یک مقدار را ست کنیم و همون موقع که تابع ایجاد میشود آن را فرخوانی کنیم:// using an Immediately Invoked Function IIFE)var greetFunc = function(name) {   console.log(&#x27;Hello &#x27;+name);   }(&#x27;John&#x27;);به محض ایجاد شدن تابع، فراخوانی میشود. اگر داشته باشیم:var greetFunc = function(name) {   return &#x27;Hello &#x27;+name;   };console.log(greeting);خروجی به ما function(name) {return &#x27;Hello &#x27;+name;} را برمیگرداند. اگر بگوییم:var greetFunc = function(name) {   return &#x27;Hello &#x27;+name;   };console.log(greeting(&#x27;John&#x27;)); خروجی Hello John را برمیگرداند. اگر داشته باشیم:var greeting = function(name) {   return &#x27;Hello &#x27;+name;   }(&#x27;John&#x27;);console.log(greeting);آنچه اتفاق می افتد این است که با function expression بالا یک شیء تابع ایجاد میشود و سپس invoke میشود و مقدار آن برگردانده میشود و در greeting قرار داده میشود. بنابراین با اجرای کد بالا خروجی Hello John میدهد. بنابراین متغیر greeting مقدار تابع را ذخیره میکند، نه خود تابع را. اگر بخواهیم greeting را invoke کنیم به ما خطا میدهد: string is not a function.حتی میتوانیم IIFE را تنها هم داشته باشیم. اگر در کد بنویسیم:3;معتبر است. ; هم گذاشتیم تا مطمئن بشیم که syntax parser متوجه شده خط تمام شده است. این خط کد هیچ خطایی به ما نمیدهد. چون یک js expression معتبر است. expression فقط اجرا میشود و نیازی به ذخیره هیچ مقداری ندارد. این خط کد هم همین طور است. هیچ کاری باهاش نمیشه ولی معتبره. برای کد زیر  حاوی یک رشته همین طور است:&quot;I am a string&quot;;یا کد زیر حاوی یک شیء:{ name: &#x27;John&#x27; };فقط یک خط کد است که اجرا میشود. در مورد تابع چطور؟ اگر فقط داشته باشیم:function(name) { return &#x27;Hello&#x27;+name; }اگر بخواهم که این کد یک function expression باشید، باید on the fly ایجاد شود. اگر این کد را اجرا کنیم خطا میدهد: unexpected token (. چون syntax parser کلمه کلیدی function را اول یک خط جدید میبیند و انتظار دارد که این یک function statement باشید و منتظر یک اسم برای تابع است و نمیتواند anonymous باشد. بنابراین سینتکس بالا اشتباه است. اگر فقط یک تابع بنویسیم، یک function expression نیست بلکه یک function statement است. اما این چیزی نبود که میخواستیم. میخواستم مثل خط کد 3; فقط اونجا باشد. چطور میتوانیم به syntax parser بفهمانیم که قصد نوشتن یک function statement نداشته ایم؟ باید مطمئن شویم که کلمه function اولین چیزی که در خط جدید میبیند نباشد. چند راه برای این کار وجود دارد. اما پذیرفته شده ترین روش (به دلیل سادگی و کمترین میزان تایپ) این است که کل تابع را در پرانتز wrap کنیم:(function(name) { return &#x27;Hello&#x27;+name; })این کار را زمانی انجام میدهیم که function expression میخواهیم. پرانتز در js عملگر است. از پرانتزها فقط با expression ها کار میکنیم که مقداری را برمیگردانند. هیچ وقت داخل پرانتز statement نمیگذاریم (مثلا (if(...)) را نداریم). چون موتور js میداند که هر چیزی که داخل پرانتز باید expression باشد، فرض میکند که این تابع یک function expression است که on the fly ایجادش کرده ایم. اگر کد بالا را اجرا کنیم خطایی نمیدهد. فقط یک تابع داریم که داخل کد قرار گرفته و از آن استفاده نمیکنیم. ولی سینتکسش معتبر است.(function(name) {var greeting = &#x27;Hello&#x27;;console.log(greeting + &#x27;   &#x27; name);});حال اگر کد بالا را اجرا کنیم چه اتفاقی می افتد؟ قبلا که مثلا 3; را اجرا کردیم هیچ اتفاقی نیفتاد. اما در مورد شیء تابع چطور؟ ما میتوانیم آن را invoke کنیم. بنابراین بعد از تابع میتوانیم آن را invoke  کنیم. این هم یک IIFE است و معمولا به همین شکل IIFE را میبینیم:var firstname = &#x27;John&#x27;;(function(name) {var greeting = &#x27;Hello&#x27;;console.log(greeting + &#x27;   &#x27; name);}(firstname));یک function expression که در پرانتز wrap شده (موتور js میفهمد که یک function statement نیست و یک function expression است که وقتی کد اجرا شود on the fly ایجاد میشود) و سپس اضافه کردن () به آخر تا اجرا شود. یعنی کاملا همزمان یک تابع را ایجاد و اجرا کردیم. این یک مثال کلاسیک از IIFE است. تابع را داخل پرانتز گذاشتیم، آن را on the fly ایجاد کردیم و invoke کردیم. چنین فرمتی در هر framework یا کتاخانه اصلی استفاده میشود. این تابع on the fly ایجاد میشود و همان موقع اجرا میشود.در مورد کد بالا میتوانیم پرانتزهای مربوط به invoke کردن را داخل پرانتز اصلی یا بیرون از آن بگذاریم:(function(name) {...})(firstname);یا:(function(name) {...}(firstname));هر دوی این کدها مثل هم کار میکنند اما درست این است که قسمت invoke داخل پرانتز اصلی باشد. هر کدام از دو روش را که انتخاب میکنید، همیشه از همان استفاده کنید.45 -  جاوااسکریپت: IIFEs and Safe Codeکد IIFE زیر را در نظر بگیرید:// IIFE(function(name) {var greeting = &#x27;Hello&#x27;;console.log(greeting + &#x27;   &#x27; name);}(&#x27;John&#x27;)); // IIFEبا اجرای این کد خروجی Hello John را خواهیم داشت. میخواهیم ببنیم پشت صحنه چه اتفاقی می افتد. در execution stack چه اتفاقی می افتد؟ وقتی این کد تازه لود میشود global execution context داریم و هیچی داخل آن نیست چون هیچ متغیر یا function statement نداریم که hoisted شود. سپس وقتی به این خط از کد که یک IIFE است میرسد، به محض اینکه به قسمت function expression میرسد آن شیء تابع را در global execution context میسازد که anonymous است: () یک تابع بدون اسم با کدهایی داخلش است. سپس قسمت پرانتز (&#x27;John&#x27;) را میبیند که دارد تابع را invoke میکند. پس یک execution context جدید برای تابعی که on the fly ایجاد شده درست میشود. سپس کد داخل آن تابع خط به خط اجرا میشود. متغیر greeting هم داخل execution context variable environment ش قرار میگیرد. این متغیر به قسمت global اضافه نمیشود. چون داریم تابع را اجرا میکنیم، execution context خود تابع را داریم. بنابراین هر متغیری که داخل تابع تعریف میشود به global ارتباطی ندارد. این ویژگی باعث میشود که IIFE روش خیلی مفیدی برای کدنویسی باشد.برای مثال:var greeting = &#x27;Hola&#x27;;(function(name) {var greeting = &#x27;Hello&#x27;;console.log(greeting + &#x27;   &#x27; name);}(&#x27;John&#x27;)); این کد خروجی Hello John را میدهد. اگر در کنسول greeting را بنویسیم مقدار Hola را برمیگرداند. در این مثال global execution context بعد از اینکه اولین خط اجرا میشود، در حافظه مقدار متغیر greeting را Hola میگذارد. سپس کل IIFE دیده میشود و function expression باعث میشود که تابع ایجاد شود و (&#x27;John&#x27;) باعث میشود که invoke شود و execution context جدید ایجاد میشود. وقتی به خط اول کد داخل تابع میرسیم، مقدار متغیر greeting داخل execution context تابع برابر با Hello میشود. پس دو تا متغیر greeting در قسمت های مجزا داریم. پس مطمئن هستیم که کدی که در IIFE م wrap شده، تناقض یا تاثیری روی هیچ کد دیگری در برنامه ندارد و کدمان safe است. وقتی به کد داخل framework ها و کتابخانه ها نگاه میکنیم، اولین چیزی که بالا میبینیم یک پرانتز و function است و انتهای کد پرانتز بسته شده. این کار برای این است که کل کد را در یک IIFE م wrap کند. ما هم میتوانیم همین روش را برای کد reusable خودمان استفاده کنیم تا مطمئن باشیم کدمان با کدهای دیگر تصادمی نخواهد داشت و مطمئن باشیم که اشتباهی چیزی را داخل global object قرار نداده ایم. اما اگر بخواهیم که چیزی را در global قرار دهیم چه؟ میتوانیم این کار را با پاس دادن پارامترها انجام دهیم.همان طور که قبلا گفته شد شیء ها by reference پاس داده میشوند. پس اگر میخواهیم که به global object دسترسی داشته باشیم، آن را به تابع مان پاس میدهیم:var greeting = &#x27;Hola&#x27;;(function(global, name) {var greeting = &#x27;Hello&#x27;;global.greeting = &#x27;Hello&#x27;;console.log(greeting + &#x27;   &#x27; name);}(window, &#x27;John&#x27;)); پس در این کد یک reference به شیء global را به IIFE خود پاس دادیم. پس در این حالت میتوانیم آگاهانه و عمدی تغییری در global object ایجاد کنیم. اینجا اسمش را global گذاشتیم چون ممکن است بخواهیم که این کد روی سرور هم reusable باشد و global object همان window نباشد و چیز دیگری باشد. اسمش را global گذاشته ایم و یک reference به آن داریم. با اجرای کد بالا خواهیم داشت: Hello John و اگر در کنسول greeting را بنویسیم به ما خروجی Hello را میدهد. یعنی کد داخل تابع روی global تاثیر گذاشته. پس ممکن است شیء هایی داخل تابع ایجاد کنید و بخواهید همه جای کد قابل دسترس باشند. در این حالت میتوانیم آنها را به global object بچسبانیم، اما این کار را عمدی انجام میدهیم، نه به اشتباه. فرمت IIFE تاثیرگذاری روی global object را سخت و آگاهانه کرده تا کد ایمن باشد.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sat, 20 Apr 2019 15:55:00 +0430</pubDate>
            </item>
                    <item>
                <title>40 - جاواسکریپت: Framework, Function Overloading</title>
                <link>https://virgool.io/@pazirehsarafraz/40-%D8%AC%D8%A7%D9%88%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-framework-function-overloading-p49izwccd8pl</link>
                <description>میخواهیم ببینیم آنچه تا به حال گفته شد چگونه در framework ها یا کتابخانه های رایج به کار گرفته شده اند.یک چیزی که در js نداریم ولی خیلی از زبان های برنامه نویسی دارند function overloading است. در زبان های برنامه نویسی دیگر مثل c# و جاوا میتوانیم تابع هایی با یک اسم و با تعداد مختلف پارامتر داشته باشیم. ولی در js چنین چیزی نداریم چون در js تابع ها شیء هستند و چنین چیزی در دسترس نیست. اما مشکلی نیست چون با داشتن first class function آپشن های خیلی بیشتری داریم. اگر بخواهیم جایگزین هایی برای نحوه فراخوانی متد greet داشته باشیم، برای مثال نخواهیم همیشه پارامتر language را پاس دهیم:function greet(firstname, lastname, language) { ... }همان طور که قبلا گفته شد میتوانیم برای language مقدار پیش فرض تعیین کنیم و با منطق داخل تابع برای مقادیر مختلف language تصمیم گیری کنیم. مثلا:function greet(firstname, lastname, language) {language = language || &#x27;en&#x27;;if (language === &#x27;en&#x27;) {   console.log(&#x27;Hello &#x27;+fristname+&#x27;  &#x27;+lastname);   }if (language === &#x27;es&#x27;) {   console.log(&#x27;Hola &#x27;+fristname+&#x27;  &#x27;+lastname);   }}greet(&#x27;John&#x27;, &#x27;Doe&#x27;, &#x27;en&#x27;);greet(&#x27;John&#x27;, &#x27;Doe&#x27;, &#x27;es&#x27;);اما ممکن است نسخه دیگری از این تابع را بخواهیم که در آن لازم نباشد اطلاعات زیادی به تابع پاس دهیم. میتوانیم با ایجاد یک تابع دیگر این کار را انجام دهیم. در این تابع مقادیر پیش فرض مشخص به تابع greet پاس داده میشوند. مثلا: function greetEnglish(lastname, firstname){ greet(firstname, lastname, &#x27;en&#x27;); } function greetSpanish(lastname, firstname){ greet(firstname, lastname, &#x27;es&#x27;); }greetEnglish(&#x27;John&#x27;, &#x27;Doe&#x27;);greetSpanish(&#x27;John&#x27;, &#x27;Doe&#x27;); به جای پاس دادن پارامتر از تابعی که مقدار پیش فرض رو پاس داده استفاده کردیم. تابع های greetEnglish و greetSpanish هر دو تابع greet را فراخوانی میکنند ولی به صورت پیش فرض یک پارامتر مشخص را پاس میدهند. این یک روش برای داشتن فراخوانی های ساده تر تابع ها است. نیازی به نگرانی در مورد نداشتن امکان function overloading در js نیست چون الگوهای دیگه و حتی بهتری در js وجود دارد. یکی از این الگوها روش بالا بود. این روش در framework ها زیاد استفاده میشود تا استفاده از framework یا کتابخانه را راحتتر کند و مشخص باشد که تابع دارد چه کار میکند.41 - جاوااسکریپت: Syntax Parserکدی که مینویسیم به طور مستقیم در کامپیوتر اجرا نمیشود. بلکه یک برنامه واسطه بین کد ما و کامپیوتر وجود دارد که کد را ترجمه میکند به چیزی که کامپیوتر بتواند بفهمد. موتور js روی بروزر هم این کار را میکند. برای این کار از مفاهیم و المنت های مختلفی استفاده میکند که یکی از آنها syntax parser است که کد ما را میخواند و تشخیص میدهد آیا معتبر است یا نه و میخواهد چه کار انجام دهد. بنابراین اگر بعد از خواندن کاراکتر به کاراکتر از کد ما به حرف r برسد، فرض میکند که احتمالا میخواهیم return بنویسیم و منتظر e است. اگر چیزی ببیند که در انتظارش نباشد خطا میدهد. ولی اگر چیزی ببیند که از نظر سینتکسی معتبر باشد به خواندن کد ادامه میدهد و میداند میخواهیم چه کار کنیم. تا زمانی که به ; برسد.بنابراین تصور کنید که syntax parser که قسمتی از موتور js  است کد ما را کاراکتر به کاراکتر میخواند و فرضهایی را بر اساس قوانینش ایجاد میکند و حتی ممکن است قبل از اجرای کد، تغییراتی در کد ما ایجاد کند. پس موتور js کد ما را کاراکتر به کاراکتر میخواند و از مجموعه ای از قوانین استفاده میکند تا سینتکس معتبر را تشخیص دهد و تصمیم بگیرد که ما میخواهیم چه کار کنیم. همه اینها قبل از اجرای کد انجام میشود.42 - جاوااسکریپت: Automatic Semicolon Insertionهیچ زبان برنامه نویسی کامل و بی نقص نیست. الان میخواهیم در مورد خطری صحبت کنیم که خیلی ساده ممکن است پیش بیاید و پیدا کردن آن ممکن است خیلی سخت باشد. این خطر در مورد syntax parser در js است: اضافه کردن ; به صورت خودکار. syntax parser در js با هدف مفید بودن این کار را انجام میدهد. در هسته js استفاده از ; اختیاری است. چون موتور js در هر زمان یک کاراکتر را در statement میبیند و میداند که زبان در انتظار چی هست، یعنی میداند که سینتکس باید چه شکلی باشد. پس اگر ببیند که داریم یک خط را تمام میکنیم یعنی enter زده ایم (return و بعد enter)، میگوید در این statement خاص مجاز به رفتن به خط بعد نیستی پس خودم به طور خودکار یک ; میگذارم (return;). بنابراین هر جایی که syntax parser منتظر یک ; باشد، خودش برای ما ; میگذارد. به همین دلیل گذاشتن آن توسط ما اختیاری است.اما ما باید همیشه خودمان ; را بگذاریم. چون نمیخواهیم که موتور js برای ما تصمیم بگیرد. این مسئله در مورد کلمه کلیدی return خیلی مهم است. چون اضافه کردن ; به صورت خودکار میتواند مشکل بزرگی ایجاد کند.function getPerson() {   return   {         firstname: &#x27;Tony&#x27;   }}console.log(getPerson());اگر این کد را اجرا کنیم خروجی undefined میدهد. چون موتور js اگر کاراکتر enter را بعد از کلمه کلیدی return ببیند، خودش به طور اتوماتیک یک ; اضافه میکند. یعنی با گذاشتن object literal syntax در خط جدید باعث شدیم که موتور js تصمیم بگیرد یک ; اضافه کند. پس این خروجی را خط بعد تایپ نمیکنیم و با یک اسپیس از return تایپ میکنیم:function getPerson() {   return {         firstname: &#x27;Tony&#x27;   }}console.log(getPerson());در این حالت خودش به طور خودکار ; اضافه نمیکند. پس همیشه { را در همان خط از کد، بعد از تعریف تابع، بعد از حلقه for، بعد از if statement و ...  تایپ میکنیم. این کار همیشه ضروری نیست، اما همیشه این کار را میکنیم تا در مواقع ضروری به مشکلی برنخوریم. پس همیشه اگر بعد از return باید object literal برگردونده بشه، شیء در همان خط کد return شروع بشه. همچنین هر جا از کد که ; نیاز هست خودمان ; را میگذاریم. چون این مسئله در debug کردن خیلی مشکل است.43 - جاوااسکریپت: Whitespaceتعریف whitespace: کاراکترهای غیر قابل مشاهده که در کد نوشته شده فاصله ایجاد میکنند. مثل enter و اسپیس و tab. برای خوانایی بیشتر کد استفاده میشود و اجرا نمیشود. syntax parser در js در این مورد خیلی لیبرال عمل میکند. مثلا:var firstname, lastname, language;var person = {   firstname: &#x27;John&#x27;,   lastname: &#x27;Doe&#x27;}console.log(person);خیلی خوب است که موقع نوشتن کد از کامنت استفاده کنیم. چون js خیلی در مورد whitespace منعطف است میتوانیم به صورت زیر در کد بالا کامنت بگذاریم:var   // first name of the person   firstname,   // last name of the person   lastname,   // the language   // can be &#x27;en&#x27; or &#x27;es&#x27;   language;var person = {   // the first name   firstname: &#x27;John&#x27;,   // the last name   // (always required)   lastname: &#x27;Doe&#x27;}console.log(person);در اجرا دو کد بالا هیچ فرقی با هم ندارند. چون syntax parser از همه این whitespace ها صرف نظر میکند. وقتی source code یک کتابخانه یا framework را باز میکنیم میبینیم که از whitespace ها و کامنت ها خیلی زیاد استفاده شده است. ممکنه است مثل مثال بالا یک دفعه ببینیم که در یک خط از کد فقط یک متغیر و یک کاما ننوشته شده و قبل و بعد آن کامنتهای زیادی هست. این کامنتها به فهم راحتتر کد کمک میکند. ما هم باید تا جایی که میتوانیم در کدمان از کامنت استفاده کنیم و کد را خوانا کنیم.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Sat, 20 Apr 2019 12:05:57 +0430</pubDate>
            </item>
                    <item>
                <title>38 - جاوااسکریپت: Arrays, Collections of Anything</title>
                <link>https://virgool.io/@pazirehsarafraz/38-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-arrays-collections-of-anything-su0mpixrscmw</link>
                <description>آرایه یک مجموعه است. برای تعریف آرایه میتوانیم از دستور زیر استفاده کنیم:var arr = new Array();این روش طولانی برای تعریف آرایه است. میتوانیم از array literal syntax استفاده کنیم:var arr = [ ];در js آرایه ها کمی متفاوت هستند. چون js م dynamically typed است. در اکثر زبان های برنامه نویسی آرایه میتواند مجموعه ای از داده ها با یک نوع خاص باشد. ولی js اینطور نیست و نوع چیزها را on the fly میفهمد. پس میتوانیم هرچه میخواهیم داخل آرایه بگذاریم و آنها را مخلوط بگذاریم:var arr = [ 1,  false,  {name:&#x27;Tony&#x27;,address:&#x27;Main 111 St&#x27;},  function(name){console.log(name);},  &quot;hello&quot;];تابعی که در آرایه بالا گذاشته یک expression است چون فقط خودش تنها نیست و داخل تعریف آرایه است. js میفهمد که باید این تابع را on the fly ایجاد کند. اگر کنسول arr را ببینیم:[1, false, Object, function, &quot;hello&quot;]در این مثال اگر بخواهیم تابع را اجرا کنیم:arr[3](arr[2].name);خروجی میشه Tony. پس آرایه ها حتی میتونن شامل تابع هم باشن. این ویژگی میتواند مفید باشد.39 - جاوااسکریپت: arguments, spreadوقتی تابعی را اجرا میکنیم، موتور js کلمه کلیدی arguments رو به صورت اتوماتیک ست میکنه. چون در نسخه بعدی js زیاد از arguments استفاده نمیشود، روش جدید را که SPREAD نام دارد معرفی میکنیم.اگر به هر کدی در framework ها یا کتابخانه ها نگاه کنیم، متغیرهای arguments را میبینیم.زمانی که تابعی را اجرا میکنیم یک execution context جدید ایجاد میشود و موتور js چیزهایی را برای ما تنظیم میکند، مثل variable environment که همه متغیرها را نگه میدارد و outer environment reference برای scope chain و کلمه کلیدی this که به محل قرار گرفتن تابع و چگونگی فراخوانی آن ارتباط دارد. به غیر از اینها کلمه کلیدی دیگری را هم به نام arguments تنظیم میکند. arguments شامل یک لیست است از همه مقادیر و همه پارامترهایی که به یک تابع پاس میدهیم. یعنی arguments همه آن مقادیری را که به تابعی پاس میدهیم نگه میدارد.تعریف arguments: مفهوم آن در حالت کلی پارامترهایی است که به یک تابع پاس میدهیم. در js از کلمه کلیدی با همین نام استفاده میشود و همه آنها را شامل میشود. پس وقتی در مورد مفهوم arguments صحبت میکنیم فقط در مورد پارامترهایی که به تابع پاس داده میشود صحبت میکنیم. اما کلمه کلیدی arguments را js ایجاد کرده است.function greet(firsname, lastname, language) {console.log(firstname);console.log(lastname);console.log(language);}آنچه در js متفاوت است این است که میتوانیم تابع بالا را فقط با کد زیر فراخوانی کنیم و هیچ پارامتری به آن پاس ندهیم:greet();در زبان های برنامه نویسی دیگر این کار خطا میدهد. خروجی میشود:undefinedundefinedundefinedبنابراین hoisting آنچه با اجرای تابع اتفاق می افتد یا مقادیر را تنظیم میکند، از این پارامترها مراقبت میکند با اینکه ما هیچ مقداری بهش ندادیم. تابع greet را اجرا میکند و اولین کاری که میکند این است که فضایی از حافظه را برای firstname و lastname و language تنظیم کند و آنها را undefined بگذارد. js به این موضوع که ما هیچ مقداری به تابع ندادیم اهمیتی نمیدهد، همچنان فضای حافظه را تنظیم میکند و آن را undefined میگذارد.اگر به تابع arguments را بدهیم، از چپ به راست پردازش میشوند. پس اگر داشته باشیم:greet(&#x27;John&#x27;); فرض میکند که &#x27;John&#x27; همان firstname است و برای lastname و language چیزی پاس نداده ایم و این دو را همان undefined میگذارد.پس میتوانیم پاس دادن پارامتر به تابع را skip کنیم یا میتوانیم بخشی از لیست پارامترها را skip کنیم و js مشکلی با این کار ندارد. در نسل بعدی js این امکان را داریم که مقدار پیش فرض برای پارامترها قرار دهیم. یعنی بهش بگیم اگر مقداری داده نشد آن مقدار پیش فرض را در نظر بگیرد:function greet(firsname, lastname, language = &#x27;en&#x27;) { ... }اما این روش هنوز در همه بروزرها قابل استفاده نیست، پس میتوانیم از مفهوم پارامتر پیش فرض استفاده کنیم:function greet(firsname, lastname, language) {language = language || &#x27;en&#x27;;...}پس اگر language مقدار undefined داشته باشد و به عملگر || پاس داده شود، به false م coerce میشود و &#x27;en&#x27; به عملگر = پاس داده میشود. در این حالت اگر داشته باشیم:greet();خروجی میدهد:undefinedundefinedenو اگر داشته باشیم:greet(&#x27;John&#x27;, &#x27;Doe&#x27;, &#x27;es&#x27;);خروجی میدهد:JohnDoeesپس با این روش مقدار پیش فرض را تعیین کردیم ولی در نسخه جدید js میتوانیم مقدار پیش فرض را همون بالا جلوی پارامتر بگذاریم.کلمه کلیدی arguments را js تنظیم کرده و نیازی به تعریف کردن ندارد و قابل دسترس است. اگر داخل تابع بالا اضافه کنیم:function greet(firsname, lastname, language) {console.log(arguments);}اگر بگوییم greet(); خروجی [ ] را میدهد. اگر بگوییم greet(&#x27;John); خروجی [&#x27;John&#x27;] را میدهد. اگر بگوییم greet(&#x27;John&#x27;, &#x27;Doe&#x27;, &#x27;es&#x27;); خروجی [&#x27;John&#x27;, &#x27;Doe&#x27;, &#x27;es&#x27;] را میدهد. یعنی شامل لیستی از همه مقادیر پارامتری است که پاس داده ایم. نحوه نمایش آن شبیه به آرایه است ولی آرایه نیست و در ظاهر هم ایتالیک است و براکت نیست. به آن array-like میگوییم. یعنی شبیه به آرایه عمل میکند و ظاهرا شبیه به آرایه است ولی دقیقا یک آرایه نیست. مثلا همه ویژگی های آرایه js را ندارد. اما در خیلی از شرایط میتوانیم مثل آرایه با آن رفتار کنیم. برای مثال اگر بخواهیم وقتی پارامتری پاس داده نمیشود تابع کاری نکند، میتوانیم به اول کد تابع این را اضافه کنیم:function greet(firsname, lastname, language) {if (argument.length===0) { console.log(&#x27;missing parameters&#x27;);return; }...}پس میتوانیم بسته به تعداد آرگومانهایی که پاس داده شده اند کار خاصی انجام دهیم. اگرچه آرگومانها شامل اسم نیستند و فقط مقدار دارند، میتوانیم مثل یک آرایه از براکت استفاده کنیم و position آرگومان رو بدهیم:console.log(arguments[0]);اگر بگوییم greet(&#x27;John&#x27;); خروجی John را میدهد.هنوز arguments هنوز وجود دارد اما بهترین روش برای انجام یک کار نیست. چیز جدید پارامتر spread است. یعنی اگر پارامترهایی را که به تابع پاس داده ایم داشته باشیم، میتوانیم یک پارامتر را با فرمت ...name به آخر پارامترهای تابع اضافه کنیم:function greet(firsname, lastname, language, ...other) { ... }اگر موقع فراخوانی این تابع پارامترهای بیشتری به تابع پاس دهیم، مثل:greet(&#x27;John, &#x27;Doe&#x27;, &#x27;ed&#x27;, &#x27;Main 111 St&#x27;, &#x27;New York&#x27;);این دو پارامتر اضافه که صریحا تعریف نشده اند، در یک آرایه wrap میشوند. پس ...other یعنی همه چیز اضافی را بگیر و در یک آرایه با اسم other م wrap کن. البته این روش هم هنوز به طور کامل در دسترس نیست. ولی زمانی که در دسترس باشد، روش مناسبتری برای کار کردن با آرگومانهای متنوع است. اما هنوز از arguments استفاده های زیادی میشود.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Thu, 18 Apr 2019 20:35:46 +0430</pubDate>
            </item>
                    <item>
                <title>37 - جاوااسکریپت: Objects, Functions, this</title>
                <link>https://virgool.io/@pazirehsarafraz/37-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-objects-functions-this-nkj0czswkzzw</link>
                <description>گفتیم که تابع یک شیء است. حالا میخواهیم بدانیم که وقتی قسمت CODE تابع invoce میشود چه اتفاقی می افتد. وقتی تابعی فراخوانی میشود یک execution context جدید ایجاد میشود. شیء ای که تابع است متدها و ویژگی هایی دارد. ویژگی NAME و CODE دارد. وقتی که تابع invoce میشود، execution context ایجاد میشود و در استک execution context قرار میگیرد. پس execution context را با توجه به قسمت CODE نگاه میکنیم. وقتی کد داخل CODE را اجرا میکنیم چه اتفاقی می افتد؟ میدانیم که execution context ایجاد میشود. هر execution context یک variable environment دارد. یعنی جایی که متغیرهای داخل تابع ایجاد میشوند. همچنین reference ای به outer environment دارد. با توجه به جای فیزیکی و lexical کد تعیین میشود و scope chain را ایجاد میکند. یعنی اگر دنبال متغیری میگردیم که داخل variable environment تابع نیست، تا global environment بیرون میرود و دنبالش میگردد. همچنین موتور js هر موقع که execution context ایجاد میشود (هر موقع که تابع اجرا میشود) به ما (بدون نیاز به ایجاد کردن) متغیر this را میدهد. متغیر this بسته به اینکه تابع چگونه فراخوانی میشود به چیزی اشاره میکند.چند سناریو وجود دارد که this را تغییر میدهد، بسته به اینکه تابع چگونه فراخوانی شود و کجا قرار دارشته باشد.اگر در سطح global execution context داشته باشیم:console.log(this);به ما خروجی شیء Window را میدهد. چون در این سطح این this به global object اشاره میکند و داخل بروزر global object همان شیء Window است. حال اگر یک تابع داشته باشیم:function a() { console.log(this); }a();با فراخوانی تابع a ویژگی CODE (حاوی همه خطوط کد داخل تابع) اجرا میشود و ابتدا execution context ایجاد میشود که یکی از قسمت های آن ایجاد this است. این this داخل execution context مربوط به فراخوانی تابع a به چی اشاره میکند؟ در کنسول میبینیم که خروجی کد بالا باز هم شیء Window است. بنابراین وقتی یک تابع ایجاد میکنیم، کلمه کلیدی this داخل آن به global object اشاره میکند. همین اتفاق وقتی از function expression استفاده میکنیم هم رخ میده:var b = function() { console.log(this); }در این کد متغیر b این function expression را میگیرد تا آن را ایجاد کند. اگر این تابع را invoke کنیم باز هم خروجی Window داده میشود. بنابراین هر موقع که در این سطح از کد تابعی ایجاد کنیم (با function expression یا با function statement)، داخل این تابع ها this به global object اشاره میکند. پس حتی وقتی سه تا execution context داریم (یکی global و دو تا برای تابع های a و b)، با اینکه هر کدام از آنها یک this خودشان را دارند، اما در هر سه آنها this به یک آدرس یکسان اشاره میکند. پس همه به global object اشاره میکنند. بنابراین مثلا میتوانیم در کد تابع a اضافه کنیم:function a() {console.log(this);this.newVariable = &#x27;hello&#x27;;}متغیر newVariable را به global object مان attach کرده ایم. پس میتوانیم در سطح global از آن متغیر استفاده کنیم:console.log(newVariable);به هر متغیری که به global object مان attach شده باشد میتوانیم فقط با صدا زدن اسمش دسترسی داشته باشیم و نیازی به استفاده از عملگر . نیست. خروجی به ما hello را میدهد. پس وقتی که فقط یک تابع را invoke میکنیم، this به global variable اشاره میکند.اگر داخل شیء مقدار primitive باشد property و اگر تابع باشد method نام دارد. مثلا:var c = {   name: &#x27;The c object&#x27;,   log: function() { console.log(this); }}c.log();همان طور که گفته هر موقع که تابعی invoke شود یک execution context جدید ایجاد میشود و موتور js تصمیم میگیرد که این کلمه کلیدی باید چه چیزی اشاره کند. در مثالهای قبلی پاسخ شیء Window بود. اما در این حالت یک متد در یک تابع داریم. خروجی Object{name:&#x27;The c object&#x27;, log:function} است. در حالتی که تابع یک متد اتچ شده به یک شیء باشد، کلمه کلیدی this همان شیئی خواهد بود که آن متد داخل آن است. یعنی همان شیئی که شامل آن تابع است. پس میتوانیم داشته باشیم:var c = {   name: &#x27;The c object&#x27;,   log: function() { this.name = &#x27;updated c object&#x27;; }}c.log();و خروجی Object{name:&#x27;updated c object&#x27;, log: function} است. property شیء پدر را تغییر دادیم. شیئی که شامل تابع بود. پس اگر متدی در یک شیء باشیم، میتوانیم با کلمه کلیدی this شیء نگهدارنده را mutate کنیم. یعنی میتوانیم به property ها و متدهای دیگر همان شیء دسترسی داشته باشیم.یک نکته دیگر هم در این مورد this هست که اگر در موردش چیزی ندانیم فکر میکنیم باگ است. اما js یک زبان برنامه نویسی است و موتورهای زبان ها توسط افراد نوشته شده اند. افراد در مورد چگونگی کار کردن آنها تصمیم گرفته اند. در این مورد افراد زیادی احساس میکنند که تصمیم گیری درست انجام نشده است.فرض کنید یک تابع داخل یک متد ایجاد کرده ایم:var c = {   name: &#x27;The c object&#x27;,   log: function() {         this.name = &#x27;updated c object&#x27;;          var setName = function(newName) { this.name = newName; }         setName(&#x27;updated again&#x27;);         console.log(this);   }}c.log();در کد بالا سعی کرده ایم که شیء مان را mutate کنیم. در این کد انتظار داریم که this نوشته شده داخل setName به شیء c اشاره کند. چون این یک تابع داخل یک تابع دیگر داخل یک شیء است. همان طور که this داخل log به شیء اشاره میکند، انتظار داریم  که در یک سطح عمیقتر هم در تابع this به شیء اشاره کند. پس انتظار داریم که بعد از فراخوانی setName و گرفتن console.log اسم updated again را برای c ببینیم. اما در خروجی داریم:Object { name: &#x27;updated c object&#x27;, log: function }به نظر میرسد که setName(&#x27;updated again&#x27;); هیچ کاری انجام نداده. اما انجام داده. اگر در قسمت کنسول window را بنویسیم، شیء global پنجره را به ما نشان میدهد و به ویژگی های آن name: &#x27;updated again&#x27; اضافه شده. یعنی وقتی execution context این تابع internal ایجاد شد، کلمه کلیدی this در آن به global object اشاره میکند. حتی وقتی که داخل شیئی است که ایجاد کرده ایم. خیلی افراد فکر میکنند که این اشتباه است ولی این روشی است که js با آن کار میکند. پس در چنین سناریویی چه کار میتوانیم انجام دهیم تا مطمئن باشیم از شیء درست استفاده میکنیم و کلمه this اونطور که میخوایم اشاره میکنه؟ یک الگوی خیلی رایج در این حالت استفاده میشود. چون ما میدانیم که شیء با by reference کار میکند پس میتوانیم این الگو را بفهمیم. همان خط اول متدمان this را داخل متغیری به اسم that یا self میریزیم. با این کار یک متغیر جدید داریم به نام self و چون برابر با یک شیء قرار داده شده پس by reference است. یعنی self به همان مکانی از حافظه اشاره میکنید که کلمه کلیدی this اشاره میکند. در این خط از کد this به شیء نگهدارنده یعنی c اشاره میکند. سپس در ادامه کد به جای this از self استفاده میکنیم. حتی داخل تابعی که در آن تعریف شده:var c = {   name: &#x27;The c object&#x27;,   log: function() {         var self = this;         self.name = &#x27;updated c object&#x27;;          var setName = function(newName) { self.name = newName; }         setName(&#x27;updated again&#x27;);         console.log(self);   }}c.log();بنابراین دیگه نیازی نیست فکر کنیم آیا داریم به شیء درستی اشاره میکنیم یا نه. در setName هم که از self استفاده شده نگرانی در مورد متغیر self نداریم. self داخل این تابع تعریف نشده، پس موتور js در scope chain پایین میره. تابع setName به طور فیزیکی کجای کد نوشته شده؟ outer lexical reference آن به log برمیگردد و مقدار self را پیدا میکند. پس داخل تابع setName هم میتوانیم شیءمان را mutate کنیم. پس یک رفرنس مناسب به شیءمان تهیه کردیم: var self = this و بعد از آن ازش استفاده کردیم. پس در این حالت خروجی:Object { name: &#x27;updated again&#x27;, log: function }هیچ زبان برنامه نویسی ای بی نقص نیست و js هم استثنا نیست. اما الگوهایی وجود دارند که میتوانیم از آنها برای مدیریت مشکل زبان استفاده کنیم. این الگو که اینجا گفته شد خیلی زیاد استفاده میشود. کلمه کلیدی let که جایگزینی برای var است برخی از این مشکلات را برطرف میکند. بنابراین با در دسترس قرار گرفتن let در بروزرهای مدرن و بسته به نوع پروژه (مثلا پروژه ای که در آن نگرانی در مورد بروزرهای قدیمی نداریم) میتوانیم از آن استفاده کنیم. اما در حال حاضر همین الگو روش مناسبی است.پس دیدیم وقتی که فقط یک تابع را invoke میکنیم، کلمه کلیدی this همان global variable در global object است. وقتی که تابع یک متد از یک شیء باشد، کلمه کلیدی this به همان شیء اشاره میکند. اما هر تابع internal ای مشکلی دارد، پس میتوانیم از مفهوم مساوی قرار دادن یک متغیر با this استفاده کنیم تا مطمئن باشیم به خطایی برنمیخوریم یا به اشتباه با global object کار نکرده ایم.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Thu, 18 Apr 2019 18:02:39 +0430</pubDate>
            </item>
                    <item>
                <title>36 - جاوااسکریپت: By Value, By Reference</title>
                <link>https://virgool.io/@pazirehsarafraz/36-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-by-value-by-reference-yxmqjpddpbub</link>
                <description>در این مبحث در مورد متغیرها صحبت میکنیم. فرض کنید یک مقدار primitive داریم و یک متغیر را مساوی با آن قرار میدهیم. پس مثلا متغیر a یک آدرس 0x001 دارد که میداند مقدار primitive کجای حافظه قرار دارد. فرض کنید کد b=a را اجرا کردیم یا a را به یک تابع پاس دادیم و اسم پارامتر در تابع b است. اگر یک مقدار primitive باشد در js اتفاقی که می افتد این است که متغیر جدید b به یک آدرس جدید و یک جای جدید در حافظه مثلا 0x002، به یک کپی از مقدار primitive اشاره میکند. یعنی دو مقدار primitive در دو جای مختلف از حافظه داریم که کپی هم هستند. این شیوه called by value است. یعنی پاس دادن یا reference کردن یا مساوی قرار دادن یک مقدار به یک مقدار دیگر با کپی کردن آن مقدار.حالا اگر یک شیء در js داشته باشیم (هر نوع شیء ای مثل تابع)، وقتی متغیر a را برابر با آن شیء قرار میدهیم یک آدرس در حافظه 0x001 داریم که میداند شیء کجا قرار دارد. وقتی یک متغیر دیگر مثلا b را برابر با a قرار میدهیم، یا a را به تابعی پاس میدهیم، متغیر جدید b به جای گرفتن یک جای جدید در حافظه به همان جای حافظه 0x001 اشاره میکند که a اشاره میکرد. شیء جدیدی ایجاد نمیشود. کپی جدیدی از شیء ایجاد نمیشود. فقط دو اسم به یک آدرس اشاره میکنند. پس a و b یک مقدار دارند چون وقتی میپرسیم که مقدارشان چیست، به یک مکان یکسان در حافظه نگاه میکنند. این شیوه called by reference نام دارد.خیلی مهم است که بدانیم همه شیء ها وقتی با هم مساوی قرار داده میشوند یا به تابعی پاس داده میشوند by reference عمل میشود و اگر این را ندانیم مشکلات زیادی پیش می آید.مثلا داریم:var a = 3;var b;b = a;در این حالت هر دو متغیر a و b برابر با 3 میشوند. چون در مورد primitive type صحبت میکنیم پس by value است. پس وقتی b=a میشود عملگر = میبیند که primitive type داریم و یک جای جدید در حافظه برای b ایجاد میکند. یک کپی از مقدار a تهیه کرده و برای b ست میکند. پس b هم 3 میشود. بعد از این میتوانیم مقدار a را تغییر دهیم و تاثیری روی b ندارد.a = 2;چون دو جای مختلف در حافظه داریم. اگر در کنسول مقدار a و b را ببینیم، a برابر با 2 و b برابر با 3 است.اما مثلا اگر داشته باشیم:var c = { greeting:&#x27;hi&#x27; };var d;d = c;عملگر = میبیند که متغیرهای شیء هستند. پس به جای آنکه d به محل جدید اشاره کند، فقط d به همان آدرس و جایی از حافظه که c اشاره دارد اشاره میکند. پس c و d یک مقدار دارند ولی کپی در کار نیست. پس اگر c را mutate کنیم:c.greeting = &#x27;hello&#x27;;تعریف mutate: تغییر دادن چیزی. immutable یعنی چیزی که قابل تغییر نباشد.اگر در کنسول c و d را نگاه کنیم، هر دو Object{greeting:&#x27;hello&#x27;} شده اند. چون هر دو به یک مکان از حافظه اشاره میکنند. پس اگر تغییری در شیء ایجاد کنیم، مهم نیست از کدام اسم متغیر استفاده کنیم. بنابراین با by reference که کار میکنیم، وقتی یکی را تغییر دهیم دیگران هم تغییر میکنند. همین حالت موقع پاس دادن به تابع هم اتفاق می افتد:var c = { greeting:&#x27;hi&#x27; };var d;d = c;function changeGreeting(obj) { obj.greeting = &#x27;hola&#x27;; }changeGreeting(d);در این کد obj به همان جایی اشاره میکند که d و c اشاره میکنند. اگر در کنسول c و d را چک کنیم، هر دو Object{greeting:&#x27;hola&#x27;} شده اند.عملگر = یک فضای جدید (آدرس جدید) در حافظه میگیرد. اگر در ادامه کدهای قبل داشته باشیم: c = { greeting:&#x27;howdy&#x27; };در این حالت عملگر = داره c رو به یک مقدار جدید نسبت میده و یک فضای جدید براش ایجاد میکنه. پس دیگر c و d به یک مکان از حافظه اشاره ندارند. در کنسول مقدار c برابر با Object{greeting:&#x27;howdy&#x27;} و مقدار d برابر با Object{greeting:&#x27;hola&#x27;} خواهد بود. پس کد بالا حالت خاصی است که by reference اعمال نمیشود. چون عملگر = میبیند که سمت راستش یک مکان از قبل تعیین شده نیست و یک شیء جدید است که on the fly ایجاد شده است. پس چون پارامتر دوم عملگر = شیء ای نیست که از قبل در حافظه وجود داشته باشد، باید یک فضای جدید در حافظه برای آن در نظر گرفته شود. پس این فضا را ایجاد کرده و متغیر c به آن اشاره میکند. اما در حالت قبلی که نوشته بودیم d = c شیء c از قبل وجود داشت. پس فقط d به همان مکان اشاره میکند.در برخی زبان های برنامه نویسی میتوانیم تصمیم بگیریم که از by value یا by reference استفاده کنیم ولی در js چنین گزینه ای نداریم. همه primitive type ها by value و همه شیء ها by reference هستند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Thu, 18 Apr 2019 10:56:54 +0430</pubDate>
            </item>
                    <item>
                <title>34 - جاوااسکریپت: Functions are Objects</title>
                <link>https://virgool.io/@pazirehsarafraz/34-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-functions-are-objects-lzly5dhwgyza</link>
                <description>تعریف first class function: هر چیزی که میتوانیم با انواع دیگر انجام دهیم (شیء ها، string ها، عددها، boolean ها، ... ) با تابع ها هم میتوانیم انجام دهیم. میتوانیم یک تابع را به عنوان یک مقدار به متغیری assign کنیم. میتوانیم تابع ها را به عنوان پارامتر به تابع دیگری پاس دهیم. میتوانیم on the fly تابع ها را با literal syntax ایجاد کنیم. first class function سبک برنامه نویسی را تغییر میدهد. میتواند افق های کاملا متفاوتی را در حل مسئله ایجاد کند.وقتی میگوییم که در js تابع ها شیء هستند، یک شیء تابع چه شکلی است؟ شبیه هر شیء دیگری در js است. یک نوع خاص از شیء است. چون همه ویژگی های یک شیء نرمال را دارد و ویژگی های خاص دیگری هم دارد. یکی از چیزهایی که افراد را در مورد js سورپرایز میکند این است که میتوانیم در js به یک تابع property ها و method هایی را attach کنیم. چون تابع یک شیء است. پس میتوانیم به یک تابع یک Primitive (یعنی name/value) را attach کنیم. میتوانیم یک Object را attach کنیم. میتوانیم یک Function دیگر را attach کنیم. در js یک تابع ویژگی های دیگری هم دارد.مهم ترین ویژگی آن NAME آن است. یک تابع در js الزامی به داشتن اسم ندارد. اگر اسم نداشته باشد anonymous نامیده میشود. ولی میتواند اسم داشته باشد.یک ویژگی دیگر آن CODE است. جایی که کدها قرار گرفته اند. کدی که نوشته ایم به صورت یک ویژگی خاص از شیء تابع در می آید. پس کدی که نوشته ایم تابع نیست. تابع یک شیء است با یک سری ویژگی و کدی که نوشته ایم یکی از ویژگی های آن است. یک نکته در مورد این ویژگی این است که invocable است. یعنی میتوانیم بگوییم که کد داخل این ویژگی را اجرا کن و execution context ایجاد میشود و ....باید به تابع به چشم یک شیء نگاه کنیم که کد آن فقط یک ویژگی آن است. تابع میتواند جابجا شود و کپی شود و به المنتها یا بخش هایی از کدمان داده شود، مثل همه شیء های دیگر. مثل یک string یا یک عدد. برای اینکه از روش های حل مسئله استفاده یا سینتکس ها را متوجه شویم باید به تابع به این شکل نگاه کنیم.function greet() { console.log(&#x27;Hi&#x27;); }چون تابع یک شیء است، پس با استفاده از . میتوانیم برای آن property ایجاد کنیم:greet.language = &#x27;english&#x27;;در زبانهای برنامه نویسی دیگه چنین چیزی امکان پذیر نیست. اگر در console بخواهیم greet را ببینیم به ما text تابع را که نوشته ایم نشان میدهد:function greet() { console.log(&#x27;Hi&#x27;); }و اگر در console بخواهیم greet.language را ببینم به ما english را برمیگرداند.پس وقتی چنین تابعی را ایجاد میکنیم، یک شیء تابع در حافظه قرار میگیرد. در این مثال در global object قرار میگیرد. یک ویژگی NAME با مقدار greet دارد و یک ویژگی CODE دارد که کد داخل تابع را شامل میشود. وقتی تابع را با greet(); فراخوانی میکنیم ویژگی CODE م invoce میشود و execution context ایجاد میشود و ... . پس تابع فقط یک نگهدارنده کد نیست، یک شیء است.35 - جاوااسکریپت: Function Statements, Function Expressionsدیدیم که در js تابع شیء است. میخواهیم بدانیم چگونه js به ما اجازه میدهد کارهای جالب و قدرتمندی با مفهوم first class function انجام دهیم. ابتدا نیاز هست فرق بین تعریف و استفاده از function statement و function expression را بدانیم.تعریف expression: بخشی از کد که مقداری را برمیگرداند. الزامی به ذخیره متغیر ندارد. statement فقط کاری را انجام میدهد ولی expression مقداری را برمیگرداند.مثلا وقتی در کد فقط داریم var a; اگر به console بریم a را در حافظه داریم. اگر در همان کنسول expression م a=3; را بنویسیم، میدانیم که = یک عملگر است. یعنی یک تابع که دو مقدار a و 3 را میگیرد و یک مقدار را برمیگرداند. در این مثال 3 را برمیگرداند. اگر در همین کنسول expression دیگری مثل 1+2; را بنویسیم، + یک عملگر است که مقادیر 1 و 2 را میگیرد و آنها را با هم جمع کرده و نتیجه را برمیگرداند. با اینکه نتیجه را داخل هیچ متغیری در حافظه ذخیره نکرده ایم ولی مقدار 3 به ما برگردانده شده. این مقدار برگرداند شده میتواند string یا شیء یا ... باشد. مثلا اگر در کنسول بنویسیم a={greet:&#x27;Hi&#x27;}; مقدار Object{greet:&#x27;Hi&#x27;} برگردانده میشود.اما وقتی داریم در مورد statement صحبت میکنیم، مثل if statement، داخل پرانتز جلوی if یک expression قرار میدهیم چون مقداری را به عنوان نتیجه برمیگرداند ولی خود if statement مقداری را برنمیگرداند. مثلا نمیتوانیم بگوییم var b = if (...) { ... }. ولی داخل پرانتز آن باید expression داشته باشیم.در js چون تابع ها شیء هستند، هم function statement و هم function expression داریم. مثلا میخواهیم یک function statement تعریف کنیم:function greet() { console.log(&#x27;Hi&#x27;); }وقتی این تابع اجرا میشود مقداری را نتیجه نمیدهد. تابع در حافظه قرار دارد اما فقط یک statement است و تا زمانی که اجرا نشود مقداری برنمیگرداند. پس وقتی کد تابع را میبینیم یعنی تابع را در حافظه قرار دادیم ولی این تکه کد مقداری را نتیجه نمیدهد ولی کارهای خاصی را انجام میدهد، hoisted میشود و در مرحله execution در execution context در حافظه قرار میگیرد و میتواند در دسترس قرار بگیرد. میتوانیم greet را قبل از تعریف آن در کد فراخوانی کنیم. یعنی در حافظه در دسترس است.حالا میخواهیم از یک function expression استفاده کنیم:var anonymousGreet = function() { console.log(&#x27;Hi&#x27;); };چون در js تابع یک شیء است میتوانیم کد را به صورت بالا بنویسیم. پس در کد بالا داریم یک شیء رو on the fly ایجاد میکنیم و آن را به متغیر anonymousGreet مان assign میکنیم. این متغیر قسمتی از حافظه است که به آدرسش اشاره میکند. با این کد این متغیر حاوی یک شیء تابع است.در function statement بالا وقتی execution context ایجاد میشد تابع در حافظه قرار میگرفت و ویژگی NAME و CODE داشت. وقتی آن را فراخوانی میکردیم به آن قسمت از حافظه که تابع بود متصل میشد و قسمت CODE را فراخوانی میکرد. اما در function expression یک عملگر = داریم که این تابع را در حافظه قرار میدهد و اشاره میکند به آدرس متغیر anonymousGreet. به اسم تابع نگاه نمیکند، فقط آدرس را در حافظه میداند. پس در این حالت هم موتور js یک شیء تابع ایجاد میکند ولی در این حالت NAME نداریم (anonymous) چون قبل از پرانتز چیزی قرار نداده ایم و لزومی هم به این کار نیست، چون متغیری داریم که میداند تابع کجا هست. پس به اسمی نیاز ندارم که با آن ارجاع دهیم. پس anonymous function تابعی است که در ویژگی NAME ش اسمی ندارد و با اسم یک متغیر به آن ارجاع میدهیم. ولی همان ویژگی CODE را دارد. برای فراخوان این تابع نیاز هست به شیء اشاره کنیم و به آن بگوییم کد را اجرا کند: anonymousGreet(); متغیر به جایی که تابع هست اشاره میکند و با گذاشتن پرانتز کد را invoce میکنیم.در کدvar anonymousGreet = function() { console.log(&#x27;Hi&#x27;); };قسمت function() { console.log(&#x27;Hi&#x27;); } یک function expression است چون یک مقدار نتیجه میدهد. این قسمت قابل اجراست. اما در کد function greet() { console.log(&#x27;Hi&#x27;); }فقط function statement داریم. چون وقتی کد اجرا میشود حتی با اینکه تابع در حافظه وجود دارد، این قسمت از کد در مرحله execution اجرا میشود. واقعا کاری نمیکند، فقط میگوید که یک تابع آنجا هست. ولی وقتی خطvar anonymousGreet = function() { console.log(&#x27;Hi&#x27;); };اجرا میشود، قسمتfunction() { console.log(&#x27;Hi&#x27;); }در آن باعث ایجاد یک شیء میشود و یک تابع را برمیگرداند. پس یک expression است.اشتباه نیست اگر برای تابع زیر اسم بگذاریم:var anonymousGreet = function greet() { console.log(&#x27;Hi&#x27;); };ولی کار اضافی است. کد خوب باید شفاف و قابل فهم و در عین خلاصه باشد.حالا اگر خط های کد را جابجا کنیم:anonymousGreet ();var anonymousGreet = function() { console.log(&#x27;Hi&#x27;); };میدانیم که execution context ایجاد میشود و سپس اجرا میشود. ابتدا function statement ها و متغیرها را در حافظه قرار میدهد و سپس کد را خط به خط اجرا میکند. پس خروجی کد بالا: undefined is not a function. در اینجا موتور js یک متغیر میبیند و متغیر را در حافظه قرار میدهد. قبل از شروع اجرای کد مقدار متغیرها را undefined میگذارد و سپس شروع به اجرای کد میکند. وقتی به خط anonymousGreet(); میرسد میگوید که آن را در حافظه دیده و undefined بوده. در این خط با پرانتز خواسته ایم که کد تابع را اجرا کند، پس js به ما میگوید که undefined تابع نیست. پس function expression ها hoisted نیستند. چون فقط متغیر را hoisted میکند و متغیر تا قبل از اجرا شدن آن خط از کد حاوی شیء تابع نیست. پس حتما باید اول از عملگر = استفاده کنیم تا در حافظه قرار بگیرد و سپس آن را فراخوانی کنیم.ولی وقتی در کد داریم:greet();function greet() { console.log(&#x27;Hi&#x27;); }تابع hoisted است. یعنی وقتی موتور js کلمه function را میبیند میفهمد که تابعی ایجاد کردیم و آن را در حافظه قرار میدهد. پس greet(); را اجرا میکند و میبیند که در حافظه وجود دارد. سپس به function statement میرسد و کاری نمیکند.یک تابع را با function statement ایجاد کرده ایم:function log(a) { console.log(a); }مثلا log(3) را اجرا میگیریم. متغیر 3 را on the fly ایجاد کرده ایم. مثلا قبلش نگفتیم var b = 3; و بعد log(b);. خروجی 3 میشود. اگر log({greeting:&#x27;Hi&#x27;}); را اجرا بگیریم در خروجی Object{greeting:&#x27;Hi} داریم. در اینجا هم پارامتر شیء را on the fly ایجاد کردیم و به تابع log پاس دادیم. همان طور که گفتیم تابع یک شیء است و یک function expression یک شیء on the fly ایجاد میکند. پس میتوانیم این کار را انجام دهیم: log( function(){ console.log(&#x27;Hi&#x27;); } );تابع را on the fly ایجاد کردیم. خروجی به ما متن تابعی که نوشتیم را میدهد: function(){ console.log(&#x27;Hi&#x27;); }. این یک تابع anonymous است اما با پارامتر a به آن ارجاع میدهیم.پس first class function باعث میشود که تابع پاس داده شود یا on the fly ساخته شود یا متغیری برابر با تابع قرار داده شود. در مثال بالا یک تابع را به تابعی پاس دادیم و a دارد به تابع اشاره میکند. پس برای اجرای تابعی که به log دادیم از a(); استفاده میکنیم:function log(a) { a(); }log( function(){ console.log(&#x27;Hi&#x27;); } );وقتی در خط دوم log را فراخوانی میکنیم و با function expression یک تابع به آن پاس میدهیم، یک تابع همانجا ایجاد کرده ایم. پس a یک تابع شده و به جایی که این شیء هست اشاره میکند. سپس با a(); کد اجرا میشود.پس یک function statement داریم که در حافظه در مرحله creation execution context م hoisted میشود. یک function expression داریم که قسمت از عملگر = است و در متغیری قرار میگیرد و برای فراخوانی تابع از آن متغیر استفاده میکنیم. و یک function expression داریم که به یک تابع دیگه به عنوان پارامتر پاس میدهیم. این ویژگی first class function است که میتوانیم تابع را به تابع دیگری پاس دهیم یا از آن مثل یک متغیر استفاده کنیم و از سبک جدید برنامه نویسی به نام functional programming استفاده کنیم.پس چنین خط کدی:log( function(){ console.log(&#x27;Hi&#x27;); } );همان function expression است و به خاطر first class function چنین امکانی وجود دارد. چون تابع ها در js شیء هستند.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Wed, 17 Apr 2019 14:33:52 +0430</pubDate>
            </item>
                    <item>
                <title>33 - جاوااسکریپت: JSON, Object Literals</title>
                <link>https://virgool.io/@pazirehsarafraz/33-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-json-object-literals-zbth5sdmruzg</link>
                <description>کلمه JSON مخفف JavaScript Object Notation است. چون از notation در js الهام گرفته است. خیلی شبیه سینتکس object literal است اما کاملا با آن یکسان نیست.var objectLiteral = { firstname:&#x27;Mary&#x27;, isAProgrammer:true };console.log(objectLiteral);در سالهای قبل داده در اینترنت با فرمت های متنوعی فرستاده میشد. از فرمت xml مدتی استفاده شد. xml شبیه کد زیر بود:&lt;object&gt;&lt;firstname&gt;Mary&lt;/firstname&gt;&lt;isAProgrammer&gt;true&lt;/isAProgrammer&gt;&lt;/object&gt;سرور این اطلاعات رو میگرفت و آن را parse میکرد. مشکل این بود که وقتی زمان دانلود برایمان مهم است، مقدار band استفاده شده و مقدار داده مهم است، در xml از کاراکترهای اضافی غیرضروری خیلی زیادی استفاده میشود که باعث میشود حجم داده ارسالی زیادتر شود. همین که اسم property دو بار نوشته میشود باعث میشود که اگر با داده های زیادی کار کنیم، مقدار wasted download bandwidth خیلی زیاد شود. پس برای حل مشکل از js notation استفاده شد. پس به جای کد بالا در xml از کد زیر استفاده شد:{ firstname:&#x27;Mary&#x27;, isAProgrammer:true }امروزه از فرمت JSON برای انتقال داده استفاده میکنیم. پس فقط یک string از داده است که شبیه سینتکس object literal است. البته تفاوت هایی هم دارد. برای مثال property ها باید در &quot; &quot; گذاشته شوند:{ &quot;firstname&quot;:&quot;Mary&quot;, &quot;isAProgrammer&quot;:true }خط بالا یک سینتکس معتبر برای object literal است. یعنی در js هم میتوانیم اسم property ها را داخل &quot; &quot; بگذاریم. ولی داخل JSON حتما باید این کار را بکنیم وگرنه معتبر نیست. بنابراین JSON به صورت تکنیکی یک زیرمجموعه از object literal syntax است. یعنی هرچه که در JSON معتبر باشد در js object literal syntax هم valid است، اما نه برعکس. پس JSON واقعا بخشی از js نیست. اما چون خیلی رایج است و فهم آن برای js ساده است، js برخی built-in functionality هایی دارد که این دو را به هم ترجمه کند. پس برای هر شیء در js یک ویژگی built-in در js داریم که میتواند تبدیل کند شیء js را به JSON string:var objectLiteral = { firstname:&#x27;Mary&#x27;, isAProgrammer:true };console.log( JSON.stringify(objectLiteral) );این کد شیء js را به یک رشته JSON تبدیل میکند که مثلا میتوانیم به سرور بفرستیم. خروجی:{ &quot;firstname&quot;:&quot;Mary&quot;, &quot;isAProgrammer&quot;:true }و اگر یک رشته JSON داشته باشیم میتوانیم با JSON.parse آن را بگیریم و به شیء js تبدیل کنیم:var jsonValue = JSON.parse( &#x27;{ &quot;firstname&quot;:&quot;Mary&quot;, &quot;isAProgrammer&quot;:true }&#x27; );console.log(jsonValue);در این کد یک رشته معتبر در JSON گرفته شده و یک شیء برگردانده شده. خروجی:Object{ firstname:&quot;Mary, isAProgrammer:true&quot; }پس JSON و js object literal دو چیز مختلف هستند. js برخی utility هایی دارد تا این دو را به هم ترجمه کنیم. ولی این دو یکی نیستند. JSON بیشتر strict است و حتما باید اسم ها در &quot; &quot; باشند. ترجمه این دو به هم خیلی راحت است برای وقتی که میخواهیم داده ای را از کلاینت در بروزر به سرور push کنیم یا وقتی میخواهیم مثلا با اجرای node.js (که js را روی سرور اجرا میکند) داده ای را از سرور بگیریم.</description>
                <category>pazirehsarafraz</category>
                <author>pazirehsarafraz</author>
                <pubDate>Wed, 17 Apr 2019 11:57:34 +0430</pubDate>
            </item>
            </channel>
</rss>