JavaScript geliştirici yolunda emin adımlarla ilerlemek istiyorsanız bazı temel kavramların yanınıda Symbol dediğimiz Sembollere hakim olmanızda yarar olacaktır. Bu yazıda bazı yerlerde Symbol=Sembol olarak kullanacağız. 

Hazırsak başlayalım; 

Öncelikle Symbol nedir? 
Symbol ECMAScript 6 ile sunulan yeni bir ilkel veri türüdür. Temel yapıcı ile oluşturulan her Symbol  benzersizdir.
 

const symbol1 = Symbol(); // create first symbol
const symbol2 = Symbol(); // create second symbol

console.log(symbol1 == symbol2); // false
console.log(symbol1 === symbol2); // false

Symbol yapıcıda açıklamalarda oluşturulabilir ancak hata ayıklama dışında kullanılmaması gerekmektedir. Bunu sakın unutmayın!

const niceSymbol = Symbol('Yup');
console.log(niceSymbol.description); // Yup  

Global Symbol Kayıtları

const symbol1 = Symbol.for('ynet');
const symbol2 = Symbol.for('ynet');

console.log(symbol1 == symbol2); // true
console.log(symbol1 === symbol2); // true
console.log(symbol1.description); // ynet

Örnekte görüldüğü üzere Global Symbol kayıtları tüm sembollerin depolandığı konumdadır. Herhangi bir yöntem için bir kez kullandığınızda kayıt defterine yeni bir Symbol eklenir ve bir dahaki kullanımda oradan çağırılır. 

Burada dikkat etmemiz gereken herhangi bir yöntem ile oluşturulan Symboller temel ile oluşturulan Symbollerden farklıdır. Symbol.keyFor() yöntemiyle global olarak kaydedilen sembolün tuşunu kontrol edebilirsiniz .
 

const a = Symbol.for('ynet'); // globally registered symbol
console.log(Symbol.keyFor(a)); // ynet

const b = Symbol(); // local unique symbol
console.log(Symbol.keyFor(b)); // undefined

Symboller diziye dönüşmezler herhangi bir Symbol diziye dönüştürmek isterseniz TypeError alırsınız. 

console.log(`${Symbol()}`); // TypeError: Can't convert Symbol to string

Symboller genellikle nesnelerdeki özelliklere doğrudan erişimi gizlemek için kullanılır. Symbol ile yarı özel bir alan oluşturabilirsiniz.
 

const tree = {
  [Symbol('species')]: 'birch',
  [Symbol('height')]: 7.34,
};
console.log(tree);

Bir sembole başvurmadan, altında özelliklerin ağaca bağlı olduğu bir değeriniz yoktur.

Sıralama

Sembollerle ilgili bir başka harika numara Enum yaratmaktır. Başka bir programlama dilindeki numaralandırmalar, olası tüm değerlere sahip türlerdir. Örneğin, tam olarak iki araba durumuna sahip olmak isteyebilirsiniz: DRIVE ve IDLE ve araba durumunun bu numaradan geldiğinden emin olun, böylece dize veya sayı kullanamazsınız.

Sembollü numaralandırma örneği:

const CarState = Object.freeze({
  DRIVE: Symbol('drive'),
  IDLE: Symbol('idle'),
});

const car = {
  state: CarState.DRIVE
}

if (car.state === CarState.DRIVE) {
  console.log('Wroom, wroom!');
} else if (car.state === CarState.IDLE) {
  console.log('Waiting for ya!');
} else {
  throw new Error('Invalid state');
}

Semboller neden bu kadar önemli? Bu örneği kontrol edin. Nesneyi numaradan sembolün arkasında başka bir değerle değiştirmeye çalışırsanız bir hata alırsınız.

const CarState = Object.freeze({
  DRIVE: Symbol('drive'),
  IDLE: Symbol('idle'),
});

const car = {
  state: CarState.DRIVE
}

// you cannot set the state without reference to symbol-based enum
car.state = 'idle';

if (car.state === CarState.DRIVE) {
  console.log('Wroom, wroom!');
} else if (car.state === CarState.IDLE) {
  console.log('Waiting for ya!');
} else {
  throw new Error('Invalid state');
}

Dizelerle benzer kod geçerli olacak ve bu bir sorun oluşturacaktır. Biz tüm olası durumları kontrol etmek istiyoruz. O halde; 

const CarState = Object.freeze({
  DRIVE: 'drive',
  IDLE: 'idle',
});

const car = {
  state: CarState.DRIVE
}

// you can set car state without calling for enum prop, so data may be lost or incorrect
car.state = 'idle';

if (car.state === CarState.DRIVE) {
  console.log('Wroom, wroom!');
} else if (car.state === CarState.IDLE) {
  console.log('Waiting for ya!');
} else {
  throw new Error('Invalid state');
}


Symbol. iterator : 
Döngü ile yineleme yaparken yineleyici davranıştan sorumludur .

const tab = [1, 7, 14, 4];

for (let num of tab) {
  console.log(num);
}

Peki ya elimizde Roma rakamından  ve karışık rakamlardan oluşan bir for döngüsü var diyelim. Roma rakamları dışında tüm sayıları döndürmek istiyorsak ve bunu döngüyü değiştirmeden yapmak istiyorsak?
İşte tamda bu noktada Symbol.iterator kullanabilir ve değerleri döndürmekten sorumlu olan geçersiz kılma işlevini kullanabiliriz .

Örnek ; 

const tab = [1, 7, 14, 4];

tab[Symbol.iterator] = function () {
  let index = 0;
  const total = this.length;
  const values = this;
  return {
    next() {
      const romanize = num => {
        const dec = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
        const rom = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
        let output = "";

        for (let i = 0; i < dec.length; i++) {
          while (dec[i] <= num) {
            output += rom[i];
            num -= dec[i];
          }
        }

        return output;
      };

      return index++ < total ? {
        done: false,
        value: romanize(values[index - 1])
      } : {
        done: true
      };
    }

  };
};

for (let num of tab) {
  console.log(num);
}
// I
// VII
// XIV
// IV

Diğer iyi bilinen semboller:

  • asyncIterator,
  • match,
  • replace,
  • search,
  • split,
  • hasInstance,
  • isConcatSpreadable,
  • unscopables,
  • species,
  • toPrimitive,
  • toStringTag,

Şimdi sizde bu Symboller ile birkaç antreman yaparak bilginizi pekiştirebilirsiniz. 

Kolay gelsin....