آموزش جاوا اسکریپت

جاوااسکریپت ES6 از سیر تا پیاز. همه چیز درباره ES6

فهرست مطالب:

جاوااسکریپت ES6 چیست و چرا؟

جاوااسکریپت ES6 یا EcmaScript6 ششمین نسخه استاندارد جاوااسکریپت هستش.

برای اینکه متوجه بشین ES6 از کجا اومده و نسخه های قبلی و بعدیش چی هستن، ۳ دقیقه وقت بذارید و مطلب تاریخچه جاوااسکریپت رو بخونید.

بعدش برگردید اینجا تا داستانو باهم ادامه بدیم.

در ES6 چه چیزهایی تغییر کرده؟

متغیرهای جدید let و const

فانکشن های خطی arrow functions

کلاس ها در جاوااسکریپت

مقادیر دیفالت برای پارامترها

متدهای جدید کلاس Array

تعدادی متد و پراپرتی جدید در مورد آبجکت های Number و کار با اعداد و محاسبات.

(این تغییرات به نظرم خیلی کاربردی و متحول کننده نبود. بنابراین توضیحشون ندادم. اگر خواستید همه تغییرات و آپشن های جاوااسکریپت ES6 رو به صورت کامل بخونید، از این سایت استفاده کنید. )

متغیر let در ES6

متغیر let یک نوع متغیره که میدادن دید اش با var فرق داره. میدادن دید متغیر let به بلوکی که اون let داخلش قرار گرفته محدود هست.

این مثال رو ببینید:

var x = 10;
// ایکس رو بیرون بلوک مقداردهی می کنیم ومقدارش 10 میشه
{
  let x = 2;
  // ایکس رو داخل بلوک مقداردهی می کنیم و مقدارش 2 میشه
}
// هنوز بیرون بلوک، مقدار ایکس 10 هستش

رفع سوء تفاهم: در بعضی از زبان های برنامه نویسی، از کلمه let برای تعریف ثابت ها استفاده میشه. اما کلمه let در جاوااسکریپت ES6 برای تعریف ثابت ها نیست!

بنا بر این، متغیر let رو میشه مجدداً مقداردهی کرد:

let x = 2; 
// مقدار ایکس برابر با 2 هستش
x = 12; 
// مقدار ایکس تغییر کرده و برابر 12 هست

ثابت const در جاوااسکریپت ES6

متغیر const یا ثابت const؟ چی صدا کنم تو رو؟

ما اصطلاحاً به const و let و var میگیم متغیر. ولی در حقیقت فقط var و let متغیر هستن ولی const ثابت هست.

یعنی بعد از مقداردهی اولیه دیگه نمیشه مقدارش رو عوض کرد.

تلاش برای تغییر مقدار const در جاوااسکریپت ES6 منجر به خطای Uncaught TypeError: Assignment to constant variable میشه.

مثال زیر رو ببینید:

const x = 2; 
x = 12; 
-> Uncaught TypeError: Assignment to constant variable.
    at <anonymous>:1:3

میدان دید const:

از نظر میدان دید (به انگلیسی: scope) ثابت const دقیقا مثل متغیر let عمل میکنه.

یعنی میدان دید const، میدادن دید داخل بلوک هستش.

var x = 10;
// ایکس رو بیرون بلوک مقداردهی می کنیم ومقدارش 10 میشه
{
  const x = 2;
  // ایکس رو داخل بلوک مجدداً تعریف و مقداردهی می کنیم و مقدارش 2 میشه
}
// هنوز بیرون بلوک، مقدار ایکس 10 هستش

متد های تیری(!) Arrow Functions در جاوااسکریپت ES6

متدهای تیری چه مسخره بازیه؟

پاسخ سریع: متدهای تیری -که در مدرسه کله تیری صدایشان می کرده اند!- (به انگلیسی: arrow functions) روشی برای خلاصه نویسی متدهای جاوااسکریپت ES6 هستش.

چه فرقی می کنه؟

به صورت خلاصه:

  • کلمه function از تعریف متد حذف شده.
  • در متدهای تک خطی میتونیم آکولاد بدنه متد و کلمه return رو حذف کنیم.
  • در متدهایی که فقط یک پارامتر ورودی دارن، میتونیم پرانتز مربوط به پارامتر رو حذف کنیم.

حذف کلمه function از متد

در متدهای تیری، کلمه کلیدی function (که قبل از پرانتز بودش) حذف شده و بجاش یک علامت تیر میاد بعد از پرانتز.

یک متد ساده:

var salam = function() {
  return "salam bachz!";
}

همون متد به صورتarrow:

var salam = () => {
  return "salam bachz!";
}

حذف آکولادهای بدنه و حذف کلمه return

نوشتن آکولادهای بدنه متد و کلمه return برای متدهایی که بدنه آنها فقط شامل یک خط دستور است، الزامی نیست. (خودش به صورت اتوماتیک نتیجه همون یک خط رو return می کنه)

در مثال زیر، می بینید که چجوری در جاوااسکریپت ES6 کلمه function، آکولادهای بدنه متد، و کلمه return حذف شده اند:

// ES5 متد سنتی جاوااسکریپت
var x = function(x, y) {
   return x + y;
}

// ES6 Arrow Function
var x = (x, y) => x + y;

نکته مهم: در متدهای arrow کلمه function کاملا حذف شده. اما حذف آکولادهای بدنه بلوک متد و حدف کلمه return اختیاری هستش.

در واقع چون حذف آکولادها و کلمه return فقط مختص متدهای تک سطری هست، پیشنهاد میشه که بعنوان یک عادت در نظرتون باشه و این دوتا رو حذف نکنید و همیشه بنویسیدشون که احتمال بروز خطا در کدهاتون کمتر بشه.

همون مثال بالا رو به صورت متد arrow که آکولاد ها و کلمه return داره براتون بازنویسی کردم:

// ES6 بدون آکولاد و ریترن
var x = (x, y) => x + y;

// ES6 با آکولاد و ریترن
var x = (x, y) => { return x + y };

حذف پرانتز پارامترها، برای متدهایی که فقط یک پارامتر ورودی دارند

در حالتی که متد ما فقط یک پارامتر ورودی داشته باشه، ما فراخی رو به حدا اعلای خودش میرسونیم و پرانتزی که پارامتر قرار بوده توش نوشته بشه رو هم حذف می کنیم!

// متد ستنی 
var myVar = function(name){
return "salam " + name;
}

// متد نرمال arrow function 
var myVar = (name) => "salam " + name;

// حالت فراخ مضاعف 
var myVar = name => "salam " + name;

تفاوت در اونجایی که this بهش اشاره می کنه!

در متد های عادی، کلمه this به شیئی اشاره می کنه که تابع رو صدا زده (مثلا به دکمه ای که onClick اش این متد رو صدا زده). اما در arrow function ها، کلمه this به شیئی اشاره می کنه که متد داخلش تعریف شده (مثلا به object Window).

کلاس ها در جاوااسکریپت ES6

در نسخه جاوااسکریپت ES6 شما میتونید وارد بحث شئ گرایی بشید و کلاس تعریف کنید. و از روی کلاسهای خودتون شئ (به انگلیسی: object) بسازید.

ویژگیهای کلاس در جاوااسکریپت ES6

  • هر کلاس با کلمه کلیدی class شروع میشه.
  • نام کلاس ها باید با حروف بزرگ شروع بشن.
  • دقت کنید که کلاس (بر خلاف فانکشن) پارامتر ورودی نداره و بنابراین جلوی اسمش پرانتز نمیاد.
  • برای کلاسها همیشه باید خودتون constructor بنویسید.
  • دقت کنید که constructor در جاوااسکریپت، (برخلاف جاوا) همنام کلاس نیست و با کلمه کلیدی constructor تعریف میشه.

این مثال از کلاس person رو ببینید:‌

class Person {
  constructor(name) {
    this.firstName = name;
  }
}
person01 = new Person("ali");
console.log(person01.firstName);

توضیح کامل کد بالا:‌

خط اول:

با استفاده از کلمه کلیدی class و اسم دلخواه person، کلاس رو تعریف می کنیم.

همچنان خط اول:

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

خط دوم:

متد constructor (به فارسی:‌ آغازگر) رو با کلمه کلیدی constructor تعریف می کنیم. در این مثال ما یک پارامتر به نام name هم به این متد پاس دادیم. (کانستراکتور بدون پارامتر ورودی هم میشه تعریف کرد)

خط سوم:

یک پراپرتی (به انگلیسی: property) با نام دلخواه firstName تعریف کردیم و با آوردن اون بعد از کلمه کلیدی .this مشخص کردیم که این پراپرتی مربوط به همین کلاس – یعنی کلاس person – هستش.

باز هم خط سوم:

مقدار پارامتر ورودی constructor رو داخل this.firstName میریزیم.

خط پنجم:

تعریف کلاس تا اینجا تمام شده و بقیه خط ها، مربوط به استفاده از کلاس برای ساختن شئ جدید هستش/

خط ششم:

بوسیله کلمه کلیدی new میخوایم یک شئ جدید از کلاس Person با نام دلخواه person01 بسازیم. بعد از کلمه کلیدی new، اسم کلاس به همراه یک جفت پرانتز آمده. این دستور باعث میشه consrtuctor کلاس اجرا بشه و یک نمونه شئ جدید از روی کلاس ایجاد کنه. چون constructor در مثال ما یک پارامتر ورودی می گیره، موقع new کردن هم باید مقدار پارامتر ورودی رو وارد کنیم. ما اینجا یک رشته به اسم “ali” وارد کردیم.

توضیح کل خط ششم:

در کل خط ششم یک نمونه شئ جدید از کلاس Person میسازه (اسم اون شئ رو به دلخواه خودمون person01 گذاشتیم) و مقدار ali رو بهش پاس میده. کانستراکتور هم این مقدار رو داخل this.firstName میریزه. چون this به خود شئ اشاره می کنه، در حقیقت کانستراکتور مقدار ali رو داخل person01.firstName میریزه.

خط هفتم:

در اینجا ما مقدار person01.firstName رو بوسیله console.log چاپ می کنیم. روی کنسول کلمه ali برای ما چاپ میشه.

نکته مهم درباره this داخل بدنه کلاس ها:

یخورده بالاتر درباره اینکه this توی متدهای ستنی و متدهای arrow function به چه چیزی اشاره می کنه صحبت کردیم.

حالا یادتون باشه که توی کلاس ها، هر this که داخل بدنه کلاس یا متدهای داخل کلاس نوشته شده باشه، به خود شئ جاری که از روی کلاس ساخته شده اشاره می کنه.

بحث مربوط به شئ گرایی در جاوااسکریپت ES6 و کلاسها رو در یک مطلب مفصل براتون آماده کردم که به زودی منتشرش می کنم.

مقادیر دیفالت برای پارامترها

در واوااسکریپت ES6 میتونید به پارامترهای ورودی تابع، مقدار پیشفرض بدید.

وقتی یه پارامتر ورودی مقدار پیشفرض داشته باشه،‌موقع استفاده ازش حتما لازم نیست که اون پارامتر وارد بشه.

در صورتی که اون پارامتر وارد بشه، از مقدار وارد شده استفاده میشه ولی در صورتی که وارد نشه، از مقدار پیشفرض استفاده میشه.

این مثالو ببینین:

function myFunction(x, y = 10) {
  // اگر ایگرگ وارد نشه یا مقدارشتعریف نشده باشه، مقدارش برابر ۱۰ خواهد بود
  return x + y;
}
myFunction(5); // پنج رو بعنوان ایکس میگیره و از ایگرگ پیشفرض استفاده می کنه
// بنابر این پنج رو با مقدار پیشفرض ۱۰ جمع میکنه و ۱۵ رو بر می گردونه 

متدهای جدید کلاس Array

در جاوااسکریپت ES6 دو متد جدید به کلاس Array اضافه شده:

متد Arrey.find در جاوااسکریپت ES6

متد Array.find یک متد تست کننده بعنوان پارامتر ورودی می گیره و مقدار اولین عضوی از آرایه که اون تست رو پاس کنه رو بر می گردونه (یعنی return می کنه)

var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(testerFunction);

function testerFunction(value, index, array) {
  return value > 18;
}
console.log(first);
-> 25

توضیح مثال بالا:

  • خط اول: یک آرایه به نام numbers تعریف و مقداردهی کردیم.
  • خط دوم: متد Array.find رو برای آرایه numbers نوشتیم و متد تست کننده testerFunction رو بعنوان پارامتر بهش دادیم. و نتیجه حاصل شده رو داخل متغیر first ریختیم.
  • خط چهار تا شش: یک متد تست کننده نوشتیم که اگر هر وقت یک مقدار بزرگتر از 18 بود، آن را return کنه. (اگه پیاده سازی این تستر رو متوجه نشدین،‌اشکالی نداره. خیلی سعی نکنید اینجا توی پیاده سازی این متده با خودتون کلنجار برید)
  • خط هفتم: مقدار متغیر first رو توی کنسول چاپ کردیم.
  • خط هشتم: کنسول مقدار 25 رو برای ما چاپ میکنه. چون اولین عددیه که تست بزرگتر از 18 رو پاس کرده. (منم اولین محتوای مثبت ۱۸ خودم رو اینجا تولید کردم 😐 )

متد Arrey.findIndex در جاوااسکریپت ES6

متد Array.findIndex یک متد تست کننده بعنوان پارامتر ورودی می گیره و شماره اندیس اولین عضوی از آرایه که اون تست رو پاس کنه رو بر می گردونه (یعنی return می کنه)

var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(testerFunction);

function testerFunction(value, index, array) {
  return value > 18;
}
console.log(first);
-> 3

توضیح مثال بالا:

  • خط اول: یک آرایه به نام numbers تعریف و مقداردهی کردیم.
  • خط دوم: متد Array.findIndex رو برای آرایه numbers نوشتیم و متد تست کننده testerFunction رو بعنوان پارامتر بهش دادیم. و نتیجه حاصل شده رو داخل متغیر first ریختیم.
  • خط چهار تا شش: یک متد تست کننده نوشتیم که اگر هر وقت یک مقدار بزرگتر از 18 بود، آن را return کنه. (اگه پیاده سازی این تستر رو متوجه نشدین،‌اشکالی نداره. خیلی سعی نکنید اینجا توی پیاده سازی این متده با خودتون کلنجار برید)
  • خط هفتم: مقدار متغیر first رو توی کنسول چاپ کردیم.
  • خط هشتم: کنسول مقدار 3 رو برای ما چاپ میکنه. چون اولین عددی که تست بزرگتر از 18 رو پاس کرده عدد ۲۵ هست. و اندیس این عدد توی آرایه ما ۳ هستش. (میدونم چهارمیه. ولی یادتون باشه اندیس های آرایه از صفر شروع میشه. پس اندیس عضو چهارم میشه ۳ 🙂 )

خلاصه نویسی property های object ها در ES6

مثال زیر رو در نظر بگیرین:

const name = 'hamed'
const family = 'askarian'
const myAge = 33

const user = {
    name: "hamed",
    family: "askarian",
    age: 33
}
console.log(user)

-> { name: 'hamed', family: 'askarian', age: 33 }

توی این مثال ما property های user رو به صورت دستی و هارد کد وارد کردیم. میدونین که برای مقداردهی به این مقادیر، میتونیم از مقادیر داینامیک هم استفاده کنیم. یعنی متغیرها رو پاس بدیم بهش. اینجوری:

const name = 'hamed'
const family = 'askarian'
const myAge = 33

const user = {
    name: name,
    family: family,
    age: myAge
}
console.log(user)

-> { name: 'hamed', family: 'askarian', age: 33 }

توی ES6 ما میتونیم پراپرتی هایی که یک متغیر همنام دارن رو به صورت خلاصه بنویسیم. توی مثال بال، پراپرتی های name و family اسمشون با متغیرهایی که قبل از اون تعریف شده بود، برابر.

پس میتونیم به صورت زیر، خلاصه بنویسیمش :

const name = 'hamed'
const family = 'askarian'
const myAge = 33

const user = {
    name,
    family,
    age: myAge
}
console.log(user)

-> { name: 'hamed', family: 'askarian', age: 33 }

دقت کنید که ما این کار رو برای age و myAge نمیتونیم انجام بدیم. چون اسمهاشون باهم فرق داره.

حالا برعکس این کار رو هم میشه انجام داد که بهش میگن object destructuring :

تغییر ساختار آبجکت ها object destructuring

حالا فرض کنین که ما یه object داریم که میخوایم هر کدوم از پراپرتی هاش رو توی یه متغیر ذخیره کنیم.

const product = {
    name:"iPad",
    price: 47000000,
    stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const name = product.name
const price = product.price
const stock = product.stock
const color = product.color
const display = product.display
const memory = product.memory

می بینید که برای ساخت متغیر از روی پراپرتی های یک object چقدر باید زحمت بکشیم؟ تازه این یه آبجکت کوچولوئه. تصور کن برای ساخت متغیرهای یک آبجکت که اطلاعات هواشناسی رو توش نگه میداره چند خط کد باید بنویسیم؟

اما میتونیم برای این کار از دستور خوشگل {} const استفاده کنیم و هر کدوم از پراپرتی هایی که لازم داریم رو توش بنویسیم تا خودش برامون متغیر همنام و متناظر اون رو تولید کنه.

const product = {
    name:"iPad",
    price: 47000000,
    stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const {name, price, stock, color} = product

console.log(price)

-> 47000000

متغیر های اضافه در object destructuring

ما میتونیم علاوه بر پراپرتی هایی که در object هستن، متغیرهای اضافی هم داخل {}const تعریف کنیم. برنامه هیچ خطایی نخواهد داد و این متغیرها با مقدار undefined ایجاد خواهند شد.

تغییر نام متغیرها در object destructuring

ما حتماً ملزم نیستیم که برای متغیرهای متناظر با پراپرتی ها، از اسم خود پراپرتی استفاده کنیم. بلکه میتونیم یک اسم دلخواه به متغیرمون بدیم و اون رو متناظر با پراپرتی قرار بدیم. برای این کار از کاراکتر دونقطه استفاده می کنیم :

const product = {
    name:"iPad",
    price: 47000000,
    stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const {name:productName, price:gheymat, stock, color} = product

console.log(gheymat)

->47000000

مقادیر پیشفرض برای object destructuring

میتونیم برای متغیرهایی که داخل {}const تعریف می کنیم، مقادیر پیشفرض هم در نظر بگیریم. در صورتی که اون پراپرتی در آبجکت مقداددهی نشده باشه، از مقدار پیشفرض استفاده خواهد شد.

ولی در صورتی که اون پراپرتی در آبجکت مقدار داشته باشه،‌از مقدار داخل آبجکت استفاده میشه و مقدار پیشفرض نادیده گرفته میشه.

مقادیر پیشفرض با کاراکتر مساوی = اعمال میشن:

const product = {
    name:"iPad",
    price: 47000000,
    // stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const {name:productName, price:gheymat, stock = 1, color} = product

console.log(stock)

-> 1

استفاده از object destructure در پارامتر ورودی تابع

مثال زیر رو در نظر بگیرین:

const product = {
    name:"iPad",
    price: 47000000,
    stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const myFunction = (type, product) => {

    console.log(product.name)
    
}

myFunction('ersaal', product)

-> iPad

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

برای اینکه بتونیم به راحتی پراپرتی های آبجکت product رو به صورت یک متغیر، داخل تابع داشته باشیم، میتونیم این کارو انجام بدیم:

const product = {
    name:"iPad",
    price: 47000000,
    stock: 104,
    color:"Space Gray",
    display: "12 inch",
    memory: "512 Gb"
}

const myFunction = (type, {name, price, color}) => {

    console.log(name, price, color)

}

myFunction('ersaal', product)

-> iPad 47000000 Space Gray

دقت کنید در این روش، ما موقع تعریف تابع، بجای اینکه یک اسم برای پارامتر ورودی بنویسیم، پراپرتی های مورد انتظارمون رو داخل {} نوشتیم.

اما موقع فراخوانی تابع، اسم آبجکتی که می بایست دارای این پراپرتی ها باشه رو بعنوان آرگومان ورودی می نویسیم.

این هم آموزش object destructuring در جاوااسکریپت ES6 🙂

برچسب ها

حامد عسکریان

برنامه نویس و عاشق تکنولوژی

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

دکمه بازگشت به بالا
بستن
بستن