loader
banner

ES6’dan önce, bir değişkeni tanımlamanın tek yolu ‘var’ anahtar kelimesiydi. Artık gelişmiş işlevsellik sağlayan birkaç farklı seçeneğimiz var.

Const

Const kelimesi ‘constant’ kelimesinden gelir ve sabit anlamını taşımaktadır. Kısaca const, değiştirilemeyen bir değişkendir. JavaScript, ES6’da sabitleri tanıttı. Const’lardan önce, sadece üzerine yazılabilen değişkenler vardı.

var user = true
user = false
console.log(user) // false

Sabit bir değişkenin değerini sıfırlayamayız, eğer değerin üzerine yazmaya çalışırsak, bir konsol hatası alırız.

const user = true
user = false

Let

Let ile tanımlanan değişkenler sonradan değiştirilebilir ancak bir kez tanımlanabilir.

let login = true;
console.log(login); // true
...
login = false; 
console.log(login); // false

Tekrar tanımlamaya çalışırsanız hata meydana gelecektir.

let user = "Emre";
...
var user = "Acar";

JavaScript’te curly bracket (kıvrımlı parantez { } ) ile kod blokları oluşturuyoruz. Fonksiyonlar ile curly bracket ile oluşturulan bloklar değişkenlerin kapsamını engellerler.

for(let i = 0; i < 5; i++) {
  console.log(i); // 0, 1, 2, 3, 4
}
console.log(i); // undefined

Herhangi bir kod bloğunun içerisinde ‘let’ kullanmak global değişkenin değerini korur:

var title = "JavaScript"
if (title) {
  let title = "React"
  console.log('block', title) // React
}
console.log('global', title) // JavaScript

Templete String

Templete string’ ler bize dize birleştirme işlemine bir alternatif sunuyorlar. Ayrıca dizeler içerisine değişkenler eklememize izin veriyorlar.

Geleneksel dize birleştirme işlemi,

console.log("Adım:" + firstName + " Soyadım: " + lastName)

Artık bir dize oluştururken değişkenleri ${} ile çevreleyerek ekleyebiliriz.

console.log(`Adım: ${fistName} Soyadım: ${lastName}`)

Bu özellik çok daha büyük yazılar içerisinde değişkenleri kullanmamız gerektiğinde işimizi çok kolaylaştırıyor ve daha anlaşılır olmasını sağlıyor.

document.body.innerHTML = `
    <section>
      <header>
        <h1>The HTML5 Blog</h1> 
      </header>
      <article> 
          <h2>${article.title}</h2>
          ${article.body}
      </article>
      <footer>
          <p>copyright ${new Date().getYear()} | The HTML5 Blog</p> 
      </footer>
</section>
`

Varsayılan Parametreler

Fonksiyonlara gönderilen argümanlara değer atanmadığında varsayılan değer kullanılacaktır.

function getUser(name="Emre Acar", permit="leave"){
   console.log(`${name} is ${permit}`)
}

‘getUser’ fonksiyonuna argüman verilmese dahi varsayılan değerler kullanılarak doğru şekilde çalışacaktır.

Arrow Function

Function anahtar sözcüğü kullanmadan fonksiyon oluşturabiliriz. Ayrıca return anahtar sözcüğünü de kullanmamız gerekmez.

var person = function(firstname){
   return `${firstname} of Ankara`
}
// arrow function 
var person = firstname => `${firstname} of Ankara`

Artık bir satırda tanımlanan bir fonksiyonumuz var. Dikkat ettiyseniz fonksiyon anahtar sözcüğü kaldırıldı, => işareti neyin return olması gerektiğini söylüyor. Son olarak eğer fonksiyon tek bir argüman alırsa ( ) işaretlerini kaldırabiliriz.

var user = (firstName, lastName) => `${firstName}, ${lastName}`

Birden fazla satır var ise curly bracket kullanmak gerekir.

var user = (firstName, lastName) => {
  if (!firstName) {
    throw New Error('A firstName is required')
  }
  if (!lastName) {
    throw New Error('A lastName is required')
  }
  return `${fistName}, ${lastName}`
}

İlginç bir örneği birlikte inceleyelim. Aşağıdaki örneğe dikkat edin.

var cars = {
  models: ["BMW", "Mercedes", "Renault", "Peugeot", "Citröen"], 
  print: function(delay=1000){
    setTimeout(function() {
      console.log(this.models.join(","))
    }, delay)
  }
}
cars.print() // Cannot read property 'join' of undefined

Bu fonksiyonu çalıştırdığınızda hata alacaksınız, çünkü .join yöntemini this üzerinde kullanmaya çalışıyor. Bu durumda this, window nesnesidir. Alternatif olarak this’in kapsamını korumak için arrow function sözdizimini kullanabilirsiniz.

var cars = {
  models: ["BMW", "Mercedes", "Renault", "Peugeot", "Citröen"], 
  print: function(delay=1000){
    setTimeout(() => {
      console.log(this.models.join(","))
    }, delay)
  }
}
cars.print() // BMW, Mercedes, Renault, Peugeot, Citröen

Yukarıdaki gibi setTimeout içerisinde arrow function kullanılırsa this.model kullanarak model’e ulaşılabilir. Her zaman scope’u aklınızda tuttuğunuza dikkat edin. Arrow fonksiyon, this’in kapsamını engellemez.

Not: Daha iyi kavramak için javaScript’ deki this kavramını araştırmanız gerekebilir.

Destructuring Assignment

Dizilerden veya nesnelerden gelen özellikleri farklı değişkenlere açılmasını mümkün kılan bir JavaScript ifadesidir.

var cities = {
  ankara: "çankaya",
  bursa: "inegöl",
  izmir: "bornova",
  istanbul: ["adalar", "beşiktaş", "beyoğlu", "maltepe", "üsküdar"]
}
var {ankara, izmir} = cities
console.log(ankara, izmir) // çankaya bornova

Kod, Ankara ve İzmir’i nesneden çıkarır ve onlar için yerel değişkenler yaratır. Ayrıca Ankara ve İzmir değişkenleri değiştirilebilir.

var {ankara, izmir} = cities
ankara = "mamak"
izmir = "buca"
console.log(ankara) // mamak
console.log(izmir) // buca
console.log(cities.ankara, cities.izmir) // çankaya bornova

Fonksiyon argümanına {} ile belirterek sadece o değeri de alabiliriz.

var user = ({firstName}) => {
  console.log(`$firstName` of Ankara)
}
var regularPerson = {
  firstName: "Mustafa",
  lastName: "Yılmaz"
}
user(regularPerson)   // Mustafa of Ankara

FirstName’i imha ederek, yalnızca firstName değişkenini kullanacağımızı beyan ederiz.

Değerler ayrıca dizilerden de yok edilebilir. Bir dizinin ilk değerini bir değişken ismine atamak istediğimizi düşünün.

var [firstResort] = ["elma", "armut", "kira"]
console.log(firstResort)  // elma

Ayrıca gereksiz değerleri virgül kullanarak liste eşleştirmesiyle iletebiliriz. Liste eşleştirme, virgüllerin atlanması gereken öğelerin yerini aldığında gerçekleşir. Aynı dizi ile ilk iki değeri virgüllerle değiştirerek son değere erişebiliriz.

var [,,thirdResort] = ["elma", "armut", "kiraz"]
console.log(thirdResort)  // kiraz

Object Literal Enhancement

Object Literal Enhancement, destructuring assignment’ in tam tersidir. Yeniden yapılanma ya da bir araya getirme sürecidir. Değişkenleri global kapsamdan alıp bir nesneye çevirebiliriz.

var name = "Tahta"
var elevation = 4839
var funCase = {name, elevation}
console.log(funCase) // { name: 'Tahta', elevation: 4839 }

Nesne yöntemlerini tanımlarken artık function anahtar sözcüğünü kullanmak gerekmez

// Eski
var user = {
  name: name,
  lastName: lastName,
  fullName: function(){
    var name = this.name.toUpperCase() + this.lastName.toUpperCase()
    console.log($name)
  }
}
// Yeni
const user = {
  name,
  lastName,
  fullName(){
    var name = this.name.toUpperCase() + this.lastName.toUpperCase()
    console.log($name)
  }
}

Spread Operatörü

Spread operatörü, birkaç farklı görevi yerine getirir. İlk olarak yayma operatörü dizilerin içeriğini birleştirmemize izin verir. Örneğin iki dizimiz olsaydı, iki diziyi bir araya getiren üçüncü bir dizi yapabilirdik.

var meyveler = ["Karpuz", "Kiraz", "Muz"]
var sebzeler = ["Havuç", "Salatalık"]
var buzdolabi = [...meyveler, ...sebzeler]
console.log(buzdolabi.join(', ')) // Karpuz, Kiraz, Muz, Havuç, Salatalık

Şimdi bir diziyi tersine çevirip ilk elemanını almak istersek;

var meyveler = ["Karpuz", "Kiraz", "Muz"]
var [son] = meyveler.reverse()
console.log(son) // Muz
console.log(meyveler.join(', ')) // Muz, Kiraz, Karpuz

Yukarıdaki örnekte ne olduğuna dikkat edin. Reverse işlevi aslında orijinal diziyi değiştirdi. Spread operatörünü kullanarak orijinal diziyi değiştirmemize gerek yoktur, dizinin bir kopyasını oluşturabilir ve sonra tersine çevirebiliriz.

var meyveler = ["Karpuz", "Kiraz", "Muz"]
var [son] = [...meyveler].reverse()
console.log(son) // Muz
console.log(meyveler.join(', '))  // Karpuz, Kiraz, Muz

Spread operatörü, dizideki öğelerin bir kısmını veya kalanını almak için de kullanılabilir.

var meyveler = ["Karpuz", "Kiraz", "Muz", "Elma", "Limon"]
var [ilk, ...rest] = meyveler
console.log(rest.join(", ")) // Kiraz, Muz, Elma, Limon

Spread operatörünü fonksiyon argümanlarını bir dizi olarak toplamak için de kullanabiliriz. Burada spread operatörünü kullanarak n sayısı argümanını alan ve bazı konsol mesajlarını yazdırmak için bu argümanları kullanan bir fonksiyon tanımlıyoruz.

function tellMe(...args){
  var [start, ...remaining] = args
  var [finish, ...stops] = remaining.reverse()
console.log(`drive through ${args.length} towns`)
  console.log(`start in ${start}`)
  console.log(`the destination is ${finish}`)
  console.log(`stopping ${stops.length} times in between`)
}
tellMe(
  "Ankara",
  "İstanbul",
  "İzmir",
  "Manisa",
  "Bursa"
)

Spread operatörü ayrıca nesneler için de kullanılabilir. Spread operatörü nesnelerle kullanmak dizilerle kullanmaya benzer.

var computer = {
  cpu: "i5 1.6GHz",
  ram: "8 GB DDR"
}
var disk = "320 GB SSD"
var clientComputer = {
  ...computer,
  disk
}
console.log(clientComputer) 
// {cpu: "i5 1.6GHz", ram: "8 GB DDR", disk: "320 GB SSD"}

Promise

Promise bize eşzamanlı olmayan davranışlardan bir anlam çıkarmanın yolunu gösterir. Eş zamansız bir istek yaparken, iki şeyden biri gerçekleşir; her şey umduğumuz gibi gider ya da bir hata oluşur.

Aşağıdaki örnekte, getFakeMembers fonksiyonu yeni bir promise döndürür. Promise, API’ ya bir istekte bulunur. Eğer promise başarılı olursa veriler yüklenecektir; başarışız olursa, bir hata meydana gelecektir:

const getFakeMembers = count => new Promise((resolves, rejects) => {
  const api = `https://api.randomuser.me/?nat=TR&results=${count}`
  const request = new XMLHttpRequest()
  request.open('GET', api)
  request.onload = () =>
    (request.status === 200) ?
    resolves(JSON.parse(request.response).results) :
    reject(Error(request.statusText))
  request.onerror = (err) => rejects(err)
  request.send()
})

Yukarıda promise oluşturuldu, ancak henüz kullanılmadı. Promise öğesini getFakeMembers işlevini çağırarak ve yüklenmesi gereken üye sayısını girerek kullanabiliriz. Function, promise yerine getirildikten sonra bir şeyler yapmak için zincirlenebilir. Buna kompozisyon denir. Ayrıca hataları işleyen ek bir geri bildirim (callback) kullanacağız.

getFakeMembers(5).then(
  members => console.log(members),
  err => console.error(
    new Error("Cannot load members"))
)

Class’lar

Daha önce JavaScript’te class yoktu ve tipler fonksiyonlarla tanımlanırdı. Şimdi bir örnekle fonksiyon yaratalım ve prototype kullanarak fonksiyon nesnesindeki yöntemleri tanımlayalım.

function Tatil(hedef, sure) {
    this.hedef = hedef
    this.sure = sure
}
Tatil.prototype.yazdir = function() {
    console.log(this.hedef + " | " + this.sure + " gün")
}
var antalya = new Tatil("Antalya", 7);
antalya.yazdir();

Klasik nesne oryantasyonuna alışkınsanız, bu muhtemelen hoşunuza gitmeyecektir.

ES6 class tanımlamasına izin verir ancak JavaScript hala aynı şekilde çalışır. Fonksiyonlar nesnedir ve kalıtım prototype ile ele alınır, ancak klasik nesne yönelmesinden geliyorsanız bu sözdizimi daha anlamlı olur:

class Tatil {
  constructor(hedef, sure) {
    this.hedef = hedef
    this.sure = sure
  }
  yazdir() {
    console.log(`${this.hedef}'a ulaşım ${this.sure} gün sürer.`)
  }
}
var antalya = new Tatil("antalya", 7)
antalya.yazdir() // antalya'a ulaşım 7 gün sürer.

Modüller

Bir JavaScript modülü, diğer JavaScript dosyalarına kolayca dahil edilebilen ve yeniden kullanabilen bir kod parçasıdır. Yakın zamana kadar, modüler JavaScript ile çalışmanın tek yolu, modül alma ve verme işlemlerini yapabilen bir kütüphane kullanmaktı. ES6 ile JavaScript artık modülleri desteklemektedir.

text-helper.js

export const print(message) => log(message, new Date())
export const log(message, timestamp) =>
  console.log(`${timestamp.toString()}: ${message}`)

Export, başka bir modülde kullanılacak olan herhangi bir JavaScript türünü export yapmak için kullanılabilir. Bu örnekte, yazdırma işlevi ve log işlevi dışa aktarılmaktadır.

Bazen bir modülden yalnızca bir değişkeni dışa aktarmak isteyebilirsiniz. Böyle durumlarda export default kullanabilirsiniz.

mt-freel.js

const freel = new Expedition("Mt. Freel", 2, ["water", "snack"])
export default freel

Modüller, import ifadesi kullanılarak diğer JavaScript dosyalarında kullanılabilir. Birden fazla dışa aktarma içeren modüller, object destructuring yapılarak tanımlanabilir.

import { print, log } from './text-helpers'
import freel from './mt-freel'

print('printing a message')
log('logging a message')

freel.print()

Modül değişkenlerini yerel olarak farklı değişken isimleri altında tanımlayabilirsiniz.

import { print as p, log as l } from './text-helpers'

p('printing a message')
l('logging a message')

Ayrıca * ile her şeyi tek bir değişkene de aktarabilirsiniz.

import * as fns from './text-helpers

ES6 ile gelen tüm farklılıkları sizlere aktarmaya çalıştım. Umarım sizler için yararlı olmuştur.

Emre Acar – STELAB Product Development Manager