<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های بیژن حجازی</title><link>https://virgool.ir/feed/@bizhan.he1996</link><description>سلام! نوشتن به منزله مطالعه «خود» هست. من بیشتر تو زمینه برنامه نویسی و روان شناسی مطلب میذارم. خوشحال میشم نظرات تون رو باهام در میون بذارین.</description><language>fa</language><pubDate>2026-11-10 19:23:21</pubDate><image><url>https://files.virgool.ir/upload/users/1415684/avatar/LhgETX.jpg</url><title>بیژن حجازی</title><link>https://virgool.ir/@bizhan.he1996</link></image><item><title>تکنیک Destructuring در JavaScript</title><link>https://virgool.ir/Rocket/تکنیک-destructuring-در-javascript-ufzivvqbnn8i</link><description>با استفاده از Destructuring می تونیم عناصر یک array یا مقادیر یک object رو به صورت متغیر های جدا ذخیره کنیم.مقدمهبا استفاده از تکنیک Destructuring در JavaScript می تونیم خیلی راحت عناصر یک آرایه یا مقادیر یک object رو توی متغیر های جدا ذخیره کنیم. این ویژگی که در ES6 معرفی شد باعث میشه کدمون کوتاه و خوانا تر بشه. در ادامه مقاله به بررسی مفصل این ویژگی نسبتا جدید JS می پردازیم.راهکار قدیمیفرض کن که یک آرایه داریم با ۵ عنصر. حالا میخایم که هر عنصر رو در قالب یک متغیر جدا ذخیره کنیم. به صورت کلاسیک می تونستیم این طوری بگیم:const items = [1, 2, 3, 4, 5];&#xA;let one = items[0];&#xA;let two = items[1];&#xA;let three = items[2];&#xA;let four = items[3];&#xA;let five = items[4];اگه به جای آرایه، object داشتیم هم این طوری می شد:const user = {&#xA;    name: &#39;Bizhan&#39;,&#xA;    family: &#39;Hejazi&#39;,&#xA;    age: 26,&#xA;    gender: 1&#xA;};&#xA;let name = user.name;&#xA;let family = user.family;&#xA;let age = user.age;&#xA;let gender = user.gender;Array Destructuringدر ورژن های جدید JS با استفاده از Destructuring می تونیم کد های بالا رو در یک خط بنویسیم. به کد زیر دقت کن:const items = [1,2,3,4,5];&#xA;[one, two, three, four, five] = items;کد بالا دقیقا همون کاری رو میکنه که با راهکار قدیمی سعی کردیم انجام بدیم. به عبارتی این کد آرایه items رو destructure میکنه و مقادیر عناصرش رو در متغیر های one تا five قرار میده. حالا اگه فقط مقادیر ۱ و ۲ رو میخاستیم چی؟! خیلی راحت این طوری:[one, two] = items;کد بالا مقادیر ۱ و ۲ رو به ترتیب در متغیر های one و two قرار میده و بقیه عناصر آرایه رو بی خیال میشه. می تونیم یک عنصر رو هم skip کنیم. این طوری:[one, , three] = items;کد بالا مقدار ۱ رو داخل متغیر one قرار میده. دومین عنصر آرایه items رو skip میکنه و بی خیالش میشه و سومین عنصر آرایه که ۳ هست رو داخل متغیر three قرار میده. ترکیب Array Destructuring با Rest Syntax خیلی قدرتمند میشه. این طوری می تونیم هر چیزی که مونده (rest تو زبان انگلیسی یعنی بقیه) رو هم توی یک متغیر دیگه ذخیره کنیم. به کد زیر دقت کن:[one, two, ...others] = items;کد بالا مقادیر ۱ و ۲ رو داخل متغیر های one و two قراره میده و مقادیر ۳ و ۴ و ۵ رو داخل متغیر others قرار میده (هر چی که باقی مونده از items). دقت کن که متغیر others آرایه خواهد شد در حالی که متغیر های one و two عدد معمولی هستند. استفاده از اون سه تا نقطه قبل از others اشاره میکنه که این متغیر باید هر چی مونده رو توی خودش جمع کنه. متغیری که قراره rest عه باید آخرین متغیر باشه.با استفاده از Array Destructuring متغیر هایی مثل one و two در مثال های ما به window می چسبن که این استاندارد نیست. یعنی اگه بگی  هم می بینی که مقدار ۱ رو داره!Object Destructuringداستان Destructuring برای object ها هم تکرار میشه. در object ها به جای element های ساده جفت های key: value داریم. از اون جایی که value برای ما ارزشمنده object destructuring مقادیر رو برای ما destructure میکنه. به کد زیر دقت کن:const user = {&#xA;    name: &#39;Bizhan&#39;,&#xA;    family: &#39;Hejazi&#39;,&#xA;    age: 26,&#xA;    gender: 1,&#xA;    city: &#39;Tabriz&#39;&#xA;};حالا میخایم که مقادیر (values) شئ بالا رو توی متغیر های جدا ذخیره کنیم. راهکار قدیمی رو که اول این مقاله توضیح دادیم. ولی راهکار مدرن خیلی راحت تره:({name, family, age, gender, city} = user);در این صورت مقدار Bizhan داخل متغیر name، مقدار Hejazi داخل متغیر family، مقدار 26 داخل متغیر age، مقدار ۱ داخل متغیر gender و مقدار Tabriz داخل متغیر city ذخیره میشه. نام این متغیر ها باید با نام key متناظرشون در object یکی باشه. در این جا هم متغیر ها به window می چسبن که استاندارد نیست. اگه کل value های object رو نمیخاستی هم هیچ ایرادی نداره. می تونی فقط key های مد نظرت رو بیاری (مثل همون آرایه ها:({name, family} = user);در این جا هم می تونی با استفاده rest operator جفت های key: value باقی مانده رو بگیری و تو یک متغیر برای خودت ذخیره کنی. جنس این متغیر object خواهد شد. به کد دقت کن:({name, family, ...other} = user);کد بالا مقادیر Bizhan و Hejazi رو داخل متغیر های name و family قراره میده به ترتیب و بقیه جفت های key: value رو (شامل age, gender, city) داخل متغیر other قرار میده که یک object عه. در این جا هم متغیر rest باید آخرین متغیر باشه.Spread Operatorحالا که صحبت از rest operator شد فرصت بسیار مناسبی هست که از spread operator هم صحبت کنیم. بر خلاف rest که مقادیر باقی مونده رو جمع میکنه، عملگر spread یک مقدار متجمع (مثلا یک آرایه رو) پخش میکنه. از نظر ظاهری دقیقا همون سه نقطه است. به مثال دقت کن:const nums = [1, 2, 3]&#xA;console.log(Math.max(nums));    // NaNدر کد بالا میخایم بزرگترین عنصر آرایه nums رو به دست بیاریم. برای به دست آوردن max متدی به همین نام روی object ای از پیش تعریف شده به نام Math هست ولی مشکل این جاست که این متد آرایه دریافت نمیکنه بلکه هر عنصر رو به صورت یک پارامتر دریافت میکنه. خوب ممکنه بگی می شد این طوری کد زد:console.log(Math.max(nums[0],nums[1],nums[2]));ولی اومدیم و طول آرایه مون رو دقیقا نمی دونستیم. باید راهی پیدا کنیم که عناصر آرایه رو پخش کنیم. یعنی به جایی درون یک آرایه متجمع باشن به صورت مقادیر مستقل عمل کنن. این کاریه که عملگر spread (تو انگلیسی یعنی پخش کردن) برامون انجام میده. این طوری باید کد بزنیم:console.log(Math.max(...nums));کد بالا آرایه nums رو تبدیل به ۳ مقدار جداگانه میکنه (آرایه رو پخش میکنه) که هر کدوم به صورت یک پارامتر به تابع max روی Math داده میشن.  این داستان برای object ها هم هست. فرض کن که object ای داریم به صورت زیر:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    family: &#39;hejazi&#39;,&#xA;    gender: 1&#xA;};حالا میخایم object دیگری درست کنیم به نام advancedUser که همه key های object عه user رو داره و یک سری key هم اضافه داره. می شد این طوری بگیم که:const advancedUser = {&#xA;    name: user.name,&#xA;    family: user.family,&#xA;    gender: user.gender,&#xA;    type: &#39;admin&#39;,&#xA;    city: &#39;Rasht&#39;&#xA;};ولی با استفاده از spread operator می تونیم این کار رو خیلی راحت تر انجام بدیم. این طوری:const advancedUser = {&#xA;    ...user,&#xA;    type: &#39;admin&#39;,&#xA;    city: &#39;Rasht&#39;&#xA;};در این حالت فرقی نداره که spread operator رو در ابتدا، وسط یا انتها استفاده کنیم. می شد این طوری هم گفت مثلا:const advancedUser = {&#xA;    type: &#39;admin&#39;,&#xA;    ...user,&#xA;    city: &#39;Rasht&#39;&#xA;};از جمله کاربرد های اصلی spread operator کپی کردن آرایه ها و object هاست. از اون جایی که مقادیر پیشرفته مثل object و array ها در JS به اصطلاح Pass By Reference میشن به صورت عادی نمیشه کپی شون کرد. یعنی مثلا:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    family: &#39;hejazi&#39;&#xA;};&#xA;const copy = user;در کد بالا دو متغیر user و copy هر دوشون به یک object اشاره میکنن و هر تغییری که روی user انجام بدیم روی copy هم اثر میذاره. یعنی در واقع چیزی کپی نشده. سابق بر این باید برای کپی کردن این کارو میکردیم:const copy = Object.assign({}, user);ولی با استفاده از spread operator کارمون خیلی راحت تر میشه. این طوری کد میزنیم:const copy = {...user};این داستان برای کپی کردن آرایه ها هم تکرار میشه:const odds = [1, 3, 5, 7, 9];&#xA;const copy = [...odds];هم چنین در بسیاری از موارد برای تبدیل مقادیر به آرایه واقعی میشه از عملگر spread استفاده کرد. مثلا فرض کن میخایم یک string رو به array تبدیل کنیم به طوری که هر کاراکتر در string بشه یک element در array. سابق بر این باید این طوری کد میزدیم:let name = &#39;bizhan&#39;;&#xA;const array = name.split(&#39;&#39;);ولی با استفاده از spread میشه گفت:const array = [...&#39;bizhan&#39;];نتیجه گیریمباحث جدید در JavaScript این زبان رو شیرین و راحت تر میکنه. JS به معنای واقعی کلمه یک زبان زنده است که از زمان تولدش تا الان خیلی رشد کرده و دائما پیشرفته تر شده. تکنیک های Destructuring و Rest و Spread رو اگه در کنار هم دیگه یاد بگیری خیلی برات راحت تر میشه درکشون. در نهایت ازت ممنونم که برای خوندن این مطالعه وقت گذاشتی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sun, 17 Jul 2022 00:42:09 +0430</pubDate></item><item><title>تابع fetch در JavaScript</title><link>https://virgool.ir/Rocket/تابع-fetch-در-javascript-q7z2h2jk0t1t</link><description>با استفاده از تابع fetch دیگه نیازی به xhttp نیست!مقدمهسابق بر این عادت کرده بودیم برای ارتباط با سرور از AJAX و XMLHttpRequest استفاده کنیم. این روش در زمان خودش انقلاب بزرگی بود. مرورگر های مدرن امروزی راهکار راحت تری هم برای ارتباط با سرور ارائه میدن. این راهکار که fetch API نام داره با استفاده از تابع fetch و از طریق HTTP با سرور ارتباط برقرار می کنه. این طوری می تونیم HTTP Verb هایی مثل GET, POST, DELETE و ... رو صرف کنیم.درخواست GETبذار مستقیم بریم سر کد! با استفاده از fetch می تونیم این طوری اطلاعات رو از یک آدرس GET کنیم:const url = &#39;https://api.dictionaryapi.dev/api/v2/entries/en/cool&#39;;&#xA;fetch(url).then(response =&gt; {&#xA;    return response.json();&#xA;}).then(response =&gt; {&#xA;    console.log(response);&#xA;});از اون جایی که fetch یک Promise بر می گردونه (واسه مطالعه بیشتر در مورد promise ها این مقاله رو بخون) از متد های then استفاده میکنیم تا وقتی که Promise مون به وضعیت fulfilled رسید response اومده از سمت سرور رو parse کنه (هر چند اسم متد json هست ولی در عمل برعکس کار میکنه) و مجددا پاس بده به then بعدی. همین کد رو میشد این طوری نوشت :let url = &#39;https://api.dictionaryapi.dev/api/v2/entries/en/cool&#39;;&#xA;const response = await fetch(url);&#xA;object = await response.json();&#xA;console.log(object);درخواست POSTواسه درخواست هایی مثل POST و یا DELETE و امثالهم باید یک پارامتر دومی هم به تابع fetch بدیم که یک object هست متشکل از مخلفات request مثل headers و body و امثالهم. به کد زیر دقت کن:const url = &#34;https://reqres.in/api/users&#34;&#xA;fetch(url, {&#xA;    method: &#39;POST&#39;,&#xA;    headers: {&#xA;        &#39;Content-Type&#39;: &#39;application/json&#39;&#xA;    },&#xA;    body: JSON.stringify({&#xA;        name: &#39;bizhan hejazi&#39;,&#xA;        moveis: [&#34;I Love You Man&#34;, &#34;Role Models&#34;]&#xA;    })&#xA;})&#xA;.then(response =&gt; response.json())&#xA;.then(object =&gt; console.log(object))در کد بالا قسمتی که bold شده همون object ای هست که به عنوان پارامتر دوم به تابع fetch میدیم. این object جزئیات درخواست به صورت مفصله. حتما دقت کن که body این object رو تبدیل به JSON کردیم. اگه این کارو نکنیم درست عمل نمیکنه. مجددا همین کد بالا رو می شد این طوری هم نوشت:const url = &#34;https://reqres.in/api/users&#34;&#xA;const response = await fetch(url, {&#xA;    method: &#39;POST&#39;,&#xA;    headers: {&#xA;        &#39;Content-Type&#39;: &#39;application/json&#39;&#xA;    },&#xA;    body: JSON.stringify({&#xA;        name: &#39;bizhan hejazi&#39;,         &#xA;        moveis: [&#34;I Love You Man&#34;, &#34;Role Models&#34;]&#xA;    })&#xA;});&#xA;const object = await response.json();&#xA;console.log(object);نتیجه گیریمتد fetch در نهایت ساده بودن می تونه بسیار کار راه انداز باشه. کتاب خونه هایی مثل Axios هم هستن که کم و بیش مشابه همین fetch کار میکنن ولی استفاده از این کتاب خونه ها تو پروژه های بزرگ اهمیت پیدا میکنه. به object دوم تابع fetch که جزئیات request رو در بر داره میشه خیلی key:value های دیگه هم داد که تو این مقاله توضیح ندادم (واسه مطالعه بیشتر می تونی به این لینک سر بزنی). در نهایت یادت باشه که fetch توسط مرورگر های مدرن پشتیبانی میشه (یعنی IE بدون شک ازش پشتیبانی نمیکنه).</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Mon, 11 Jul 2022 17:44:10 +0430</pubDate></item><item><title>متد های call, bind و apply در JavaScript</title><link>https://virgool.ir/@bizhan.he1996/متد-های-call-bind-و-apply-در-javascript-pdccakx76dfz</link><description>متد های call, bind و apply مقدار this تعریف شده یک متد رو عوض میکنن.مقدمهبرای درک این ۳ متد کاربردی در JavaScript باید پیش از هر چیزی معنی this در موقعیت های مختلف رو بدونیم (واسه مطالعه بیشتر درباره this به این مقاله مراجعه کن). با استفاده از این ۳ متد میتونیم از متد های Object های دیگه روی Object های خودمون استفاده کنیم. بهترین روش واسه فهم این ۳ متد مثاله که در ادامه مقاله بهش می پردازیم.متد ها به عنوان Objectهمون طوری که میدونیم متد (Method) یعنی function ای که به یک Object تعلق داره. جنس متد ها و function ها در JavaScript برابر با function عه. یعنی typeof شون میشه function.// a simple function&#xA;const my_function = function() {&#xA;    console.log(&#34;This is my function.&#34;);&#xA;}&#xA;console.log(typeof my_function);    // &#39;function&#39;&#xA;&#xA;// a simple object&#xA;const my_object = {&#xA;    name: &#39;bizhan&#39;,&#xA;    family: &#39;hejazi&#39;,&#xA;    fullName: function() {&#xA;        console.log(this.name + &#39; &#39; + this.family);&#xA;    }&#xA;}&#xA;console.log(my_object.fullName);    // &#39;function&#39;اما function ها هم در حقیقت object هستن. در JavaScript تقریبا هر چیزی یک object عه و حتی اگر مستقیما هم object نیست میشه مثل object باهاش رفتار کرد. چون که function ها هم prototype دارن پس در واقع object هایی هستن که از روی prototype شون نوشته شدن. اگه شک داری می تونی کد زیر رو اجرا کنی:Object.getPrototypeOf(my_function);    // {}همون طوری که دیدی پروتوتایپ (واسه درک مفهوم پروتوتایپ ها در JavaScript می تونی این مقاله رو بخونی) تابعی که در بالا تعریف کردیم یک object خالی عه.متد callخوب حالا که متوجه شدیم هر متدی خودش یک object عه که از روی پروتوتایپ اش درست شده، پس بیراه نیست اگر توقع داشته باشیم که یک سری متد هم از پروتوتایپ اش به ارث برده باشه. یکی از متد هایی که function ها به ارث میبرن call هست. این متد از ما یک object دریافت میکنه و این object رو به متدی که از روش call رو صدا زدیم تزریق میکنه. متوجه نشدی؟! طبیعیه. بذار مثال زیر رو بررسی کنیم. به کد زیر دقت کن:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    family: &#39;hejazi&#39;,&#xA;    fullName: function() {&#xA;        return this.name + &#39; &#39; + this.family;&#xA;    }&#xA;}&#xA;console.log(user.fullName);در کد بالا object ای رو داریم که با استفاده از متد fullName اش نام کامل user رو تولید میکنه. داخل این متد کلیدواژه this رو داریم که به خود این object اشاره میکنه. حالا فرض کن که یک object دیگه میسازیم به صورت زیر:const admin = {&#xA;    name: &#39;Hazhir&#39;,&#xA;    family: &#39;Dehestani&#39;&#xA;}خوب در کد بالا object ای به نام admin درست کردیم که property های name و family رو داره، ولی مثل user در بالا متد fullName رو نداره. می تونیم متد fullName رو برای این یکی هم تعریف کنیم، ولی چرا دوباره نویسی کنیم؟! یکی از اصول خیلی مهم برنامه نویسی اصل DRY عه که یعنی: Don&#39;t Repeat Yourself. یعنی همش کد های خودت رو تکرار نکن. یک جوری کد بنویس که یک بار بنویسی و هزار بار استفاده کنی. در برابر اصل DRY، روش خطایی هست به نام WET که مخفف Write Everything Twice عه. یعنی طوری کد بنویسی که همش یک چیزی رو دوباره نویسی کنی. در مثال بالا اگه برای admin هم بخایم دوباره متد fullName رو تعریف کنیم WET کردیم. متد call به ما این توانایی رو میده که متد fullName عه user رو برای admin صدا بزنیم! دیگه چی بهتر از این میخای؟! این طوری:console.log(user.fullName.call(admin));    // Hazhir Dehestaniبذار به زبان خیلی ساده تری برای متد call رو توضیح بدم. متد call مصداق this در تعریف fullName رو عوض میکنه. توی تعریف fullName منظور از this خود object ای بود که fullName روش تعریف شده. ولی متد call باعث میشه که این this تبدیل به object ای بشه که به call دادیم.پارامتر هاخوب حالا اومدیم و متدی که میخایم call رو روش اعمال کنیم parameter هم داشت. مثلا به کد زیر دقت کن:const user = {&#xA;    name: &#39;Bizhan&#39;,&#xA;    family: &#39;Hejazi&#39;,&#xA;    intro: function(age, city) {&#xA;        return this.name + &#39; &#39; + this.family + &#39; is &#39; + age + &#39; from &#39; + city;&#xA;    }&#xA;}&#xA;console.log(user.fullName(26, &#39;Shiraz&#39;));    // Bizhan Hejazi is 26 from Shiraz;اگه بخایم متد call رو روی متد intro صدا بزنیم و object دیگری رو بهش بدیم تکلیف age و city چی میشه؟! هیچی! خیلی راحت age و city رو هم بعد از admin و به ترتیب به متد call میدیم! این طوری:const admin = {&#xA;    name: &#39;Behrad&#39;,&#xA;    family: &#39;Azizi&#39;&#xA;}&#xA;console.log(user.intro.call(admin, 28, &#39;Tabriz&#39;));    // Behrad Azizi is 28 from Tabrizمتد applyمتد apply هم شبیه به متد call عه با این تفاوت که پارامتر های اضافی رو به صورت یک آرایه میگیره. اگه برای همین مثال بالا میخایم به جای call از apply استفاده کنیم باید این طوری می گفتیم:console.log(user.intro.apply(admin, [28, &#39;Tabriz&#39;]));متد apply به خصوص در ترکیب با آبجکت Math به کار میاد. فرض کن آرایه ای از اعداد داریم و میخایم max و min این اعداد رو حساب کنیم. روی آبجکت Math در JavaScript متد های min و max هست. اگه فقط متد call رو داشتیم باید تک تک عنصر های آرایه مون رو به صورت دستی به متد call می دادیم (که عملا غیر ممکنه) ولی با استفاده از متد apply خیلی راحت خود آرایه رو میدیم. به کد زیر دقت کن:const nums = [1,5,12,98, 234, -1, 0, 54.2];&#xA;console.log(Math.min.apply({}, nums));در قسمت bold شده کد بالا اولین پارامتری که به متد apply دادیم یک آبجکت خالی عه. ولی چه نیازی هست یک object خالی بدیم؟ چون متد min اصلا با this کاری نداره و هر کاری میکنه با پارامتر هایی هست که میگیره اما برای این که متد apply قاطی نکنه یک آبجکت خالی دادیم. میشد null یا undefined هم بدیم به جای object خالی. دومین پارامتر هم که آرایه اعدادمونه. اگه میخاستیم همین کارو با متد call بکنیم باید می گفتیم:console.log(Math.min.call({}, 1,5,12,98,234,-1,0,54.2));که خوب طبیعتا متد apply خیلی راحت تره. متد bindهمون طوری که در ابتدای این مقاله گفتیم هر function ای در JavaScript در حقیقت یک object عه. تفاوت اش با بقیه object ها در اینه که callable هست. یعنی اگه جلوش () قرار بدیم، صداش کردیم تا رسالتش رو انجام بده. اگر هم جلوش () قرار ندیم بدون صدا زدن ازش استفاده کردیم. یکی از مواقعی که بدون صدا زدن یک function ازش استفاده میکنیم، موقعی هست که یک function رو به عنوان callback به function دیگری میدیم. callback ها function هایی هستند که بدون () به function های دیگه میدیمشون تا وقتی که function دریافت کننده callback کارش تموم شد، جلوی callback پرانتز بذاره و صداش بزنه. به کد زیر دقت کن:const user = {&#xA;    name: &#39;Bizhan&#39;,&#xA;    family: &#39;Hejazi&#39;,&#xA;    fullName: function() {&#xA;        console.log(this.name + &#39; &#39; + this.family);&#xA;    }&#xA;}&#xA;&#xA;setTimeout(user.fullName, 3000);    // undefined undefinedدر کد بالا متد fullName از user رو به تابع setTimeout دادیم تا ۳ ثانیه بعد از اجرای کد این متد رو صدا بزنه. در این جا user.fullName رو به عنوان یک callback به تابع setTimeout دادیم. ولی مشاهده میکنیم که بعد از ۳ ثانیه به جای Bizhan Hejazi برای ما undefined undefined پرینت میگیره! چرا؟!دلیلش اینه که متد fullName رو به صورت منفرد و جدا از object اش به setTimeout دادیم. در تعریف fullName از کلیدواژه this استفاده شده که منظور ازش user هست ولی وقتی که متد رو به صورت انفرادی به عنوان یک callback میدیم به setTimeout دیگه object ای نداره! انگاری یتیم شده باشه. تکلیف چیه؟!تکلیف اینه که با استفاده از متد bind بیایم و user رو به متد fullName بچسبونیم تا هر جایی که به عنوان callback ازش استفاده کردیم، object اش رو هم به خودش چسبونده باشه. این طوری:user.fullName = user.fullName.bind(user);حالا دیگه خیلی سفت و سخت مقدار this رو برای متد fullName مشخص کردیم. این طوری هر جایی که به صورت انفرادی هم بره this اش رو فراموش نمیکنه. حالا اگه مجددا این متد رو به عنوان callback به setTimeout بدیم بعد از ۳ ثانیه برامون Bizhan Hejazi پرینت میکنه.نتیجه گیریاگه متد های call و apply و bind رو درک کنی، میشه گفت که سواد JavaScript ات در حد بالایی قرار داره چرا که پیش نیاز درک این ۳ متد، درک Prototyping در JavaScript، درک Callback ها و شئ گرایی (OOP) هست که این ۳ تا هم از مباحث پیشرفته حساب میشن. این ۳ متد در کنار هم دیگه انعطاف پذیری بی مثالی به JavaScript میدن که بدون شک یکی از رمز های ماندگاری این زبانه. وقتی که JavaScript به بازار عرضه شد شاید کسی تصورش رو هم نمی کرد که تا این حد محبوب بشه ولی در عمل دیدیم که تبدیل به یکی از محبوب ترین و پرکاربرد ترین زبان های جهان شده و هر روز هم داره قوی تر میشه.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sun, 10 Jul 2022 12:20:18 +0430</pubDate></item><item><title>کلیدواژه async در JavaScript</title><link>https://virgool.ir/@bizhan.he1996/کلیدواژه-async-در-javascript-rupvns4kgw1w</link><description>کلیدواژه async یک تابع رو مجبور میکنه که Promise‌ برگردونه.مقدمهبرای درک عمیق کلیدواژه async در JavaScript باید مسیر نسبتا طولانی ای رو طی کنیم. داستان از تفاوت بین کد های Synchronous و Asynchronous شروع میشه. بعدش باید در باره Promise ها مطالعه کنیم و در انتهای داستان متوجه میشیم که async در حقیقت یک میانبر برای کار کردن با Promise هاست. به این میانبر ها میگن Syntactic sugar. یعنی در پشت صحنه چیزی فرق نمیکنه ولی نوشتن کد برای برنامه نویس راحت تر میشه.کد synchronous و asynchronousترجمه واژه synchronous میشه «همزمان». همون طوری که میدونیم زبان های برنامه نویسی خط به خط خونده میشن و در نهایت کل کد در لحظه و در یک زمان اجرا میشه. به این میگن کد synchronous. در مقایسه با کد همزمان، کد غیر همزمان یا همون asynchronous رو داریم. این کد هر چند خط به خط خونده میشه ولی خط به خط اجرا نمیشه. بذار با یک مثال توضیح بدم. در کد زیر یک کد همزمان رو مشاهده میکنید که خط به خط، به ترتیب از بالا به پایین خونده و اجرا میشه:let a = 1;&#xA;let b = 2;&#xA;console.log(a);    // 1&#xA;console.log(b)     // 2کد بالا خیلی ساده بود. حالا کد پایین رو نگاه کن. در کد پایین که به صورت asynchronous نوشته شده هر چند برنامه به صورت خط به خط خونده میشه، ولی به صورت خط به خط اجرا نمیشه. بخشی از برنامه در یک زمان اجرا میشه و بخش دیگری که asynchronous هست در زمان دیگری اجرا میشه.let a = 1;&#xA;let b = 2;&#xA;setTimout(()=&gt;console.log(a), 1000);&#xA;console.log(a);&#xA;a = 10;&#xA;console.log(a);قسمتی از کد که bold کردیم asynchronous هست چون ۱۰۰۰ میلی ثانیه بعد از این که بقیه قسمت های کد اجرا شدن، اجرا میشه. به همین دلیل غیر همزمان بودن اجرای این قسمت از کد در مقایسه با بقیه قسمت های کد میگن asynchronous بودن. حالا به نظر شما بعد از ۱۰۰۰ میلی ثانیه خروجی خط bold شده چه خواهد بود؟! ۱ یا ۱۰؟ شاید باعث تعجب بشه ولی خروجی ۱۰ خواهد بود! چرا که قسمت a = 10 زودتر از خط bold شده اجرا میشه و مقدار a رو عوض میکنه. زمانی که بعد از ۱۰۰۰ میلی ثانیه خط bold شده میخاد اجرا بشه دیگه مقدار متغیر a تغییر کرده. به همین دلیله که کد نویسی به صورت asynchronous چالش های بیشتری داره. باید حواسمون باشه با توجه به این تاخیر در اجرا شدن کد asynchronous متغیر ها مقدارشون عوض نشه.مفهوم Promiseخوب حالا که با مفهوم asynchronous آشنا شدیم می تونیم Promise ها رو درک کنیم. واژه promise در انگلیسی یعنی «قول». در JavaScript هم promise «قول» ای هست که داده میشه. بذار با یک مثال توضیح بدم:فرض کن میری رستوران و غذا سفارش میدی. آماده شدن غذا طول میکشه. رستوران بهت یک دونه buzzer (از این دایره هایی که وقتی غذات آماده میشه بوق میزنه) میده و میگه فعلا این دست شما باشه تا ما داریم غذا رو آماده میکنیم. این جا رستوران به جای این که غذای اصلی رو به شما بده یک buzzer به شما داده که به عنوان «قول» هست. شما هم پای میز پیشخوان وای نمیستین تا غذا آماده بشه و دریافت کنین! میرین با buzzer پشت میز میشینین بقیه کاراتون رو انجام میدین تا buzzer بوق بزنه.به این ها میگن buzzerتوی برنامه نویسی هم promise همین طوری عمل میکنه. فرض کن میخای از سمت سرور یک سری اطلاعات دریافت کنی. دریافت اطلاعات طول میکشه. به همین دلیل یک فرآیند asynchronous عه. JavaScript نمیاد و بگه خوب پس من صبر میکنم تا اطلاعات از سمت سرور دریافت بشه و بعدش میرم بقیه کد رو اجرا میکنم. اومدیم و اجرای کد asynchronous تا شب طول کشید! به جای این کار یک promise دریافت میکنه و میره بقیه قسمت های کد رو بدون درنگ اجرا میکنه.در مثال بالا دریافت اطلاعات از سمت سرور همون دریافت غذا از رستوران، promise همون buzzer ای هست که رستوران به ما میده و JavaScript هم خود شما هستین که صبر نمیکنین پای پیشخوان رستوران تا غذا آماده بشه بلکه میرین سر میز میشینین و بقیه کاراتون رو انجام میدیم تا اون buzzer خودش بوق بزنه.کد نویسی Promise هااز نظر کد نویسی Promise ها object هایی هستند که با استفاده از تابع سازنده Promise درست شده و یک سری method و property روی خودشون دارن (مثل هر object دیگری). در صورتی که نتیجه نهایی (مثلا دریافت اطلاعات از سمت سرور) به صورت موفقیت آمیز حاصل بشه یک callback رو اجرا میکنن و در صورتی که هر مشکلی وسط داستان پیش بیاد هم یک callback دیگه ای رو صدا میکنن. این callback ها که به ترتیب resolve و reject نام دارن به صورت پیش فرص توسط خود JavaScript تعریف شدن و نیازی نیست به صورت دستی تعریف شون کنیم.const promise = new Promise((resolve, reject) =&gt; {&#xA;    resolve();    // if successful&#xA;    reject();    // if error&#xA;});وضعیت Promise هابذار برگردیم به مثال مون. اون buzzer که از رستوران گرفته بودی رو یادته؟! اون buzzer سه تا وضعیت می تونه داشته باشه: زمانی که میگیریش و منتظری که غذات آماده بشه.زمانی که غذات آماده میشه و چراغ میزنه.زمانی که به هر دلیلی درست کردن سفارشت به مشکل بر می خوره (مثلا رستوران کاهو تموم کرده !) و میان ازت معذرت خواهی میکنن و buzzer رو پس میگیرن!توی JavaScript هم Promise ها سه تا وضعیت (state) مشابه دارن:در حال کار (pending): یعنی promise هنوز داره صبر میکنه تا حاصل نهایی به دست بیاد.انجام شده (fulfilled): حاصل نهایی حاضر شده و promise ازش آگاه هست. حالا میتونیم با حاصل نهایی هر کاری دوست داریم بکنیم. مثلا پرینتش کنیم.پس زده شده (rejected): به هر دلیلی حاصل نهایی نتونسته حاضر بشه و promise دستش تو پوست گردو مونده. حالا باید با این وضعیت ناگوار دست و پنجه نرم کنیم.متد های then و catchدسترسی مستقیم به وضعیت promise ها ممکن نیست. به جاش یک سری متد روی آبجکت promise هست که ما می تونیم باهاشون کار کنیم. مثلا تابعی در browser ها هست به نام fetch که از یک آدرس اینترنتی اطلاعاتی رو برای ما دریافت میکنه. این تابع به صورت پیش فرض یک promise بر می گردونه که متد های مد نظر ما روش هست. یکی از این متد ها then هست که یک callback دریافت میکنه. این callback هر زمان که وضعیت promise به fulfilled عوض بشه صدا زده میشه. متد بعدی catch هست که اون هم یک callback دریافت میکنه. این callback زمانی صدا زده میشه که وضعیت promise به rejected عوض شده باشه. به کد زیر دقت کن:fetch(&#39;https://api.dictionaryapi.dev/api/v2/entries/en/smash&#39;).then(response =&gt; {&#xA;    console.log(response);&#xA;});کد بالا از آدرسی که نوشته شده قراره که یک object دریافت کنه. تا زمانی که این object دریافت نشده باشه تابع fetch به ما یک promise بر می گردونه. promise ها متدی دارن به نام then که یک callback دریافت میکنه. این callback در صورتی اجرا میشه که promise به وضعیت fulfilled برسه. در کد بالا هم وقتی که پاسخ از سمت URL داده شده دریافت بشه arrow function ای که داخل متد then به عنوان callback دادیم اجرا میشه و response رو برای ما log میکنه. متد then ها در نهایت promise بر میگردونه. این یعنی دقیقا بعد از آوردن متد then می تونیم متد catch رو هم برای مدیریت error زنجیر وار بنویسیم:fetch(&#39;https://api.dictionaryapi.dev/api/v2/entries/en/smash&#39;).then(response =&gt; {&#xA;    console.log(response); &#xA;}).catch(error =&gt; {&#xA;    console.error(error);&#xA;});الگو کد نویسی بالا چیزی هست که هنگام کار کردن با کتاب خونه هایی مثل Axios دائما باهاش سر و کار داریم و خیلی راهگشاست.کلیدواژه asyncخوب حالا که این همه صحبت کردیم تازه رسیدیم به اصل داستان. کلیدواژه async یک میانبره. این کلیدواژه رو قبل از تعریف توابع میذارن تا به صورت خودکار اون تابع Promise برگردونه. اگر قرار بود بدون کلیدواژه async کار کنیم برای برگردوندن یک promise از یک تابع باید این طوری کد میزدیم:function getData() {&#xA;    const promie = new Promise((resolve, reject) =&gt; {&#xA;        // any other code goes here&#xA;    });&#xA;    return promise;&#xA;}ولی با استفاده از کلیدواژه async خیلی راحت این طوری کد میزنیم (واسه راحت تر شدن از کد های ساده استفاده کردم):async function getData(url) { &#xA;    return `${url} is ready`;&#xA;}در کد بالا ظاهرا مقداری که توسط تابع return میشه یک string عه ولی کلیدواژه async باعث میشه مقدار return شده توسط تابع به صورت اتوماتیک یک promise باشه.کلیدواژه awaitاین کلیدواژه باعث میشه که اجرای قسمتی از کد درون یک تابع که با کلیدواژه async اعلان شده تا حاصل شدن نتیجه نهایی promise متوقف بشه. این طوری می تونیم خیلی راحت تر کد های asynchronous رو مدیریت کنیم. فرض کن که داریم از سمت سرور یک سری اطلاعات دریافت میکنیم و قصد داریم که حاصل رو داخل HTML نمایش بدیم. فرض کن بدون استفاده از کلیدواژه await این طوری کد بزنیم:async function changeHTML() {&#xA;    let promise = new Promise((resolve, reject) =&gt; {&#xA;        resolve(&#34;All OK.&#34;);&#xA;    });&#xA;    document.querySelector(&#34;#demo&#34;) = promise;&#xA;}در کد بالا همون طوری که قبلا هم گفتیم JavaScript نمیاد صبر کنه تا نتیجه promise مشخص بشه و بعدش خط bold شده رو اجرا کنه. پس وقتی که به خط bold شده میرسه هنوز نتیجه promise مشخص نیست. حالا که نتیجه promise مشخص نیست پس چی داخل demo# نمایش بدیم؟باید راهی باشه که اجرا کد رو تا نهایی شدن نتیجه promise متوقف کنیم. این راهکار کلیدواژه await عه. کافیه خط bold شده کد بالا رو این طوری تغییر بدیم: document.querySelector(&#34;#demo&#34;) = await promise;کلیدواژه await باعث میشه که function های async برای نهایی شدن حاصل یک promise صبر کنن. این در عمل یعنی اجرا کد داخل async function متوقف میشه تا اون promise حاصل نهاییش مشخص بشه.نتیجه گیریجاوا اسکریپت زبان زنده ای هست که از زمان تولدش تا الان تغییرات زیادی کرده. کلیدواژه های async و await در سال 2017 معرفی شدن و کار کردن با promise ها رو در JavaScript خیلی راحت تر کردن. این طوری عملا همه چیز به پشت صحنه میره و توسط خود JavaScript مدیریت میشه. در نهایت از وقتی که برای مطالعه این مقاله گذاشتی خیلی متشکرم.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Thu, 07 Jul 2022 02:15:18 +0430</pubDate></item><item><title>کلیدواژه this در javaScript</title><link>https://virgool.ir/@bizhan.he1996/کلیدواژه-this-در-javascript-bajdjv15lc8z</link><description>در JS کلیدواژه this به یک object اشاره میکنه.مقدمهتقریبا هر چیزی توی JS یک object به حساب میاد. حتی function ها و class ها هم در نهایت object هستن. در بسیاری از اوقات لازمه که به object جاری، یعنی object ای که داریم روش کار می کنیم اشاره کنیم. این جاست که کلیدواژه this مطرح میشه. در بقیه زبان ها هم کلیدواژه های مشابهی هست. مثلا در PHP از this$ استفاده میشه. در JS بر اساس جایی که کلیدواژه this رو استفاده میکنیم، به object های مختلفی اشاره میکنه. this درون یک class معنی متفاوتی داره در مقایسه با this داخل یک event. در ادامه مقاله به بررسی معانی مختلف this در JS می پردازیم.شئ سراسری (Global Object)میدونیم که JavaScript داخل مرورگر و یا با استفاده از node اجرا میشه و این محیط ها هم object های خودشون رو دارن. زمانی که this رو به صورت ساده داخل console مرورگر (واسه ورود به console می تونی F12 رو بزنی) تایپ میکنیم و enter میزنیم به ما آبجکت window رو بر می گردونه. window همون global object در مرورگر هاست. در node هم زمانی که this رو تایپ میکنیم به ما یک object بر می گردونه که همون global object محیط node هست.console.log(this);داخل functionزمانی که داخل یک function کلیدواژه this رو استفاده میکنیم هم مجددا منظورمون global object هست. البته این تا زمانی درسته که از use strict استفاده نکرده باشیم. در حالت use strict مقدار this در یک تابع برابر با undefined خواهد بود.با توجه به معنی this داخل function ها دو تابع زیر عملکرد برابری با هم خواهند داشت:function hello() {&#xA;    window.alert(&#39;hello&#39;);&#xA;}&#xA;function hello() {&#xA;    this.alert(&#39;hello&#39;);&#xA;}تابع سازنده (Constructor Function)توابع سازنده، توابعی هستند که یک object رو میسازند و به صورت خودکار return اش میکنن. در خود JS چندین تابع سازنده داخلی داریم مثل String, Number و امثالهم. کلیدواژه this در توابع سازنده به معنی object ای هست که این توابع قصد ساختنش رو دارن. به کد زیر دقت کن:// Construction function&#xA;function Person(name){&#xA;    this.name = name;&#xA;}&#xA;// Instantiating&#xA;const user = new Person(&#39;bizhan&#39;);&#xA;console.log(user.name);    // &#39;bizhan&#39;شاید برات سوال پیش بیاد که خوب بالاخره تابع سازنده هم یک تابعه. پس چرا معنی this در تابع سازنده با تابع ساده فرق داره؟! جواب اینه که وقتی از روی تابع سازنده میخایم یک شئ درست کنیم باید از کلیدواژه new (که تو کد بالا bold اش کردم) استفاده کنیم. این طوری JS متوجه میشه که این تابع یک تابع سازنده است و منظور از this در اون با توابع ساده فرق داره.داخل object literalاول این مقاله ذکر کردیم که تقریبا هر چیزی در JS یک object حساب میشه. البته منظور از این object با object literal که با استفاده از { } اعلانش میکنیم دقیقا یکسان نیست. object الزاما به معنی object literal نیست و مفهوم خیلی وسیع تری داره. به مثال زیر دقت کن:let age = new Number(26);&#xA;console.log(typeof age);    // &#39;object&#39;همون طوری که می بینی جنس age در کد بالا object عه. حالا به کد زیر دقت کن:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    age: 26&#xA;};&#xA;console.log(typeof user);    // &#39;object&#39;مجددا در این کد هم جنس user برابر با object عه. پس متوجه شدی که برای درست کردن یک object الزامی به استفاده از { } نداریم. در JS در اکثر مواقع منظور ما از object متغیری هست که با استفاده از { } اعلان شده. وقتی درون یک object (به عبارت دقیق تر درون یک object literal) از کلیدواژه this استفاده میکنیم، منظورمون خود اون object هست. به کد زیر دقت کن:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    family: &#39;hejazi&#39;,&#xA;    fullName: function() {&#xA;        return this.name + &#39; &#39; + this.family;    &#xA;    }&#xA;}&#xA;console.log(user.fullName());    // &#39;bizhan hejazi&#39;در کد بالا متد (تابعی که متعلق به یک object باشه رو میگن متد) fullName برای تولید نام کامل user از کلیدواژه this استفاده میکنه. از اون جایی که this درون یک object به معنی خود اون object هست پس this.name یعنی نام کاربر. داخل classاز ورژن ES6 به بعد میتونیم با استفاده از کلیدواژه class مثل زبان های معروف دیگه در JavaScript هم class اعلان کنیم. البته این کلیدواژه صرفا میانبری برای Prototyping عه و در پشت صحنه هنوز هم از پروتوتایپ ها استفاده میشه (واسه مطالعه بیشتر درباره پروتوتایپ ها این مقاله رو بخون). درون یک class کلیدواژه this به معنای object ای خواهد بود که قراره از روی این کلاس درست بشه. به کد زیر دقت کن:class Person {&#xA;    constructor(name, family) {&#xA;        this.name = name;&#xA;        this.family = family;&#xA;    }&#xA;    fullName() {&#xA;        return this.name + &#39; &#39; + this.family;&#xA;    }&#xA;}&#xA;const user = new Person(&#39;bizhan&#39;,&#39;hejazi&#39;);&#xA;console.log(user.fullName());    // &#39;bizhan hejazi&#39;داخل eventدر یک event معنی this آبجکتی هست که event رو دریافت کرده. برای درک بهتر این مورد به کد زیر دقت کن:&lt;button =&#34;console.log(this)&#34;&gt;Click on Me&lt;/button&gt;در کد بالا منظور از this عنصر button هست. با استفاده از this در event ها می تونیم همون عنصری که روش کلیک شده (یا هر event دیگری) رو به عنوان یک object درون JS دریافت کنیم و اعمال مد نظرمون رو روش انجام بدیم. مثلا در کد بالا می شد عنصری که روش کلیک شده رو پنهان کرد یا مثلا رنگ پس زمینه اش رو عوض کرد و غیره.نتیجه گیریانعطاف پذیری JS در همه گوشه و کنار این زبان قابل لمسه. در مورد کلیدواژه this هم این نکته کاملا ملموسه. حالا که با this آشنا شدی بهتره بدونی که متد هایی مثل call, apply و bind می تونن معنی this رو برای یک متد عوض کنن. این طوری می تونیم از متد یک object روی object دیگری استفاده کنیم تا از دوباره نویسی کد خودداری بشه. در حوصله این مقاله نیست که این ۳ متد رو توضیح بده ولی بد نیست که در موردشون یک مطالعه داشته باشی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Mon, 04 Jul 2022 17:55:34 +0430</pubDate></item><item><title>پروتوتایپ در javaScript</title><link>https://virgool.ir/Rocket/پروتوتایپ-در-javascript-rjatje4ramub</link><description>جاوا اسکریپت از Prototype برای پیاده سازی inheritance استفاده میکنه.مقدمهپروتوتایپ در زبان انگلیسی یعنی نمونه اولیه. مثلا وقتی که میخای یک محصولی رو به سرمایه گذار عرضه کنی میگن که یک پروتوتایپ ازش ارائه بده تا بررسی بشه. در برنامه نویسی هم Prototype مفهوم مشابهی داره ولی هر وقت گفتن prototype در jS چیه و چی نیست از این فرمول استفاده کن: prototype یک key رو Function object هاست. تمام! اگه این طوری به پروتوتایپ نگاه کنی درکش برات راحت تر میشه. در ادامه این مقاله به بررسی مفهومی پروتوتایپ می پردازیم.ارث بری (Inheritance)در برنامه نویسی (فرقی هم نداره کدوم زبان) مفهوم ارث بری (inheritance) نمود های مختلفی داره. مثلا وقتی یک class رو از روی کلاس دیگری extend می کنیم، کلاس فرزند (Child class) ویژگی ها (property) و متد های کلاس والد (Parent) رو به ارث می بره. جاوا اسکریپت از Design Pattern ای استفاده می کنه (در ES6 به بعد jS کلاس ها رو هم اضافه کرد ولی استفاده از کلیدواژه class در jS هم در واقع راه دیگری برای پروتوتایپ کردن عه) به نام Prototyping که یعنی object ای رو از روی object دیگری clone کرد.شئ (Object)بیا یک بررسی دقیق تر داشته باشیم که object یعنی چی اصلا. در زبان انگلیسی object یعنی یک شئ واقعی که تو جهان فیزیکی وجود داره. مثلا ماشین، درخت، دیوار ... در برنامه نویسی هم تقریبا هر چیزی یک object حساب میشه. البته ممکنه این object ها مفاهیم انتزاعی باشن. مثلا یک Account هر چند که وجود فیزیکی نداره ولی توی برنامه نویسی می تونیم object اش رو داشته باشیم. jS از Prototyping برای درست کردن object ها استفاده میکنه. یعنی به جای درست کردن object ها از روی یک class، آبجکت ها از روی object دیگری درست میشن. مجددا تاکید میکنم که از سال 2015 به بعد و با معرفی ES6 جاوا اسکریپت توانایی اعلان کردن class و درست کردن object از روی class رو به خودش اضافه کرد. ولی این راهکار هم در واقع مسیر دیگری هست برای پروتوتایپ کردن و در عمل چیزی فرق نکرده.کلون کردن (Cloning)منظور از clone کردن درست کردن یک object از روی object دیگری هست. به عبارتی object ای که جدیدا ایجاد کردیم از روی prototype اش (که اونم یک object عه) درست بشه. به کد زیر دقت کن:const user1 = {&#xA;     name: &#39;Bizhan&#39;,&#xA;     family: &#39;Hejazi&#39;,&#xA;     age: 26&#xA;}; &#xA;// cloning user2 from user1 &#xA;const user2 = Object.create(user1);در مثال بالا اگه user2 رو console.log کنیم یک object با یک object خالی رو به رو میشیم:console.log(user2);اما اگر سعی کنیم که به ویژگی name روی user2 دسترسی پیدا کنیم با مقدار Bizhan رو به رو خواهیم شد !!! خوب چطوری ممکنه که یک object رو وقتی console.log می کنیم خالی باشه ولی درونش یک ویژگی هم موجود باشه که مقدار خاصی داشته باشه؟! console.log(user2.name);همون طوری که گفتیم user2 از روی user1 کلون شده. پس به عبارتی پروتوتایپ user2 برابر است با user1. این قضیه رو می تونیم با کد زیر متوجه بشیم:console.log(Object.getPrototypeOf(user2))&#xA;// {name: &#39;Bizhan, family:&#39;Hejazi&#39;, age: 26} و همون طوری هم که گفتیم مفهوم inheritance در prototyping هم وجود داره. پس user2 هر چند که خودش property ای به نام name نداشت ولی چون که این property در prototype اش موجود بود بهش به ارث رسیده. در حقیقت زمانی که ما گفتیم user2.name رو برامون console.log کنه مفسر jS این گام ها رو پیموده تا به ما خروجی بده:اول نگاه میکنه به خود object که آیا property ای به نام name وجود داره یا نه.اگر داشت که پرینت میکنش ولی اگر نداشت میره سراغ پروتوتایپ اش که در مثال ما میشه user1اگر پروتوتایپ object مون ویژگی name رو داشت که پرینتش میکنه، اگر نه مجددا میره سراغ پروتوتایپِ پروتوتایپ. (چون خود user1  هم یک object عه و پس باید یک prototype داشته باشه)و این چرخه همین طوری ادامه داره تا اولین پروتوتایپ (که میشه Object.prototype)به مفهوم بالا میگن Prototype Chain که یعنی زنجیره ای از پروتوتایپ ها. دقیقا برای همینه که در jS می تونیم یک رشته رو به صورت primitive اعلان کنیم ولی از متد های پروتوتایپ String.prototype استفاده کنیم. به مثال زیر دقت کن:const name = &#39;bizhan&#39;;&#xA;console.log(name.length);در مثال بالا متغیر name یک متغیر عینی عه (به عبارتی literal عه). یعنی فقط مقدار داره. پس اگه literal عه چطوری مثل یک object باهاش برخورد کردیم و حتی property ای ازش به نام length رو پرینت کردیم؟! دلیلش اینه که وقتی جلوی یک literal نقطه میذاریم مفسر jS به صورت خودکار این مقدار ساده رو تبدیل به object ای میکنه که از روی prototype مرتبط درست شده باشه. مثلا در کد بالا name رو تبدیل به object ای میکنه که از روی پروتوتایپ String درست شده باشه و چون روی این پروتوتایپ ویژگی length هست پس مشکلی پیش نمیاد. اگر میخاستیم به صورت دستی از همون اول به جای literal string یک object string اعلان می کردیم باید این طوری می گفتیم:const name = new String(&#39;bizhan&#39;);ولی این عادت جالبی نیست و سرعت اجرای کد رو کاهش میده. از طرفی ممکنه باعث ایجاد خطا های ناخواسته باشه. مثلا دو تا متغیر که هر دو تا شون string literal هستن (یعنی به صورت ساده و با استفاده از &#34; یا &#39; اعلان شدن) می تونن با هم دیگه مقایسه بشن ولی وقتی که دو تا object string داریم حتی اگه مقدارشون هم دقیقا برابر باشه مقایسه شون نتیجه false میده. چرا؟! چون object ها با هم قابل مقایسه نیستن.// Literal strings&#xA;const name1 = &#39;bizhan&#39;;&#xA;const name2 = &#39;bizhan&#39;;&#xA;console.log(name1 === name2);    // true&#xA;&#xA;// Object strings&#xA;const name3 = new String(&#39;bizhan&#39;);&#xA;const name4 = new String(&#39;bizhan&#39;);&#xA;console.log(name3 === name4);    // falseتابع سازنده (Constructor)حالا که با object string ها آشنا شدیم وقتشه با constructor function ها آشنا بشیم. به کد زیر دقت کن:const name = new String(&#39;bizhan&#39;);در کد بالا String دقیقا چیه؟! شاید فکر کنی که یک class عه. ولی همون طوری که میدونیم jS از prototype استفاده میکنه به جای class. شاید هم بگی که پس یک prototype عه که نشون میده نزدیک شدی ولی دقیق نگفتی هنوز. در کد بالا String دقیقا یک constructor function عه. یعنی تابعی که یک object رو میسازه. در jS به صورت پیش فرض Constructor function هایی داریم مثل: Number, Boolean, String, Array و ... ولی می تونیم constructor function خودمون رو هم اعلان کنیم تا باهاش object های مد نظرمون رو بسازیم. به روایت دیگه به جای این که یک object رو با استفاده از Object.create کلون کنیم با استفاده از تابع اختصاصی خودش درست کنیم. در کد زیر یک تابع سازنده رو اعلان کردیم:function Person(name) {&#xA;    this.name = name;&#xA;    this.sayHello = function() {&#xA;        console.log(&#39;Hello&#39;);&#xA;    }&#xA;}به عنوان یک عادت خوب اسم توابع سازنده رو با حروف بزرگ شروع کن. حالا در کد زیر یک object رو با استفاده از این تابع سازنده درست میکنیم:const bizhan = new Person(&#39;bizhan&#39;);&#xA;console.log(bizhan.name);&#xA;bizhan.sayHello();از طرف دیگه میدونیم که یک function در jS خودش یک object عه! یادته که گفتم تقریبا هر چیزی توی jS یک object حساب میشه. اگه شک داری کد زیر رو اجرا کن:console.log(Person instanceof Object);    // trueحالا که تابع سازنده خودش یک object عه پس باید پروتوتایپ داشته باشه. برای رسیدن به پروتوتایپ تابع Person از کد زیر استفاده می کنیم:Object.getPrototypeOf(bizhan);    // {}مشاهده میکنیم که یک object خالی به ما داده! یعنی پروتوتایپ تابع Person یک object خالی بوده! منطقی هم هست. چون با استفاده از Object.create تابع Person رو درست نکردیم بلکه به صورت مستقل اعلانش کردیم. حالا که prototype اش خالیه آیا نمیشه به prototype تابع Person چیزی اضافه کرد؟! چرا. میشه. این طوری:Person.prototype.age = 26;یادته که اول این مقاله گفتم prototype یک property از Function Object هاست؟! تو کد بالا دقیقا از این property استفاده کردیم. حالا که Prototype عه Person رو عوض کردیم آیا object هایی که با استفاده از Person درست شدن هم عوض شدن؟! بله. همه اون ها هم دیگه property ای به نام age بهشون اضافه شده. پس زمانی که prototype رو عوض کنیم object هایی که از روش نوشته شدن هم عوض میشن. البته برعکس این قضیه درست نیست. یعنی زمانی که object ای رو عوض میکنیم prototype اش کاری نمیشه. بذار با یک مثال درک این قضیه رو برات راحت کنم:زمانی که قالب کیک رو عوض کنیم هر کیکی که درست کنیم با اون قالب هم عوض میشه. ولی وقتی که یک کیک که با هر قالبی درست کردیم رو رنگ کنیم، برش بزنیم، بخوریم ... در هر صورت به قالب آسیبی نمیرسه.البته دستکاری prototype ها کار قشنگی نیست و توصیه میشه که به هیچ وجه prototype های داخلی jS رو دستکاری نکنین. مثلا Array.prototype رو عوض نکنین. از طرفی prototype های خودتون رو هم (یعنی اونایی که خودمون تابع سازنده اش رو اعلان کردیم مثلا همین Person) تا حد امکان دستکاری نکنین.با استفاده از تابع سازنده Person اومدیم و Object ای به نام bizhan رو درست کردیم و مشاهده کردیم که prototype اش یک object خالی بود. از طرفی یک object هر چند که خالی باشه ولی چون یک object عه پس خودش هم یک prototype داره. پروتوتایپ یک object خالی میشه Object پس در jS هر شئ ای که درست کنیم در نهایت زنجیره پروتوتایپ هاش ختم میشه به Object! برای همینه که توی jS تقریبا هر چیزی یک object عه. این پروتوتایپ Object یک سری متد هایی داره که به همه فرزندانش به ارث میرسه. مثلا:Object.hasOwnProperty()&#xA;Object.valueOf()&#xA;Object.toLocaleString()&#xA;...و به همین دلیل متد هایی مثل valueOf و hasOwnProperty در هر object ای که توی jS اعلان کنیم وجود داره.نتیجه گیریدر سال 2015 و با منتشر شدن نسخه ES6 توانایی اعلان کردن class ها و ایجاد object از روی class به وجود اومد. اعلان کردن class در jS در ظاهر شبیه به زبان هایی مثل Java هست ولی در پشت صحنه مجددا همون prototyping عه پس در عمل چیزی فرق نکرده. همون طوری که در توی prototyping تابع سازنده داشتیم در class ها هم متد سازنده داریم. در هر صورت prototyping یکی از Design Pattern های معروفه که تسلط بهش باعث میشه دید بازتری به جهان برنامه نویسی و مهندسی نرم افزار داشته باشی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sat, 02 Jul 2022 17:56:30 +0430</pubDate></item><item><title>حلقه های for in و for of در javaScript</title><link>https://virgool.ir/Rocket/حلقه-های-for-in-و-for-of-در-javascript-i4pmukqtbwlp</link><description>این دو تا حلقه از ویژگی های مدرن jS هستن که کار رو راحت میکنن.مقدمهبا حلقه for کلاسیک که مثل زبان C عمل میکنه کم و بیش آشنایی داریم. این for کلاسیک که ۳ تا statement می گرفت همین الان هم همه نیاز هامون رو می تونه بر طرف کنه ولی در ورژن های جدید تر jS حلقه های for جدیدی اضافه شدن که کار رو راحت تر میکنن. با استفاده از حلقه های for in و for of احتمال خطا هم کاهش پیدا میکنه. از طرفی کد کوتاه تر و خوانا تر میشه. در ادامه این مقاله به بررسی این حلقه های مدرن میپردازیم.حلقه for inاین حلقه بین کلید های (key) های یک object گردش میکنه. مثال زیر رو در نظر بگیر:const user = {&#xA;    name: &#39;bizhan&#39;,&#xA;    age: 26,&#xA;    type: &#39;admin&#39;&#xA;};همون طور که می بینی یک object به اسم user داریم که از جفت های key : value درست شده. فرض کن لازم داریم که اسامی key ها رو دونه به دونه پرینت بگیریم. با حلقه for کلاسیک باید این طوری می گفتیم:const keys = Object.keys(user);&#xA;for (let i = 0; i &lt; keys.length; i++) {&#xA;    console.log(keys[i]);&#xA;}ولی با حلقه for in خیلی راحت و ساده این طوری می نویسیم:for (let key in user) {&#xA;    console.log(key);&#xA;}اگه با زبان Python یا Bash هم کار کرده باشی اون جا هم for in هست ولی حواست باشه که با این for in که در jS هست دقیقا یکی نیست. اگه سعی کنی همین for in رو روی یک آرایه ساده پیاده کنی می بینی که به جای مقادیر اون آرایه، index ها رو میده:const evens = [2,4,6,8];&#xA;for (let num in evens) {&#xA;     console.log(num);    // 0, 1, 2, 3&#xA;}البته می شه که کد بالا رو به صورت زیر نوشت تا به مقادیر برسیم:for (let num in evens) {&#xA;      console.log(evens[num]);    // 2, 4, 6, 8&#xA;}ولی در این صورت ممکنه که مقادیر به ترتیب پرینت نشن. واسه همین بهتره که کلا آرایه ها رو با for in ترکیب نکنیم. برای گردش در یک آرایه بهتره از for کلاسیک، متد forEach که روی خود آرایه هست و یا حلقه for of استفاده کنیم.حلقه for ofاین حلقه میان مقادیر یک شئ iterable می چرخه. پس بر خلاف for in که میان key ها می چرخید این حلقه میان value ها می چرخه. منظور از iterable هر شئ ای هست که بشه توش iterate کرد. مثلا آرایه ها، رشته ها، NodeList ها و ... مثال زیر رو در نظر بگیر:const odds = [1,3,5,7];با حلقه for کلاسیک که همه میدونیم چطوری میشه دونه به دونه عناصر odds رو پرینت کرد. در بالا با for in هم این کار رو انجام دادیم (هر چند توصیه نمیشه). حالا همین کار رو با for of انجام میدیم که ساده تر از همه است:for (let num of odds) {&#xA;    console.log(num);&#xA;}نتیجه گیریهمون طوری که jS توی اعلان متغیر ها به ما ۴ تا حالت داده (let, const, var و بدون کلیدواژه اعلان کردن) این جا هم بهمون ۴ نوع حلقه داده (for, for in, for of, while)! درکش برای من به شخصه عجیبه که چرا jS این قدر مسئله رو برای خودش پیچیده میکنه. مثلا تو زبان پایتان شما کلا یک for in داری و while و باهاش هر کاری می تونی بکنی. شاید دلیل این که jS این قدر زبان متنوع و گسترده ای هست سر و کله زدن با مرورگر های مختلف و همه فن حریف بودنشه. </description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sun, 26 Jun 2022 13:51:50 +0430</pubDate></item><item><title>رشته ها در javaScript</title><link>https://virgool.ir/@bizhan.he1996/رشته-ها-در-javascript-pkxx4pmbmuzc</link><description>در jS با کمک متد هایی که رشته ها دارن می تونیم اعمال مد نظرمون رو انجام بدیم.مقدمهمنظور از رشته (String) در زبان های برنامه نویسی رشته ای از کاراکتر هاست که می تونن در کنار هم یک کلمه، جمله یا عبارت های طولانی تر رو تشکیل بدن. این کاراکتر ها انواع و اقسام مختلفی دارن و از عدد گرفته تا حروف الفبا رو شامل میشن. حتی فضای خالی (space) و شکستن خط (Line break) هم کاراکتر حساب میشن. در ادامه این مقاله به بررسی رشته ها در jS می پردازیم.اعلانمنظور از اعلان کردن یک متغیر (Declaration) اینه که به صورت رسمی برای یک متغیر نامی در نظر بگیریم. برای مثال در کد زیر متغیر name رو declare کردیم:let name;برای اعلان متغیر با توجه به نیازی که داریم باید از کلیدواژه مناسب استفاده کنیم. این کلیدواژه های در jS مدرن let و const هستن. برای مطالعه بیشتر در خصوص let و const این مقاله رو بخون. در اکثر مواقع رشته ها رو با let اعلان می کنیم. در کد زیر به همین متغیری که در کد بالا اعلان کردیم مقدار میدیم (Assignment):name = &#39;bizhan&#39;;در ضمن میشد که همزمان هم declare کنیم و هم مقدار بدیم. این طوری:let name = &#39;bizhan&#39;;رشته ها رو میشه درون &#34; &#34; و یا درون &#39; &#39; اعلان کرد. به &#34; میگن Double Quotation mark و به &#39; میگن Single Quotation mark. در هر کدوم که اعلان میکنیم نباید جوری کد بنویسیم که jS قاطی کنه اول و آخر رشته رو. اگه قراره بخشی از خود رشته &#34; داشته باشه باید کل رشته داخل &#39; &#39; محصور بشه و برعکس. مثلا کد زیر اشتباهه:let sentence = &#39;Don&#39;t call me&#39;;چون که jS گیج میشه که کدوم دو تا از ۳ تا &#39; رو ابتدا و انتهای رشته در نظر بگیره. کد بالا رو باید در حقیقت این طوری می نوشتیم:let sentence = &#34;Don&#39;t call me&#34;این طوری jS می فهمه که چون فقط تا ۲ &#34; داریم این ها ابتدا و انتهای رشته هستن و هر چیزی بین این ها بخشی از رشته است.Escape charactersخوب حالا فرض کن که یک جمله این طوری داریم:The signs &#34; and &#39; are used in jS.این رو چطوری توی یک متغیر ذخیره کنیم؟! اگه توی &#39; &#39; ذخیره اش کنیم با &#39; قبل از are تداخل داره و اگه توی &#34; ذخیرش کنیم با &#34; قبل از signs تداخل داره!؟ در این موارد باید یک \ (به این کاراکتر میگن backslash) قبل از اون quotation mark داخل جمله که تداخل ایجاد میکنه قرار بدیم تا خنثی اش کنیم.let sentence = &#34;The signs \&#34; and &#39; are used in jS.&#34;خیلی چیزا رو میشه با این کاراکتر \ ترکیب کرد (حواست باشه با / که برای تقسیم اعداد استفاده میشه اشتباه نگیری). به این ها اصطلاحا میگن escape characters و اصل کاری هاش شامل این ها میشه:\n خط را می شکند\t فاصله زیاد ایجاد میکند\\ a real backslash\&#39;\&#34;مثلا فرض کن جمله زیر رو میخایم در یک متغیر ذخیره کنیم:My Nameis BizhanHejazi.اگه مثل کد زیر بگیم jS گیج میشه چون &#34; های ابتدا و انتهای رشته رو همیشه در یک خط باید قرار داد:let sentence = &#34; My Name&#xA;is Bizhan&#xA;Hejazi.&#34;در این جاست که از n\ کمک میگیریم:let sentence = &#34;My Name\nis Bizhan\nHejazi&#34;برای مشاهده این ۳ خط جدا از هم باید از console.log کمک بگیریم:console.log(sentence);    // 3 linesجنس دادهحالا که یک داده (data) رو در متغیر name ذخیره کردیم باید درک کنیم که جنس این داده (data type) اش چیه. در jS جنس داده های متنوعی داریم که String هم یکیش عه. برای درک جنس یک رشته در jS از عملگر typeof استفاده میکنیم. مثلا typeof متغیر name میشه &#39;string&#39;:console.log(typeof name);    // &#39;string&#39;در بالا ذکر کردیم که جنس داده های رشته String عه. ولی عملگر typeof بهمون &#39;string&#39; داد ! عملگر typeof به طور پیش فرض جنس داده رو تبدیل به یک رشته lowercase میکنه و تحویل میده. برای مثال اگه متغیری از جنس Object داشتیم هم typeof اش میشد &#39;object&#39; در حالی که جنس داده اش Object عه. اگر بخایم خیلی دقیق اظهار نظر کنیم باید گفت که متغیر name در حقیقت String literal هست چرا که وقتی با instanceof بررسی اش میکنیم String نیست! (اگه گیج شدی نگران نباش! در ادامه متوجه میشی)console.log(name instanceof String);    // falseدر حالی که عملگر typeof میاد و جنس داده رو بررسی میکنه، عملگر instanceof بررسی میکنه که داده از روی چه کلاسی درست شده. به عبارتی عملگر instanceof وقتی کاربرد داره که با String object سر و کار داریم نه با String literal. برای اعلان کردن یک رشته به صورت String object باید این طوری بگیم:let name = new String(&#39;bizhan&#39;);&#xA;console.log(typeof name);    // &#39;object&#39;&#xA;console.log(name instanceof String);    // trueدر کد بالا برای این که از کلیدواژه new استفاده کردیم (این کلیدواژه واسه ایجاد object از روی کلاس استفاده میشه) متغیر name تبدیل به object ای شد که از روی کلاس String درست شده. برای همین typeof اش میشه &#39;object&#39; و instanceof String اش true از آب در میاد. از همین الان یاد بگیر که رشته ها رو به صورت literal اعلان کنی. استفاده از String object ها سرعت کد رو میاره پایین و مشکلات دیگری هم داره.موقعیت کاراکترهر کاراکتری در یک رشته دارای موقعیت (index, position) عه. اولین کاراکتر هر رشته موقعیت ۰ داره و کاراکتر های بعدی به همین  ترتیب موقعیت هاشون اضافه میشه. برای خوندن کاراکتری از یک رشته در یک موقعیت خاص می تونیم با رشته مثل آرایه رفتار کنیم و از [ ] استفاده کنیم.let name = &#39;bizhan&#39;;&#xA;console.log(name[0]);    // &#39;b&#39;&#xA;console.log(name[1]);    // &#39;i&#39;اگر بخایم برعکس رشته رو بخونیم هم می تونیم از ویژگی (property) ای به نام length که طول رشته رو بهمون میده استفاده کنیم:console.log(name[name.length - 1]);    // &#39;n&#39;حالا برای تک به تک خوندن کاراکتر های یک رشته می تونیم از یک حلقه for ساده استفاده کنیم (سعی کن کدش رو اول خودت بنویسی حتی شده با سرچ تو گوگل):for (let i = 0; i &lt; name.length; i++) {&#xA;    console.log(name[i]);&#xA;}در ورژن های مدرن jS با حلقه for of این کار راحت تر صورت می گیره:for (let char of name) {&#xA;    console.log(char);&#xA;}به کاری که در کد بالا کردن اصطلاحا میگن loop کردن در یک رشته.تغییر ناپذیریدر زبان jS رشته ها تغییر ناپذیر هستن. این یعنی که شما می تونی کاراکتر هاش رو دونه دونه بخونی، بخشی از رشته رو ببری، حتی می تونی یک کاراکتر رو با کاراکتر جدید جایگزین کنی ... ولی همه ی این کار ها اثری روی متغیر اولیه نداره بلکه مقدار جدید return میشه و اون مقدار رو می تونی توی یک متغیر دیگه ذخیره کنی. اصطلاحا میگن که رشته ها immutable هستن. در مقایسه با رشته ها Array ها رو داریم که mutable هستن و می تونیم خود آرایه اولیه رو عوض کنیم. کد زیر رو در نظر بگیر:let nums = [1,2,3,4,5,6,7,8,9];&#xA;nums[0] = 10;    // WORKSکد بالا بدون هیچ مشکلی اجرا میشه و مقدار متغیر nums که یک آرایه هست رو عوض میکنه. ولی اگه همین کار رو بخایم با یک رشته انجام بدیم هیچ اثری نداره (ارور نمیده ولی اثری هم نداره):let name = &#39;bizhan&#39;;&#xA;name[0] = &#39;B&#39;;   // DOESN&#39;T WORKهمین داستان دست نخورده باقی موندن رشته اصلی وقتی با متد های رشته ها هم کار میکنیم تکرار میشه و مقدار اولیه سالم باقی می مونه.متد های رشته هااگه با برنامه نویسی شئ گرا آشنا باشی (OOP) می دونی که بر اساس class ای که یک object از روش نوشته میشه این object یک سری property ها و یک سری method هایی داره. در jS هم کلاس String داریم و می تونیم String Object درست کنیم تا از متد هاش بهره ببریم. ولی یک کار خیلی قشنگی که jS میکنه اینه که می تونیم با String literal هم از متد ها استفاده کنیم. وقتی که جلوی یک string literal نقطه میذاریم jS در نظر میگیره (هر چند واقعا مقدار ما object نباشه) که این یک object از کلاس String عه و مثلا یک object باهاش رفتار میکنه. مثلا متد includes بررسی میکنه که آیا مقدار خاصی در رشته وجود داره یا نه:let name = &#39;bizhan&#39;;&#xA;console.log(name.includes(&#39;z&#39;));    // trueاگه با برنامه نویسی شئ گرا آشنا نیستی ایرادی نداره. بذار این طور برات توضیح بدم: متد ها ابزار های دم دستی ای هستن که می تونیم باهاشون یک سری اعمالی رو انجام بدیم. در ادامه به بررسی متد های مهمی که رشته ها دارن می پردازیم.indexOfاین متد بررسی میکنه که اولین موقعیت یک رشته (می تونه یک کاراکتر باشه یا یک کلمه یا هر چی) کجای رشته است. اگر پیدا نکنه اون کاراکتر رو 1- بر می گردونه:&#34;banana&#34;.indexOf(&#39;n&#39;);    // 2&#xA;&#34;my name is bizhan&#34;.indexOf(&#39;bizhan&#39;);    // 11می تونستیم یک آرگومان (همین چیزایی که به متد ها میدیم توی پرانتز) دومی هم به متد indexOf بدیم که موقعیت شروع به جست و جو باشه و هر کاراکتری در موقعیت های قبلی رو بی خیال بشه.&#34;banana&#34;.indexOf(&#39;n&#39;,3);    // 4lastIndexOfاین متد هم مثل متد قبلی عه با این تفاوت که برعکس رشته رو بررسی میکنه و موقعیت آخرین حضور رشته مد نظر درون رشته اصلی رو میده. اگر هم پیدا نکنه 1- پس میده :&#34;banana&#34;.lastIndexOf(&#39;n&#39;);    // 4&#xA;&#34;bizhan is always bizhan&#34;.lastIndexOf(&#39;bizhan&#39;);    // 17می تونستیم یک آرگومان دومی هم به متد lastIndexOf بدیم که موقعیت شروع به جست و جو باشه و هر کاراکتری در موقعیت های قبلی رو بی خیال بشه. (به برعکس سیر کردن این متد دقت کن)&#34;banana&#34;.lastIndexOf(&#39;n&#39;, 3);    // 2replaceاولین حضور یک رشته رو درون یک رشته پیدا میکنه و با رشته دیگری جایگزین میکنه:&#34;I love music.&#34;.replace(&#34;music&#34;,&#34;movies&#34;);دقت کن که این متد فقط اولین باری که اون کلمه پیدا میشه رو عوض میکنه. برای این که همه مصادیق رشته مد نظرت رو جایگزین کنی باید از متد replaceAll استفاده کنی. میشه از این دو تا متد حرفه ای تر هم استفاده کرد که در حوصله بحث نمی گنجه.sliceاین متد رشته رو برش میده. منظور از برش دادن یک رشته جدا کردن بخشی از رشته است. برای این که بدونه از کجا بریدن رو شروع کنه و کجا تموم کنه ۲ تا مقدار باید بهش بدیم که اولش موقعیت شروع به برش و دومیش موقعیت توقف برش عه (خود کاراکتری که در موقعیت توقف حضور داره بریده نمیشه چون مشخصا در این موقعیت بریدن متوقف میشه!)let sentence = &#34;She has 2 apples.&#34; &#xA;let sliced = sentence.slice(0, 3);&#xA;console.log(sentence);    // &#39;She has 2 apples&#39;&#xA;console.log(sliced);    // Sheهمون طوری که قبلا هم گفتیم رشته های immutable هستن و هر کاری که باهاشون بکنیم رشته اصلی تغییری نمیکنه. اگر به متد slice فقط یک مقدار بدیم برش رو از همون موقعیت شروع میکنه و تا آخر رشته رو می بره. مثلا با همین متغیر های بالا:let sliced = sentence.slice(4);&#xA;console.log(sliced)    // &#39;has 2 apples.&#39;searchاین متد رشته رو برای اولین حضور یک regular Expression بررسی میکنه و موقعیت اش رو به ما میده. منظور از regular expression ترکیبی از نشانه ها و علائم هست که می تونه مصادیقی در رشته داشته باشه. بذار با مثال توضیح بدم. با متد indexOf می تونیم موقعیت کاراکتر 9 در جمله زیر رو گیر بیاریم:let sentence = &#34;I have 9 apples.&#34;&#xA;console.log(sentence.indexOf(&#39;9&#39;));ولی اگه نمیدونستیم عدد مون دقیقا چنده چی؟! اینجاست که Regular Expression ها به کار ما میان که به اختصار بهشون میگن RegEx. RegEx ها مخصوص زبان jS نیستن و در اکثر زبان ها با مقدار ناچیزی تفاوت میشه ازشون استفاده کرد. مثلا در همین چالش بالا:console.log(sentence.search(/\d/));    // 7در کد بالا بخشی که bold شده همون RegEx عه. RegEx ها موضوع شیرین، ساده و قدرتمندی هستن که آشنایی و تسلط بهشون به هر برنامه نویسی توانایی بالایی میده. در این مقاله تخصصا به RegEx ها نمی پردازیم.matchاین متد قسمت هایی از رشته ما رو که با RegEx خاصی match میشه استخراج میکنه. مثلا در کد زیر همه کاراکتر های Capital رو از رشته اولیه استخراج کردیم و به صورت یک array تحویل گرفتیم:let input = &#39;AaBbCcDd&#39;;&#xA;console.log(input.match(/[A-Z]/g));    // [&#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;];در خصوص RegEx ها بحث تخصصی میشه و در حوصله این مقاله نیست.toUpperCaseاین متد رشته رو به صورت UpperCase تحویل میده. یعنی همه کاراکتر هاش Capital میشن. مشابه همین متد toLowerCase هم داریم که باز اون همه کاراکتر های رو small میکنه.let upper = &#34;bizhan&#34;.toUpperCase();&#xA;console.log(upper);    // BIZHANsplitاز متد های مهم رشته ها هست. این متد یک رشته رو به آرایه تبدیل میکنه (واسه مطالعه درباره آرایه ها به این لینک مراجعه کن). همون طوری که از اسمش مشخصه یک رشته رو جدا میکنه. بر اساس چی؟! بر اساس چیزی که بهش میدیم. مثلا در کد زیر بر اساس space رشته رو جدا میکنه:let items = &#34;a b c d&#34;&#xA;const chars = items.split(&#39; &#39;);حالا در مثال زیر میخایم کلمات یک جمله رو در قالب یک آرایه ذخیره کنیم:let sentence = &#39;My name is Bizhan.&#39;;&#xA;const words = sentence.split(&#39; &#39;);یا مثلا در مثال زیر مقادیر جدا شده توسط comma رو میخایم به آرایه تبدیل کنیم:let digits = &#39;1,2,3,4,5,6,7&#39;;&#xA;const numbers = digits.split(&#39;,&#39;);startsWithاین متد بررسی میکنه که آیا رشته ما با مقدار خاصی شروع میشه یا خیر. برای مثال:let companies = &#34;Apple, Microsoft, Samsung&#34;&#xA;console.log(companies.startsWith(&#34;Apple&#34;));    // true&#xA;console.log(companies.startsWith(&#34;apple&#34;));    // falseهمون طوری که تو مثال بالا باید متوجه شده باشی متد startsWith به Capital و‌ Small بودن حساسه برای همینه که خط سوم false شد. مشابه همین متد endsWith رو هم داریم که این یکی بررسی میکنه آیا رشته ما با مقدار خاصی تموم میشه یا نه.trimاین متد اضافاتی مثل space و line break رو از ابتدا و انتهای رشته ما پاک میکنه. این بحث به خصوص زمانی مهمه که میخایم داده ها رو از سمت کاربر دریافت کنیم و نیازی به اضافات نداریم.let name = &#39;     bizhan      &#39;;&#xA;let trimmed = name.trim();&#xA;console.log(trimmed);    // &#39;bizhan&#39;نتیجه گیریمانور دادن روی رشته ها یک مهارت مهمه. برای مثال یک توسعه دهنده وب که اطلاعات رو به صورت رشته از سمت کاربر دریافت میکنه باید بتونه که بررسی کنه آیا این اطلاعات به فرمت صحیح، به صورت ایمن و بدون هیچ گونه عبارت های خرابکارانه، با حجم مناسب و ... اومدن یا نه. همین طور خیلی وقتا لازمه ظاهر نمایش رشته رو عوض کنیم. مثلا ممکنه توی Database برای کاهش حجم به صورت UpperCase ذخیره کنیم ولی به کاربر به صورت lower case نشون بدیم. من در این مقاله اصلی ترین متد های رشته ها در jS رو گفتم و هنوزم متد هایی هستن (که به نظرم اون قدر ها پر کاربرد نبودن) که میتونی از رفرنس ها مطالعه کنی. امیدوارم از مقاله خوشت اومده باشه و در نهایت این که ممنون میشم اگه من رو به یک کامنت مهمون کنی. </description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sat, 25 Jun 2022 09:31:53 +0430</pubDate></item><item><title>آرایه ها در JavaScript</title><link>https://virgool.ir/@bizhan.he1996/آرایه-ها-در-javascript-rydgaw6yd2pw</link><description>جاوا اسکریپت توانایی منحصر به فردی در کار کردن با آرایه ها داره که در این مقاله بررسی می کنیم.مقدمهآرایه ها (Array) نوعی از داده هستن (data type) که مقادیر رو به صورت یک زنجیره ذخیره میکنن. به جای این که ۳ مقدار رو توسط ۳ متغیر جدا از هم ذخیره کنیم، می تونیم این ۳ مقدار رو در یک آرایه ذخیره کنیم. let x = 1;&#xA;let y = 2;&#xA;let z = 3;&#xA;const items = [1, 2, 3];پس آرایه ها مثل یک قطار هستن که هر واگنش میشه یکی از اون مقدار ها. به هر کدوم از این مقادیر میگن یک عنصر (element) اون آرایه (برخی وقتا عضو هم میگن). این عناصر می تونن خودشون از هر جنسی باشن. مثلا ممکنه آرایه ای از چندین Object داشته باشیم (که اتفاقا خیلی هم رایجه). در jS آرایه ها می تونن Heterogeneous باشن. یعنی عناصر آرایه می تونن جنس داده های مختلفی داشته باشن. مثلا آرایه ای از چند عدد، چند رشته و غیره. از همین الان یاد بگیر که به عنوان یک عادت خوب، آرایه ها رو با const اعلان کنی.const bag = [&#39;key&#39;, &#39;money&#39;, 12, true]; &#xA;const users = [&#xA;    {name: &#39;bizhan&#39;, age: 26},&#xA;    {name: &#39;hazhir&#39;, age: 28},&#xA;    {name: &#39;sepehr&#39;, age: 25}&#xA;];اعمال روی آرایه هامفهوم آرایه ها منحصر به jS نیست. در بقیه زبان ها هم آرایه داریم. در پایتان هم جنسی از داده به نام list داریم که به شدت شبیه به آرایه هاست. در واقع آرایه یک جور Data Structure عه. منظور از data structure (ساختار داده) روشی برای ساماندهی به داده هاست که خودش انواع مختلفی داره و یک بحث خیلی مهم و شیرینه. فارغ از این که با چه زبان کار میکنیم، روی آرایه ها (با توجه به این که چندین عنصر دارن) طبیعتا و بدیهتا این اعمال رو باید انجام بدیم (اصلا نیازی به حفظ نیست. به تدریج خودت یاد می گیری):بررسی تعداد عناصر آرایه (طول آرایه)دسترسی به عنصر خاصی از آرایه: بر اساس جایگاهش از نظر ترتیب در آرایهعوض کردن عنصر خاصی از آرایه: بر اساس جایگاهش از نظر ترتیب در آرایهمرتب کردن آرایه: صعودی، نزولی (به این کار میگن sort کردن)معکوس کردن ترتیب آرایهاضافه کردن عنصر به آرایه: به اول آرایه، به آخر، به وسطکم کردن عنصر از آرایه: از اول آرایه، از وسط، از آخربریدن چندین عنصر از یک آرایه و ایجاد آرایه ای جدیدپیدا کردن موقعیت (ترتیب) یک عنصر در آرایهالصاق چند آرایه به هم و ایجاد یک آرایه یکپارچهچسبوندن عناصر‌ آرایه به هم و ایجاد یک رشتهتبدیل آرایه به آرایه ای دیگر بر اساس عناصر آرایه اولیه (به این کار میگن map کردن)فیلتر کردن آرایه و انتخاب عناصری که از فیلتر می تونن عبور کنن (به این کار میگن filter کردن)انجام کاری به ازای هر عضو آرایهبررسی این که آیا فلان عنصر تو آرایه هست یا نهکاهش دادن کل آرایه به یک مقدار ساده (مثل عدد یا رشته)و ...خواندن عناصر آرایه (reading)برای خواندن مقدار عناصر یک آرایه از [ ] استفاده میکنیم. اولین عنصر آرایه شاخصه (index) ۰ رو داره و عنصر بعدی ۱ و الی آخر. این طوری (در همه این کد ها هدف استفاده از console.log مشاهده اثر نهایی در کنسول عه و ربطی به اصل بحث نداره. چون در jS چیزی به نام print به معنی زبان هایی مثل Python نداریم):const letters = [&#39;a&#39;,b&#39;,&#39;c&#39;,&#39;d&#39;];&#xA;console.log(letters[0])    // &#39;a&#39;&#xA;console.log(letters[1])    // &#39;b&#39;برای مشاهده طول یک آرایه (یعنی این که چند تا عنصر داره) از ویژگی (property) ای به نام length استفاده میشه:console.log(letters.length);    // 4حالا فرض کن میخایم برعکس عناصر رو بخونیم. مثلا آخرین عنصر رو بخونیم. این طوری عملی میکنیم:console.log(letters[letters.length - 1]);    // &#39;d&#39;برای عوض کردن مقادیر هم همین طوری عمل میکنیم:letters[0] = &#39;الف&#39;;متد ها (Methods)آرایه ها در jS نوعی object حساب میشن و هر object ای هم متد های خاص خودش رو داره. به کد زیر دقت کن:const items = [1,2,3,4,5];&#xA;typeof items;    // &#39;object&#39;&#xA;items instanceof Array;    // trueکد بالا به ما نشون میده که جنس داده یک آرایه object عه و از روی کلاس Array رونویسی شده. حالا که items یک object عه که از روی کلاس Array درست شده پس باید یک سری متد هم داشته باشه. همین متد ها هستن که به ما کمک میکنن تا اعمالی که در بالا لیست کرده بودیم رو پیاده سازی کنیم. این متد ها اکثرا مقدار اولیه خود آرایه رو عوض میکنن (هر چند برخی هاشون این طوری نیستن و نیازی هم نیست حفظ کنی چون بدیهیه). در ادامه به بررسی این متد ها می پردازیم.مرتب کردن آرایه (sort)با استفاده از متد sort روی خود آرایه انجام میشه. اگه بهش هیچ آرگومان ای (Argument) ندیم به صورت پیش فرض و بر اساس الفبا مرتب میکنه عناصر رو. می تونیم بهش یک function هم به عنوان آرگومان بدیم که به صورت دلخواه خودمون عناصر رو مرتب کنه.const nums = [10, 2, 12, 9, 1];&#xA;nums.sort();    // [1, 10, 12, 2, 9];چی شد !!!! این طوری که اشتباه مرتب کرده! یعنی ۲ از ۱۲ بزرگتره!!!! این به دلیل اینه که متد sort اعداد رو بر اساس رقم اولشون مقایسه میکنه برای همینه که هر عددی با رقم اول ۱ کوچکتر از بقیه اعداد میشه حتی ۱۰۰۰۰۰. برای حل این مشکل چه کار کنیم؟! همون function عه که بالا بهت گفتم. باید اون رو بدیم به متد sort:nums.sort( function(a, b){&#xA;    return a-b;&#xA;}); در کد بالا منظور از a و b دو عنصر پشت سر هم هستند که قراره با هم مقایسه بشن. اگر حاصل return a-b مقدار منفی بشه آرایه به صورت صعودی و اگر مقدار مثبتی بشه آرایه به صورت نزولی مرتب میشه. ولی خوب اگه هیچ a-b مقدار مثبتی نشد چی؟! چطوری نزولی مرتب کنیم؟ کاری نداره. به جای a-b می نویسیم b-a. حفظ هم لازم نیست بکنی. شکل اش گویاست دیگه. a-b خودش ترتیب صعودی داره چون b از a تو الفبای انگلیسی بزرگتره. b-a هم ظاهر نزولی داره. استفاده از متد sort با function به صورت آرگومان به خصوص در مواقعی کار گشاست که با آرایه ای از شئ ها رو به رو هستیم:const users = [&#xA;     {name: &#39;bizhan&#39;, age: 26},&#xA;     {name: &#39;hazhir&#39;, age: 28},&#xA;     {name: &#39;sepehr&#39;, age: 25} &#xA;];&#xA;users.sort(function(a,b){&#xA;    return a.age-b.age;&#xA;});برعکس کردنبا متد reverse می تونیم ترتیب عناصر رو برعکس چیزی که هست کنیم. این متد آرایه اولیه رو تغییر میده.const nums = [1,12, 5, 2, 13];&#xA;nums.reverse();    // [13, 2, 5, 12, 1];فرض کن که میخای بررسی کنیم که آیا یک کلمه پالیندروم هست یا نه. منظور از رشته های پالیندروم اینه که از هر دو طرف یک جور خونده بشه. مثلا damad یک پالیندرومه. برای این کار:رشته مورد بررسی رو به آرایه تبدیل میکنیم.سپس آرایه ایجاد شده رو reverse میکنیم.حالا آرایه برعکس شده رو دوباره به رشته تبدیل میکنیم.مقدار حاصل از مرحله سوم رو با مقدار اولیه مقایسه می کنیم.کدش میشه این (سعی کن اول خودت بنویسی بعدش به این نگاه کن. می تونی تو گوگل هم سرچ کنی که هر مرحله رو چطوری انجام بدی).let word = &#39;damad&#39;;&#xA;const chars = word.split(&#39;&#39;);&#xA;chars.reverse();&#xA;let reversed = chars.join(&#39;&#39;);&#xA;if (word === reversed) console.log(&#34;Palindrome&#34;);اضافه کردن عنصر به آرایهبسته به این که به کجای آرایه بخایم عنصر جدید اضافه کنیم می تونیم از چند متد استفاده کنیم.متد push: اضافه کردن عنصر به انتهای آرایهمتد unshift: اضافه کردن عنصر به ابتدای آرایهمتد splice: اضافه کردن عنصر به هر جایی از آرایه (من جمله ابتدا و انتها)همگی این متد ها آرایه اولیه رو تغییر میدن. اول متد push رو بررسی کنیم:const letters = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];&#xA;letters.push(&#39;e&#39;);    // returns the new length of array: 5&#xA;console.log(letters);    // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;,&#39; e&#39;]در ضمن متد push طول آرایه حاصل رو هم return میکنه. متد unshift هم مثل متد push عنصر اضافه میکنه با این تفاوت که به اول آرایه اضافه میکنه.const nums = [1,2,3,4,5];&#xA;nums.unshift(0);    // returns the new length of array: 6&#xA;console.log(nums);    // [0,1,2,3,4,5]این متد هم مثل متد قبلی طول جدید آرایه رو بر می گردونه. به متد های push و unshift میشه به جای یک مقدار (که قراره به آرایه اضافه بشه) چند مقدار داد. در این صورت مقادیر باید با کاما از هم جدا بشن. const odds = [1,3,5];&#xA;odds.push(7,9,11);    // returns the new length of array: 6&#xA;console.log(odds); [1,3,5,7,9,11];متد spliceمتد splice حرفه ای تر از push و unshift عه و نه تنها میشه باهاش عنصر اضافه کرد بلکه میشه از هر جای آرایه عنصر حذف کرد. این متد هم مثل بقیه متد هایی که تا این جا بررسی کردیم مقدار اولیه رو عوض میکنه (یعنی این طوری نیست که بر اساس آرایه اولیه یک آرایه جدید درست کنه. بلکه همون آرایه اولیه رو عوض میکنه). حداقل ۲ تا آرگومان میگیره که به این طریقه:Array.splice(start, removed, addings ....);اولین مقدار این متد index ای هست که میخاد فعالیت رو شروع کنه. همون طوری که قبلا گفتم هر عنصری در آرایه ها یک index عددی داره که انگاری میشه همون موقعیتش در آرایه. آرگومان بعدی تعداد عناصری هست که بعد از موقعیت شروع باید حذف بشن (اگه نمیخای عنصری رو حذف کنی ۰ بذار) و در نهایت یک یا چند مقدار که این ها باید اضافه بشن. مثلا کد زیر در موقعیت ۲ (یعنی سومین موقعیت چون اگه یادت بشه موقعیت ها از ۰ شروع میشد) یک مقدار جدید اضافه میکنه:const nums = [1, 2, 3, 4, 5, 6];&#xA;nums.splice(2, 0, 3.5);    // [1, 2, 3.5, 3, 4, 5, 6]حالا با استفاده از همین متد splice میخایم از وسط آرایه دو تا عنصر رو حذف کنیم. const chars = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;, &#39;g&#39;];&#xA;chars.splice(3, 2);&#xA;console.log(chars); // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;f&#39;, &#39;g&#39;];وقتی که با متد splice عنصر از آرایه حذف میکنیم، آرایه اولیه تغییر میکنه و در اثر این عمل (یعنی در اثر خط دوم کد بالا) عناصر حذف شده return میشن. توی همین کد بالا مثلا اگه میخاستیم عناصر حذف شده رو در قالب یک متغیر ذخیره کنیم میشد این طوری کد بنویسیم:const chars = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;, &#39;g&#39;]; &#xA;const removeds = chars.splice(3, 2);&#xA;console.log(removeds); // [&#39;d&#39;, &#39;e&#39;];کم کردن عنصر از آرایهتا این جا یاد گرفتیم که با متد splice از هر جای آرایه که دوست داریم عنصر حذف کنیم (من جمله ابتدای و انتها). برای موقعیت های ساده تر متد های راحت تری هم هست مثل pop و shift. متد pop از انتهای آرایه آخرین عنصر رو حذف میکنه و مقدار این عنصر حذف شده رو return میکنه. متد shift هم همین کار رو از ابتدای آرایه انجام میده و اولین عنصر آرایه رو حذف میکنه و مقدارش رو return میکنه.const evens = [2, 4, 6, 8, 10, 12, 14];&#xA;let popped = evens.pop();&#xA;console.log(popped);    // 14&#xA;console.log(evens);    // [2,4,6,8,10,12]همین داستان برای متد shift تکرار میشه با این تفاوت که shift از اول آرایه عنصر حذف میکنه.const primes = [2,3,5,7,11,13];&#xA;let removed = primes.shift();&#xA;console.log(removed);    // 2&#xA;console.log(primes);    // [3,5,7,9,11,13]بریدن چند عنصر از آرایه و ایجاد آرایه ای جدیدمتد slice یک آرایه رو قیچی میکنه و آرایه جدیدی شامل عناصر بریده شده بهمون بر می گردونه. این متد آرایه اولیه رو بدون تغییر میذاره. بدیهی هم هست چون اگه آرایه اولیه رو تغییر میداد کلی از عناصر که در برش انتخاب نشده بودن از دست می رفتن. const years = [1385, 1386, 1387, 2006, 2007, 2008, 2009];&#xA;const shamsi_years = years.slice(0, 3);&#xA;const gregorian_years = years.slice(3)به متد slice دو تا آرگومان می تونیم بدیم. آرگومان اول موقعیت شروع به برش هست (اولین موقعیت ۰ عه) که از اون جا شروع میکنه به بریدن و عنصری که تو موقعیت ۰ باشه رو هم حساب میکنه. آرگومان دوم موقعیتی هست که این برش متوقف میشه ولی عنصری که در این موقعیت قرار داده بریده نمیشه. به عبارت آرگومان اول موقعیت start و آرگومان دوم موقعیت stop عه. در کد بالا مشاهده میکنی که در خط سوم به متد slice فقط یک آرگومان دادیم. در این صورت از موقعیت ۳ شروع به برش میکنه و تا انتهای آرایه رو می بره. یعنی همه سال های میلادی.پیدا کردن موقعیت یک عنصر در آرایههمون طوری که گفتیم هر عنصری در آرایه بر اساس این که به چه ترتیبی در تعریف آرایه قرار داده شده باشه دارای یک شاخص (index) هست. از دو عبارت موقعیت (position) و شاخص (index) اکثر اوقات به صورت هم معنی استفاده میشه ولی اصطلاح تخصصی برنامه نویسیش همون index عه.حالا فرض کن که ما یک آرایه به هم ریخته و بدون ترتیب داریم. در این صورت برای پیدا کردن موقعیت مقدار خاصی باید از متد indexOf استفاده کنیم. (عناصر تکراری در آرایه هیچ مشکلی نداره)const nums = [4,2,7,4,2,9,6,3,2,6,8];&#xA;let position = nums.indexOf(2);&#xA;console.log(position);    // 1ولی خوب در آرایه بالا چندین عنصر با مقدار ۲ داریم. متد indexOf موقعیت اولین عنصری که مقدار خواسته شده رو داره به ما میده. اگه موقعیت عناصر بعدی با مقدار یکسان رو خواستیم چی؟! آرگومان دومی می تونیم به این متد بدیم که موقعیت شروع به جست و جو در آرایه است. برای مثال در موقعیت ۴ همین آرایه کد بالا هم یک ۲ داریم. اگه بخایم گیرش بیاریم این طوری کد میزنیم:let position = nums.indexOf(2, 2);در نهایت به خاطر بسپار که اگه متد indexOf مقدار مورد نظر رو در آرایه پیدا نکرد 1- بر می گردونه.الصاق چند آرایه به همبرای ترکیب چند آرایه با هم روش های مختلفی هست. ساده ترین روش استفاده از spread syntax عه که خیلی کار رو راحت میکنه:const evens = [2,4,6,8];&#xA;const odds = [1,3,5,7,9];&#xA;const nums = [...odds, ...evens];به استفاده از اون ۳ تا نقطه میگن spread syntax که تو ورژن های جدید jS اضافه شده و خیلی کار رو راحت میکنه. در ضمن میشه از این spread syntax هر طوری دوست داری استفاده کنی. این طوری مثلا:const ages = [1,2,3,4, ...odds];&#xA;const digits = [1,2,3, ...evens, 4,5,6];راهکار دیگه برای الصاق دو آرایه به هم استفاده از متد concat عه. const evens = [2,4,6,8]; &#xA;const odds = [1,3,5,7,9]; &#xA;const nums = evens.concat(odds);به متد concat میشه چندین آرگومان هم داد تا چندین آرایه رو به هم وصل کنیم.چسبوندن عناصر آرایه به هماصطلاحا میگن که آرایه ها Human readable نیستن. منظور چیه؟! یعنی کسی که برنامه نویس نیست و نمیدونه که ] و یا [ به چه معنی عه گیج میشه. اگه بخایم یک آرایه رو به صورت عرف نگارشی انسان ها نشون بدیم باید Human readable اش کنیم. برای این کار باید عناصر آرایه رو به هم بچسبونیم و با یک علامتی (اکثرا کاما) از هم جداشون کنیم. به کد دقت کن:const letters = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;];&#xA;let humanReadable = letters.toString();&#xA;console.log(humanReadable);    // &#39;a,b,c,d,e&#39;مشاهده کردی که آرایه ای که برنامه نویس ها و ماشین ها ازش سر در می آوردن رو تبدیل کرد به a,b,c,d,e که برای هر انسانی هم قابل فهم باشه. متد join هم همین کار رو میکنه با این فرق که می شه بهش گفت با چی عناصر رو به هم بچسبونه. به کد دقت کن:const letters = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;];&#xA;humanReadable = letters.join(&#39; - &#39;);&#xA; console.log(humanReadable);    // &#39;a - b - c - d - e&#39;;حتی میشه به جای &#39; - &#39; هر چیز دیگه ای که دوست داریم بذاریم. مثلا: &#39;اصغر&#39;!!! متد join روی آرایه ها و متد split روی رشته ها (برای مطالعه در باره متد split روی رشته ها به این لینک مراجعه کن) در کنار هم خیلی مفید هستن. برای مثال فرض کن یک چالش به این صورت داریم: از رشته AaBbCcDdEe فقط کاراکتر های UpperCase رو جدا کنید و به صورت یک رشته نمایش دهید.برای حل این مسئله ابتدا گام هاش رو می نویسیم:تبدیل رشته اولیه به آرایهتبدیل همه عناصر آرایه حاصله از مرحله اول به UpperCaseحذف عناصر تکراری از آرایهتبدیل آرایه حاصل از مرحله ۳ به رشتهاین چالش رو این طوری حل میکنیم (سعی کن اول خودت با سرچ در گوگل چالش رو حل کنی. مرحله هاش رو که بهت گفتم. هر مرحله رو تو گوگل سرچ کن دربارش و راهکارش رو پیدا کن.)let chars = &#34;AaBbCcDdEe&#34;&#xA;const splitteds = chars.split(&#39;&#39;);&#xA;splitteds.sort();&#xA;const answer = splitteds.slice(0,5);&#xA;console.log(answer.join(&#39;&#39;));شاید تعجب کرده باشی‌! این کدی که من نوشتم دقیقا برابر با مراحلی که در بالا گفتم نبود! بله. همین طوره. من کلک زدم. چرا وقتی می تونم یک مسئله رو راحت تر حل کنم راه حل پیچیده رو انتخاب کنم. من به جای بررسی تک تک عناصر می تونستم خیلی راحت آرایه حاصل از جدا کردن کاراکتر های رشته اولیه رو از نظر الفبایی مرتب کنم. از اون جایی که حروف Capital توی sort شدن اول ظاهر میشن و ما کلا ۶ تا حرف Capital داشتیم پس ۶ عنصر اول من همون عناصر Capital بودن. همون ها رو slice کردم. ایجاد آرایه ای جدید بر اساس آرایه اول (map کردن)به این کار در عرف برنامه نویسی میگن map کردن یک آرایه. یعنی آرایه ای جدید درست کنیم بر اساس آرایه اولیه. به موازات هر عنصر از آرایه اولیه، عنصری جدید در آرایه ای جدید خواهیم داشت. مثلا فرض کن آرایه ای از اعداد فرد داریم و میخایم بر اساس اون آرایه ای از اعداد زوج درست کنیم. خوب مشخصه که باید به هر عضو آرایه اولیه ۱ واحد اضافه کنیم تا آرایه ای از اعداد زوج درست بشه. const odds = [1,3,5,7,9];&#xA;const evens = odds.map(odd =&gt; odd + 1);نکته: در کد بالا odd =&gt; odd + 1 استایل جدید arrow function هست که جز ویژگی های مدرن jS حساب میشه و برابر با اینه:function(odd) {&#xA;    return odd + 1;&#xA;}مپ کردن آرایه ها خیلی کار راه اندازه و در عین حال واقعا هم ساده است. بذار یک مثال دیگه بررسی کنیم. آرایه ای از رشته های عددی داری. یعنی به جای ۱ و ۲ و ۳ با &#39;1&#39; و &#39;2&#39; و ... رو به رو هستیم. خوب مشخصا نمی تونیم با این اوضاع روی عناصر این آرایه فعالیت های ریاضی انجام بدیم چون جنس داده شون String عه نه Number. باید آرایه اولیه رو به Number مپ کنیم.const digits = [&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;];&#xA;const nums = digits.map(Number);به همین راحتی به همین خوشمزگی!!! در توضیح عرض کنم که Number خودش یکی از function های jS عه که هر چیزی که می تونه به عدد تبدیل بشه رو به عدد تبدیل میکنه. ما در کد بالا حتی به خودمون زحمت ندادیم که function تعریف کنیم. چرا این کار رو بکنیم وقتی خود jS فانکشن اش رو تعریف کرده؟!حتما تا این جا متوجه شدی که متد map آرایه جدید درست میکنه و آرایه اولیه رو دست نخورده باقی میذاره. کاملا هم مشخصه و بدیهیه چون خیلی خطرناکه اگه بخایم تک تک عناصر آرایه اولیه رو عوض کنیم و مقدار اولیه شون رو از دست بدیم.فقط عناصر دلخواه رو بیرون کشیدن (filter کردن)یک صافی رو در نظر بگیر. تک تک عناصر آرایه رو دونه دونه بهش میدیم و اون هایی که از سوراخ های صافی ریزتر هستند عبور میکنن و بقیه گیر میکنن پشت صافی. این کاریه که متد filter برامون میکنه. خیلی گویاست. یک آرایه رو فیلتر میکنه. فیلترش رو هم خودمون می تونیم تعریف کنیم. برای مثال: آرایه از اعداد ۱ تا ۱۰ داریم و میخایم فقط اعداد فرد رو ازش بیرون بکشیم. خوب مراحل حل این مسئله میشه:تقسیم تک تک عناصر آرایه بر ۲اگر باقی مانده تقسیم ۰ شد عدد زوج است (و از فیلتر عبور نمیکند)اگر باقی مانده تقسیم ۱ شد عدد فرد است (و از فیلتر عبور میکند)کدش میشه این (بهتره اول خودت یک تلاشی بکنی و یک کد بنویسی حتی با کمک از گوگل و بعد به کد من نگاه کنی)const nums = [1,2,3,4,5,6,7,8,9,10];&#xA;cont odds = nums.filter(num =&gt; num % 2 === 1);عملگر ٪ در کد بالا باقی مانده تقسیم ۲ مقدار رو به ما میده. مجددا تاکید میکنم که متد filter هم آرایه اولیه رو دست نخورده باقی میذاره و آرایه جدیدی درست میکنه. متد filter متد دم دستی و راه گشایی هست به خصوص موقع کار کردن با database. مثلا فرض کن که یک web application داریم که بر اساس یک آرایه، جدولی رو با استفاده از HTML برای کاربر پرینت کرده. (این تکنیک توی Angular و امثالش خیلی رایجه مثلا). حالا ما برای کاربر یک input گذاشتیم که هر چی توش تایپ کنه در اسرع وقت اون جدول فقط ردیف هایی رو نشون میده که مقدار تایپ شده درش باشن. یعنی یک سرچ live. خوب حالا که با filter آشنا شدی می بینی که چیز خاصی رخ نداده. اون جدول بر اساس آرایه اولیه از ردیف ها پرینت نشده، بر اساس filter شده اش پرینت شده. و هر وقت کاربر مقداری رو داخل اون input تایپ کنه آرایه اولیه filter میشه و ردیف هایی نشون داده میشن که مقدار تایپ شده توسط کاربر درشون موجود باشه.انجام کاری به ازای هر عضو آرایهفرض کن که آرایه ای از اعداد داریم و میخایم هر عنصر رو log کنیم. به صورت کلاسیک میشد این طوری از یک for استفاده کرد:const nums = [3,4,5,6,7,8];&#xA;for (let i=0; i &lt; nums.length; i++) {&#xA;    console.log(nums[i])&#xA;}در ورژن های جدید تر حلقه مدرنی اضافه شده به اسم for in که کار رو راحت میکنه:for (let i in nums) {&#xA;    console.log(nums[i])&#xA;}حتی میشه راحت تر از این از for of استفاده کرد. این دیگه واقعا معرکه است:for (let x of nums) {&#xA;    console.log(x);&#xA;}به همه این کار ها اصلاحا میگن loop کردن در آرایه. به عبارتی «چرخیدن» در آرایه. ولی من میخایم یک راه دم دستی و ساده تر بهتون یادم بدم. استفاده از متد forEach ! در یک خط همه این کار ها رو میکنه:nums.forEach(num =&gt; console.log(num));متد forEach به ازای هر عضو از آرایه کاری رو انجام میده. این متد نه آرایه جدیدی درست میکنه و نه آرایه اولیه رو عوض میکنه. (نیازی هم به این کار نداره). هنگام کار کردن با SPA (Single Page Application) ها این متد forEach خیلی کمکت میکنه. فرض کن آرایه ای از email ها داری و میخای به هر email یک متنی رو ارسال کنی. چه چیزی بهتر از forEach؟!بررسی حضور فلان مقدار در آرایهاین کار رو میشد با indexOf هم انجام داد به این صورت که اگه مقدار ۰ به بالا داد یعنی هست و اگه -۱ داد یعنی نیست. ولی این یک کم می لنگه. چون ۰ در jS تفسیر به false میشه و -1 و بقیه مقادیر مثبت تفسیر به true! متد includes ولی کار رو برای ما راحت میکنه. چون که سر راست false یا true بر می گردونه. const nums = [1,2,3,4,5,6,7,9];&#xA;console.log(nums.includes(1));    // true&#xA;console.log(nums.includes(8));    // falseکاهش دادن آرایه به یک مقدار سادهبه این کار میگن reduce کردن یک آرایه. یعنی یک آرایه که از جنس داده های پیچیده است رو تبدیل کنیم به جنسی از داده که ابتدایی باشه مثلا عدد یا رشته. فرض کن که آرایه ای از اعداد داریم و میخایم که جمع همه عناصر رو به دست بیاریم. یعنی عناصر رو دو نه به دونه با هم جمع کنیم. خوب ممکنه که با یک حلقه for ساده کارت رو انجام بدی و یا اگه حرفه ای تر باشی از for in  و for of استفاده کنی. ولی راهکار ساده تری هم هست. متد reduce.const nums = [1,2,3,4,5,6,7];&#xA;nums.reduce((acc, cur) =&gt; {acc += cur});در کد بالا منظور از acc مخفف شده عبارت accumulative عه (تو انگلیسی یعنی تجمیعی) و cur هم current عه. به عبارتی متد reduce میاد و مثل forEach توی آرایه می چرخه و متغیر cur نماینده عنصر همون دور چرخش هست و acc هم محصول جمع همه cur ها تا اون دور چرخشه. این متد هم آرایه اولیه رو دست نخورده باقی میذاره و در نهایت یک حاصل فقط return میکنه که همون جمع همه عناصر. با متد reduce میشه مسائل دیگری هم حل کرد. مثلا آرایه از اسامی داریم و میخایم همه اسامی رو به هم بچسبونیم و یک رشته یک پارچه درست کنیم. با متد reduce این کار رو میکنیم و توی هر چرخش cur رو به acc می چسبونیم. ولی صبر کن!!! چرا راه سخت رو بریم؟! وقتی متد join رو داریم چرا از reduce استفاده کنیم؟!نتیجه گیریببخشید طولانی شد! من سعی کردم اصلی ترین متد ها رو به صورت مفهومی توضیح بدم. تازه هنوز یک سری متد دیگه مونده! (کمتر کاربرد دارن ولی واسه مطالعه بیشتر از این لینک استفاده کن). تسلط به آرایه ها در jS مثل تسلط به جمله سازی در زبان فارسی عه. و تسلط به آرایه ها هم یعنی تسلط به متد هایی که روی آرایه ها هست. اگه واقعا تا این جا حوصله کردی که بخونی بهت تبریک میگم تو یک قهرمانی!</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Thu, 23 Jun 2022 13:52:27 +0430</pubDate></item><item><title>کلیدواژه های let و const در javaScript</title><link>https://virgool.ir/Rocket/کلیدواژه-های-let-و-const-در-javascript-asd2wicuqmdv</link><description>این کلیدواژه ها به ما کمک میکنن به بهترین روش ممکن متغیر هامون رو اعلان کنیم.مقدمهزبان javaScript در سال های اخیر تغییرات خوبی داشته. این تغییرات به صورت کلی در راستای منظم تر شدن و دقیق تر شدن jS بودن. از اصلی ترین ویژگی هایی که از سال ۲۰۱۵ به بعد و با ورژن ES6 معرفی شد دو تا کلیدواژه جدید به نام های let و const بوده. این دو کلیدواژه اعلان متغیر ها رو دقیق تر میکنن. شاید بپرسی که خوب مگه قبلا نمی شد متغیر اعلان کرد؟! چرا میشد ولی یک کم می لنگید. در ادامه مقاله توضیح میدم. (اگه حوصله خوندن نداری می تونی در آخر مقاله در قسمت «خلاصه» دستورات رو حفظ کنی و خودت رو راحت کنی!)اعلان متغیر (Declaration) و مقداردهی (Assignment)به این که یک متغیری رو تعریف کنی میگن Declaration. این کلمه تو زبان انگلیسی یعنی «اعلان کردن». دادن مقدار به این متغیر هم میشه مقداردهی یا همون assignment انگلیسی ها. تو jS برای اعلان کردن یک متغیر عادت کرده بودیم که از کلید واژه var استفاده کنیم. این طوری:var x;    // Declaration اعلان&#xA;x = 12;    // Assignment مقداردهییا این که اصلا می شد از هیچ کلیدواژه ای استفاده نکرد. این طوری:x = 12;    // Declaration and assignmentاستفاده از var یا استفاده نکردن از کلیدواژه در ورژن های جدید jS توصیه نمیشه. چرا؟! برای درک این قضیه باید با مفهوم scope آشنا بشیم.اسکوپ (scope)منظور از scope محدوده ای هست که یک متغیر در اون محدوده معنی میده. مثلا کد زیر رو در نظر بگیر:y = 12;&#xA;function print() {&#xA;    var x = 12;&#xA;    console.log(x);&#xA;    console.log(y);&#xA;} در کد بالا متغیر x فقط داخل تابع print معنی میده. یعنی اگه خارج از براکت های تابع سعی کنیم به این متغیر دسترسی داشته باشیم فایده نداره. به عبارت دقیق تر: اسکوپ متغیر x تابع print هست. به صورت کلی دو تا اسکوپ داریم:محدود (local): این اسکوپ یعنی محدود به بخش خاصی از کد. مثلا تو همین مثال بالا اسکوپ متغیر x لوکال بود. محدود به تابع print. سراسری (global): این اسکوپ یعنی همه جایی. برای مثال در کد بالا متغیر y اسکوپ سراسری داره. چه داخل تابع چه خارج تابع بهش دسترسی داریم. حالا بر گردیم سر اصل داستان. در jS وقتی که یک متغیر رو با var داخل تابع اعلان می کنیم اسکوپ محدود به خودش می گیره. وقتی هم یک متغیری رو بدون کلیدواژه اعلان می کنیم اسکوپ سراسری به خودش می گیره. خوب ایراد چیه پس؟!ایراد در این جاست که این محلی بودن اسکوپ محدود به تابع میشه نه محدود به block. بلاک؟! بلاک دیگه یعنی چی؟! به طور کلی به قسمت های کد میگن بلاک. تو jS این بلاک ها رو با استفاده از { } مشخص میکنیم. مثلا هر تابع خودش یک block حساب میشه. چون موقع تعریف کد اش رو داخل { } قرار دادیم. یک مثال دیگه:var x = 12;&#xA;if (x &gt; 10) {&#xA;    window.alert(&#39;Hello&#39;);&#xA;}در کد بالا هر چیزی که داخل { } های جلوی if قرار دادیم هم یک بلاک محسوب میشه. این داستان برای for و while هم صحت داره. حالا با کلیدواژه var و یا بدون کلیدواژه اعلان کردن یک متغیر چطوری باید متغیری تعریف کنیم که محدود به بلاک باشه؟! اگه با var تعریف کنیم در کل تابع بهش دسترسی داریم (و هر بلاکی که توی اون تابع هست) و اگه بدون کلیدواژه تعریف کنیم در همه جای کد حتی خارج تابع! تکلیف چیه؟!کلیدواژه letاین جاست که کلیدواژه let معرفی میشه. کلیدواژه let به ما امکان میده که متغیر های محدود به بلاک تعریف کنیم (پس اگر بلاکمون تابع باشه، مثل var عمل میکنه). مثلا در کد زیر:x = 12;&#xA;for (let x = 0; x &lt; 100; x++) {&#xA;    console.log(x)&#xA;}در کد بالا متغیر x ای که خارج از حلقه for عه یک متغیره و متغیری که داخل for و با استفاده از let تعریف شده یک متغیر دیگست. به عبارتی اون متغیری که با let تعریف شده فقط و فقط داخل بلاک ‌for معنی میده. چنین چیزی با var ممکن نبود. به عبارت دقیق تر:کلیدواژه let متغیر های block-scoped اعلان میکنه.چون در اکثر مواقع ما با بلاک کد رو به رو هستیم (و خود تابع هم اصلا یک بلاکه) استاندارد تره که var رو به فراموشی بسپاریم و با let کار کنیم. هم چنین توصیه میشه که از اعلان متغیر بدون کلیدواژه خودداری بشه. ولی این همه ماجرا نیست. Redeclarationبا declare کردن یک متغیر آشنا شدیم. یکی دیگه از تفاوت های let با var و بدون کلیدواژه اعلان کردن در اینه که تو حالت قدیمی اگه با var یک متغیری رو اعلان کنیم می تونیم دوباره هم اعلانش کنیم. این جالب نیست چون احتمال خطا رو می بره بالا. بعدشم اگه چند نفر روی یک کد کار کنن هر کسی می تونه متغیر های نفر قبلی رو دوباره برای خودش اعلان کنه. به عبارت دقیق تر:با var و یا بدون کلیدواژه اعلان کردن، امکان redeclaration هست. ولی با let امکان redeclaration نیست.این سهل انگاری هم توسط let اصلاح شده. زمانی که با let متغیری اعلان میشه دیگه ممکن نیست برای بار دوم اعلانش کنیم. این دقت رو می بره بالا و از خطا جلوگیری میکنه.کلیدواژه constحالا بیایم از اینی هم که هست دقیق تر بشیم. وقتی با let کار کنیم میشه یک متغیری رو صرفا اعلان کرد ولی مقدار بهش نداد و بعدا مقدارش رو مشخص کرد. ولی فرض کن میخایم یک متغیری رو اعلان کنیم که مجبورمون کنه دقیقا همون موقع اعلان (declare) کردن مقدارش رو هم مشخص کنیم (assignment).. در قدیم چنین چیزی ممکن نبود ولی با کلیدواژه const این امکان فراهم شده. const هم مثل let اسکوپش به بلاک محدوده.let x;&#xA;x = 12;&#xA;&#xA;const y;    // ERROR: const variables must be assigned&#xA;&#xA;const z = 12;&#xA;z = 13;    // ERROR: const variables cannot be reassignedدر کد بالا به چند نکته مهم دقت کن:در بخش دوم کد نمی تونستیم بگم const x چون که وقتی با let کار میکنیم امکان redeclare کردن یک متغیر نیست. (در بخش اول یک بار x رو اعلان کردیم)نمی تونیم متغیری که با کلیدواژه const اعلان میشه رو بدون مقدار رها کنیم. ارور میده. باید همون جا مقدارش رو هم مشخص کنیم.با کلیدواژه const هم امکان redeclare کردن نیست برای همین بخش سوم کد از z استفاده کردیم.کلیدواژه const که سخت گیر تره حتی امکان عوض کردن مقدار متغیر رو هم به ما نمیده. یعنی نمی تونیم کل مقدار رو برداریم و یک مقدار دیگه به جاش بذاریم. به عبارت دقیق تر:کلیدواژه const امکان reassignment به ما نمیده.برای مقادیر ساده (مثل رشته، عدد، بولین ...) این عملا یعنی این که کلیدواژه const یک متغیر تغییر ناپذیر اعلان کرده (که اصلا متغیر نیست! ثابته). ولی در مورد مقادیر پیشرفته مثل Array و Object این داستان فرق داره. وقتی که یک مقدار پیشرفته (مثل آرایه، آبجکت، تابع ...) رو با کلیدواژه const اعلان می کنیم (و دقیقا توصیه هم بر اینه که با const اعلان بشن این ها)، هر چند نمیشه کل اون مقدار پیشرفته رو برداشت و یک مقدار جدید قرار داد (نمیشه reassign کرد) ولی می تونیم اون مقدار پیشرفته رو دستکاری (manipulate) کنیم. مثلا این طوری:const user = {&#xA;    age: 24,&#xA;    name: &#39;bizhan&#39;,&#xA;    os: &#39;linux&#39;&#xA;};&#xA;user = &#39;bizhan&#39;    // ERROR: you cannot reassign a const variable&#xA;user.age = 26;     // WORKS: you just manipulated (it is not reassignment)Global Abatementاین همه تفاوتی که بین let و const و var و بدون کلیدواژه اعلان کردن گفتم همه داستان نیست. let و const مزایای دیگری هم دارن. بسته به این که jS رو در browser یا node (یک محیط برای اجرا jS عه که با مرورگر فرق داره و خیلی هم باحاله. عملا jS رو تبدیل به یک زبان برنامه نویسی همه فن حریف کرده) اجرا کنیم در هر صورت با یک شئ گلوبال سر و کار داریم. مثلا توی مرورگر این شئ گلوبال اسمش window عه که از همه جا بهش دسترسی داریم و یک جورایی مالک همه چیزه. (شئ گلوبال == Global object)وقتی که یک متغیر رو بدون کلیدواژه اعلان کنیم علاوه بر این که اسکوپش Global میشه، به global object مون هم attach میشه و به صورت یکی از property های اون global object در میاد (ولی با let و const این حالت پیش نمیاد). این استاندارد نیست. ممکنه پیش فرض های شئ گلوبال مون رو عوض کنه یا با کتاب خونه هایی مثل React تداخل داشته باشه.x = 12;&#xA;alert(x)    // 12&#xA;alert(window.x)    // 12&#xA;&#xA;let y = 12;&#xA;alert(y);    // 12&#xA;alert(window.y)    // undefinedاونایی که سعی میکنن استاندارد کد بنویسن از یک مفهومی پیروی میکنن به نام Global Abatement که یعنی:تا حد ممکن از دستکاری Global object خودداری کنیم.خوب اومدیم و به متغیر global نیاز داشتیم. با let و const که نمیشه متغیر global اعلان کرد. از طرفی استاندارد هم میگه که شئ گلوبال رو دستکاری نکن. تکلیف چیه؟ اومدن و یک چیزی درست کردن به نام State که اون هم مثل window یک global object عه با این تفاوت که مال خودمونه و هر چه قدر دوسته داشته باشیم می تونیم دستکاریش کنیم. اصلا برای همین کار درست شده! به کار کردن با state میگن state management. مثلا توی چهارچوب Vue برای state management باید از Vuex استفاده کنی. خلاصهتفاوت های دیگری هم هست بین var و let و cont بدون کلیدواژه اعلان کردن. یکی از این تفاوت ها Hoist شدنه که در حوصله بحث نمی گنجه ولی می تونی تو این لینک مطالعه کنی. این مثنوی طولانی رو گفتیم! حالا گذشته از همه اینا بذار خلاصه کل این مقاله رو به صورت چند تا دستور مشخص و صریح برات لیست کنم:در اعلان متغیر ها از کلیدواژه var استفاده نکن. فراموشش کن.متغیر ها رو بدون کلیدواژه اعلان نکن. این روش رو فراموش کن.برای مقادیر متغیر ابتدایی (مثل رشته، عدد، بولین ...) از کلیدواژه let استفاده کن.برای مقادیر ثابت ابتدایی (مثلا عدد PI که همیشه همون ۳.۱۴ هست) از کلیدواژه const استفاده کن.برای مقادیر پیچیده (مثلا Array, Object, Function ....) از کلیدواژه const استفاده کن.نتیجه گیریدر عکس بالا (که از اینترنت گیر آوردم) منظور از این که میگه همه سه تا کلیدواژه function scoped هستن واسه اینه که هر تابع هم خودش در واقع یک بلاکه. به عبارتی این طوری میخاد بگه: بلاک تابع و همه بلاک های داخلشپس از این به بعد از let و const استفاده کن. نه این که بیشتر استفاده کنی ها، نه. کلا از این ۲ تا استفاده کن. راستشو بخای برای من درکش سخته که چرا jS این همه اعلان متغیر رو پیچیده کرده. به خدا تو پایتان میگی x = 1 و تموم! حالا باز جای شکرش باقیه که مجبورمون نمیکنه همون دم اعلان جنس متغیر رو هم بهش بگیم (مثل ++c). امیدوارم که از این مقاله خوشت اومده باشه. در نهایت خوشحال میشم نظرت درباره مقاله رو با یک کامنت بهم بگی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Wed, 22 Jun 2022 04:03:46 +0430</pubDate></item><item><title>متغیر محیطی PATH در لینوکس</title><link>https://virgool.ir/Rocket/متغیر-محیطی-path-در-لینوکس-urj156jsuujv</link><description>متغیر محیطی PATH مسیر هایی رو ذخیره میکنه که فایل های executable دارن.مقدمهاولین باری که خودم با متغیر محیطی PATH رو به رو شدم موقع نصب Java بود. بعد ها وقتی که به سمت Ubuntu حرکت کردم بیشتر با این متغیر و کاربرد هاش آشنا شدم. متغیر محیطی PATH همون طوری که از اسمش بر میاد یک متغیر محیطی (Environment Variable) عه. مقدار PATH یک رشته است که از مسیر (Path) هایی که با : (اسم این علامت دو نقطه colon عه) از هم جدا شدن درست شده. در ادامه این مقاله بیشتر با این متغیر آشنا میشیم.مفهوم متغیر محیطیبرای درک بهتر متغیر محیطی PATH اول از همه باید با متغیر های محیطی آشنا بشیم. متغیر های محیطی (Environment variable) همون طوری که از اسمشون مشخصه به متغیر هایی اطلاق میشن که اطلاعاتی در خصوص محیط پردازش رو نگهداری میکنن. منظور از محیط در این جا هر فضایی هست که بشه درش عملیات رایانه ای انجام داد. برای مثال وقتی که یک نرم افزار رو روی ۲ تا کامپیوتر جدا نصب می کنیم، هر سیستم عاملی یک محیط برای اون نرم افزار حساب میشه و هر محیطی هم ویژگی های خاص خودش رو داره که این ویژگی ها در متغیر های محیطی ذخیره میشن. اصطلاح متغیر های محیطی کلی تر از این حرفاست. حتی روی یک رایانه هم که ۲ تا اکانت کاربری متفاوت داریم، هر کاربری متغیر های محیطی خودش رو داره. متغیر های محیطی مختص Unix یا Windows نیستن و در معماری نرم افزار هم ازشون استفاده میشه. مثلا وقتی که Laravel رو نصب می کنیم یک فایل به اسم env. داریم که متغیر های محیطی رو در خودش نگهداری میکنه.مثال اکانت کاربریفرض کن که روی یک سیستم عامل Ubuntu دو تا کاربر داریم. نام کاربری یکی bizhan و نام کاربری اون یکی sepehr عه. همون طوری که توضیح دادیم هر کدوم از این کاربر ها متغیر های محیطی خودشون رو دارن. یکی از این متغیر های محیطی USER نام داره که username کاربری که داره از سیستم استفاده میکنه رو در خودش نگهداری میکنه. وقتی که با اکانت کاربری bizhan از ترمینال استفاده کنیم و دستور زیر رو وارد کنیم مقدار bizhan برامون پرینت گرفته میشه:echo $USERولی وقتی که با اکانت کاربری sepehr از سیستم عامل استفاده کنیم و دقیقا همین کد بالا رو توی ترمینال اجرا کنیم مقداری که پرینت میشه sepehr عه.متغیر های محیطی در لینوکسحالا که با مفهوم کلی متغیر محیطی آشنا شدیم وقتشه که به صورت عملی با متغیر های محیطی ای که در سیستم عامل لینوکس باهاشون سر و کار داریم رو به رو بشیم. برای مشاهده همه متغیر های محیطی دستور env رو داخل terminal وارد می کنیم.envوقتی دستور بالا اجرا بشه، میبینی که همه متغیر های محیطی به صورت UPPERCASE نام گذاری شدن. مثلا متغیر محیطی HOME که آدرس مسیر خانه کاربر رو در خودش نگهداری میکنه. چند تا از متغیر های محیطی معروف لینوکس رو این زیر برات لیست کردم:PWD: آدرس مسیری که کاربر در حال حاضر توش هستHOME: آدرس پوشه خانه کاربر لاگین کردهUSER: نام کاربری کاربر لاگین کردهPATH: مسیر هایی که سیستم عامل در اون ها دنبال فایل های قابل اجرا می  گردهتعریف متغیر محیطی در لینوکسحالا که این همه از متغیر های محیطی صحبت کردیم حیف نیست که متغیر محیطی خودمون رو تعریف نکنیم؟! با دستور export میشه متغیر محیطی مخصوص خودمون رو تعریف کنیم.export MY_ENV_VAR=&#39;bizhan.he1996&#39;همون طوری که متوجه شدی برای تعریف متغیر محیطی نیازی به علامت $ نیست. علامت $ وقتی استفاده میشه که بخایم به مقدار یک متغیر دست پیدا کنیم. برای مثال بعد از اجرای کد بالا اگه دستور زیر رو اجرا کنم:echo MY_ENV_VARتنها چیزی که عایدم میشه عبارت MY_ENV_VAR هست. ولی اگه دستور زیر رو اجرا کنم مقدار متغیر MY_ENV_VAR که برابر با bizhan.he1996 بود برام پرینت گرفته میشه:echo $MY_ENV_VARهم چنین برای عوض کردن مقدار یک متغیر محیطی هم مجددا از همین دستور export استفاده میشه:export MY_ENV_VAR=&#39;new value&#39;جهت حذف یک متغیر از دستور unset استفاده میشه:unset MY_ENV_VARهر کاری که با متغیر های محیطی تعریف شده انجام دادیم به محض این که terminal رو ببندیم و یک ترمینال جدید باز کنیم از بین خواهد رفت. به عبارتی عمر متغیر های محیطی که خودمون تعریف میکنیم یا تغییراتی که روی متغیر های محیطی خود لینوکس میدیم محدود به طول عمر همون یک terminal ای هست که باز کردیم. این جا سوال پیش میاد که پس اگه بخایم یک متغیر محیطی رو مادام العمر تغییر بدیم یا یک متغیر محیطی همیشگی برای خودمون تعریف کنیم باید چه کار کنیم؟!فایل bashrc.پاسخ سوال بالا در فایلی به نام bashrc. نهفته است که توی home directory موجوده (برای پرش به مسیر خانه فقط کافیه که cd رو داخل ترمینال اجرا کنی بدون هیچ اضافاتی). این فایل از اون جایی که اول اسمش یک dot هست hidden عه و برای مشاهده اش با دستور ls باید آپشن a- رو وارد کنیم:ls -aوقتی که پیداش کردیم با یک ویرایشگر متن مثل nano یا gedit می تونیم ویرایشش کنیم. gedit .bashrc در انتهای فایل bashrc. (بدون این که به بقیه چیزای فایل کار بگیریم) عبارت زیر رو اضافه میکنیم و در نهایت فایل رو ذخیره میکنیم، ترمینال رو می بندیم و یک ترمینال جدید باز میکنیم:export MY_ENV_VAR=&#39;bizhan.he1996&#39;حالا که ترمینال جدید باز کردیم تست می کنیم که آیا متغیر محیطی مون تعریف شده یا نه:echo $MY_ENV_VARخاصیت مهم فایل bashrc. اینه که هر باری که یک terminal جدید باز میکنیم دستورات درون این فایل اجرا میشه. پس از این به بعد هر مرتبه که terminal رو باز کنیم خط بالا هم اجرا میشه و متغیر محیطی مون تعریف میشه. فایل bashrc. مخصوص non-login shell هاست. برای login shell ها فایل profile. اجرا میشه که این فایل هم داخل home directory‌ قرار داره. در حد این مقاله، با همون فایل bashrc. کار کنیم کافیه.متغیر محیطی PATHحالا که هم با مفهوم متغیر محیطی و هم با متغیر های محیطی در لینوکس آشنا شدیم وقتشه که بریم سر اصل مطلب. متغیر محیطی PATH در لینوکس مسیر هایی (directory) هایی رو در خودش ذخیره میکنه که سیستم عامل باید در اون مسیر ها دنبال فایل executable بگرده. منظور از فایل executable فایلی هست که خودش قابل اجراست و نیازی به compiler هایی مثل gcc نداره. البته اجرا کردن این فایل های قابل اجرا مشروط بر اینه که اجازه (permission) اجرا کردن اون فایل به کاربری که قصد اجراش رو داره داده شده باشه. بذار با یک مثال بریم جلو. فرض کن که قصد داریم دستور مخصوص خودمون رو درست کنیم. یعنی همون جوری که از دستور هایی مثل ls و cd یک عمره داریم استفاده میکنیم یک دستور هم برای خودمون درست کنیم. مثلا فرض کن اسم دستور مون bizhan باشه. برای این کار قدم به قدم:فایلی به نام bizhan.sh توی مسیر خانه درست می کنیم. این طوری:touch bizhan.shدرون این فایل (که به زبان Bash هست) این کد رو قرار میدیم:echo &#39;My Name is Bizhan&#39;فایل رو ذخیره میکنیم و می بندیم. حالا برای این که تست کنیم این فایل درست کار میکنه یا نه به دستور bash میدیمش:bash bizhan.shمشاهده میکنیم که عبارت My name is Bizhan رو برامون پرینت کرد. در گام بعدی برای این که این فایل رو قابل اجرا کنیم (یعنی بدون نیاز به دستور bash به عبارت My name is Bizhan برسیم) باید permission اجرا شدن رو به کاربر بدیم. این طوری:chmod u+x bizhan.shحالا اگه توی ترمینال و در آدرس خانه عبارت زیر رو وارد کنیم عبارت My name is Bizhan برامون پرینت میشه:./bizhan.shبه عبارتی فایل bizhan.sh رو بدون نیاز به bash اجرا کردیم، مستقیما. ولی راهکاری هست که حتی از این هم مستقیم تر اجرا کنه این فایل رو. پسوند sh. فایل رو پاک میکنیم (یعنی اسم فایل بشه bizhan خالی). این جاست که متغیر PATH میاد وسط. اگه یادت باشه گفته بودیم متغیر محیطی PATH آدرس مسیر هایی رو نگه داری میکنه که درش فایل های executable وجود دارن. برای اضافه کردن home directory به PATH داخل فایل bashrc. میریم و عبارت زیر رو در انتهاش اضافه میکنیم، ذخیره میکنیم و می بندیم:export PATH=~:$PATHحالا از این به بعد هر بار که ترمینالو باز کنیم خط بالا اجرا میشه و مقدار متغیر PATH رو عوض میکنه. پس از این به بعد توی هر مسیری که دستور bizhan رو وارد کنیم عبارت My name is Bizhan پرینت خواهد شد چون که فایل bizhan تو مسیر خانه قرار داشت که مسیر خانه هم به متغیر PATH اضافه شده بود. مسیر هایی که توی متغیر PATH ذخیره شدن جهت فایل های executable اسکن میشن و فایل bizhan هم اگه یادت باشه executable کرده بودیم.نتیجه گیریببخشید اگه طولانی شد. سعی کردم با مثال و ریز توضیح بدم که قابل درک باشه. در نهایت خیلی خوشحال میشم اگه نظرت در مورد این مقاله رو به صورت یک کامنت زیر خودش بهم بگی. </description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Wed, 15 Jun 2022 16:24:37 +0430</pubDate></item><item><title>استاندارد سلسله مراتب فایل ها در لینوکس</title><link>https://virgool.ir/@bizhan.he1996/ساختار-مسیر-ها-در-لینوکس-jq6jkzw1c9ob</link><description>در سیستم عامل Linux برخلاف ویندوز که با درایو ها سر و کار داریم، با یک سری directory رو به رو هستیم. &#xA;مقدمهبرای اون هایی که از پس زمینه ویندوزی میان در نگاه اول ساختار پوشه ها و نحوه دسته بندی شون در لینوکس اندکی عجیب به نظر میرسه. در حالی که توی ویندوز چند تا درایو داریم (که اصل کاری شون C عه) این جا فضای هارد دیسک به صورت یکپارچه نگه داشته شده و همه فولدر ها داخل یک فولدر مادر به نام root قرار داده شدن.در دنیای لینوکس بیشتر از directory به جای فولدر استفاده میشه و تو این مقاله هم این دو تا کلمه به صورت هم معنی استفاده شدن.در ادامه به بررسی فولدر های اصلی در لینوکس می پردازیم.مسیر (Path)وقتی میخایم تو فولدر ها گشت و گذار کنیم باید آدرس (مسیر) هر فولدر رو بلد باشیم. با دستور cd که مخفف change directory هست می تونیم مسیر مون رو عوض کنیم. دستور cd یک argument از ما میگیره که همون آدرس (مسیر، path) مقصد مورد نظر هست. به دو صورت می تونیم آدرس رو بدیم:مطلق (absolute): یعنی از root شروع میکنیم و به ترتیب میریم جلو. مثلا آدرس مطلق دسکتاپ کاربری به نام bizhan میشه:/home/bizhan/Desktopنسبی (relative): یعنی به نسبت مسیری که الان درش حضور داریم آدرس میدیم. برای مثال اگه تو مسیر خانه حضور داشته باشم برای ورود به Desktop باید این مسیر رو به دستور cd بدیم:cd Desktopنمودار کلی ساختار سلسله مراتبی فایل ها (FHS) در لینوکس/home/[username]زمانی که ترمینال رو باز می کنیم به صورت پیش فرض در مسیر خانه (home directory) قرار داریم که به صورت اختصار با ~ هم نشون داده میشه. برای مثال اگر نام کاربری شما bizhan باشه آدرس مطلق (absolute path) مسیر خانه میشه: /home/bizhanتو پوشه خانه کاربری شما فولدر هایی مثل Desktop, Pictures, Videos و ... قرار داره که انگاری همون Documents توی ویندوز میشه. یک سری فایل های مخفی هم هست توی این مسیر که اول اسمشون dot داره (همون نقطه) مثلا bashrc. و bash_history. که هر کدوم کاربرد های خاص خودشون رو دارن. به صورت کلی ۳ روش برای ورود به مسیر خانه هست:cd&#xA;cd /home/bizhan&#xA;cd ~می تونین در مسیر خانه هر فولدر و یا فایلی که دوست دارین درست کنین. به عبارتی این مسیر فایل هایی رو در بر می گیره که شخصی همون کاربر باشن. از یک یادداشت ساده گرفته تا کد های یک پروژه.روت (Root)این مسیر که با / هم نشون داده میشه مسیر مادر همه مسیر های دیگست. همه پوشه ها و فایل ها زیر شاخه های این پوشه هستن. وقتی که ترمینال رو باز می کنیم برای این که وارد root بشیم باید دستور زیر رو وارد کنیم:cd /حالا با دستور ls می تونیم محتویات این مسیر رو مشاهده کنیم. برای مثال همون طوری که بالا گفتیم اگر نام کاربری مون bizhan باشه و بخایم وارد خانه این کاربر بشیم (به نسبت مسیر root) باید دستور زیر رو وارد کنیم:cd home/bizhanدقت کن که تو مثال بالا اول آدرس / قرار ندادیم چون این آدرس نسبی عه. در کد بالا فرض رو بر این گذاشتیم که تو مسیر root حضور داریم (برای درک این که در حال حاضر تو چه مسیری هستیم می تونی دستور pwd رو توی ترمینال وارد کنی).مسیر root خودش یک سری فولدر داره که فقط کاربر root حق دستکاری (write) روشون رو داره. این کاربر هم مثل بقیه کاربر های یک home directory داره برای خودش با این فرق که آدرس خانه اش root/ عه. یعنی تو پوشه home نیست خانه اش./binاین مسیر که مخفف binary هست فایل های binary دستور هایی رو نگه داری میکنه که به صورت عمومی ازشون استفاده میکنیم مثلا ls. این فایل ها executable هستن به این معنی که خودشون رو می تونیم اجرا کنیم و نیازی به واسطه برای اجرا شدنشون نداریم./bootفایل هایی که برای درست بوت شدن (بارگذاری اولیه) سیستم عامل لازمه در این مسیر نگه داری میشن مثل kernel. کرنل در لغت به معنی هسته است و قسمت مرکزی سیستم عامله که فعالیت های اصلی مثل مدیریت منابع سخت افزازی شامل RAM رو انجام میده./devاین مسیر که مخفف شده device هست فایل های مربوط به device های ضروری متصل به سیستم رو نگه داری میکنه. مثلا وقتی که یک USB drive به سیستم وصل می کنیم یک فایل همنام اسم USB Drive داخل مسیر زیر درست میشه:/dev/disk/by-label /etcاین فولدر فایل هایی رو در خودش نگه داری میکنه که تنظیمات پیکربندی (configuration) مربوط به کل سیستم رو انجام میدن. اگر دقت کنی برخی فایل های داخل این مسیر پسوند conf. دارن که مخفف همون configuration عه. مثلا تنظیمات پیکربندی مربوط به mysql داخل مسیر زیر نگه داری میشه:/etc/mysql/libفایل های binary که داخل فولدر هایی مثل bin ذخیره میشن برای اجرا شدن نیاز به یک سری پیش نیاز هایی دارن (library) که در این مسیر نگهداری میشن./mediaاین مسیر، فولدر های حافظه های جانبی مثل CD-ROM و USB Flash رو نگهداری میکنه و از طریق فولدر هایی که در این مسیر هستن می تونیم به حافظه های جانبی دسترسی داشته باشیم. در مقایسه با مسیر dev/ که فایل های مورد نیاز این تجهیزات رو نگهداری میکنه، این مسیر فولدر هایی رو نگهداری میکنه که نقطه ورود به اون حافظه های جانبی هستن./mntفایل هایی که توسط ادمین به صورت موقتی mount میشن در این مسیر نگهداری میشن./optمخفف optional عه. بسته های نرم افزاری اختیاری (همون هایی که خودمون نصب میکنیم) در این مسیر ذخیره میشن. مثلا Google Chrome که به صورت پیش فرض روی لینوکس نصب نیست رو وقتی خودمون نصب میکنیم در این مسیر نگهداری میشه فایل هاش./sbinاین مسیر شبیه به مسیر bin/ عه با این تفاوت که binary هایی رو نگهداری میکنه که توسط ادمین سیستم با اهدافی مثل نگهداری سیستم استفاده میشن. حرف s اول این مسیر هم نشون دهنده همین system هست. به عبارت دیگه این مسیر system binaries رو نگهداری میکنه./srvمخفف service عه. همون طور که از اسمش هم مشخصه فایل هایی رو نگهداری میکنه که به سرور مربوطه (چون این سرور عه که سرویس میده) مثلا دیتا ها و اسکریپت هایی که به سرور مربوطه./tmpمخفف شده temporary عه. فایل های موقتی ای رو نگهداری میکنه که توسط خود سیستم عامل و یا توسط کاربر درست میشن. این فایل ها با ریست کردن سیستم از بین میرن. هم چنین طول عمر کمی دارن و محدودیت هایی هم بر سایزشون اعمال میشه. /usrمخفف user هست. اکثرا برنامه ها و ویژگی هایی رو نگهداری میکنه که چندین کاربر ازش استفاده میکنن. فایل های داخل این مسیر اصطلاحا second hierarchy هستن. برای مثال usr/bin فایل های binary برنامه های کاربر رو نگهداری میکنه. اگه توی مسیر bin/ یک فایل binary رو پیدا نکردین باید توی usr/binary دنبالش بگردین مثلا scp. /procمخفف process عه. اطلاعاتی حاوی پردازش های سیستم داره که به صورت فایل ذخیره شدن. این فایل ها به صورت خودکار و آنی توسط خود سیستم عامل ایجاد و به روزرسانی میشن. نتیجه گیریدر بیشتر مواقع ما با مسیر خانه (home directory) و زیرشاخه های اون سر و کار داریم. زمانی که لینوکس رو به عنوان یک سرور استفاده میکنیم ممکنه برای نصب یک سری نرم افزار ها به پوشه های دیگری غیر از خانه هم سر بزنیم (چون وقتی سیستم عامل میخاد به عنوان سرور نقش بازی کنه به غیر از کاربری خودمون، از همه جای دنیای وسیع اینترنت هم افراد دیگه ای میخان ازش سرویس بگیرن). یاد داشتن ساختار فایل ها در لینوکس باعث میشه بدونیم کجا رو دست بزنیم و کجا حساسه که نباید کاری به کارش بگیریم. در نهایت ممنون میشم اگر من رو به یک کامنت مهمون کنی و نظرت رو درباره مقاله بهم بگی. </description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Tue, 14 Jun 2022 17:20:46 +0430</pubDate></item><item><title>دسترسی ها در Unix‌</title><link>https://virgool.ir/@bizhan.he1996/دسترسی-ها-در-unix-zyg6zr9xdt9h</link><description>در سیستم عامل های بر اساس Unix می تونیم دسترسی فایل ها و پوشه ها رو مشخص کنیم.مقدمهتعیین سطوح دسترسی فایل ها و پوشه ها در هر سیستم عاملی اهمیت داره. در سیستم عامل های بر اساس Unix مثل Linux می تونیم با دستور chmod سطوح دسترسی قشر های مختلف کاربری رو برای فایل ها و پوشه ها تعیین کنیم. این طوری می تونیم مطمئن بشیم که فایل های (یا پوشه ها) حساس فقط توسط کاربران دارای صلاحیت قابل دسترسی هستند. در این مقاله به بررسی مفصل دسترسی ها در Unix می پردازیم.مشاهده دسترسی هادر یونیکس، هر فایل یا پوشه یک رشته از دسترسی ها داره که برای راحت تر شدن کار تو این مقاله بهش «رشته دسترسی» میگیم. برای مشاهده رشته های دسترسی همه فایل ها یا پوشه های مسیر جاری می تونیم از دستور ls با آپشن l- استفاده کنیم.ls -lاگه بخایم رشته دسترسی یک فایل یا پوشه خاص رو مشاهده کنیم کافیه به دستور بالا اسم اون فایل یا پوشه رو اضافه کنیم. مثلا کد زیر رشته دسترسی فایل names.txt رو نشون میده:ls -l names.txtرشته دسترسیرشته های دسترسی یا با - شروع میشن یا با d. - (اسم این کاراکتر hyphen عه) نشون دهنده اینه که اون رشته دسترسی متعلق یه یک فایل عه و اگه با d شروع بشه یعنی اون رشته دسترسی متعلق به یک پوشه (directory) هست. برای درک رشته های دسترسی باید سطوح دسترسی در Unix رو بلد باشیم.drwxrwxr-x        # directory&#xA;-rwxrwxrwx       # Fileسطوح دسترسی ۳ تا سطح دسترسی در Unix داریم که برای هر کدوم یک حرف از الفبای انگلیسی به اختصار در نظر گرفته میشه (رمز rwx رو یادت باشه):read (r)write (w)execute (x)همون طوری که از اسم این ۳ سطح دسترسی مشخصه read به معنای داشتن اجازه برای خوندن محتویات فایل یا پوشه، write برای دستکاری کردن و execute برای اجرا کردنه. پس برای مثال در رشته های دسترسی بالا حرف r نشان دهنده اینه که اجازه read داده شده. ولی به کی؟!دسترسی های بالا می تونن به مالک فایل (owner) که یک کاربره (user)، یا گروه فایل (group) یا بقیه (other) اختصاص داده بشن. به بقیه world هم میگن. برای هر کدوم از این ۳ تا یک حرف اختصاری وجود داره (رمز ugo رو یادت باشه):owner (u)group (g)other (o)حالا با توجه به ۳ سطح دسترسی و ۳ قشری که میشه بهشون دسترسی ها رو داد می تونیم رشته دسترسی رو تفسیر کنیم. مثلا رشته دسترسی زیر رو در نظر بگیر:-rw-r--r--اول از همه با توجه به این که رشته دسترسی با hyphen شروع شده متوجه میشیم که این رشته دسترسی به یک فایل تعلق داره. بعد از اون سطح دسترسی رو داریم که به ترتیب دسترسی های مالک فایل (user)، گروه فایل (group) و بقیه (other) است. پس رشته دسترسی بالا این طوری تفسیر میشه:user: read + writegroup: readother (world): readبه عبارت دیگه، رشته دسترسی بالا اجازه خواندن و نوشتن رو به کاربر مالک فایل میده، اجازه خواندن رو به گروهی که فایل بهش تعلق داره میده و اجازه خواندن رو به بقیه اقشار (همون world) میده. تغییر دسترسی هاحالا که تونستیم رشته های دسترسی رو درک کنیم به این جا میرسیم که چطوری سطوح دسترسی قشر های مختلف رو عوض کنیم. این کار با دستور chmod انجام میشه که فرمول کلیش این طوریه:chmod [changes] [filename] برای کار کردن با دستور chmod باید تغییراتی که مد نظرمون هست و اسم فایل (یا پوشه) ای که میخایم تغییرات روش اعمال بشه رو داشته باشیم. تغییرات مد نظرمون باید با فرمت خاصی نگارش بشن. به این طریق که اول اسم قشری که میخایم دسترسی اش رو عوض کنیم (یکی از ۳ حالت u, g, o)، سپس عملگر نوع تغییر (+ برای افزودن دسترسی، - برای حذف دسترسی و = برای مشخص کردن دسترسی) و در نهایت سطح دسترسی. بذار با مثال بریم جلو.مثال ۱: افزودن دسترسی x به مالک (u) فایل برای فایل calc.shchmod u+x calc.shمثال ۲: کم کردن دسترسی w از گروه فایل برای فایل calc.shchmod g-w calc.shمثال ۳: مشخص کردن دسترسی world برای فایل calc.shchmod o=r calc.shمثال ۴: مشخص کردن یک جای سطوح دسترسی هر ۳ قشر برای فایل calc.shchmod u=rwx,g=rw,o=r calc.shعدد دسترسیموقع کار کردن با دستور chmod علاوه بر علائم دسترسی (rwx) میشه از اعداد دسترسی هم استفاده کرد. این طوری هم سریع تر و هم راحت تر به هدف مون میرسیم. هر سطح دسترسی یک عدد داره:read (4)write (2)execute (1)no permission (0)با جمع کردن مقادیر این اعداد می تونیم دسترسی های یک قشر رو مشخص کنیم. مثلا عدد ۷ که حاصل جمع ۴ و ۲ و ۱ عه یعنی همه دسترسی ها. از اون جایی که ما با ۳ قشر مختلف سر و کار داریم (ugo) پس باید یک عدد ۳ رقمی درست کنیم که صدگان اش نشان دهنده دسترسی های مالک فایل، دهگانش نشان دهنده دسترسی های گروه فایل و یکانش نشان دهنده دسترسی های world عه. بذار با مثال بریم جلو.مثال ۱: دادن همه دسترسی ها به همه قشر ها برای فایل calc.shchmod 777 calc.shمثال ۲: دادن هر ۳ نوع دسترسی به مالک فایل و فقط read به دو قشر دیگر برای فایل calc.sh:chmod 744 clalc.shمثال ۳: دادن هر ۳ نوع دسترسی به مالک فایل و هیچ نوع دسترسی به ۲ قشر دیگر برای فایل calc.sh:chmod 700 calc.shتغییر مالک فایلجدا از تغییر سطح دسترسی فایل ها گاهی اوقات ممکنه لازم باشه که مالک فایل ها رو عوض کنیم. برای عوض کردن مالک یک فایل باید وارد محیط super user بشیم که با دستور su انجام میشه. بعدش از دستور chown استفاده میکنیم تا مالک فایل رو عوض کنیم که فرمول کلیش این طوریه:chown username filenameبه جای username باید اسم کاربری رو بذاریم که قراره مالک جدید فایل بشه.تغییر گروه فایلاگه یادت باشه تو قشر هایی که می تونستن به فایل دسترسی داشته باشن یک group هم بود که با g نشونش میدادیم. برای عوض کردن مالک یک فایل باید وارد محیط super user بشیم که با دستور su انجام میشه. بعدش برای عوض کردن گروهی که فایل بهش تعلق داره از دستور chgrp استفاده میکنیم که فرمول کلیش این طوریه:chgrp groupname filenameبه جای groupname باید اسم گروهی که قراره گروه جدید فایل باشه رو بذاریم.نتیجه گیریوقتی که به صورت شخصی داریم از سیستم عامل های بر اساس Unix (مثل لینوکس) استفاده میکنیم ممکنه اهمیت سطوح دسترسی درک نشه ولی زمانی که بحث server میاد وسط و یا رایانه هایی در یک سازمان که چندین کاربر دارن ازش استفاده میکنن خیلی مهم میشه که مالک هر فایل مشخص باشه و یا این که سطح دسترسی برای هر قشر رو مشخص کنیم. در نهایت خیلی خوشحال میشم که نظرت رو درمورد مقاله به صورت یک کامنت بگی. </description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Mon, 13 Jun 2022 11:17:16 +0430</pubDate></item><item><title>ویژگی های زبان Bash</title><link>https://virgool.ir/@bizhan.he1996/ویژگی-های-زبان-bash-cwabrogvfj0l</link><description>زبان Bash به عنوان زبان پیش فرض سیستم عامل های بر اساس Unix ویژگی های خاص خودشو داره.مقدمهزبان ‌Bash یکی از زبان های پرکاربرد به خصوص در سیستم عامل های بر اساس Unix عه. در عین شباهت به زبان های رایجی مثل Python، این زبان ویژگی های خاص و تا حدودی عجیبی هم داره. تسلط به زبان Bash می تونه قدرت باورناپذیری به ما بده به خصوص زمانی که داریم با سرور کار می کنیم. تو این مقاله به بررسی چند تا از ویژگی های جالب زبان Bash می پردازیم.داده ها جنس ندارندر زبان Bash داده ها جنس ندارن! شاید فکر کنی که خوب این طوری که نمیشه! جواب اینه که زبان ‌Bash خودش هنگام محاسبات میاد و بررسی میکنه که آیا جنس داده ها برای اون عملیات مناسب هست یا نه. حتی تو error هایی که میده ممکنه اشاره کنه که متغیر داده شده عدد نیست ولی در هر صورت جنس داده ها دقیقا مشخص نیست.رشته ها می تونن بدون quotation mark باشنمنظور از quotation mark ها همون &#39; و &#34; عه که تو اکثر زبان ها وقتی میخایم یک رشته رو تعریف کنیم برای این که با متغیر ها اشتباه نشن مقدار رشته رو داخل quotation mark میذاریم. مثلا تو زبان /p&gt;var name = &#34;bizhan&#34;ولی تو زبان bash خیلی راحت میگیم:name=bizhanالبته می تونیم داخل quotation mark هم قرارش بدیم ولی الزامی نیست. اون جایی مجبور میشیم یک رشته رو داخل quotation mark قرار بدیم که توش space داره. مثلا:name=&#39;bizhan hejazi&#39;چیزی به نام return نداریمتو زبان های معروف وقتی که یک function کارش رو انجام میده میتونه حاصل نهایی همه محاسباتش رو به صورت یک مقدار return کنه ولی توی Bash کلیدواژه ای به اسم return نداریم! برای شبیه سازی return می تونیم حاصل نهایی محاسبات function رو داخل یک global variable ذخیره کنیم. یا این که می تونیم یک رشته رو echo بگیریم که مثلا بگه با موفقیت انجام شد.مقادیر عددی رو با استفاده از flag ها مقایسه میکنیم نه عملگر ها!تو زبان های شناخته شده ای مثل PHP وقتی میخایم دو تا مقدار عددی رو با هم مقایسه کنیم از عملگر های شبیه به ریاضی مثل &gt; و یا مثلا == استفاده میکنیم. تو Bash برای همین منظور باید از flag ها استفاده کنیم. flag ها عملگر هایی هستن که اولشون یک - (اسم این علامت hyphen عه) قرار داده و بعد از hyphen عبارت دو حرفی ای مثل eq. مثلا فلگ eq- برای بررسی برابر بودن دو مقدار عددی استفاده میشه. بذار با مثال توضیح بدم:# in PHP&#xA;if ($x &gt; 3) {&#xA;    echo &#34;OK&#34;&#xA;}&#xA;# in Bash&#xA;if [ $x -gt 3 ]&#xA;then&#xA;    echo OK&#xA;fiبلوک هایی مثل if و for رو با کلیدواژه ها می بندیمعادت کردیم که تو اکثر زبان ها بلوک هایی مثل if رو با { } مشخص کنیم. یا مثلا در زبان Python از indentation استفاده میشه. ولی تو زبان Bash بلاک های کد رو مشخصا با یک کلیدواژه می بندیم (البته برخی جا ها از { } هم میشه استفاده کرد مثلا تو تعریف function ها). مثلا برای بستن و اعلام تمام شدن بلاک if از کلیدواژه fi استفاده میکنیم.if [ 3 -eq $x ]&#xA;then&#xA;    echo OK&#xA;fiهمین داستان برای loop ها هم تکرار میشه و loop ها رو باید با کلیدواژه done خاتمه بدیم:x=-3&#xA;while [ $x -le 4 ]&#xA;do&#xA;    echo OK&#xA;    let x=$x+1&#xA;doneشاید در نگاه اول این اضافه کاری به نظر برسه ولی وقتی متوجه میشیم که میشه زبان Bash رو به صورت خط به خط مستقیما داخل terminal نوشت می فهمیم این ویژگی خیلی هم کاربردی و خوبه.متغیر با مقدار متغیر فرق داره!تو زبان Bash برای دسترسی به مقدار یک متغیر باید حرف $ رو قبل از اسم متغیر قرار بدیم. این یعنی اگه مثلا اسم متغیر ما name باشه و بگیم که echo name چیزی که برامون پرینت گرفته میشه مقدار متغیر name نیست بلکه خود عبارت name عه! name=bizhan&#xA;echo name    # name&#xA;echo $name    # bizhanعملگر ضرب *\ هست نه *از اون جایی که زبان Bash از * (اسم این علامت asterisk یا به طور ساده star عه) به عنوان یک wildcard استفاده میکنه (wildcard علامتی هست که میتونه به مفهوم هر چیزی باشه) برای ضرب کردن دو مقدار عددی در هم باید یک \ قبلش قرار بدیم که خنثی اش کنه:x=3&#xA;y=4&#xA;expr $x \* $yمحاسبات اکثرا با bc انجام میشهدر حالی که عادت کردی خیلی راحت با زبان مهربونی مثل Python پیچیده ترین محاسبات رو عین درس جبر انجام بدی، در Bash محاسبات اکثرا با برنامه ای به اسم bc صورت می گیره که مخفف bench calculator هست. bc یک برنامه داخلی Unix عه که معادلات و محاسبات رو ازت میگیره و حاصلش رو بهت میده. نکته جالب این جاست که داخل خود کد bash هم میتونی از این bc استفاده کنی.if [ `echo &#39;3 + 3&#39; | bc` -eq 6 ]&#xA;then&#xA;    echo OK&#xA;fiاستفاده از دستورات ترمینال داخل کداین هم یکی دیگه از چیزای جالبه. می تونیم دستوراتی که به صورت روتین داخل ترمینال وارد میکنیم رو داخل کد bash بیاریم و با حاصلش کار کنیم. مثلا میخایم اسم تک تک فایل های موجود در directory حاضر رو پرینت بگیریم:for x in `ls`&#xA;do&#xA;    echo $x&#xA;doneکار کردن با آرایه ها عذابه!این یکی از رو مخ ترین ویژگی های Bash هست. کار کردن با آرایه ها واقعا دردناکه. مثلا برای دسترسی به مقدار یکی از عناصر یک آرایه با از {}$ استفاده کنی. بذار چند تا مثال تو کد توضیح بدم:# declaration&#xA;names=(bizhan behrad hazhir sina)&#xA;# length&#xA;echo ${#names[*]}&#xA;# reading&#xA;echo ${names[0]}تقسیم به صورت پیش فرض حاصل رو به پایین گرد میکنه!شاید فکر کنی که حاصل تقسیم ۵ بر ۲ میشه ۲.۵ ولی تو Bash میشه ۲! بش به صورت پیش فرض حاصل تقسیم رو به نزدیک ترین عدد صحیح و به پایین گرد میکنه! برای این که ۲.۵ دریافت کنی باید از bc استفاده کنی و آپشن l- رو هم بهش بدی. که در این صورت هم یک قطاری از صفر بعد از ۲.۵ ردیف میکنه برات!expr 5 / 2    # 2&#xA;echo &#39;5 / 2&#39; | bc -l    # 2.50000000000000000000تو پایتان ۲ هم تقسیم ۵ بر ۲ میشد ۲ ولی از پایتان ۳ به بعد دیگه تقسیم رو مثل جبر و به صورت دقیق انجام دادن.حلقه for خیلی دوست داشتنی ترهبر خلاف زبانی مثل C که حلقه for اش عملا همون while عه، این جا توی Bash همه چیز به صورت خودکار حساب میشه و خیلی راحت تره. در عین حال احتمال خطا هم کمتره. حلقه for در پایتان هم همین طوری مثل Bash کار میکنه:# in C&#xA;for (int i=0; i &lt; 10; i++) {&#xA;    print(i)&#xA;}&#xA;# in Bash&#xA;for x in my_list&#xA;do&#xA;    echo $x&#xA;done&#xA;# in Python&#xA;for x in my_list:&#xA;    print(x)نتیجه گیریتو این مقاله سعی کردم چند تا از ویژگی های عجیب Bash رو توضیح بدم. با وجود همه این ها Bash یار غار سیستم عامل Unix عه و Unix هم اساس دنیای وسیع اینترنت. بلد بودن Bash قدرت اعجاب آوری به یک برنامه نویس میده چرا که می تونه با Bash خیلی از کار ها رو اتوماتیک کنه. تسلط به Bash باعث میشه زبان های سطح بالاتری مثل Python رو هم بهتر درک کنیم. در نهایت خوشحال میشم که نظرت رو به صورت یک comment با من به اشتراک بذاری.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sun, 12 Jun 2022 09:31:01 +0430</pubDate></item><item><title>پرکاربردترین دستور های Unix</title><link>https://virgool.ir/Rocket/پرکاربردترین-دستور-های-unix-tcyfj6vjt5zf</link><description>در این مقاله پرکاربردترین دستور های Unix رو بررسی می کنیم.مقدمهدر سیستم عامل های بر اساس Unix مثل Linux دستورات (Command) های زیادی داریم که با استفاده از CLI (Command Line Interface) اون ها رو وارد می کنیم. همون طوری که با استفاده از رابط های گرافیکی مثل Gnome میشه از سیستم عامل به صورت گرافیکی استفاده کرد، از رابط متنی هم میشه استفاده کرد که اتفاقا رابط متنی قدرتمند تره. این رابط متنی توی Linux به Terminal مشهوره. برای باز کردن یک ترمینال جدید توی Linux کافیه عبارت terminal رو سرچ یا این که از میانبر Ctrl + Alt + T استفاده کنی. تو این مقاله کاربردی ترین دستور هایی که توی رابطه کاربری Unix هست رو بررسی می کنیم.تصویری از رابطه متنی Linux - Ubuntuساختار کلی یک دستور در Unixبه صورت کلی یک دستور ساختار زیر رو داره:command [options] [arguments]آپشن ها باعث تغییر در عملکرد دستور میشن و argument ها مقادیری هستن که برخی از دستور ها لازم دارن تا با توجه به اون ها کار کنن. option ها قبلشون - یا -- قرار داده میشه. argument ها می تونن چند تا باشن و ممکنه یک رشته، یک عدد، اسم یک فایل و ... باشن.دستورالعمل یک دستوربرای مشاهده دستورالعمل (manual) یک دستور می تونیم از دستور man استفاده کنیم. بعد از man اسم دستوری که میخایم manual اش رو مطالعه کنیم قرار میدیم. تو پنجره ای که باز میشه با زدن دکمه / می تونیم جست و جو کنیم یا با زدن q می تونیم خارج شیم و برگردیم به محیط اولیه.man lsکاربردی ترین دستور هاwhatisاین دستور توضیح بسیار کوتاهی (در حد ۱ خط) درباره یک دستور بهمون میده. مثلا:whatis echopwdاین دستور که مخفف شده path of working directory هست مسیری که درش حضور داریم رو به ما میده. برخی دستوراتی که وارد می کنیم (مثلا دستور کپی کردن یک فایل) بستگی دارن به این که تو چه مسیری حضور داریم و تو این مسیر چه فایل هایی موجود هست.cdاین دستور که مخفف change directory هست مسیری که درش حضور داریم رو عوض میکنه. مثلا کد زیر یک مسیر به عقب بر میگرده:cd ..یا برای پریدن مستقیم به مسیر خانه کافیه cd رو تنهایی بنویسیم:cdمی تونیم به cd یک path مطلق هم بدیم تا مستقیما به اون جا بپره:cd /home/bizhan/Desktopیا این که یک مسیر نسبی بدیم بهش. یعنی به نسبت مسیری که درش حضور داریم، بررسی بشه. مثلا اگه تو مسیری که الان درش هستیم یک پوشه به اسم Links وجود داشته باشه برای وارد شدن بهش می گیم:cd Linksحالا فرض کن که اسم فولدر مون خیلی طولانیه و دنبال یک میانبر می گردیم که کل اسمش رو تایپ نکنیم. کافیه چند حرف اولش رو تایپ کنیم و بعدش دکمه tab رو بزنیم تا به صورت اتوماتیک کامل بشه. به این ویژگی میگن Auto completion که جاهای دیگه هم کاربرد داره.lsاین دستور فایل ها و پوشه های موجود در اون مسیر رو برای ما لیست میکنه. این طوری می تونیم مطمئن بشیم که چه فایل ها و پوشه هایی هست. آپشن 1- هر فایل یا پوشه رو به صورت یک خط پرینت می گیره.ls -1آپشن a- باعث میشه که همه محتویات اون مسیر (حتی فایل های hidden) نشون داده بشن.ls -aآپشن l- سطوح دسترسی ها فایل یا پوشه رو هم مشخص میکنه.ls -lبرای ترکیب چند تا آپشن با هم این طوری کد میزنیم:ls -1aهمین طور می تونیم از wildcard هایی مثل * استفاده کنیم که جایگزینی برای هر چیزی هست. مثلا دستور زیر همه فایل هایی که فرمت jpeg دارن رو برامون لیست میکنه:ls *.jpegclearبعد از مدتی کار کردن با یک terminal (به هر terminal باز شده اصطلاحا یک shell گفته میشه) ممکنه شلوغ بشه و لازم باشه که shell رو پاک کنیم. این کار با دستور clear انجام میشه.touchبرای درست کردن یک فایل جدید استفاده میشه.touch READMD.mdمیشه که چند تا فایل رو همزمان با یک دستور touch درست کرد:touch a.txt b.txt c.txtبرای درست کردن یک فایل hidden قبل از اسمش یک dot قرار بده:touch .gitignoremkdirبرای درست کردن یک پوشه درست میشه. به پوشه ها توی یونیکس directory میگن:mkdir Photosمیشه که چند تا پوشه رو همزمان درست کرد:mkdir Photos Videos Musicsrmdirبرای حذف کردن یک (یا چند) پوشه خالی استفاده میشه. دقت کن که با این دستور فقط پوشه های خالی رو میشه پاک کرد. برای پاک کردن پوشه هایی که توش محتویات هست باید از دستور rm استفاده کرد:rmdir Photosیا این که به صورت چند تایی:rmdir Photos Videos Musicsrmاین دستور برای پاک کردن یک (یا چند) فایل یا پوشه استفاده میشه:rm README.mdیا به صورت چند تاییrm README.md package.jsonبرای پاک کردن پوشه هایی که دارای محتوا است باید آپشن r- رو اضافه کنیم:rm -r Photosechoبرای پرینت گرفتن یک عبارت توی shell استفاده میشه. مثلا:echo &#34;Hello World!&#34;این دستور به خصوص در ترکیب با &lt;&lt; کاربرد داره زمانی که میخایم به انتهای یک فایل عبارتی رو اضافه کنیم.echo &#34;Bizhan&#34; &gt;&gt; names.txtcatبرای پرینت گرفتن محتویات یک فایل (اکثرا فایل های کوچک) به صورت مستقیم داخل shell استفاده میشه:cat README.mdدر حقیقت کاربرد اصلی این دستور concatenate کردن محتویات دو فایل و نمایش محصول ترکیب این دو در terminal عه. برای همین میشه چند تا argument هم بدیم به این دستور:cat names.txt families.txheadده خط اول یک فایل رو پرینت می گیره. برای فایل های بزرگ که نمایش همه اش توی shell ممکن نیست از این دستور استفاده میکنن تا با یک نگاه ساده به ۱۰ خط اولش متوجه بشن همون فایلی عه که میخان یا نه.head names.txttailده خط آخر یک فایل رو پرینت می گیره. برای فایل های بزرگ که نمایش همش توی یک shell ممکن نیست از این دستور استفاده میشه.tail log.txtcpاین دستور یک فایل یا پوشه رو به مسیر مد نظر کپی میکنه. مثلا دستور زیر فایل a.txt رو به دسکتاپ کپی میکنه.cp a.txt ~/Desktopبرای کپی کردن یک پوشه دارای محتویات باید آپشن r- رو بهش اضافه کنیم. منظور از r در این جا recursive بودن دستوره.cp -r Photos ~/Desktopهم چنین میشه چندین فایل (یا پوشه) رو به صورت همزمان طی یک دستور به مسیر مد نظر کپی کرد:cp a.txt b.txt c.txt ~/Textsmvاین دستور که مخفف شده move هست یک (یا چند) فایل یا پوشه رو به مسیر مد نظر منتقل میکنه. مثلا دستور زیر فایل a.txt رو به دسکتاپ منتقل میکنه.mv a.txt ~/Desktopبرای منتقل کردن یک پوشه دارای محتویات باید آپشن r- رو بهش داد. مثلا دستور زیر پوشه Photos توی دسکتاپ رو به پوشه Temp توی home directory منتقل میکنه (~ به معنی home هست):mv ~/Desktop/Photos ~/Tempیکی از کاربرد های اصلی mv علاوه بر منتقل کردن، عوض کردن اسم یک فایله. مثلا کد زیر اسم فایل a.txt رو به b.txt عوض میکنه:mv a.txt b.txtهم چنین میشه چند تا فایل (یا پوشه) رو به صورت همزمان به مسیر خاصی منتقل کرد. مثلا کد زیر فایل های a.txt و b.txt رو به دسکتاپ منتقل میکنه:mv a.txt b.txt ~/Desktopnanoاین دستور ما رو وارد یک محیط جدید میکنه که ویرایشگر متنی Nano هست. Nano یک ویرایشگر متن ساده و در عین حال کاربردی عه که می تونیم باهاش با فایل های متنی کار کنیم. توضیح دادن ویژگی های nano در حوصله این مقاله نیست. whoamiاین دستور که به هم چسبیده who am i هست بهمون میگه که با کدوم user داریم از سیستم استفاده میکنیم. البته هر وقت که یک shell باز میکنیم درون خود shell و ابتدای هر خطی برامون نام کاربری و رایانه ای که این کاربر درش وجود داره رو پرینت گرفته. مثلا نام کاربری من اگه bizhan باشه و اسم رایانه ام liberty این طوری میشه:bizhan@liberty:~$aproposاین دستور که قطب نمای لینوکس عه یک کلیدواژه دریافت میکنه و سپس هر چیزی که مربوط به این کلید واژه باشه رو برامون نمایش میده. مثلا فرض کن من یادم رفته اسم editor های اصلی چی بوده. این دستور رو وارد میکنم:apropos editorو برام هر چیزی که به editor مربوط باشه رو پرینت می گیره.sudoاین دستور که مخفف شده عبارت super user do هست باعث میشه که دستورات با سطح دسترسی بالاتری اجرا بشن. اصلی ترین جایی که این دستور استفاده میشه هنگام نصب یک package توسط apt عه که چون قراره یک نرم افزار تازه نصب بشه باید super user اجراش کنه. مثلا:sudo apt install inkscapeنتیجه گیریتوانایی استفاده از command line برای افرادی که میخان حرفه ای باشن حیاتی عه. قدرتی که terminal در اختیار ما میذاره بسیار بیشتر از رابط گرافیکی عه. هم چنین terminal انعطاف پذیر تره. اگه زبان bash بلد باشیم می تونیم دستورات خودمون رو هم درست کنیم. جهت تسلط بیشتر به Unix می تونی در مورد سطوح دسترسی ها مطالعه کنی. هم چنین یادگیری زبان هایی مثل Python هم می تونه کمک کننده باشه. خیلی خوشحال میشم اگه نظرت رو در انتهای این مقاله کامنت کنی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sat, 11 Jun 2022 10:29:08 +0430</pubDate></item><item><title>mySQL در پایتان</title><link>https://virgool.ir/@bizhan.he1996/mysql-در-پایتان-cowraobp9uxl</link><description>کار کردن با database در زبان پایتان راحت و سریعه.مقدمهپایگاه های داده مختلفی مثل mySQL و sqlite هست که هر کدوم مزایای خودش رو داره. در زبان پایتان ماژول هایی داریم که به ما امکان ارتباط برقرار کردن با این پایگاه های داده رو میده. برای مثال ماژول sqlite3 برای کار کردن با پایگاه های داده sqlite و ماژول mysql برای کار کردن با پایگاه های داده mySQL. روش کار کردن با این ماژول ها کم و بیش یکسانه. به صورت کلی ابتدا باید import شون کنیم، بعدش به پایگاه داده متصل شیم و سپس یک cursor درست کنیم. دستورات SQL رو از طریق متد های cursor به پایگاه داده میدیم و نتایج رو به دست میاریم. در ادامه این مقاله قدم به قدم با ماژول mysql آشنا میشیم.نصب Driverپیش از هر چیزی باید MySQL Connector رو به عنوان driver نصب کنیم. این طوری:python -m pip install mysql-connector-python منظور از pip در دستور بالا package manager عه پایتان هست. زبان های مطرحی مثل Python برنامه هایی دارن که package هاشون رو مدیریت میکنه. برای مثال تو PHP برنامه Composer این مسئولیت رو به عهده داره. تو Node.js این قابلیت با NPM فراهم میشه و تو پایتان هم PIP عه که سردمدار مدیریت بسته هاست.ایجاد اتصالاین جا فرض میکنیم که mysql از قبل روی سیستم شما نصبه. mysql.connector هم که تو قسمت بالا توضیح دادیم چطوری نصب بشه. اول از هر چیزی باید ماژول mysql.connector رو import کنیم. بعدش connection اش رو تشکیل میدیم.import mysql.connector&#xA;conn = mysql.connector.connect(&#xA;    host=&#34;localhost&#34;,&#xA;    user=&#34;root&#34;,&#xA;    password=&#34;any_password&#34;,&#xA;    database=&#34;test&#34;,    # this parameter is optional&#xA;)تو کد بالا اگه پارامتر چهارم رو ندیم دستورات مون برای کل mySQL اجرا میشه. حالا در گام بعدی برای این که بتونیم دستورات SQL رو به Database برسونیم باید یک cursor درست کنیم:cur = conn.cursor()این شئ cur که کوتاه شده همون cursor هست مثل cursor در command line عمل میکنه و دستورات SQL رو از ما دریافت خواهد کرد.اجرا دستورات SQLحالا که شئ cur رو داریم می تونیم با استفاده از متد execute روش دستورات SQL مون رو به پایگاه داده ارسال کنیم:cur.execute(&#34;SHOW TABLES&#34;)حاصل این دستورات توی همون شئ cur ذخیره میشه و می تونیم با استفاده از یک حلقه for نتایج رو print کنیم:for row in cur:&#xA;    print(row)در نتایجی که حاصل میشه هر ردیف به صورت یک tuple هست که هر عضوش متناظر یکی از ستون های جدول ما در database میشه. برای مثال:cur.execute(&#34;SELECT * FROM tags&#34;)&#xA;rows = [row for row in cur]&#xA;print(rows[0])حاصل کد بالا (دقت کردی که با استفاده از comprehension کل ردیف ها رو توی یک list ذخیره کردیم) چیزی شبیه به این میشه:(1,&#xA; 1,&#xA; &#39;minima&#39;,&#xA; datetime.datetime(2022, 4, 20, 15, 46, 32),&#xA; datetime.datetime(2022, 4, 20, 15, 46, 32))مشاهده میکنی که یک tuple داریم. نکته جالب این جاست که خود python زحمت کشیده و ستون هایی که جنس date بودن رو به object هایی از کلاس datetime تبدیل کرده! راه ساده تری هم هست برای ذخیره نتایج! استفاده از متد fetchall مثل زیر:cur.execute(&#34;SELECT * FROM users&#34;)&#xA;users = cur.fetchall()متد بالا همه ردیف ها رو به صورت list ای از tuple ها (هر تاپل به منزله یک ردیف) دریافت میکنه.Statement Bindingیکی از اصول کلیدی امنیت در پایگاه داده جلوگیری از SQL Injection هست. منظور از تزریق SQL اینه که وقتی میخایم رشته دستور SQL رو با استفاده از متغیر ها درست کنیم (هر چیزی کاربر وارد کرده رو در غالب یک متغیر ذخیره کردیم) از کجا معلوم که کاربر مثلا به جای اسمش دستور زیر رو وارد نکرده باشه:DROP TABLE usersاگه حواسمون نباشه این SQL به پایگاه داده تزریق میشه و بعدشم که فاتحه مع صلوات! راهکار جلوگیری از این آسیب پذیری استفاده از Statement Binding هست. این یعنی به جایی که خودمون بیایم و متغیر های مد نظرمون رو به رشته SQL بچسبونیم اجازه بدیم خود Python این کار رو برامون بکنه. این شکلی:data = (&#39;bizhan&#39;, 26, &#39;male&#39;)&#xA;cur.execute(&#34;INSERT INTO users(name, age, gender) VALUES (%s, %s, %s)&#34;, data)در کد بالا چندین نکته وجود داره.اولا این که عدد ۲۶ هر چند از جنس integer هست ولی برای bind کردنش به رشته SQL از s% استفاده کردیم. شاید در نگاه اول شبیه به string formatting برسه ولی این تشابه اتفاقی عه.دوم این که به جای &#39;s%&#39; نوشتیم s%. در غیر این صورت ارور میده.و نکته آخر این که اگه بعد از اجرای این دستور جدول users رو نگاه کنیم می بینیم که چیزی اضافه نشده؟!!! چرا؟!اضافه نشدن ردیف جدید به جدول users واسه اینه که commit نکردیم. منظور از commit کردن اینه که دستوراتی که در پایگاه داده تغییرات مهمی مثل INSERT کردن یک ردیف ایجاد میکنن باید commit بشن. commit از طریق conn انجام میشه و به صورت زیر:conn.commit()دستوراتی که قراره تو پایگاه داده تغییر ایجاد کنن باید commit بشن. مثلا: INSERT, UPDATE, DELETE و ... ولی دستوراتی که صرفا اطلاعات رو استخراج میکنن مثل SELECT نیازی به commit ندارن.اجرای چندبارهحالا فرض کن list ای از data داریم و میخایم به ازای هر کدومش یک بار دستور INSERT رو اجرا کنیم. ممکنه از حلقه for استفاده کنیم ولی راه ساده تری هم هست. متد executemanyinformations = [(1, &#39;a&#39;), (2, &#39;b&#39;), (3, &#39;c&#39;)]&#xA;cur.executemany(&#34;INSERT INTO tags(user_id, name) VALUES(%s, %s)&#34;, informations)&#xA;conn.commit()عادت های خوباز همین الان که داری یاد میگیری سعی کن این عادت ها رو در خودت پرورش بدی:هنگام تمام شدن عملیات conn رو ببندی. این طوری:conn.close()کد هایی که ممکنه exception درست کنه رو داخل try قرار بدی. مثلا فرض کن که یکی از ستون های جدولت مقادیر تکراری نمی پذیره (Unique داره) و تو همه کد هات رو درست زدی و خطایی نیست منتها به حاصل نهایی نمیرسی. از statement binding خود متد execute استفاده کنی به جای این که خودت string format کنی.قبل از استفاده از هر گونه data ای که از سمت کاربر میاد، بررسیش کنی. شاید خطرناک باشه. به این کار میگن validate کردن که در عین سادگی، مهم و ظریفه. نیازی نیست همه کارای validation رو خودت بکنی. کتاب خونه هایی مثل Django امکانات از پیش آماده شده ای برای validation در نظر گرفتن.نتیجه گیریکار کردن با پایگاه داده یک مهارت اصولی حساب میشه. به خصوص زمانی که با مباحثی مثل web development سر و کار داریم database در مرکز اهمیت قراره میگیره. حتی نرم افزار هایی مثل firefox هم پایگاه داده های local خودشون رو دارن. برای مثال history در مرورگر google chrome به صورت یک sqlite database ذخیره میشه. بر خلاف mySQL که خیلی مفصل تر و مرکزی عه، پایگاه های داده sqlite به صورت یک فایل داخل همون پوشه برنامه خودت می تونن ذخیره بشن. کار کردن با ماژول sqlite هم ۹۰ درصد شبیه به همین mysql.connector عه.در نهایت خوشحال میشم اگه من رو به یک کامنت مهمون کنی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Thu, 12 May 2022 12:15:06 +0430</pubDate></item><item><title>datetime در پایتان</title><link>https://virgool.ir/@bizhan.he1996/datetime-در-پایتان-ojmeaxrxhhq1</link><description>در پایتان علاوه بر date و time ساده datetime هم داریم که ترکیبی از هر دوتاست و کاربردی تره.مقدمههر برنامه نویسی میدونه کار کردن با date ها چقدر می تونه سردردآور باشه. به خصوص زمانی که در زبان هایی مثل PHP بخایم مانور بدیم. زبان هایی مثل jS کتاب خونه های معرکه ای مثل Moment رو برای کار کردن با زمان ها دارن. زبان پایتان با به شدت ساده کردن قضیه کلاس جدید به نام datetime رو معرفی کرده که خیلی جذابه. کار کردن باهاش ساده است و به خصوص زمانی که میخایم با DB کار کنیم (مثلا قرار دادن تاریخ و زمان دقیق قراردادن یک رکورد) به کارمون میاد.ایجاد شئ از کلاس datetimeبرای درک مفهوم شئ و کلاس باید به مفهوم شئ گرایی مسلط بشی. به زبان ساده یک شئ میشه مصداق یک کلاس. انگاری کلاس نقشه ساختمان باشه و شئ خود ساختمان. یا مثلا کلاس قالب کیک باشه و شئ خود کیک.خوب قبل از هر چیزی مثل همه module های دیگه باید ماژول datetime رو import کنیم. دقت کن که ماژول datetime دقیقا برابر با کلاس datetime نیست. ماژول رو میشه این طوری تفسیر کرد: بسته ای که همه کلاس ها، متغیر ها و ملزومات کار کردن با یک موضوع رو داره. مثلا ماژول هایی مثل math که جعبه ابزار عملیات ریاضی و یا مثلا re که جعبه ابزار کار کردن با regular expression ها هستن.import datetime as dt&#xA;print(dt.datetime.now())تو کد بالا ماژول datetime رو به عنوان dt وارد کردیم و حالا توی این ماژول مجددا کلاسی هست به اسم datetime که از متد now اش استفاده می کنیم برای پرینت گرفتن object ای که زمان حاضر رو نشون میده.ویژگی های کلاس datetimeمنظور از ویژگی همون attribute ها هست. (اسامی دیگری مثل field و property هم بهشون داده میشه) هر شئ datetime چندین ویژگی کاربردی داره که می تونیم ازش استفاده کنیم. برای مشاهده کامل این ویژگی ها می تونی کد زیر رو اجرا کنی:import datetime as dt&#xA;print(dir(dt.datetime))ولی به صورت کلی مهمترین ویژگی های کلاس datetime این هاست: year, month, day, hour, minute, second (دقت کن که به صورت مفرد هست. مثلا seconds غلطه)import datetime as dt&#xA;date1 = dt.datetime.now()&#xA;print(date1.day)&#xA;print(date1.hour)فرمت کردنتو عالم برنامه نویسی فرمت کردن (با فرمت کردن یک درایو یا فلش اشتباه نگیر) یعنی شکل دادن و به شکل در آوردن یک چیزی. مثلا یک شئ datetime که دارای چندین attribute (مثلا روز، ماه، سال ...) هست رو تبدیل به یک رشته قشنگ و شیک کنیم و print بگیرم. چون مشخصا object برای انسان اون قدر ها قابل هضم نیست. فرمت کردن اشیاء کلاس datetime با متد strftime صورت می گیره (این طوری یاد بگیر: strftime = string format time):import datetime as dt&#xA;date1 = dt.datetime.now()&#xA;print(date1.strftime(&#34;%Y-%m-%d&#34;)) # 2022-05-10به اون Y% و اینا میگن Format codes که زیادن. مثلا Y برای عدد ۴ رقمی سال و m برای عدد دو رقمی ماه استفاده میشه. تو این لینک می تونی همه شون رو ببینی (مشخصا نیازی به حفظ کردنشون نیست. اکثرا مواقع با همین فرمتی که تو مثال هست سر و کار داریم).متوجه شدی که datetime رو میشه به صورت date فرمت کرد! (مجددا تاکید میکنم هم کلاسی به اسم datetime داریم هم ماژولی به همین نام. به عبارتی کلاس datetime یکی از کلاس های موجود در ماژول datetime هست.)parse کردنبر خلاف format کردن که به معنی ایجاد string از object هست در parse کردن از string میخایم object در بیاریم. این جا از متد strptime استفاده می شه (این طوری یاد بگیر: string parse time)مفهوم parse و format نه تنها تو مبحث date ها بلکه تو مباحث دیگه ای مثل json هم دیده میشه. مثلا تو زبان js برای تولید object از رشته json باید از متد JSON.parse استفاده کنیم.import datetime as dt&#xA;my_string_date = &#34;2012-01-01&#34;&#xA;my_date_object = dt.datetime.strptime(my_string_date, &#34;%Y-%m-%d&#34;)&#xA;print(my_date_object.day)همون طوری که مشاهده میکنی یک رشته که خودمون نوشته بودیم رو دادیم به متد strptime و علاوه بر این رشته دومی هم به این متد میدیم که فرمت رشته اولی هست. یعنی بهش میگیم آقا جان این از تاریخ به صورت رشته ایی و اینم از فرمتی که این تاریخ رشته ای داره. حالا بیا و این رشته رو که بر اساس این فرمت درست شده زحمت بکش برای ما تبدیل به object کن.کسر دو datetime از همبرای مشاهده تفاوت میان دو datetime از هم پایتان شاهکاری داره که واقعا لذت بخشه! می تونین خیلی راحت با استفاده از عملگر تفریق (همون - خودمون) دو شئ datetime رو از هم کسر کنین. حاصل این تفریق میشه یک شئ از کلاس timedelta که یک سری متد و ویژگی روش هست. به مثال دقت کن:import datetime as dt&#xA;date1 = dt.datetime.now()&#xA;date2 = dt.datetime.strptime(&#34;2025-01-01&#34;,&#34;%Y-%m-%d&#34;)&#xA;diff = date2 - date1&#xA;print(diff.seconds)کلاس timedelta هم یک سری متد و یک سری attribute داره که ازشون استفاده میکنیم تا تفاوت بین دو datetime رو درک کنیم. بر خلاف کلاس datetime که ویژگی هاش مفرد بودن این جا ویژگی های کلاس timedelta جمع هستن. مثلا: days و secondsجمع و تفریق timedelta از datetimeحالا که به همه این مباحث مسلط شدی وقتشه شیرینی صبرت رو بچشی. می تونی به راحتی و بازم با عملگر های ساده ای مثل - و + یک شی از کلاس datetime رو با یک شئ از کلاس timedelta جمع یا تفریق کنی! حاصل این تفریق یا جمع یک شئ از کلاس datetime خواهد بود. شیرینی این راحتی در پایتان رو برنامه نویس هایی متوجه میشن که با زبان هایی مثل PHP کار کرده باشن.import datetime as dt&#xA;date1 = dt.datetime.now()&#xA;date2 = dt.datetime.strptime(&#34;2025-01-01&#34;,&#34;%Y-%m-%d&#34;)&#xA;date3 = dt.datetime.strptime(&#34;2035-01-01&#34;,&#34;%Y-%m-%d&#34;)&#xA;diff = date3 - date2&#xA;date4 = date1 + diff&#xA;print(date4.year)نتیجه گیریماژول datetime کلاس های دیگری مثل date و time هم داره (بر خلاف datetime که هم تاریخ هم زمان رو داره کلاس های date و time فقط یکیش رو دارن و محدود ترن) که اون ها هم کم و بیش شبیه به همین datetime خودمون هستن. مثلا کلاس date متد today رو داره. یاد داشتن datetime ها به این دلایل اهمیت داره:درک عالی برنامه نویسی شئ گرا (OOP)توانایی ثبت کردن فعالیت ها با ثبت تاریخ و زمان دقیق. مثلا فرض کن تو database میخای بدونی هر ردیفی در چه تاریخی و در چه زمانی ثبت شده.‌برنامه هایی مثل تقویم برنامه ریزی شخصی، شیفت چیدن برای یک شرکت کاری، محاسبه زمان حضور پرسنل در شرکت بر اساس انگشتی که میزنن، برنامه انبار داری واسه محاسبه روزهای مانده به انقضا محصولات و ...و کلی کاربرد دیگه.امیدوارم از این مقاله لذت برده باشی. نظرت برام ارزشمنده و ممنون میشم اگه کامنت کنی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Tue, 10 May 2022 04:15:27 +0430</pubDate></item><item><title>کار کردن با فایل ها در پایتان</title><link>https://virgool.ir/@bizhan.he1996/کار-کردن-با-فایل-ها-در-پایتان-blwgwumng9kw</link><description>کلیدی ترین تابع کار کردن با فایل ها در پایتان open عه.مقدمهکار کردن با فایل ها تو هر زبانی مهمه. یکی از شیرینی های زبان پایتان همین عه که کار کردن با فایل ها رو خیلی راحت میکنه. به طرز شیرینی همه چیز قابل پیش بینی عه و اصلا نیاز نیست چیز خاصی رو حفظ کنید. همه چیز خودش میاد. مثل یک شعرباز کردن فایلاولین گام برای کار کردن با یک فایل باز کردن اون فایله. این کار با تابع open انجام میشه. دقت کن که اگه فایل مد نظرت توی پوشه ای که برنامه داره اجرا میشه نباشه Traceback میده و به همین خاطره که باید ملکه ذهنت کنی از همین الان که داری واسه اولین بار یاد میگیری تابع open رو توی بلوک های 3 گانه try (که در ادامه مشاهده خواهی کرد) قرار بدی:try:&#xA;    handle = open(&#34;names.txt&#34;)&#xA;except:&#xA;    print(&#34;File not Found!&#34;)&#xA;else:&#xA;    print(&#34;File is opened successfully.&#34;)اول از همه دقت کن که حاصل تابع open خود file نیست و دستگیره ای برای فایل حساب میشه برای همین اسمش رو handle میذاریم.دوم این که از 3 تا بلوک استفاده کردیم (ممکنه به کل try تا else بگی بلوک که این طوریش رو هم من شنیدم ولی این جا منظور من از بلوک هر کدوم از این 3 تاست. اگه اطلاعات دقیق تری در این خصوص داری ممنون میشم کامنت کنی): کد داخل بلوک try تحت تست قرار میگیره. اگه exception ای درست نکرد که خوب هیچی میریم کد بلوک else رو اجرا می کنیم ولی اگه exception رخ داد (مثلا فایل نبود که بخاد باز بشه) این جا کد داخل بلوک except اجرا میشه.خوندن فایلخوب حالا نوبت به این میرسه که این فایل رو بخونیم! فقط بازکردنش که نشد کار. خوب طبق عادتی که همین پاراگراف بالایی ایجاد کردیم اولش بلوک های 3 های try رو می نویسیم:try:&#xA;    handle = open(&#34;names.txt&#34;)&#xA;except:&#xA;    print(&#34;File not Found!&#34;)&#xA;else:&#xA;    print(handle.read())میشه با استفاده از متد read کل فایل رو یک جا خوند. راه حل دیگری هم هست که به صورت خط به خط خوندن فایله. این طوری:for line in handle:&#xA;    print(line.strip())نکته: متد strip آت و آشغال های انتها و ابتدای یک رشته رو (در این جا مصداقش میشه کل خط) پاک میکنه. مثلا space یا line breakاون دوستای عزیزی که comprehension رو هم بلدن می تونن از تکنیک زیر استفاده کنن:try:&#xA;    file = [line.strip() for x in open(&#39;names.txt&#39;)]&#xA;except:&#xA;    print(&#34;Not Found&#34;)فرق این دو روشتو روش اول که کل فایل رو یک جا با استفاده از متد read می خونیم یک رشته پیوسته دریافت میکنیم با کلی line break (منظورم از line break عبارت n\ عه که توی print تفسیر به شکستن خط میشه). مثلا اگه فایل ما این باشه:bizhan&#xA;behrad&#xA;sina&#xA;hazhirاگه کل فایل رو با متد read بخونیم حاصلش میشه اینه:bizhan\nbehrad\nsina\nhazhirولی اگه خط به خط بخونیم و هر خطی رو strip کنیم این n\ ها پاک میشن (متد strip رسالتش همین پاک کردن آت و آشغالای اول و آخر یک رشته است). حالا می تونیم توی حلقه for مون خط به خط strip کنیم توی همون جا پرینت بگیریم یا این که کل فایل رو با comprehension تبدیل به یک list کنیم.حالات باز کردن فایلباز کردن و خوندن فایل رو یاد گرفتیم. اما پایتان برای اون هایی که سیر نمیشن جزئیات بیشتری هم گذاشته. یک فایل می تونه در ۴ حالت مختلف باز بشه.برای یادگیری راحت تر همین الان کلمه rawx رو حفظ کن:read, append, write, xحالت پیش فرض باز کردن یک فایل read هست و در صورتی هم که این حالت رو به تابع open ندیم (همون طوری که تا الان نداده بودیم) ایرادی نداره، چون پیش فرضه. ولی تو این حالت فقط می تونیم مطالب اون فایل رو بخونیم. اگه خاسته باشیم که به فایل چیزی اضافه کنیم یا کلا فایل رو از اول بنویسیم چی؟! اگه فایل وجود قبلی نداشته باشیم و بخایم درستش کنیم چی؟! این جاست که حالت های دیگه مثل a, w و x به کارمون میاد.حالت aتو این حالت هر چیزی که با استفاده از متد write به ‌فایل اضافه کنیم به انتهای فایل اضافه میشه (نه به عنوان یک خط جدید بلکه به همون محتوای قبلی چسبیده) و محتوای قبلی بدون تغییر باقی می مونه. اگه میخای خط به خط اضافه کنی می تونی با n\ توی string ای که میخای write بشه مشخص کنی کجا خط بشکنه. (یعنی بره خط بعدی)try:&#xA;    handle = open(&#39;names.txt&#39;, &#39;a&#39;)&#xA;except:&#xA;    print(&#34;Not Found&#34;)&#xA;else:&#xA;    handle.write(&#34;I have added this line&#34;)&#xA;    handle.close()حالت wتو این حالت هر چیزی که با متد write بنویسیم روی فایل کل خط های قبلی فایل رو پاک میکنه و به جای اون ها میشینه.try:     &#xA;    handle = open(&#39;names.txt&#39;, &#39;a&#39;) &#xA;except:     &#xA;    print(&#34;Not Found&#34;) &#xA;else:     &#xA;    handle.write(&#34;The old content is erased and\nyou see a completely new content.&#34;)     &#xA;    handle.close()حالت xتو این حالت اگه فایل وجود نداشته باشه ایجاد میشه و اگه از قبل فایلی با همین نام وجود داشته باشه Traceback براتون میندازه که حالشو ببرین! handle ای که تو این حالت ایجاد میشه مثل حالت a عمل میکنه اگه متد write روش رو صدا بزنین.try:&#xA;    new_handle = open(&#34;new_file.txt&#34;,&#34;x&#34;)&#xA;except:&#xA;    print(&#34;File already exists!&#34;)&#xA;else:&#xA;    new_handle.write(&#34;This is the 1st line\nThis is the 2ns line.&#34;)&#xA;    new.close()به عنوان یک عادت خوب (به این عادت های خوب تو جهان برنامه نویسی میگن Best Practices) از همین الان فرهنگ سازی کن واسه خودت (!!!) که وقتی کارت تموم شد handle رو با متد close ببندی. شاید فکر کنی بدون این هم میشه ولی یک روزی یک جایی به حرف من میرسی که بعد ۱ هفته وقت واسه debug پروژه متوجه میشی همین عادت بد نبستن فایله که باگ اصلی برنامت بوده.UTF-8 vs. Binaryاین چهار حالت نحوه رفتار ما با فایل رو مشخص میکنن که آیا میخایم بخونیم، بنویسیم، ایجاد کنیم و ... از منظر دیگری هم میشه به باز کردن فایل ها نگاه کرد و اون منظر باز کردن و خوندن فایل به صورت binary یا text عه. همون طوری که میدونی توی پایتان ۳ همه و همه رشته های UTF-8 هستن و حالت پیش فرض باز کردن یک فایل هم همین حالت text عه که فایل رو به صورت UTF-8 میخونه. در اکثر موارد به خصوص فایل های متنی مثل txt ها همین کافیه ولی مثلا jpeg ها binary هستن و خوندشون به صورت text دردی از ما دوا نمیکنه. برای همین ممکنه که بعد از یکی از اون کاراکتر های رمز rawx کاراکتر دیگری از بین bt بذارین که مشخص کنه این فایل رو به چه منظری بخونیم: binary یا textحالت پیش فرض پایتان text عه و در واقع هر بار که تابع open رو بدون مشخص کردن rawx یا bt اش صدا میزنیم در حقیقت داریم این کد رو اجرا میکنیم:handle = open(&#34;names.txt&#34;,&#34;rt&#34;)ولی حالت های دیگری هم قابل تصوره. مثلا اگه یک تصویر jpeg رو با کد زیر باز کنیم:handle = open(&#34;image.jpeg&#34;,&#34;rb&#34;)&#xA;print(handle.read())با چیزی این طوری رو به رو میشیم:\xf50\xa54\xb8\xd4\xa0\xa2^\x0eS\x00\xac\xee\x11a\xfb&lt;\xc0\xe4Z~`\x00F\x1c\xb7s\x17\x9ezK\x08u7\xdeB8\x01O\x11d\x19\xe1\x1e\xfan\xb2\x0f\x0c2\xf0p=Ng\x85\xbd\x92\xb5\xc2\x86\xdacr\x14\x18u\xcc\xc2\x1b\x83\xa3\xc4N\xd01\xc4\xcd\xd5\x1ay\x87\xf2\&#39;\xf2\x &#xA;همین طوری ادامه دارد. من بخش کوچکیش رو کپی کردمحالا از ترکیب rawx و bt هشت تا حالت مختلف به دست میاد! نتیجه گیریتوانایی کار کردن با file ها به خصوص زمانی که درگیر پروژه های بزرگ میشی یک مهارت کلیدی عه. فرض کن می تونی با یک program ساده Python که روی سرور اجرا میکنی هزار تا کار با فایل های قدیمی تلنبار شده انجام بدی. حتی میتونی فایل هایی با پسوند زبان های دیگه درست کنی (مثلا js) و با استفاده از Python برنامه های زبان های دیگه رو تولید کنی!!! این بحث توی Data Visualization به کارت میاد. زمانی که برای نمایش data به HTML و jS نیاز داری ولی پردازش داده است رو با Python انجام دادی. خوشحال میشم من رو به یک کامنت مهمون کنی و نظرت رو درباره مقاله بگی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Mon, 09 May 2022 02:26:38 +0430</pubDate></item><item><title>Decorators در پایتان</title><link>https://virgool.ir/@bizhan.he1996/decorators-در-پایتان-dzutx3udmoaf</link><description>دکوریتور ها باعث تغییر کارایی توابع میشن.مقدمهیکی از مباحث پیشرفته در پایتان، دکوریتور ها هستن. همون طوری که از اسمشون مشخصه کار اصلی شون دکور دادن هست. به عبارت دقیق تر، دکوریتور ها کارایی توابع رو تغییر میدن. تو این مقاله قصد داریم با این ویژگی جذاب پایتان آشنا بشیم. قبل از خود دکوریتور ها باید با یک سری پیش نیاز هایی آشنا بشیم. توصیه میکنم با حوصله این مقاله رو بخونی و صبر کنی تا به خود Decorator ها برسیم.توابع خودشون Object هستن! همیشه عادت کردیم که یک تابع رو تعریف کنیم و وقتی هم میخایم صداش بزنیم جلوش () قرار بدیم ولی از یک دید دقیق تر، خود توابع هم object هستن. تقریبا هر چیزی توی پایتان یک object حساب میشه. بذار با یک کد توضیح بدیم:def my_func():&#xA;    print(&#34;This is what this function does!&#34;)&#xA;my_func()    # This is what this function does!توی کد بالا یک به اسم my_func رو تعریف کردیم و بعدش هم صداش زدیم. حالا اگه بدون استفاده از () فقط اسم تابع رو print بگیریم چی میشه؟!print(my_func)    # &lt;function my_func at 0x7f872c7e2d30&gt;حاصل کد بالا چیزی شبیه به همونی عه که جلوش کامنت کردیم. به عبارتی توضیح میده که my_func یک object در قسمتی از حافظه است. حالا که هر تابع یک object هست، پس میشه این object رو توی متغیر دیگه ای هم ذخیره کنیم! یا حتی میشه به عنوان argument به یک تابع دیگه بدیمش. نکته جانبی: وقتی که تابعی رو تعریف می کنیم به متغیر هایی که بهش میدیم میگن parameter ولی وقتی از همون تابع استفاده میکنیم به متغیر هایی که بهش میدیم میگن argument. به عبارتی argument ها مصداق parameter هایی هستن که موقع تعریف تابع مشخص کردیم. اکثرا این دو تا عبارت رو به جای همدیگه استفاده میکنن.توابع به عنوان متغیرتو مثال بالا توضیح دادیم که تابع object هست. حالا میخایم این object رو توی یک متغیر دیگه ذخیره کنیم و از این به بعد از طریق اون متغیر ازش استفاده کنیم:x = my_func&#xA;x()    # This is what this function does!تو مثال بالا میشد به جای x هر کلمه دیگه ای قرار بدیم (تا زمانی که از قوانین نام گذاری متغیر ها در پایتان تبعیت کنه) مثلا: akbar, hasan و ....Wrapper functionsاین امکان وجود داره که داخل یک function هم دوباره یک function تعریف کنیم! به این جور توابع میگن wrapper function. تو انگلیسی wrap کردن یعنی پیچیدن یک چیزی دور یک چیز دیگه. مثلا پیچیدن کاغذ کادو دور هدیه.def f1(func):&#xA;    def wrapper():&#xA;        print(&#34;Started&#34;)&#xA;        func()&#xA;        print(&#34;Finished&#34;)&#xA;    wrapper()&#xA;f1(my_func)در کد بالا تابع معمولی f1 رو تعریف کردیم که یک پارامتر میگیره. این پارامتر خودش یک تابعه! داخل تابع f1 یک inner function تعریف میکنیم که wrapper هست. به این علت میگیم بهش wrapper که میاد و دور تابعی که به عنوان parameter دادیم می پیچه و قبل و بعدش دو تا رشته پرینت میگیره. در نهایت داخل تابع f1 تابع wrapper رو که تعریف کرده بودیم صدا میزنیم! اگه کد بالا رو اجرا کنیم حاصلش میشه این:Started&#xA;This is what this function does!&#xA;Finishedخوب حالا تو مثال بالا به جای این که تابع wrapper رو مستقیما از داخل f1 صدا بزنیم return اش میکنیم:def f1(func):&#xA;    def wrapper():&#xA;        print(&#34;Started&#34;)&#xA;        func()&#xA;        print(&#34;Finished&#34;)&#xA;    return wrapper&#xA;&#xA;x = f1(my_func)&#xA;print(x)فکر میکنی نتیجه کد بالا چی باشه؟! مجددا یک رشته ای مثل زیر:&lt;function f1.&lt;locals&gt;.wrapper at 0x7f82bc3710d0&gt;تعجب نکن! اول مقاله گفتیم که برای صدا زدن یک تابع با () جلوش قرار بدیم. اگه به جای print(x) بگیم که:print(x())در اون صورت مجددا حاصل زیر پرینت گرفته میشه:Started &#xA;This is what this function does! &#xA;Finishedخلاصه کل کد های بالا میشه این: هر تابعی در پایتان یک object عه که میشه توی variable های دیگه هم ذخیره اش کنیم و تا زمانی که جلوش () قرار ندیم صداش نکردیم. حالا که هر تابعی یک object حساب میشه می تونیم مثل مقادیر دیگه return اش کنیم یا به عنوان پارامتر بدیمش به توابع دیگه. اصلا چیز عجیب و غریبی نیست همون طوری که تا الان int و str رو return می کرد یا میدادیشون به توابع حالا هم با function ها می تونی چنین رفتاری داشته باشی. فقط کافیه جلوشون () نذاری.دکوریتور هاخوب حالا بعد از این همه پیش نیاز بالاخره می رسیم به خود decorator ها. اگه یادت باشه تو کد های بالا وقتی حاصل تابع f1 رو توی متغیر x ذخیره می کردیم برای این که بتونیم حاصل نهایی رو بگیریم باید حتما جلوی x یک () قرار می دادیم. decorator ها باعث میشن که دیگه نیازی نباشه این () رو قرار بدیم! به همین راحتی. به عبارتی هر تابعی رو می تونیم با استفاده از یک دکوریتور، decorate اش کنیم! این طوری:# f1 is a decorator&#xA;@f1&#xA;def my_func():&#xA;    # This function is decorated by f1&#xA;    print(&#34;This is what this function does!&#34;)توی کد بالا f1 میشه decorator ما و تابع my_func هم به وسیله f1 دکوریت شده. حالا دیگه هر وقت که my_func رو صدا بزنیم بدون نیاز به اضافه بازی های قبلی، حاصلش این میشه:Started&#xA;This is what this function does&#xA;Finishedهمون طوری که قول داده بودیم دیدی که f1 به عنوان یک decorator اومده و قبل از تابع مون، Started و بعدش Finished رو پرینت کرده. به عبارتی decorate اش کرد. کاربرد های دیگهدکوریتور ها از مباحث حرفه ای در پایتان هستن. این بحث به خصوص زمانی که با فریمورک هایی مثل Django کار میکنی خیلی بیشتر حس میشه. یکی از کاربر های معروف decorator ها سنجش زمان اجرا شدن یک تابعه. تو مثال بالا فرض کن به جای Started زمان شروع و به جای Finished زمان اتمام رو پرینت می کردیم. یا مثلا قبل از اجرا تابعی که decorate شده نام کاربری که login کرده رو پرینت بگیریم. همون طوری که اول این مقاله قول داده بودیم:دکوریتور ها کارایی یک تابع رو تغییر میدن.نتیجه گیرییک درس مهم تو برنامه نویسی اینه که فکر نکنی همیشه قراره خودت کد بنویسی! شاید یک روزی بخای کد دیگران رو تصحیح کنی یا کدی که قبلا نوشته شده رو اصلاح کنی! مثلا کدی که تو ۱۰۰ خط نوشته شده رو توی ۱۰ خط بنویسی. این جاست که مباحث حرفه ای به کارت میاد. شاید فکر کنی که کتاب خونه هایی مثل Django برات همه این ها رو از قبل تعریف کردن و می تونی هر وقت دوست داشته باشی از پیش تعریف شده های اون ها استفاده کنی ولی اومدیم و یک روزی با مسئله ای رو به رو شدی که با کد از پیش آماده قابل حل نبود! اون موقع چی؟! این جاست که فرق بین یک کد نویس و یک برنامه نویس مشخص میشه. برنامه نویسی یعنی تسلط. در خصوص decorator ها مباحث پیشرفته تری هم هست مثل زمانی که تابعی که میخای decorate اش کنی parameter داشته باشه که تو حوصله این مقاله نیست (هر چند چیز عجیب غریبی هم نیست) و توصیه میکنم از منابع انگلیسی مثل YouTube در موردش مطالعه کنی. در نهایت خیلی ممنون میشم اگه من رو به یک Comment مهمون کنی و در مورد مقاله ام، روش نگارش و نکات تکمیلی نظر بدی.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Sat, 07 May 2022 02:58:34 +0430</pubDate></item><item><title>Generators در پایتان</title><link>https://virgool.ir/@bizhan.he1996/generators-در-پایتان-ihgeuxqohqyl</link><description>جنریتور ها (Generators) باعث افزایش چشمگیر در کارایی کدمون میشن.مقدمههمون طوری که میدونی list ها مجموعه ای از مقادیر هستن که توی حافظه نگهداری میشن. حالا فرض کن به جای نگهداری مجموعه ای از مقادیر مشخص، فرمول درست کردن شون رو نگه داری کنیم و هر وقت که یکی شون رو لازم داشتیم محاسبه کنیم. این جاست که بحث Generator ها میاد وسط. بذار با مثال پیش بریم.مثال مربعاتفرض کن میخایم list ای از اعداد رو به یک تابع بدیم و مربع شون رو بگیریم:def squares(nums):&#xA;    results = []&#xA;    for num in nums:&#xA;        results.append(num * num)&#xA;    return resultsحاصل تابع بالا، جدا از این که هر لیستی با هر اندازه ای بهش بدیم، در هر صورت یک list خواهد بود که تک تک عناصرش عینا محاسبه میشه و در نهایت کل حاصل return میشه. حالا اگه بخایم همین تابع رو با فلسفه generator ها بزنیم:def squares(nums):&#xA;    for num in nums:&#xA;        yield num * num این جا دیگه نه return داریم و نه results بلکه هر دفعه باید از تابع next استفاده کنیم تا مقدار اون چرخه رو حساب کنیم. این طوری:results = squares([1,2,3,4,5])&#xA;print(next(results))    # 1&#xA;print(next(results))    # 4&#xA;print(next(results))    # 5تولید generator با comprehensionمیشه بدون نیاز به تعریف یک function و به صورت مستقیم با استفاده از comprehension یک generator درست کرد. این طوری:my_generator = (x*x for x in range(1,6))&#xA;print(next(my_generator))    # 1&#xA;print(next(my_generator))    # 4 &#xA;print(next(my_generator))    # 9در این حالت دیگه نیازی به تابع و کلیدواژه yield نیست.نکاتبرای تبدیل یک generator به یک لیست واقعی کافیه به تابع list بدیمش. مثل بقیه تبدیل ها!real_list = list(my_generator)اگر بیش از اندازه قابل تصور generator از تابع next استفاده کنیم حاصلی وجود نخواهد داشت که تابع next بخاد به ما برگردونه برای همین exception رخ میده. برای همین توصیه میشه از تابع next با احتیاط استفاده کنید یا این که توی بلوک try قرارش بدیم.نتیجه گیریتو پروژه های کوچیک اهمیت بین list واقعی و generator حس نمیشه ولی وقتی که حجم data مورد پردازش عظیم میشه (که تو دنیای واقعی اتفاقا این طوریه) تسلط به همین ویژگی های زبان پایتان هست که بین یک برنامه نویس Junior و Senior تفاوت ایجاد میکنه. خیلی وقت ها شنیدیم که میگن مثلا PHP در برابر Node اصلا سرعتی نداره. در یک دید کلی این درسته ولی یک برنامه نویس حرفه ای با تسلط به مباحثی مثل همین generator ها ممکنه کدی رو با PHP بنویسه که خیلی سریع باشه (generator ها مختص زبان پایتان نیستن). پس سعی کن که generator ها رو یاد بگیری.</description><category>بیژن حجازی</category><author>بیژن حجازی</author><pubDate>Thu, 05 May 2022 22:25:06 +0430</pubDate></item></channel></rss>