Veri Tipleri
İlkel veritipi nedir?
Çoğu zaman ilkel bir veri doğrudan en alt seviyede tanımlanabilendir. Tüm ilkel tipler değiştirilemez(immutable) tiplerdir.
Örn:
var yas = 12
var ad = ’Cem’
var kayitli = false
var tanimsiz = undefined
var bos = null
Standart ES içinde 7 tip tanımlıdır ve bunların 6 sı ilkel veri tipidir:
Undefined, Null, Number, String, Boolean, Symbol(Bazı programlama dillerinde atom olarak adlandırılır, objelerin key kısmında string ya da Symbol
kullanılır).Undefined ve null tipleri hep tipin hem de değerin kendisidir. Undefined tipi tanımlanmış ama değer atanmamış değişkenler için kullanılır.
Bir değişken eğer null tipinde değere sahipse(yani null değeri atanmışsa) bilinçli olarak boş değeri atanmış bir değişken olarak işaretlenmiştir. Bir
değişken değer atanmadan tanımlanmışsa Javascript otomatik olarak onu undefined olarak işaretlerken, bir değişkenin null değerine sahip olması
için programatik olarak atamanın yapılması gerekir.
İlkel olmayan tip ise Object tipidir(Key ve value ikilisidir ve key string/symbol olabilirken, value herhangi bir tip veya object bile olabilir)
ES2015 ile Object Literal tanımlanırken __proto__ bilgisi de verilebiliyor.
obj={adi:’Cem’, __proto__=new Kisi(), meslegi=’Uzay Müh.’ }
undefined ve null tipleri Javascript
için nasılsa aynı şekilde Typescript
için de geçerlidir.
4.
Symb
ol 1
ES6, JavaScriptiçin yeni bir
ilkel tür sunar: Semboller.
Genel Symbol() işlevi
tarafından bir JavaScript
sembolü oluşturulur.
Symbol() işlevi her
çağrıldığında, yeni bir
benzersiz sembol
döndürülür. Bu yüzden her
sembol bir diğerine eşit
değildir. Ayrıca Sembol
oluştururken gerek
olmasada açıklama bilgisi
verilebilir.
Symbol(‘etiket kıvamında açıklama’)
sembol oluştururken açıklama ekleyebiliriz
ancak bu bilginin etiketleme dışında bir anlamı
olmayacaktır. Her sembol eşsiz olacağı için aynı
açıklamaya sahip semboller aynı olmayacaktır.
Eşsiz olmaları sebebiyle enum türü tanımı için
enum üyelerinin değerlerinde kullanılabilirler.
Sembol türünden bir değişken new ile yaratılmaz ve toString metodu
bilinçsiz çağrılamaz! alert Fonksiyonu otomatik olara toString metodunu
çağırırken sembolde bu çalışmaz
Symbol() ile oluşturduğumuz değişkenler yerel,
Symbol.for(‘etiket’’) koduyla oluşturduklarımız
globalde kayıtlıdır. Globaldeki sembollere açıklama
bilgisiyle tüm kodumuzda erişilebilir erişebiliriz.
Enum türü Javascript içinde yok
ancak eşsiz anahtar ve değer
tanımıyla bir obje yaratarak mümkün
olabilir. Eşsiz değer kısmını Symbol
ile tanımlayabiliriz.
isim çakışmasının önüne geçmek
için önek kullanmanız yerinde
olacaktır:
5.
Symb
ol 2
Symbol ilkelbir değer tipidir. Bir nesnenin property değeri
olarak Symbol türünde bir değişken kullanabileceğimiz gibi
bu property nin anahtarı da Symbol türünde olabilir. Ancak
Symbol türündeki propertylere for in ile erişemeyiz.
6.
enu
m
Javascript içinde enumtanımı
yoktur. Ancak enum yapısı
gereği üyelerinin ve
değerlerinin eşsiz olması
gerekir. Enum tip switch
yapısında işlemlerimizi
kolaylaştırırken birbirine yakın
değerleri hatırlamak yerine
isimlendirerek ayrıştırmamızı
sağlar. Javascript dilinde bu
özellik olmamasına rağmen
object literal tanımlanarak
property olarak enum üyelerini
ve bu üyelere değer atayarak
enum gibi davranan nesnelere
sahip olabiliriz.
Aşağıdaki kodu anlamak için önce buna bakalım: Symbol kullanarak enum üyelerinin değerlerini eşsiz
olarak tanımlayabiliriz. Soldaki örnekte KADIN: 0 ve
ERKEK: 1 değerini elle veriyoruz. Bu iki üyenin
değerinin eşsizliğini Symbol ile ürettiğimiz değerleri
bu üyelere atayabiliriz.
Typescript kodlarken enum tipini oluşturabiliriz.
Ancak enum üyeleri için Symbol kullanamayız.
7.
Enum -
Typescript -1
Typescript enum değerlerini heterojen tanımlayabilir. Kimi üyelerin
değerleri number iken, kimisi string alabilir. Ancak Symbol türünde bir
değerin üyelere atanmasına itiraz eder. Bir Object olarak Javascript
dilinde değişken yaratarak enum üyelerini bu değişkenin property leri
olarak set eder. Bunu Javascript’i doğrudan kullanarak yaparsanız
Symbol türünde değerler kullanabilirken Typescript eşsiz değer
anlamına gelen Symbol yerine “sabit” anlamına gelecek değerleri
enum üyelerinde kullandırır.
8.
Enum -
Typescript -2
Bir enum tipi const
olarak tanımlanmadığı
zaman Javascript
kodunda bir nesne
yaratılır ve IIF içinden
geçirilerek tüm üyeleri
tanımlanır.
Ancak const olarak
tanımlanan bir enum
türü derleme sırasında
enum üyelerinin
değerleri kullanılarak
tüketilir.
const olmayan bir
enum içinde
hesaplanabilir değerler
olabilecekken const
enum türünde
hesaplama
fonksiyonları
kullanılamaz!
9.
Enum -
Typescript -3
C# kodlarken kullandığımız Enum.Parse metodu gibi burada
ÜYENİN ADINDAN (değerinden değil!) değerine erişebiliriz.
Nihayetinde bir nesnenin anahtarları olan enum üyelerinin
adları, karşılığında enum değerlerini veriyor!
10.
Array
Javascript içinde tanımlıhaliyle Typescript içinde geçerlidir. Ancak Typescript
generic tip tanımı gereği bir diziyi var dizi : integer[]; diye
tanımlayabildiği gibi let dizi : Array<integer>; olarak da
tanımlayabilir.
Dizilere benzer olarak Tuple kavramı ES6 da yok ama Typescript içinde
mevcuttur. Bu kavrama benzer olarak ES6 ile Map ve Set tipleri mevcuttur
11.
Longhand - Shorthand
TernaryOperator Short-circuit
Değişken Tanımlama
falsy, truthy
for loop
for(var a of arr) > ES6
obje olusturma
- default param degeri,
- fat arrow func =>
10 katli degerler
Function Declarations vs.
FunctionExpressions
function foo(){
function bar() {
return 3;
}
return bar();
function bar() {
return 8;
}
}
alert(foo()); //8
function foo(){
var bar = function() {
return 3;
};
return bar();
var bar = function() {
return 8;
};
}
alert(foo()); //3
alert(foo()); //3
function foo(){
var bar = function() {
return 3;
};
return bar();
var bar = function() {
return 8;
};
}
function foo(){
return bar();
var bar = function() {
return 3;
};
var bar = function() {
return 8;
};
}
alert(foo());
//bar fonksiyon degil
hatasi
14.
Function Expression
//anonymous functionexpression
var a = function() {
return 3;
}
//Named Function Expressions (NFEs)
var a = function bar() {
return 3;
}
//self invoking function expression
(function sayHello() {
alert("hello!");
})();
//(Fat) Arrow Function
var a =()=>3
Bir fonksiyon constructor veya class olmadığı sürece her
daim bir nesne dönebilir. Bu fonksiyonlara factory
function denir.
Bir fonksiyon new olmaksızın çalıştırılamaz hale getirilebilir.
15.
Arrow Function
Fonksiyonda tekbir is yapilacak ve sonuc dönülecekse
(param1, param2, …, paramN) => ( expression )
Iceride yapilacak isler varsa ve/veya nihayetinde bir deger dönülecekse:
(param1, param2, …, paramN) => {
return expression;
}
// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }
singleParam => expression
// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }
- arrow functionlar, this e sahip değiller. Bulundukları scope’a işaret ederler.
jQuery de DOM, Nodejs te module.exports.
- call ve apply ile this bilgisi geçirilemez ancak bulundukları fonksiyon ya da
window onlar için this olur.
First Class
Function
Bir programlamadilinin, söz konusu dilde
fonksiyonlar başka bir değişken gibi ele
alındığında birinci sınıf fonksiyonlara sahip
olduğu söylenir.
Örneğin, böyle bir dilde, bir fonksiyon diğer
fonksiyonlara bir argüman olarak
iletilebilir, başka bir fonksiyon tarafından
döndürülebilir ve bir değişkene bir değer
olarak atanabilir.
- Bir değişkene atanabilen fonksiyon
- Bir fonksiyona parametre olarak
geçirilen fonksiyon(callback function
denir)
- Bir fonksiyondan dönen değer
fonksiyon(High order function denir)
18.
High Order Function
Klasikfonksiyonlar parametre olarak
değer alıp dönecekse değer döner.
“Functions that operate on other functions, either by
taking them as arguments or by returning them, are
called higher-order functions.”
High Order Function ise ya parametre olarak fonksiyon
kabul eden veya fonksiyon dönen fonksiyonlardır.
Fonksiyon kabul eden fonksiyonlara map, filter, find
verilebilir.
Fonksiyon dönen high order function:
19.
ES6 ile HighOrder Function
Fonksiyon dönen fonksiyon:
Parametre olarak fonksiyon kabul edip fonksiyon dönen:
20.
Hoisting
// bar adindafonksiyon kac kere tanimlanirsa
tanimlansin hoisting ile scope icinde bir kere
tanimlanir ve son atamanin degeri degiskene atanmis
olur.
function foo(){
//bar tanimlaniyor
function bar() {
return 3;
}
//tekrar bar tanimlaniyor
function bar() {
return 8;
}
// hangi bar çalıştırılacak?
return bar(); //8
}
alert(foo());
// hoisting
function foo(){
//ne kadar bar adinda degisken tanimlanirsa
tanimlansin hoisting bir kez en ustte yapilir ve son
atama gecerli olacaktir.
var bar = undefined;
var bar = undefined;
bar = function() {
return 3;
};
return bar();
// return den sonra hic bir satir
calistirilmayacagi icin atama bir ise yaramayacak
}
alert(foo()); //3
21.
ES6 - HoistingTDZ
var hariç let, const, class Temporal Dead Zone denen bir bölgede erişilmek istendiğinde referance error verecektir.
TDZ değişkenin kullanılmak istendiği yer ile bulunduğu scope içinde hoist edildiği boşluk arasındaki yerdir.
function Hede(){
// burada var x; diye tanımlanır
x = 1;
let x=2; // buraya kadar kullanılırsa üst satırdaki gibi hata fırlatır
}
22.
ES6 - ClassHoisting
Hoisting ile bu çalışır:
var ben = new Yazilimci();
function Yazilimci(){ }
Yazilimci fonksiyon tanımı hoist edilerek en
üste alınacağı için ben nesnesi sorunsuz
oluşturulur.
class yapılarda hoisting yapılmaz!
var ben = new Yazilimci();
class Yazilimci{ }
23.
Neden Değişken Tanımlamalı?
functionA(){
function B(){
test = 1;
}
B();
}
A();
window.test; //1
// var test; declaration (test değişkeni deklare edilir ve bellekte yer ayrılır)
// test = 1; definition (test değişkenine değer verildiği zamandır)
// var test = 1; declare & define (hem deklare hem de tanımlanmasını bir kerede yapmak)
// diye tanımlanmadığı için global scope içinde
// yani window içinde window.test olarak hoist edilir.
24.
‘use strict’;
Değişken declareedilmeden değer atanırsa
hoist edilerek global scope içinde otomatik
olarak tanımlanır.
‘use strict’ kullanıldığı
yerden sonra, değişken
tanımlaması(declaration)
yapılmadan atama yapılamaz.
25.
Döngüler - Geçmişten
Günümüzeforxxx
ES3 ile while, do-while, for, for-in döngüleri geldi.
Diziler için for dongusu kullanılırken, indeksin herhangi bir degeri için dongu break ile kırılabilir.
Key-value ikilisine sahip enumerable olan
nesneler için for-in dongusu kullanılırken
diziler için kullanılamaz
ES5 ile birlikte every, filter, forEach, map, reduce, some metotları diziler için geldi.
[1,2,3].[every|filter|forEach|map|reduce|some](function(){....})
forEach dönülen dizi içinde break ile kirilamiyor sadece içinde return ile sadece işlediği indeks için callback fonksiyondan
çıkılabiliyordu.Buda continue gibi çalışmasını sağlıyordu. [ O(N) ]
ES6 ile gelen for-of dizilerde indeks tanımlamadan dönmemizi sağladı. string tipin bir karakter dizisi olduğunu hatırlatarak string tipli
degerlerin icinde karakter karakter donmemizi de saglamaktadir. Array ve String degerlerin haricinde ES6 ile gelen cesitli degerler (Map,
WeakMap, Set, WeakSet) gibi, fonksiyona gelen parametlere erismemizi saglayan arguments icinde de for-of dongusuyle donebiliyoruz.
Bir for döngüsüyledizi içinde dönerek
yapabileceğimiz işi reduce fonksiyonuyla daha
derli toplu yapabiliriz.
Başlangıç değeri reduce fonksiyonuna ilk
döngüde atanır!
Eğer başlangıç değeri verilmezse dizinin ilk
elemanı accumulator, ikinci elemanı
currentValue olarak atanır.
Döngüler -
[].reduce(fn, 0)
28.
Scope
Bağlama kapsamı (scopeof binding), değişkenin görünürlüğü demektir.
Lexically Scope vs Dynamic Scope
JavaScript diger bircok dil gibi lexically scope calisir.
29.
ES6- Interpolation
interpolation: aradeğer hesabı
interpolation: metne eklenmiş sözcük veya cümle
Önemli nokta `....` karakterleri arasına interpolasyon
yapacağımız metni almamız.
30.
ES6- let
var x;// hoisting scope içinde declare ya da define edilmiş değişkenleri en üstte deklare etmektir
// yazılmış onlarca satir kod oldu bu arada ;)
x = 1; // define ettik ve x değişkenine numerik değer atadık
// yine yüzlerce satir kod yazdık
var x = 100; //ikinci kez tanımlamışız gibi görünse de javascript tüm tanımlamaları hoist ederek en üste taşır
y = undefined; // y değişkenini var ile tanımlamadığımızı düşünsekte hoisting kuralı gereği y değişkeni en üste taşınır değeri
atanmayan her değişken gibi undefined ile değerlenir burada yeniden undefined diye tanımlanmış oluyor ama değişen bir şey
yok tabi
// bir döngüden gecelim binlerce satir koddan sonra
for( var x=0; x<4; x++) {
console.log(x);
}
// ve sona geldik. for içinde kullanılsın diye x değişkeni tanımladık 9 oluncaya kadar arttırdıktan sonra for bloğundan
çıktığımız için x acaba 1 mi 9 mu diye kontrol edelim
console.log(x); // 4
// çünkü en üstte ister bilinçli deklare edilsin ister hoisting ile yukarı çekilsin ister 10 farklı yerde tekrar tekrar deklare edilsin
Javascript değişkeni bulunduğu scope içinde bir kez hoist ederek en üste çekerek deklare eder sonrasında değişkenin
sadece değeri değişir çünkü javascript blok temelli değişkenler tanımlanan bir dil değildir
// Ta ki ES5 de let ile değişken deklarasyonuna kadar
let z = 8;
for(let z=0; z<6; z++) {
console.log(z);
}
console.log('z: '+z);
31.
ES6- Const
const sadeceatama işleminde 2. kez
atama yapılmasını önler. const ile
tanımlanmış değişken mutable olur ancak
reassignment yapılamaz.
ES6 - BangBang(!!) Operatörü
ternary ifade !! operatörünün sonucunda true ise
redisSonucu değilse null yada {x:1,y:2} gibi
default bir nesnesnin bilgilerini … (spread)
operatörüyle data içine açıyoruz.
Es6 -
Destructi
ng
Bir değişkeniçindeki propertyleri aynı isimli değişkenlere
atayabilmek. Destructing aynı zamanda bir dizinin elemanlarını
değişkenlere atamak için de kullanılabilir. Typescript içinde
destructing kullanılır.
Değişken sıralamasının property sırasıyla aynı olması şart değil,
isimlerinin aynı olması ya da hangi property adına atama
yapıldığının belirtilmesi şartı vardır.
ES6- class -publıc, prıvate
class içinde private bir değişken tanımlanamaz! (2017 için teklif). Google closure derki: Private
değişken olarak hayal edebilmek için değişkenin sonuna _ ekleyin. this.adi_ gibi.
public, private access modifiers(erişim belirleyicileri) kullanılamaz!
class içindeki her metot public gibi nesneye yani sınıfın prototype’ine bağlıdır.
41.
ES6-class
- class içindekitüm metotlar prototype’a bağlanır ve her nesnenin __proto__ bilgisine kopyalanır.
- this. ile tanımlı Prop for döngüsünde görünürken doWork metodu görüntülenemiyor!
- Oysa function ile tanımlı F’den yaratılan nesnenin for döngüsünde hem this. hem prototype
içindeki bilgileri görüntülenebiliyor.
- class içindeki metotlar nesne yaratıldığında ekstra adımlarla nesneye bağlandığı için for loop içinde
metotları göremiyoruz.
- Önce nesnenin prototype bilgisini Object.getPrototypeOf ile alıp içindeki key değerleri için for-
of döngüsünü kullanabiliriz.
42.
ES6 - class- new olmadan
çalıştırmak - class klasik bir fonksiyon gibi new
olmadan çalıştırılamaz!
- Ancak new ile constructor metodu
çalıştırıldığı için başka dillerden farklı
olarak return ile farklı bir nesne
döndürülebilir.
43.
Typescript -
Class -1
Typescript içinde sınıflar ön tanımlı olarak public yaratılırlar.
Yapıcı metot parametreleri otomatik olarak field veya property
olabilirler.
Yapıcı metot parametrelerinde sınıfın property leri oluşturulabilir.
Oluşan
Javascript
Kodu:
44.
Typescript -
Class -2
Miras alan sınıf, ata sınıfını yapıcı metodun
içinde super anahtarıyla çağırarak üst sınıfın
yapıcı metodunu çalıştırır.
super Anahtar kelimesi C#’ta kullanılan base
anahtar kelimesiyle aynı işi yapar.
super Çağrısını ezilen metotlarda da
çağırabiliriz.
45.
Typescript -
Class -2
Kisi sınıfında tanımlı “tanıt” metodu aynı
zamanda miras alan Muhendis sınıfında da
tanımlıdır.
Üst sınıfta bulunana metodu çağırabilmek
için super.metotAdı kullanılır.
46.
Typescript -
interface
Javascript’e dönüşümüyapılmaz interface
tanımlarının. Sadece derleme zamanında tip
kontrollerini yapmak ve implement eden
sınıfların kontratı sağlayıp sağlamadıklarını
denetlemek için kullanılır.
ES6- class -constructor
1. Türetilen sınıf içinde
constructor muhakkak
super ile üst sınıfın yapıcı
fonksiyonunu çağırmalı.
2. super çağrısı yapılmadan
constructor içinde işlem
yapılmamalı.
49.
ES6 - class- prototype İlişkisi
Neden Prototype?
- Verimlilik ve bellek
kaynağının cimri
kullanımı için.
Hepimizin telefonu
var ama hepimizin
kendine has telefon
şebekesi yok!
Telefonlarımız
nesnelere
ait(this.Adi)
üyeleri, şebeke ise
sınıfın prototype’ine
ait özellikleri
(Kisi.prototype.
Konus=function()
{..) temsil edince
kavrayışımız artmış
olur ;)
ES6- static getter,setter
Aşikar ki, tıpkı fonksiyona Object.defineProperty ile yaptığımızı arka tarafta
javascript engine kendi yapıyor.
get,set metotları static olarak tanımlandığı için sınıfa bağlıdır. Doğal olarak
Sinif.prototype.constructor içinde tanımlanıyorlar.
İlk get metodu çağrısıyla Sinif.backFieldDegisken tanımsız olduğu için
undefined dönerken, ilk set metodu çağrısından sonra backFieldDegisken,
Sinif class’ında deklare edilerek hayata başlıyor.
Son olarak get ve set metotlarından tanımlamak istemediğiniz metodu silerek
erişilemez hale getirebilirsiniz. Yani set metodunu kaldırarak sanki writable:
false sonucu elde edebilirsiniz.
56.
Klasik
Yöntemle- get,
set
Bir tipiçin getter ve setter olan property tanımı için
Object.defineProperty(FonksiyonAdı kullanılırken, bu
fonksiyondan türeyen örneklere geçirilmek için property tanımı
Object.defineProperty(FonksiyonAdı.prototype
kullanılır.
57.
ES6- class -get, set
Klasik yöntem ile function ile deklare edilen tiplerde get,set
metotlarının nasıl oluşturulduğunu önceki sayfada görmüş
olmalısınız.
class yahut function, her ikisinde de get,set metotları
__proto__ içinde oluşuyor. Bunu bize sağlayan javascript
motoruna teşekkür ediyoruz.
İşte klasik function içinde oluşturulan get,set metotlarının
nesnede nerede yer aldığını inceleyeceğiniz ekran görüntüsü.
Hemen solunda ise class içinde yaratılan get,set
metotlarının __proto__ içinde bulunduğunu gösteren ekran
çıktısıyla kıyaslayınız ve akıl edenlerden olunuz:
58.
ES6- class -get (read-only
property) Söylenecek pek bir şey yok ancak;
__proto__ içinde olan Sinif tipinin prototype
özelliğinin referansı olacak.
Bu önemli bilgidir dikkat ediniz!
async - await
Buhikayeyi callback, promise ve async-await şeklinde anlatmak lazım. Bunu
da aşağıdaki adres güzel anlatıyor.
Özellikler Promise içinde hem callback fn çağırarak çifte metot ile
çalışabileceğini görebiliyor olmak güzeldi!
Uygulamamızda Web StorageAPI (for sessions) kullanmak istiyoruz. IE8 de sessionStorage
kavramı mevcut, ancak IE7 de yok! Bu durumda bir adaptöre ihtiyacımız var. Her halükarda sanki
sessionStorage üstüne kaydediyor gibi yapabilen ve uyumluluğumuzu arttıran. Bunu yapacak
kod parçacığına POLYFIL diyoruz. Örneğimizdeki uyumluluğumuzu sağlayan bu kod parçacığı IE8
veya 7 farkı gözetmeksizin kodlamamızı kolaylaştırıyor.
Modernizr işte internet gezginlerinin arasındaki eksiklikleri, kendi yapılarına uygun şekilde
tamamlayan bir kütüphanedir.
Önce Polyfil Nedir?
Polymer Nedir?
- React,Angular, Knockout, Ember vd. gibi bir
kütüphane veya çatı değildir(kütüphane
ancak diğerleri gibi değil ;)
- Açık kaynak kodlu, kolaylıkla web bileşenleri
hazırlamak için kullanılan bir kütüphanedir.
- Bir web bileşeni hazırlarken kendimizi daha
çok bileşene odaklamamızı sağlayan bir
soyutlamadır.
- Oluşturduğumuz bileşenimizin bir çok
internet gezgininde çalışabilmesi için polyfill
içerir.
- Bileşenimizin içinde kullanılabilmesi için data
binding sağlar.
Web Uygulaması
Polymer Kütüphanesi
HTML
Templates
HTML
Imports
Custom
Elements
Shadow
DOM
70.
Polymer vs Angular
Polymer:
-Shadow DOM yaratarak kapsüllenmiş JS kodunu, CSS, ve
HTML kullanarak özelleştirilmiş elemanlar (Custom
Elements) yaratmak için kullanır. Angular gibi
- Angular’a benzer şekilde Polymer elemanları da html
şablonu, çift yönde veri bağlama sağlar. Shadow DOM
sayesinde CSS elemanları bileşen haricindeki elemanları
etkilemez.
- LiteElement polymer ile gelen bileşen hazırlama
kütüphanesidir. Her kütüphane ve çatıyla birlikte
kullanılabilir bileşenleri LiteElement ile yapabiliriz(
örnek).
- WebComponent Standartlarını takip ederek bileşen
üretir.
- Kolaylıkla sayfalarda kullanılır ve shadow dom özelliğiyle
bileşeni yalıtır.
- Sadece değişen verileri render ettiği için çok hızlıdır.
Angular
- Angular direktifleri kavramsal olarak Custom Elements
yapısına benzer ancak Web Components API sini
kullanmaz. Angular direktifleri özel bileşen yapmanın bir
yoludur ancak Polymer özel bileşen yaratmanın
standardını kullanırken Angular directives bunun
uzağındadır.
- Angular geliştiricilerinin açıkladığı üzere bir gün angular
bileşenleri web component olacak ve bunu yaptıkları
gün ya polymer gibi kütüphanelerden veya günün
şartlarında kullanılan yaygın kütüphane veya native web
component yapılarını kullanacaklar.
- Peki polymer kütüphanesinin kullandığı ve her browser
için uyum sağlasın diye kullanılan polyfill
Web Bileşeninin Parçaları
Birweb bileşeni bu 4 API kümesi browser tarafından
sağlanırsa native olarak web bileşenlerini yaratabiliriz.
Ancak tüm browserlar bu API’lere tam destek vermediği
için React Angular Vue gibi yapıları kullanarak web
bileşenlerini oluşturuyoruz.
HTML şablonları, tablo satırları veya liste öğeleri gibi şeyler için şablon tanımlamamızı sağlar.
Özel öğeler(Custom Elements), işlevsellik içeren en iyi html etiketlerini tanımlamamızı sağlar. Yeniden kullanılabilir bir bileşen oluşturmanın
temel bir parçasıdır.
Shadow DOM, bileşenin işaretleme yapısını, stilini ve davranışını sayfadaki diğer kodlardan korumamızı sağlar, böylece farklı parçalar çakışmaz.
Yeniden kullanılabilir bir bileşen oluşturmanın başka bir önemli parçasıdır.
HTML Import, web bileşenleri için paketleme mekanizması olması amaçlıdır.
Modül Temelleri
Bir fonksiyoniçeriğindeki değişken tanımlarından emindir. Yani sadece kendi kullanımında olduğunu ve sadece
kendi içinden değiştirilebileceğinden emindir. Ta ki bu fonksiyon içinde başka bir fonksiyon barındırıncaya kadar.
İçteki fonksiyon elbette kapsamı gereği kendisini barındıran fonksiyonun(veya globalin) değişkenlerine erişebilir ve
değiştirebilir. Modül kavramı bu etki alanını import ve export anahtarları ile kontrollü hale getirmeyi sağlar. Modül
kavramı sayesinde tekrar kullanılabilir yapılara kavuşuruz. CommonJS modül yapısını NodeJS kullanıyorken
browserlar EcmaScript modül sistemini kullanmaktadır.
Bir ES6 modülü JS kodları içeren bir dosyadır. module Adında reserve bir kelime yok :)
ES6 modülleri otomatik olarak strict mode çalışırlar. “use strict” yazmanıza gerek yoktur. Ve bu modülleri export ve
import rezerve kelimeleriyle modüllerin içinde kullanabilirsiniz.
export - ModülOluşturmanın
Dayanılmaz Hafifliği
Her js dosyasına yazdığınız kod aslında bir modüldür. Ancak bu kodları public
hale getirmek için export kelimesini kullanmalısınız aksi halde kodladığınız her
şey private olarak kalacak, sadece bulundukları dosya içinden erişilebilecektir.
En üst seviyedeki(dosya içinde globalde tanımlı) her şeyi(class, function, var, let
veya const) export edebiliriz.
Sadece export ile modül yazmış olursunuz. Her şeyi bir IIFE(Immediately-invoked
function expression) içine yazmanıza gerek kalmamış oldu. export ile tüm kodu
script olmaktan çıkartıp modül haline getirmiş oluyor, tüm tanımlamaları modül
kapsamına almış görünürlüklerini(public, private) değiştirmiş oldunuz.
export‘u görmezseniz son derece normal kodunuz aynı şekilde
duruyor.
IMPORT - Modüllerin
ReUsabilityOlması
● Artık başka bir js dosyasına modülünüzü dahil edip içindeki public şeyleri(class,function,var,let,const)
kullanmak için yapmanız gereken import rezerve kelimesini kullanmak olacak.
● import deklarasyonu kullanılan yerde önce import edilen modüller, bağımlılıklarına göre ihtiyaç duydukları modüllerle
yüklenir, çalıştırılır.
● import ederken modülü farklı bir isim kullanabilirsiniz
import {each as herbir, map} from "lodash";
herbir([3, 2, 1], x => console.log(x));
● aynı şekilde export ederken de farklı isimler kullanabilirsiniz
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
#26 var dizi =['a','b','c']
// for-in obje icinde key/value
// icinde gezmek icin idealken
// dizi icindeki elemanlarin
// indeks bilgisini donecektir
for (let eleman in dizi)
console.log(eleman);
// for-in geriye uyumluluk icin
// ayni sekilde birakilirken dizi
// icinde for look ile donebilmek
// icin for-of ES6 ile geldi
for (let eleman of dizi)
console.log(eleman);
#28 Bu guzel bir anlatim:
https://stackoverflow.com/a/16221247/104085
#29 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings
Türkçe'de bazen kolaylık olsun diye "interpolasyon" sözcüğü yerine yalnızca "tahmin" de kullanılmaktadır.İnterpolasyon genelde mühendislik ve deneylere/ölçümlere dayalı benzeri bilim dallarında, toplanan verilerin bir fonksiyon eğrisine uydurulması amacıyla kullanılmaktadır.
(function () {
function Kisi(_adi, _soyadi) {
this.Adi = _adi;
this.Soyadi = _soyadi;
this.tanistirKendiniYavrum = function() {
console.log(`Merhaba ben ${this.Adi} ${this.Soyadi}`);
}
}
var ben = new Kisi("Cem", "Topkaya");
ben.tanistirKendiniYavrum();
})();
#31 const ogrenciSayisi = 12;
// son anda bir ogrenci daha sinifa girmek ister ama ne mumkun
// const deklare edildigi zaman deger atamasi yapilmis ve bir daha
// deger atamak mumkun olamayacaktir
ogrenciSayisi = 13;
const ogrenciSayisi = 12;
// bir defa daha tanimlamak istedigimizde ayni scope icinde iki kez
// tanimlanamayacagi icin hata verecektir
// tipki let gibi kullanilan ve blok temelli degisken tanimlamasinda kullanilabildigi icin
// if gibi bir blok icinde tanimlanabilir ve blok bittiginde gecerliligini yitirecektir
if(true) {
const ogrenciSayisi=3;
console.log('blok icinde ogrenciSayisi: ' + ogrenciSayisi);
}
console.log('if disindaki kod blogu(ki burada global scope oluyor) icinde ogrenciSayisi: '+ogrenciSayisi);
#32 function topla(x, y) {
return x + y;
}
console.log(topla(0));
-------------------------------------
function topla(x, y) {
x = x || 0;
y = y || 0;
return x + y;
}
console.log(topla(0));
-------------------------------------
function topla(x, y) {
return (x || 0) + (y || 0);
}
console.log(topla(0));
-------------------------------------
function kuvvetiniAl(x, y=x) {
var sonuc = 1;
for(var i=1;i<=y; i++) sonuc *= x;
return sonuc;
}
console.log(kuvvetiniAl(2));
console.log(kuvvetiniAl(3,4));
#33 function eskiTipFonksiyon(a,b,c,d) {
console.log("a: "+a);
console.log("b: "+b);
console.log("c: "+c);
console.log("d: "+d);
}
eskiTipFonksiyon(1,10,100,200,300);
--------------------------------------------------------------------------
function eskiTipFonksiyon(a,b,c,d) {
console.log(arguments);
console.log("arguments dizi mi? "+ Array.isArray(arguments));
console.log("\nDiziye dönüştürelim : ");
var args = Array.prototype.slice.call(arguments);
console.log("\nargs dizi mi? "+ Array.isArray(args));
console.log("\nDizi elemanlarının içinde gezelim");
args.forEach((e)=>console.log(e));
}
eskiTipFonksiyon(1,10,100,200,300);
--------------------------------------------------------------------------
function yeniTipFn(a,b,...args) {
console.log(arguments);
console.log("\n a: "+a);
console.log("\n b: "+b);
console.log("\n kalanı: "+ args);
args.forEach((e)=>console.log(e));
}
yeniTipFn(1,10,100,200,300)
#34 let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(z); // {a: 3, b: 4}
console.log(y); // 2
console.log(x); // 1
--------------------------------------------
var elm1 = {a:1};
var elm2 = {b:2};
var dizi = new Array(elm1, elm2);
dizi;
console.log("/************************************************")
console.log("* SPREAD ile dizi elemanlarına ayırılır *********");
console.log("* ve yeni eleman eklenerek tekrar dizi olabilir *");
console.log("*************************************************/");
var elm3 = {c:3};
dizi = [...dizi, elm3];
dizi;
#36 function eskiden_moduleRevealingPattern(){
var fn1 = function(){ console.log("1. fn"); };
var fn2 = function(){ console.log("2. fn"); };
return {
fn1: fn1,
fn2: fn2
};
}
var sonucNesne = eskiden_moduleRevealingPattern();
console.dir(sonucNesne);
console.log("\n****** Bir metodunu çağıralım *****");
sonucNesne.fn1();
-----------------------------------------------------------
function moduleRevealingPattern(){
var fn1 = function(){ console.log("1. fn"); };
var fn2 = function(){ console.log("2. fn"); };
return {fn1, fn2};
}
var sonucNesne = moduleRevealingPattern();
console.dir(sonucNesne);
console.log("\n****** Bir metodunu çağıralım *****");
sonucNesne.fn1();
-----------------------------------------------------------
function hatta_moduleRevealingPattern(){
var fn2 = function(){ console.log("2. fn"); };
return {
fn1() { console.log("vuhuuuuu"); },
fn2: fn2
};
}
var sonucNesne = hatta_moduleRevealingPattern();
console.dir(sonucNesne);
console.log("\n****** Bir metodunu çağıralım *****");
sonucNesne.fn1();
#43 ------ 1 --------------
enum Cinsiyet{ KADIN, ERKEK }
class Kisi{
public adi: string; // bilinçli işaretlenmiş oldu
soyadi: string; // ön tanımlı PUBLIC
private cinsi: Cinsiyet; // artık örnek üstünde erişilemez!
constructor(ad:string, sad:string, cins:Cinsiyet) {
this.adi = ad;
this.soyadi = sad;
this.cinsi = cins;
}
}
let k = new Kisi("Cem", "Topkaya", Cinsiyet.ERKEK);
k.
-------- 2---------------------
enum Cinsiyet{ KADIN, ERKEK }
class Kisi{
public email: string;
constructor(public ad: string,
public sad: string,
private cins?: Cinsiyet = Cinsiyet.ERKEK,
eposta?: string) {
this.email = eposta||'default param kullanılabilirdi';
}
}
let k = new Kisi("Cem", "Topkaya");
k.
#44 enum Cinsiyet{ KADIN, ERKEK }
class Kisi{
public email: string;
constructor(public ad: string,
public sad: string,
private cins?: Cinsiyet = Cinsiyet.ERKEK,
eposta?: string) {
this.email = eposta||'default param kullanılabilirdi';
}
}
class Muhendis extends Kisi{
constructor(
adi: string,
soyad: string,
email: string = 'yok@nokta.net',
cinsiyet: Cinsiyet,
public diplomaNo?: string
) {
super(adi, soyad, cinsiyet, email);
}
}
let k = new Muhendis("Cem", "Topkaya",undefined,Cinsiyet.ERKEK);
k.
#45 enum Cinsiyet{ KADIN, ERKEK }
class Kisi{
public email: string;
constructor(public ad: string) {
}
tanit(): void{
console.log(`Ben ${this.ad} isimli kişiyim.`);
}
}
class Muhendis extends Kisi{
constructor(adi: string,
public diplomaNo?: string
) {
super(adi);
}
tanit(): void{
super.tanit();
console.log(`Ayrıca ${this.diplomaNo} Nolu mühendisim.`);
}
}
let k = new Muhendis("Cem","DNo123");
k.tanit();
#46 interface IKisi {
ad: string;
email: string;
tanit(): void;
}
class Kisi implements IKisi{
public email: string;
constructor(public ad: string,
eposta?: string) {
this.email = eposta||'default param kullanılabilirdi';
}
tanit() { console.log('Merhaba ben ', this.ad); }
}
class Muhendis implements IKisi{
constructor(
public ad: string,
soyad: string,
public email: string = 'yok@nokta.net',
public diplomaNo?: string
) { }
tanit() { console.log(`Ben ${this.ad} adlı mühendisim.`); }
}
let k = new Kisi("Cenk", "cenk@topkaya.com");
let m = new Muhendis("Cem", "Topkaya",undefined,"DipNo123");
let kisiler: IKisi[] = [k, m];
for (var elm of kisiler)
console.log(elm.tanit());
#48
----------------------------------------------
function Kisi() {
… //buraya yazdığımız kodlar new ile nesne yarattığımızda çalıştırılır
}
function Kisi() {
// derli toplu olsun diye init fonksiyonu yaratır onu çalıştırıyoruz
function init() {
/*başlangıçta çalışmasını istediğimiz kodları yazıyoruz */
}
init(); // en sonunda foksiyonu çalıştırıyoruz
}
----------------------------------------------
class Kisi {
constructor(_hede, _hodo) {
this.Hede=_hede;
this.Hodo=_hodo;
this.dosyalarYerindemi();
this.dbCalisiyormu();
}
dosyalarYerindemi(){ console.log("kontrol eder uyarır falan..."); }
dbCalisiyormu(){ console.log("kontrol eder uyarır falan..."); }
}
var k = new Kisi();
#49 (function(){
/** AMACIMIZ sınıf içindeki fonksiyonların nerede yer alacağı ve performansı
* class içindeki fonksiyonlar her nesne için tekrar tanımlanmaz
* Kisi sınıfından yaratılan nesneler Kisi sınıfının prototype'ına yazılmış
* fonksiyonları çağırır.
*
* Memory performansı eskisi gibi
* Kisi.prototype.tanitKendini = function(){....}
* klasik şekliyle çalışır.
*/
class Kisi {
constructor(_adi,_soyadi){
this.Adi = _adi;
this.Soyadi = _soyadi;
this.Memleket = "Kars";
}
tanitKendini() {
console.log(`Merhaba ben, ${this.Adi} ${this.Soyadi}`);
}
toString(){
return `
Adı: ${this.Adi}
Soyadı:${this.Soyadi}
Memleketi:${this.Memleket}
`;
}
}
var ben = new Kisi("Cem","Topkaya");
ben.tanitKendini();
var abim = new Kisi("Cenk","Topkaya");
abim.tanitKendini();
console.dir(Kisi);
console.dir(ben);
})();
#50 https://developer.mozilla.org/tr/docs/Web/JavaScript/Reference/Operators/super
(function(){
/** AMACIMIZ kalıtım ile sınıflarımızı genişletmek ve super kavramı
* super(..) ile bir üst sınıfın constructor metoduna parametre geçiyoruz
*
* Kalıtım ile genişletilen sınıfların yapıcı metotlarında super kullanılmak zorundadır.
* Miras alan sınıfın yapıcı fonksiyonunda önce super(..) çağırılır sonra diğer satırlar.
*/
class Kisi {
constructor(_adi,_soyadi){
this.Adi = _adi;
this.Soyadi = _soyadi;
}
toString(){
return `Adı: ${this.Adi}\nSoyadı: ${this.Soyadi}\n`;
}
}
class Calisan extends Kisi {
constructor(_adi,_soyadi,_meslegi){
super(_adi,_soyadi);
this.Meslegi = _meslegi;
}
toString(){
// Klasik yoldan, üst tipin prototype'indeki fonksiyona this parametre olarak verilir
var hede = Kisi.prototype.toString.call(this)+`Mesleği : ${this.Meslegi}`;
// ES6 ile üst tipin fonksiyonuna super ile erişilebilir
return super.toString()+`Mesleği : ${this.Meslegi}`;
}
}
var ben = new Kisi("Cem","Topkaya");
console.log(ben.toString());
var abim = new Calisan("Cenk","Topkaya","Patron");
console.log(abim.toString());
})();
#51 // Function içinde static bir değişken tanımlamak:
function Sinif(){ }
Sinif.degisken = 33;
------------------------------------------
function Sinif1(){}
// biraz daha detaylı tanımlamak istersek:
Object.defineProperty(Sinif1, 'degisken', {
// value: 33 > başlangıç değeri 33 olsun
value: 33,
// writable : true > daha sonra
// Sinif.degisken = 'yeniDegeri'
// ile atama yapılabilir
writable : true,
// configurable: true > degisken özelliği silinebilir,
// writeable, configurable, enumerable
// özellikleri değiştirilebilir
configurable: true,
// enumerable: true > for döngüsüyle içinde Sinif'in icinde dönüldüğünde
// degisken özelliği görülebilir
enumerable: true
});
console.log(`degisken: ${Sinif1.degisken}`); // 33
Sinif1.degisken = 15;
console.log(`degisken: ${Sinif1.degisken}`); // değeri değiştirilebilir
#53 // AMAÇ: Klasik yöntemle bir tipin içinde statik değişken tanımlamak
// Tipimiz:
function Fonksiyon(){ }
/***** 3. get ve set metotlarıyla tanımlamak istersek: *************/
/** Önce get set metotlarının kullanacağı bir back field oluşturalım:
* Fonksiyon tipinde tanımlı bir backFieldDegisken en başta undefined!
* Bu yüzden Fonksiyon tipine bağlı, enumrable olmayan ve bilgileri değiştirilemeyen
* Fonksiyon.backFieldDegisken property bir defalığına oluşturulacak
* Sonrasında atanacak ve çekilecek değer bu back field üstünden paylaşılacak
*/
Object.defineProperty(
Fonksiyon, // hangi tipe ya da objeye bağlı olacaks
'backFieldDegisken', // property nin adı ne olacaksa
{ // property nin temel özellikleri
value:0,
writable:true,
configurable:false,
enumerable:false
}
);
/**
* Sonra getter ve setter metotları olacak property tanımlayalım Fonksiyon tipine
*/
Object.defineProperty(Fonksiyon, 'degisken', {
// !!! value özelliği, getter ve setter metotları varsa tanımlanamaz
// !!! writable özelliği, getter ve setter metotları varsa tanımlanamaz
// configurable: true > degisken özelliği silinebilir,
// writeable, configurable, enumerable
// özellikleri değiştirilebilir
configurable: true,
// enumerable: true > for döngüsüyle içinde Fonksiyon'un içinde
// dönüldüğünde değişken özelliği görülebilir
enumerable: true ,
get: function(){
return Fonksiyon.backFieldDegisken;
},
set: function(val){
Fonksiyon.backFieldDegisken = val;
}
});
#54 // AMAÇ: Klasik yöntemle bir tipin içinde statik değişken tanımlamak
// Tipimiz:
function Fonksiyon(){ }
/***** 4. Sadece get metodu olsun istersek: *************/
Object.defineProperty(Fonksiyon, 'degisken', {
// !!! value özelliği, getter ve setter metotları varsa tanımlanamaz
// !!! writable özelliği, getter ve setter metotları varsa tanımlanamaz
// delete `Fonksiyon.degisken` işe yaramayacak!
configurable: false,
// for(var prop in Fonksiyon) { console.log(prop); } ile görüntülenemez
enumerable: false,
get: function(){
return 'Daima bu metni dönecek, çünkü set metodu yok!';
}
});
#55 // AMAÇ: ES6 ile bir tipin içinde statik değişken tanımlamak
// Tipimiz:
class Sinif{
static get Degisken(){ return Sinif.backFieldDegisken; }
static set Degisken(val){ Sinif.backFieldDegisken = val; }
}
#56 /* AMAÇ:
* Klasik yöntemle bir nesne içinde
* get, set metotlarıyla property tanımlamak
*/
// Tipimiz:
function Fonksiyon(){
// get,set içinde kullanılacak nesneye bağlı back field olsun
this.backFieldDegisken;
// this.xXXX (küçük harf ile sanki private bir değiken gibi tanımlayalım
// back field ın özelliklerini değiştirmek isteseydik
// bir init metodu içinde ya da obje yaratıldığında
// Fonksiyon tipinin herhangi bir yerinde tanımlayabilirdik
Object.defineProperty(this, 'backFieldDegisken', {
value : 33,
writable : true,
configurable : true,
enumerable : false // enumeration ile ulaşılamasın ;)
});
}
Object.defineProperty(
Fonksiyon.prototype, // Prototype içinde tanımlıyoruz
'Degisken',
{
get : function Degisken(){ return this.backFieldDegisken; },
set : function Degisken(val){ this.backFieldDegisken = val; }
}
);
var nesnemiz = new Fonksiyon;
console.log(nesnemiz.Degisken); // 33 yazacak elbette ;)
nesnemiz.Degisken = 22;
console.log(nesnemiz.Degisken); // 22
var nesne2 = new Fonksiyon;
// 33 yazacak çünkü arkadaki field this'e bağlı olan this.backFieldDegisken
// dönüyor. Her nesne kendi backFieldDegisken alanına sahip
console.log(nesne2.Degisken);
#57 (function(){
/* AMACIMIZ:
* - olmayan ancak varmış gibi yapmak istediğimiz private field notasyonu
* - getter ve setter metotları
*
* public, private gibi erişim belirleyiciler yok!
* this.xxx ile metotlar arasında kullanılabilecek değişkenleri(nesneye bağlı)
* nasıl kullanabiliriz?
*
* get prop() {...}
* set prop(val) {...}
*/
class Kisi {
constructor(_adi,_soyadi){
this.Adi = _adi; // set metodu tanımlandığı için doğrudan değer atamayacak
this.Soyadi = _soyadi; //setter yok, doğrudan değer atar
}
get Adi() {
// this.adi (back field gibi kullandığımız)degiskeninin degerini donecek
// this.kucukHarfleBaslayanDegisken "jargonumuza göre" back field olsun!
// this.bilgilerGirilmis, this.adi, this.soyadi gibi
return this.adi;
}
set Adi(val) {
console.log(`Bakalım Setter metoduna giriyor mu? val: ${val}`);
this.adi = val;
// adi ve soyadi bilgileri girilmişse true ;)
this.bilgilerGirilmis = this.Adi || this.Soyadi;
}
toString(){
if(this.bilgilerGirilmis) {
return `Adı: ${this.Adi}\nSoyadı: ${this.Soyadi}\n`;
}
throw new Error("Bilgileri girilmemiş kişinin toString'i çalışmaz!");
}
}
var ben = new Kisi("Cem","Topkaya");
console.log(ben.toString());
})();
-----------------------------------
#58 // AMAÇ: ES6 ile read-only property
class Sinif{
constructor(){
// başlangıç değerini atıyoruz ve yatıyoruz
this.backFieldDegisken=10;
}
// ömrü billah 10 dönecek
get Degisken(){ return this.backFieldDegisken; }
}
s = new Sinif;
s.Degisken; // 10 dan başka bir şey bilmiyor
s.Degisken;
s.Degisken;
s.Degisken = 20; // atama yaptığımızı zannediyoruz ama!
s.Degisken;