‘String’ nesnesi

‘String’ nesnesi

Bu makale ‘String’ nesnesini açıklar.

Açıklama, temel bilgilerden gelişmiş tekniklere kadar, Unicode ve düzenli ifadelerle ilgili tuzaklar dahil olmak üzere adım adım ve anlaşılması kolay bir şekilde her şeyi kapsar.

YouTube Video

‘String’ nesnesi

JavaScript'teki dizeler, günlük geliştirmede en sık kullanılan türlerden biridir.

İlkel Dizeler ve String Nesneleri Arasındaki Fark

İlkel dizeler (örneğin ‘"hello"’), ‘new String("hello")’ gibi sarmalayıcı nesnelerden farklı davranır. Normalde ilkel türleri kullanmalısınız, nesne formunu kullanmaya pek gerek yoktur.

1// Primitive string
2const a = "hello";
3
4// String wrapper object
5const b = new String("hello");
6
7console.log(typeof a); // "string"
8console.log(typeof b); // "object"
9console.log(a === b);  // false — wrapper objects are not strictly equal
  • Bu kod, ilkel ile sarmalayıcı arasındaki tip farkını ve kesin karşılaştırmada nasıl davrandıklarını gösterir. Çoğu durumda ‘new String()’ kullanmaktan kaçının ve ilkel türlere bağlı kalın.

Dize Oluşturmanın Yolları (Sabitler ve Şablon Sabitleri)

Şablon sabitleri, değişkenleri gömmek ve çok satırlı dizeler yazmak için kullanışlıdır. Değişkenleri yerleştirip ifadeleri sezgisel olarak değerlendirebilirsiniz.

1const name = "Alice";
2const age = 30;
3
4// Template literal
5const greeting = `Name: ${name}, Age: ${age + 1}`;
6
7console.log(greeting); // "Name: Alice, Age: 31"
  • Şablon sabitleri oldukça okunabilirdir ve çok satırlı dizeler de dahil olmak üzere karmaşık dizeler oluşturmak için idealdir.

Yaygın Yöntemler (Arama ve Alt Dize Çıkarma)

‘String’ nesnesinin birçok temel yöntemi vardır.

 1const text = "Hello, world! Hello again.";
 2
 3// search
 4console.log(text.indexOf("Hello"));       // 0
 5console.log(text.indexOf("Hello", 1));    // 13
 6console.log(text.includes("world"));      // true
 7console.log(text.startsWith("Hello"));    // true
 8console.log(text.endsWith("again."));     // true
 9
10// slice / substring
11console.log(text.slice(7, 12));           // "world"
12console.log(text.substring(7, 12));       // "world"
  • ‘slice’ ve ‘substring’ benzerdir, ancak negatif indeksleri farklı şekilde işlerler. ‘slice’ negatif değerleri sondan pozisyon olarak yorumlar. Hangisini kullanacağınız konusunda net olun.

Bölme ve Birleştirme (split / join)

Bir dizeyi işlemek için bir diziye bölmek ve ardından tekrar birleştirmek yaygındır.

1const csv = "red,green,blue";
2const arr = csv.split(","); // ["red","green","blue"]
3
4console.log(arr);
5console.log(arr.join(" | ")); // "red | green | blue"
  • Yaygın bir desen, bir diziyi ayırmak için ‘split’ kullanmak, ortaya çıkan diziyi ‘map’ veya ‘filter’ ile işlemek ve ardından ‘join’ ile tekrar birleştirmektir.

Değiştirme ve Düzenli İfadeler

‘replace’ yalnızca ilk eşleşmeyi değiştirir. Tüm eşleşmeleri değiştirmek istiyorsanız, düzenli ifade ile ‘g’ bayrağını kullanın. Değiştirici olarak bir fonksiyon geçirerek, dinamik değiştirmeler de yapabilirsiniz.

 1const s = "foo 1 foo 2";
 2
 3// replace first only
 4console.log(s.replace("foo", "bar")); // "bar 1 foo 2"
 5
 6// replace all using regex
 7console.log(s.replace(/foo/g, "bar")); // "bar 1 bar 2"
 8
 9// replace with function
10const r = s.replace(/\d+/g, (match) => String(Number(match) * 10));
11console.log(r);    // "foo 10 foo 20"
  • Bir fonksiyon kullanarak yapılan dinamik değiştirme ile, eşleşmeleri analiz eden ve dönüştüren kodu kısa şekilde yazabilirsiniz.

Büyük/Küçük Harf Dönüşümü ve Normalleştirme

Çok dilli destek ve karşılaştırma için, toLowerCase ve toUpperCase'a ek olarak, Unicode normalleştirme (normalize) da önemlidir. Bu, özellikle aksanlı karakterleri karşılaştırırken gereklidir.

 1// Case conversion example:
 2// "\u00DF" represents the German letter "ß".
 3// In some locales, converting "ß" to uppercase becomes "SS".
 4// JavaScript follows this behavior.
 5console.log("\u00DF");
 6console.log("\u00DF".toUpperCase()); // "SS"
 7
 8// Unicode normalization example:
 9// "e\u0301" is "e" + a combining acute accent.
10// "\u00e9" is the precomposed character "é".
11// These two look the same but are different code point sequences.
12const a = "e\u0301";
13const b = "\u00e9";
14
15console.log(a === b);   // false: different underlying code points
16console.log(a.normalize() === b.normalize()); // true: normalized to the same form
  • Ligatür ve birleşik karakterler gibi farklı Unicode gösterimleri doğrudan eşit olmayacaktır, bu yüzden karşılaştırmadan önce ‘normalize()’ kullanın.

Unicode ve Kod Noktaları (Surrogate Çiftlerinin Yönetilmesi)

JavaScript dizeleri, UTF-16 kod birimlerinden oluşur, bu nedenle emojiler gibi bazı karakterler tek karakter için iki kod birimi kaplayabilir. Gerçek karakter birimlerini işlemek için ‘Array.from’, yayılma operatörü veya ‘for...of’ kullanın.

 1// Emoji composed with multiple code points:
 2// "\u{1F469}" = woman, "\u{200D}" = Zero Width Joiner (ZWJ),
 3// "\u{1F4BB}" = laptop. Combined, they form a single emoji: 👩‍💻
 4const s = "\u{1F469}\u{200D}\u{1F4BB}";
 5console.log(s);
 6
 7// Length in UTF-16 code units (not actual Unicode characters):
 8// Because this emoji uses surrogate pairs + ZWJ, the length may be > 1.
 9console.log("Length:", s.length);
10
11// Iterate by Unicode code points (ES6 for...of iterates code points):
12// Each iteration gives a full Unicode character, not UTF-16 units.
13for (const ch of s) {
14  console.log(ch);
15}
16
17// Convert to an array of Unicode characters:
18console.log(Array.from(s));
  • ‘length’ kod birimi sayısını döndürür, bu nedenle emojiler veya ligatürlerde beklediğiniz sayıyı alamayabilirsiniz. ‘for...of’ ve ‘Array.from’ ekrandaki karakterlere (grafem kümelerine) yakın bir sonuç verir, ancak tam grafem desteği gerekiyorsa özel bir kütüphane kullanmayı düşünün.

Güvenli Düzenli İfade ile Değiştirme (Kullanıcı Girdisi İşlerken)

Kullanıcı girdisini bir düzenli ifadeye yerleştirirken kaçış karakteri eklemeyi unutursanız, beklenmeyen davranışlara ve güvenlik açıklarına yol açabilir. Bir desende kullanmadan önce kullanıcı girdisini her zaman kaçış karakteriyle güvenli hale getirin.

1function escapeRegex(s) {
2  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3}
4
5const userInput = "a+b";
6const pattern = new RegExp(escapeRegex(userInput), "g");
7console.log("a+b a+b".replace(pattern, "X")); // "X X"
  • Kullanıcı dizelerini doğrudan düzenli ifadede kullanmayın; regex oluşturmadan önce mutlaka kaçış karakteriyle güvenli hale getirin.

Performans İpuçları: Birleştirme ve Şablonlar

Birçok küçük dizgeyi ardışık olarak birleştirirken, bunları bir diziye koyup ‘join’ kullanmak daha verimli olabilir. Diğer yandan, şablon dizeleri çoğu durumda oldukça okunaklı ve yeterince hızlıdır.

 1// concatenation in loop (less ideal)
 2let s = "";
 3for (let i = 0; i < 1000; i++) {
 4  s += i + ",";
 5}
 6
 7// using array + join (often faster for many pieces)
 8const parts = [];
 9for (let i = 0; i < 1000; i++) {
10  parts.push(i + ",");
11}
12const s2 = parts.join("");
  • Modern JavaScript motorları oldukça optimize olduğundan, az sayıda birleştirme için performans endişesine gerek yoktur. Ancak, on binlerce kez birleştirme gerekiyorsa ‘join’ kullanmak daha verimli olabilir.

Kullanışlı Pratik Teknikler: Doldurma, Trim ve Tekrarlama

trim, padStart, padEnd ve repeat, özellikle günlük metin işleme işlemlerinde kullanışlı yöntemlerdir. Bunlar genellikle giriş değerlerini biçimlendirme veya çıktı biçimlerini standartlaştırma gibi pratik durumlarda kullanılır.

1console.log("  hello  ".trim());       // "hello"
2console.log("5".padStart(3, "0"));     // "005"
3console.log("x".repeat(5));            // "xxxxx"
  • Bu yöntemler, form girdisini normalleştirmek veya sabit genişlikte çıktı üretmek için kullanılabilir.

Dize Karşılaştırma (Yerel Karşılaştırma)

‘localeCompare’, farklı dillerde sözlük sırasına göre dizeleri karşılaştırmak için etkilidir. Dil ve hassasiyet seçeneklerini belirtebilirsiniz (örneğin büyük/küçük harf duyarlılığı).

1console.log(
2  "\u00E4".localeCompare("z", "de")
3); // may be -1 or other depending on locale
4
5console.log(
6  "a".localeCompare("A", undefined, { sensitivity: "base" })
7); // 0
  • Uluslararasılaştırılmış karşılaştırmalar için ‘localeCompare’ kullanın ve uygun yerel ayar ile seçenekleri belirtin.

Pratik Örnek: Bir CSV Satırını Nesneye Dönüştürme (Pratik İş Akışı)

Yaygın bir kullanım örneği, ‘split’, ‘trim’ ve ‘map’ kombinasyonu ile tek bir CSV satırını bir nesneye ayrıştırmaktır. Tırnak içinde alanlar veya karmaşık CSV dosyaları için özel bir CSV ayrıştırıcısı kullanın.

 1// simple CSV parse (no quotes handling)
 2function parseCsvLine(line, headers) {
 3  const values = line.split(",").map(v => v.trim());
 4  const obj = {};
 5  headers.forEach((h, i) => obj[h] = values[i] ?? null);
 6  return obj;
 7}
 8
 9const headers = ["name", "age", "city"];
10const line = " Alice , 30 , New York ";
11console.log(parseCsvLine(line, headers));
12// { name: "Alice", age: "30", city: "New York" }
  • Bu yöntem basit CSV için işe yarar, ancak bir virgül tırnak içinde bir alanın içindeyse bunu işleyemeyeceğini unutmayın.

Yaygın Tuzaklar

JavaScript dize yönetiminde kolayca gözden kaçan bazı özellikler ve davranışlar vardır. Beklenmedik hatalardan kaçınmak için aşağıdaki noktalara dikkat etmek önemlidir.

  • ‘new String()’ kullanmak, tür denetimi veya karşılaştırmalarda yanlış sonuçlara neden olabilir. Çoğu durumda ilkel dize türleri yeterlidir.
  • Unicode'da tek bir görünen karakter birden fazla kod biriminden oluşabilir. Bu nedenle ‘length’ tarafından döndürülen değer, aslında ekranda görünen karakter sayısıyla uyuşmayabilir.
  • Kullanıcı girdisini düzenli ifadeye eklerken her zaman önce onu kaçış karakteriyle güvenli hale getirin.
  • ‘String.prototype.replace()’ varsayılan olarak yalnızca ilk eşleşmeyi değiştirir. Tüm eşleşmeleri değiştirmek istiyorsanız, düzenli ifadenizde /g bayrağını kullanın.
  • Dizeler değiştirilemezdir, bu yüzden yapılan işlemler her zaman yeni bir dize döndürür. Dönen değeri daima değişkene atamak önemlidir.

Özet

JavaScript dizeleri basit görünebilir, ancak Unicode ve değişmezlik özelliklerini anlamak önemlidir. Temel bilgileri öğrenerek dize işlemenizin güvenilirliğini ve okunabilirliğini büyük ölçüde artırabilirsiniz.

Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.

YouTube Video