[TR] S2E1 : Javascript Tekrar -Part 1 | RECAP ♻️

Yasin Serbest
7 min readMay 29, 2023

--

Herkese selam, RECAP serisinin ilk bölümü ile beraberiz. Bu seride derine inmeden daha önceden öğrenmiş olduğumuz konuları hatırlamaya yönelik çalışmalar yapacağım. Önemli olan fakat unutmuş olabileceğimiz kavramları RECAP serilerinde tekrarlayacağım. İlk bölümümüzde Javascript’i ele alacağız. Çok uzun bir konu olduğu için birkaç partta ele alacağım. Bu partın konusu Veri Tipleri, Sınıflar(Objects), Fonksiyonlar, Diziler(Arrays), Döngüler(Loops), Operatörler ve Stringler.

Veri Tipleri

Verimizi ilk başta tanımlarken uygun bir tipte tanımlamak oldukça önemlidir. Değişkenin hangi tipte olduğunu typeof(değişken) ile bulabiliriz. Veri tiplerini iki ana başlığa ayıracağız.

Primitive Veri Tipleri

Primitive veri tipleri Number, String, Boolean, Undefined, Null, BigInt ve ES6 ile gelen Symbol’dur.

Referans Veri Tipleri

Referans Veri Tipleri ise Sınıflar(Objects) ve onların türevleridir. Sınıflar(Objects), Diziler(Arrays), Fonksiyonlar, Maps ve Sets referans tipinde veri tipleridir.

Primitive Veri Tipleri vs Referans Veri Tipleri

Primitive veri tipinde bir değişken tanımlandığında stack adı verilen bilgisayarın veri yığın deposunda tutulur, değişken kendi adı ve değeriyle stack’ta tutulur. Referans veri tipleri ise değişen kendi ismi ve değeriyle değil, değişkenin bulunduğu yığının adresi tutulur. Şimdi aradaki bu farkı bir örnekle göstereyim.

            //PRIMITIVE DATA TYPES                  
let variable1 = 20;
let variable2 = variable1; //variable2=variable1=20
variable1 = 25;
console.log(variable1); //outputs 25
console.log(variable2); //outputs 20

//REFERENCE DATA TYPES
let person1 = {
name: "Jack",
age: 20,
};
let person2 = person1;

//updating person1
person1.age = 25;
console.log(person1.age); //output 25
console.log(person2.age); //output 25

Yukarıdaki örnekte önce primitive bir veriyi başka bir primitive veriye atadığımızda sonrasında ise bir tanesinin değerini değiştirdiğimizde görüyoruz ki sadece değiştirdiğimiz veri etkileniyor. Fakat referans bir tipte olan object için atama yaptığımızda (person2 = person1) yığında işaret ettiği adresleri eşitlediğimizden birinde yapılan değişiklik diğerine de işleniyor. Dolayısıyla biz sadece person1.age’i değiştirmek isterken person2.age’in de yığındaki adresi aynı olduğundan onun da değeri değişmiş oluyor. Veri tiplerindeki bu temel farkı hatırlamış olduk.

Sınıflar (Objects)

const person1 = { 
firstName: 'Jack', //key ve value. İksinin birleşimine ise propery deriz.
lastName: 'Meldow',
birthYeah: 1991,
family: { //iç içe object ataması yapabilirsin.
fathersName: "Eric",
mothersName: "Susanne",
wifesName: "Katherine",
},
job: 'teacher',
friends: ['Michael', 'Peter', 'Steven'],
calcAge () { //object içinde fonksiyon tanımlaması
return 2023 - this.birthYeah;
;
}
};

Şimdi yukarıdaki gibi person1 adında bir sınıfımızın olduğunu düşünelim. Gördüğün gibi object içine array, fonksiyon, string, number hatta yeniden bir object ataması bile yapabiliyoruz. Bunların her birine property diyoruz, bu propertyler üzerinden gerçekleştirebildiğimiz bir kaç işlemi hatırlayalım.

Bracket ve dot notasyonlarıyla value değerlerini nasıl alabiliriz ona bakalım. Biz dizilerde index numarasıyla değer alırken objectlerde ise key değeriyle alırız.

console.log(jonas.lastName);  //dot notasyonu ile value alımı
console.log(jonas['lastName']); //brackets notasyonu ile value alımı
---
const nameKey = 'Name';
console.log(person1['last' + nameKey]); //Brackets notasyonu ile böyle bişey yazabilirsin. Output olarak lastName value'esi ne ise onu verir.
console.log(person1.'last' + nameKey) //Yanlış, herhengi bir sonuç döndürmez hata verir. Dot notasyonu ile böyle bir şey kullanamazsın
----
//dot ve bracket notasyonları ile aşağıdakiler gibi property ekleyebilirsin.
person1.country = "Turkey";
person1["city"] = "Istanbul";

Object Destructions

Şimdi bizim person1 adlı sınıfımızdaki valueleri biz destruction yaparak ayrı ayrı başka değişkenlere atayabiliriz, oluşturduğumuz yeni değişenlerin isimlerini dahi değiştirebiliriz.

const { firstName, lastName } = person1; //object destruction
console.log(firstName, lastName); //outputs: Jack Meldow

const { firstName: name, birthYeah: year } = person1; //hem desct. yapıp hem de oluşan yeni değişkenlere farklı isimler verebiliriz.
console.log(name, year); //Jack 1991

const {
family: { fathersName: father, mothersName: mother },
} = person1;
console.log(father, mother); //iç içe object destruction

Looping Objects

Zaman zaman bizim sınıfımızı bir döngü içine almamız gerekebilir. Javascript’te döngüyle sınıfların hem key, hem value hem de iki değere birden erişebilmek mümkün.

const keys = Object.keys(person1);
console.log(keys); //outputs: [firstName, lastName, birthYear, job, family, friends, calcAge]

const values = Object.values(person1);
console.log(values); //outputs: ['Jack', 'Meldow', 1991, 'teacher', ...]

const properties = Object.entries(person1);
console.log(properties); //outputs: ['firstName', 'Jack'], ['lastName', 'Meldow'], ['birthYear', 1991], [..]

Copying Objects

Javascript’te sınıfı kopyalamadan önce bazı kararlar vermemiz gerekiyor. Sınıfı kopyaladıktan sonra nested propertyleri değiştirecek miyiz yoksa değiştirmeyecek miyiz? Eğer değiştirmeyeceksek Spread Operatörünü veya Object.assign() metodunu kullanabiliriz.

//spread operatörü ile object kopyalama
const person2 = { ...person1 };
person2.firstName = "Bryan";
console.log(person1.firstName, person2.firstName); //outputs: Jack Bryan

//Object.assign() ile object kopyalama
const person3 = Object.assign({}, person1);
person3.firstName = "Juan";
console.log(person1.firstName, person3.firstName); //outputs: Jack Juan

Şimdi yukarıdaki propertyleri değiştirdiğimizde herhangi bir sorunla karşılaşmıyoruz, her şey beklediğimiz gibi. Fakat biz nested property olan friends veya family’den birini değiştirmek istediğimizde farklı bir sonuçla karşılaşıyoruz.

person2.friends.pop();
console.log(person1.friends, person2.friends); //Outputs: [ 'Michael', 'Peter' ], [ 'Michael', 'Peter' ]

Gördüğümüz gibi objectler birer reference value olduğundan dolayı onları ister spread ile ister object.assign( ) ile kopyaladıktan sonra nested propertylerini değiştirmeye kalktığımızda hem asıl object hem de kopyasının değeri değişir. Spread ve Object.assing( )’in yaptığı bu kopyalamalara shallow copy diyoruz. Nested propertyleri de kopyaladıktan sonra asıl object değişmeden sadece kopyaladığın object’i değiştirmek istiyorsak birkaç yöntem var buna da deep copy diyoruz. Deep copy için ben Lodash’ı tercih ediyorum. Lodash, Javascript için bir yardımcı kütüphanedir. Bu kütüphane, Javascript için birçok yardımcı fonksiyon sunar. Npm veya yarn ile lodash kütüphanesini indirdikten sonra aşağıdaki gibi bir kullanım yapabiliriz.

//Lodash ile derinlemesine kopyalama
import _ from 'lodash';

const person4 = _.cloneDeep(person1);
person4.friends.pop();
console.log(person1.friends, person4.friends); //Outputs: [ 'Michael', 'Peter', 'Steven' ] [ 'Michael', 'Peter' ]

Yukarda gördüğümüz gibi Lodash kütüphanesiyle beraber deep copy yapıp asıl object’i değiştirmeden istediğimiz property’i değiştirebiliyoruz.

Fonksiyonlar

Javascriptte birden çok fonksiyon tanımlaması mevcuttur. Bu tanımlamalar benim sık karıştırdığım konulardan olduğundan RECAP serisinde yer verdim. 3 tip fonksiyon tanımlaması anlatacağım.

//1) Function Declaration
function name(param1, paramN) {
statements...
}
//2) Function Expression
const name = function (param1, paramN) {
statements...
}
// 3) Arrow Function
const name = (param1, paramN) => {
statements...
}

Javascript’te fonksiyonlara default parametreler de atayabiliriz. Örneğin bir parametreye değer ataması yaptığımızda atadığımız değeri, yapmadığımızda ise daha önceden atanmış belirli bir değeri almasını sağlayabiliriz.

function multiply(a, b = 1) {
return a * b;
}
console.log(multiply(5)); //output: 5
console.log(multiply(5, 2)); //output: 10

Diziler (Arrays)

Javascript’in en önemli konularından biri de dizilerdir. Diziler birden fazla değişkeni tutabilen özel değişkenlerdir. Diziler dinamik olmalıdır çünkü diziyi bir kere tanımladığımızda veya datayı bir dizi şeklinde aldığımızda ilerleyen zamanlarda çoğunlukla onu işlememiz veya onda bazı değişiklikler yapma ihtiyacı duyarız. Burda da bazı dizi metodlarını size açıklamaya çalışacağım, tüm dizi metotlarına buradan ulaşabilirsiniz. Bunların başlıcaları Slice, Splice, Concat, Join, Reverse, Map, Filter, Reduce, Find, FindIndex, Includes, Some, Every ve Sort. Aşağıdaki resimde tanımlamış olduğum birkaç array üstünde bu metotları göstermeye çalıştım. Bazılarının daha iyi anlaşılabilmesi için birden fazla örnek verdim.

Dizi Metotları

Array Destructions

Zaman zaman bir dizi içinden belirli bir elemanı veya belirli bir bölümü almak isteriz. Dizilere de objectlerde olduğu gibi destruction işlemi uygulayabiliriz.

array destructions

Döngüler (Loops)

Döngüler tekrar eden bir şeyi hızlı ve kolay yoldan yapmamızı sağlarlar. Birden fazla döngü tipi vardır. Aynı sonucu farklı döngüler ile alabiliriz, döngü kullanımı gereksinimin yanı sıra alışkanlıkların da belirleyebildiği bir seçimdir. Örneğin ben for of veya forEach ile çevirebileceğim bir array’ı çoğu zaman Map metodu ile çeviririm. Şimdi döngüleri örneklerle hatırlayalım.

döngüler

Operatörler

Javascriptte Mantıksal Operatörler, Atama Operatörleri, Koşul Operatörler gibi bir çok operatör çeşidi vardır.Bu bir RECAP serisi olduğu için size tüm operatörleri değil, unutulmaya yatkın olanları göstermeye çalışacağım. Diğer operatörlere buradan ulaşabilirsiniz.

Spread ve Rest Operatörleri (…)

Spread operatörü bir stringin veya bir dizi döngüsünün genişletilmesine, bir üst katmana çıkarılmasına olanak tanır. Rest ise tam tersi elemanları bir dizi içine alır. Spread ve Rest zıt çalışır. Spread, dizilerden elemanları çıkarır ve eşitliğin sağına yazılır. Rest ise elemanları diziye sokar, eşitliğin soluna yazılır. Aşağıdaki örnekleri inceleyelim.

//SPREAD
const array = [3, 4, 5];
const newArray = [1, 2, ...array]; //output: [1, 2, 3, 4, 5];
console.log(newArray); //elemanları bir üst katmana çıkarıp yazar, bu örnekte dizinin dışına çıkardı 1 2 3 4 5

const str = "javascript";
const letters = [...str, "."];
console.log(letters); //output:['j', 'a', 'v', 'a','s', 'c', 'r', 'i','p', 't', '.']

//REST
const [a, b, ...others] = [1, 2, 3, 4, 5];
console.log(others); //output: [3,4,5]

Nullish Coalescing Operator (??)

Nullish operator ‘’(empty string), false, NaN ve 0'ı falsy value olarak kabul etmez. Onun için falsy valueler sadece null ve undefined’dır. Eşitliğin sol tarafında null veya undefined var ise eşitliğin sağ tarafını döndürür, bunun dışındaki tüm senaryolarda eşitliğin sol tarafını döndürür. Aşağıda örneklerle açıklamaya çalıştım.

console.log(null ?? "some text A"); //output: some text A
console.log(undefined ?? "some text B"); //output: some text B
console.log("" ?? "some text C"); //output: ''
console.log(0 ?? 23); //output: 0

Optional Chaining (?.)

Bir objectte olmayan bir property’e erişmeye çalışırken bizi hata almaktan kurtarır. Aynı şekilde olmayan bir fonksiyon veya verilmeyen bir parametre için kullanıldığında da bizi hata almaktan kurtarır. Örneklerle daha iyi anlayacağız.

const person1 = {
name: "Jack",
age: 20,
};

console.log( person1.friends.length); //output: TypeError: Cannot read properties of undefined (reading 'length')
console.log( person1.friends?.length); //output :undefined

console.log(person1.someNonExistentMethod?.()); // output: undefined
/* -------- */
function printMagicIndex(arr) {
console.log(arr?.[42]);
}

printMagicIndex([0, 1, 2, 3, 4, 5]); // undefined
printMagicIndex(); // yukarıda fonksiyon tanımında ?. kullanılmasaydı hata vericekti.

Stringler

Javascript’te size anlatmak istediğim bir diğer konu da Stringler. Stringler’in karakterlerini de diziler gibi index değeriyle alırız, bazı dizi metotlarını stringlere de uygulayabiliriz, string karakterlerini bir diziye ayrı elemanlar şeklinde atayabiliriz veya string’i büyük yada küçük harflerle yazabiliriz. Aşağıdaki örnekte hepsine bakalım.

string metotları

RECAP serisinin ilk bölümünde, Javascript’te bulunan bazı kavramları hatırladık. Rutin olarak Javascript tekrarlarınızdaki konuları bana iletirseniz, ilerleyen partlarda onlara da yer verebilirim :)

Happy Coding :)

Kaynakça

https://www.freecodecamp.org/news/primitive-vs-reference-data-types-in-javascript

--

--