WALKER

Dasturchi, frilanser, gik va introvert

by Sherzod Shermukhamedov

Javascriptda var, let va const

8d9b5e7d50

Javascript ES2015 (yoki ES6) da özgaruvçi e'lon qilişning ikki yangi yöli qöşilgan - const va let. Uşbu maqolada biz var, let va const haqida söz yuritamiz.

Dastlab mavzuga doir boşqa bilimlarni tuşunib oliş zarar qilmaydi. Ular özgaruvçini e'lon qiliş va qiymat beriş (declaration vs initialization), scope va hoisting (hosting emas)

Declaration vs Initialization

Özgaruvçini e'lon qiliş quyidagiça böladi.

var declaration

Biz declaration özgaruvçi e'lon qildik. **Javasciptda özgaruvçi e'lon qilinganda unga avtomatik tarzda undefined qiymati beriladi. **Bu degani console.log(declaration) - undefined qaytaradi.

Initialization esa özgaruvçiga qiymat beriş hisoblanadi.

var declaration
console.log(declaration) // undefined
declaration = 'This is an initialization'

Demak biz declaration özgaruvçiga string qiymat berib, uni initsializatsiya qildik.

Scope

Scope dasturda özgaruvçi va funksiyalarni qayerda işlatilişini belgilaydi. Javascriptda ikki turdagi scope bor - global scope va function scope. Agar özgaruvçi funksiya içida e'lon qilinsa, u function scope darajasida işlaydi, ya'ni funksiya içida işlaydi. Funksiyadan taşqarida işlamaydi.

Quyidagi misolni köramiz.

function getDate () {
  var date = new Date()

  return date
}

getDate()
console.log(date) // Uncaught ReferenceError: date is not defined

Biz date özgaruvçini getDate() funksiya içida e'lon qildik. Uni funksiyadan taşqarida çaqirganimiz uçun, kod "Reference error" qaytaradi. Bu degani date faqat getDate() içida işlaydi.

Şuningdek, özgaruvçi içki funksiyalar uçun ham işlaydi.

function getDate () {
  var date = new Date()

  function formatDate () {
    return date.toDateString().slice(4) // Işlaydi.
  }

  return formatDate()
}

getDate()
console.log(date) // Uncaught ReferenceError: date is not defined

getDate() da e'lon qilingan date özgaruvçisi formatDate() içida ham işlaydi, sababi date uçun function scope - getDate() içida.

Misolni biroz qiyinlaştiramiz. Bizda prices array bor, biz berilgan discount qiymatidan foydalanib, çegirmali narxlarni çiqarişimiz kerak bölsin. Funksiya tahminan quyidagiça işlaydi.

discountPrices([100, 200, 300], .5) // [50, 100, 150]

Kod

function discountPrices (prices, discount) {
  var discounted = []

  for (var i = 0; i < prices.length; i++) {
    var discountedPrice = prices[i] * (1 - discount)
    var finalPrice = Math.round(discountedPrice * 100) / 100
    discounted.push(finalPrice)
  }

  return discounted
}

Tuşunarli kod, menimça. Lekin bu yerda boşqa til dasturçilari (masalan PHPçilar) e'tibor bermay ötib ketadigan ğalatilik bor. for sikl içidagi özgaruvçilar sikldan taşqarida ham işlayapti. Aslida biz sikl içidagi e'lon qilgan özgaruvçilarimiz - i, discountedPrice va finalPrice yordamçi özgaruvçilar edi, töğrimi?

Nima uçun ular sikldan taşqarida ham qiymat qaytarişi kerak?

function discountPrices (prices, discount) {
  var discounted = []

  for (var i = 0; i < prices.length; i++) {
    var discountedPrice = prices[i] * (1 - discount)
    var finalPrice = Math.round(discountedPrice * 100) / 100
    discounted.push(finalPrice)
  }

  console.log(i) // 3
  console.log(discountedPrice) // 150
  console.log(finalPrice) // 150

  return discounted
}

Uşbu masalaga hoistingni körib çiqib, yana qaytamiz.

Hoisting

Yuqorida, Javasciptda özgaruvçi e'lon qilinganda unga avtomatik tarzda undefined qiymati beriladi, deb aytgan edik. Mana şu avtomatik undefined berilişining özi - hoisting. Yana bir qiziq jihat - özgaruvçi e'lon qilinişdan oldin çaqirilsa ham uning qiymati undefined böladi.

function discountPrices (prices, discount) {
  console.log(discounted) // undefined
  var discounted = []

  for (var i = 0; i < prices.length; i++) {
    var discountedPrice = prices[i] * (1 - discount)
    var finalPrice = Math.round(discountedPrice * 100) / 100
    discounted.push(finalPrice)
  }

  console.log(i) // 3
  console.log(discountedPrice) // 150
  console.log(finalPrice) // 150

  return discounted
}

Endigina biz asl mavzuga yetib keldik.

var, let va const

Dastlab var va let ni soliştiramiz. Asosiy farq - var - function scope, let - block scope. Block scope degani, let e'lon qilingan block içida işlaydi. Block deganda {} qavsli operatorlar tuşuniladi. Masalan for sikli yoki if şarti.

Discount misoliga yana bir marta qaytamiz. Yodingizda bölsa, i, discountedPrice va finalPrice yordamçi özgaruvçilar sikl taşqarisida ham işlayotgan edi. Biz ularni faqat block scope - for içidagina işlaydigan qilamiz.

function discountPrices (prices, discount) {
  let discounted = []

  for (let i = 0; i < prices.length; i++) {
    let discountedPrice = prices[i] * (1 - discount)
    let finalPrice = Math.round(discountedPrice * 100) / 100
    discounted.push(finalPrice)
  }

  console.log(i)
  console.log(discountedPrice)
  console.log(finalPrice)

  return discounted
}

Funksiyani işga tuşirsak:

discountPrices([100, 200, 300], .5) // ReferenceError: i is not defined

Sababi i özgaruvçi e'lon qilinmagan, ammo u console.log içida çaqirilgan. Aniqroği i özgaruvçisi - block scope va faqat for içidagina amal qiladi. Taşqarida işlamaydi.

Hoistingda körganimiz - özgaruvçi e'lon qilinmay turib, uni çaqirganda undefined berayotgan edi. Bu töğri işmas, katta dasturlarda debug qiliş, topiş qiyin böladigan xatolarni keltirib çiqaradi. Biz var discounted = [] ni let discounted = [] ga ögirganimizda, özgaruvçi e'lon qilişdan oldin çaqiriş işlamaydigan böladi.

var va let böyiça xulosalar

var

  • function scope
  • özgaruvçi e'lon qilinişidan oldin çaqirilganda undefined qaytaradi.

let

  • block scope
  • özgaruvçi e'lon qilinişidan oldin çaqirilganda ReferenceError qaytaradi.

let va const

const - let'dagi kabi block scope özgaruvçi e'lon qiladi. Yagona farqi - const orqali e'lon qilingan özgaruvçiga qayta qiymat bera olmaysiz.

let name = 'John'
const handle = 'worker'

name = 'John Doe' // ok
handle = 'office worker' // TypeError: Assignment to constant variable.

Lekini bor!

const person = {}

person konstant – özgarmas qiymatga ega. Lekin konstant obyekt va array e’lon qilib, uni töldiriş mumkin!

person[firstName] = "John"
person[lastName] = "Doe"

Özgarmasligi şundaki, person ning öziga qiymat beriş mumkin emas:

person = { firstName: "John", lastName: "Doe" }

^ Işlamaydi, sababi person avvalroq const bilan e’lon qilib qöyilgan. Işlaşi uçun, const’ni let’ga özgartiriş kerak.

Qaysi birini qaçon işlatiş kerak?

  1. var'dan foydalanmang.
  2. Köp holatda const'dan foydalaning.
  3. Agar özgaruvçining qiymati özgaradigan bölsa, let'dan foydalaning.

Şu usul xavfsizroq!

const let var