aboutsummaryrefslogtreecommitdiff
path: root/files/tr/web/javascript/a_re-introduction_to_javascript/index.html
blob: d6fabce7c3eb30ac25f5786568cfd1e685b67635 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
---
title: JavaScript ile Tekrar Tanışmak (JS Eğitimi)
slug: Web/JavaScript/A_re-introduction_to_JavaScript
tags:
  - BetikKodlama
  - Giriş
  - JavaScript
  - Orta düzey
  - Rehber
  - öğren
translation_of: Web/JavaScript/A_re-introduction_to_JavaScript
---
<div>{{jsSidebar}}</div>

<p>Neden yeniden tanışma? Çünkü {{Glossary("JavaScript")}}<a href="http://javascript.crockford.com/javascript.html">dünyanın en yanlış anlaşılan programlama dili</a> olma gibi bir üne sahip. Genellikle bir oyuncak olarak atfedilmesine karşın, aldatıcı sadeliğinin altında güçlü dil özellikleri barındırır. Bunlardan biri, inanılmaz sayıda yüksek profilli uygulama tarafından kullanılıyor olmasıdır. Bu da bize Javascript teknolojisine ait derin bir bilginin her web veya mobil geliştirici için önemli bir beceri olduğunu gösterir.</p>

<p>Dilin geçmişini anlatarak başlamak faydalı olacaktır. Javascript 1995 yılında Netscape'de bir mühendis olan Brendan Eich tarafından oluşturulmuştur ve Netscape 2 ile eş zamanlı olarak 1996 yılının başlarında kullanıma açılmıştır. Başta Livescript ismi ile çıkacakken -aralarında hemen hemen hiç benzerlik olmamasına rağmen- Sun Microsystem şirketine ait Java dilinin popülerliğini arttırmak adına talihsiz bir pazarlama seçimi ile Javascript ismi ile devam edilmiştir. Bu olay o zamandan beri karışıklıklığa neden olmaktadır.</p>

<p>Birkaç ay sonra Microsoft dilin çoğu platforma uyumlu bir versiyonu olan Jscript'i IE 3 ile çıkardı. Netscape, dili Avrupa standartlarında bir organizasyon olan Ecma International'a sundu ve bu da 1997'de {{Glossary("ECMAScript")}} standardının ilk versiyonu ile sonuçlandı. Standart 1999'da ECMAScript edition 3 olarak önemli bir güncellemeyi aldı ve o zamandan beri oldukça istikrarlı kaldı. Ancak dördüncü baskı, dil karmaşıklığı ile ilgili politik farklılıklar nedeniyle terk edildi. Dördüncü baskının pek çok bölümü, 2009 yılı Aralık ayında yayınlanan ECMAScript 5. versiyonunun  ve 2015 yılında yayınlanacak olan standartın 6. büyük versiyonunun temelini oluşturdu.</p>

<div class="note">
<p>Daha aşina olduğumuz için bu yazı boyunca ECMAScript yerine Javascript ismi ile devam edeceğiz.</p>
</div>

<p>Çoğu programlama dilinin aksine, JavaScript dilinin hiçbir girdi veya çıktı kavramı yoktur. Bir ana bilgisayar ortamında bir betik dili olarak çalışacak şekilde tasarlanmıştır ve dış dünyayla iletişim kurmak için mekanizmalar sağlamak ana bilgisayar ortamına bağlıdır. En yaygın ana bilgisayar ortamı tarayıcıdır, ancak JavaScript yorumlayıcıları Adobe Acrobat, Photoshop, SVG görüntüleri, Yahoo!'nun Widget altyapısında ve node.js. gibi sunucu ortamlarında da bulunabilir. JavaScript'in kullanıldığı alanların listesi burada bitmez. Ayrıca, açık kaynaklı Apache CouchDB, gömülü bilgisayarlar veya GNOME (GNU / Linux işletim sistemleri için en popüler GUI'ler) gibi tam masaüstü ortamları gibi NoSQL veritabanlarını da içerir.</p>

<h2 id="Genel_Bakış">Genel Bakış</h2>

<p>JavaScript türlere, operatörlere ve standart hazır nesnelere sahip nesneye yönelik, dinamik bir dildir. Sözdizim kuralları Java ve C dillerinden gelmektedir ve bu dillerden birçok yapıyı başarılı şekilde barındırır. Bu diller ile arasındaki önemli bir fark, JavaScript'in sınıflara (class) sahip olmamasıdır. JavaScript, sınıfların yaptığı işleri nesne prototiplerini (object prototype) kullanarak yapar. Bir diğer temel fark ise fonksiyonların birer nesne olmasıdır. Bu şekilde fonksiyonların da yürütülebilir kodu saklama ve diğer her nesne gibi aktarılma kapasitesi vardır.</p>

<p>Her dilin yapıtaşı sayılabilecek olan unsuru öğrenerek başlayalım: türler (types). JavaScript programları değerleri (value) manipüle eder ve bu değerlerin hepsi bir türe aittir. JavaScript'in türleri şunlardır:</p>

<ul>
 <li>{{jsxref("Sayı")}}</li>
 <li>{{jsxref("String")}}</li>
 <li>{{jsxref("Boolean")}}</li>
 <li>{{jsxref("Fonksiyon")}}</li>
 <li>{{jsxref("Nesne")}}</li>
 <li>{{jsxref("Sembol")}} (ES2015'de yeni)</li>
</ul>

<p>... oh, ayrıca {{jsxref("undefined")}} ve {{jsxref("null")}}, ki ... biraz garipler. Ayrıca özel bir nesne kabul edebileceğimiz {{jsxref("Array")}}. Bir de bedava elde edebileceğiniz nesneler olan {{jsxref("Date")}} ve {{jsxref("RegExp")}}.  Teknik olarak fonksiyonlar da özel bir tür nesnedir. Bu nedenle asıl diyagramımız böyle görünmeli:</p>

<ul>
 <li>{{jsxref("Sayı")}}</li>
 <li>{{jsxref("String")}}</li>
 <li>{{jsxref("Boolean")}}</li>
 <li>{{jsxref("Sembol")}} (Edition 6)</li>
 <li>{{jsxref("Nesne")}}
  <ul>
   <li>{{jsxref("Fonksiyon")}}</li>
   <li>{{jsxref("Dizi")}}</li>
   <li>{{jsxref("Date")}}</li>
   <li>{{jsxref("RegExp")}}</li>
  </ul>
 </li>
 <li>{{jsxref("null")}}</li>
 <li>{{jsxref("undefined")}}</li>
</ul>

<p>Ayrıca bazı gömme {{jsxref("Error")}} türlerinden de söz edebiliriz. Ancak ilk diyagramla hareket etmemiz bizim işimizi kolaylaştıracaktır.</p>

<h2 id="Sayılar">Sayılar </h2>

<p>JavaScript'teki sayılar, spesifikasyonlara göre "çift duyarlıklı 64 bit format IEEE 754 değerleri" dir. Ancak bunun bazı ilginç sonuçları var. Örneğin JavaScript'te tamsayı gibi bir şey yoktur, bu yüzden eğer C veya Java'da kullanılan matematiğe alışkınsanız, aritmetiğinize biraz dikkat etmelisiniz.</p>

<p>Ayrıca aşağıdaki gibi olaylara dikkat edin:</p>

<pre class="brush: js">0.1 + 0.2 == 0.30000000000000004
</pre>

<p>Pratikte tamsayı değerleri 32-bit int olarak sayılır (ve bazı tarayıcı uygulamalarında bu şekilde saklanır). Bu, bit-temelli eylemler gerçekleştirmek istediğinizde önemli bir ayrıntıdır.</p>

<p>Ekleme, çıkarma, modül (veya kalan) aritmetik ve benzeri dahil olmak üzere standart <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#Arithmetic_operators">aritmetik operatörler</a> desteklenir. Daha ileri matematiksel fonksiyonlar gerçekleştirmek istiyorsanız kullanmanız gereken gömme nesne {{jsxref("Math")}}'dir:</p>

<pre class="brush: js">Math.sin(3.5);
var d = Math.PI * r * r;
</pre>

<p>{{jsxref("Global_Objects/parseInt", "parseInt()")}} gömme fonksiyonunu kullanarak bir string'i tamsayıya çevirebilirsiniz. Bu fonksiyon isteğe bağlı ikinci bir argüman olarak sayı tabanını alır:</p>

<pre class="brush: js">parseInt('123', 10); // 123
parseInt('010', 10); // 10
</pre>

<p>Eski tarayıcılarda "0" değeri ile başlayan stringler sekizli taban kabul ediliyordu. Eğer taban değerini yazmazsanız 2013 öncesi tarayıcılarda şaşırtıcı sonuçlar alabilirsiniz:</p>

<pre class="brush: js">parseInt("010"); // 8
parseInt("0x10"); // 16
</pre>

<p>Yukarıda gördüğünüz hata, {{jsxref("Global_Objects/parseInt", "parseInt()")}} fonksiyonu, yazılan string'i baştakı 0 nedeniyle sekizli taban cinsinden işlem yapması yüzünden gerçekleşti.</p>

<p>Bir sayıyı binary'den tamsayıya dönüştürmek isterseniz tek yapmanız gereken tabanı değiştirmektir:</p>

<pre class="brush: js">parseInt("11", 2); // 3
</pre>

<p>Benzer şekilde float türü sayıları ayrıştırmak için {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} gömülü fonksiyonunu kullanabilirsiniz. Bu fonksiyon, kuzeni sayabileceğimiz  {{jsxref("Global_Objects/parseInt", "parseInt()")}} fonksiyonunun aksine 10 tabanlı sistemi kullanır.</p>

<p>Ayrıca <code>+</code>  operatörünü kullanarak değerleri sayıya çevirebilirsiniz:</p>

<pre class="brush: js">+ '42'; //42
+ '010'; //10
+ '0x10'; //16
</pre>

<p>String sayısal bir değer değil ise karşınıza {{jsxref("NaN")}} (Açılımı: "Not a Number"' = sayı değil) çıkar:</p>

<pre class="brush: js">parseInt("hello", 10); // NaN
</pre>

<p><code>NaN</code> toksik gibidir: eğer onu bir girdi olarak herhangi bir matematiksel operasyonda kullanırsanız sonuç yine <code>NaN</code> olacaktır:</p>

<pre class="brush: js">NaN + 5; // NaN
</pre>

<p><code>NaN</code>  {{jsxref("Global_Objects/isNaN", "isNaN()")}} gömme fonksiyonu ile test edilebilir:</p>

<pre class="brush: js">isNaN(NaN); // true
</pre>

<p>JavaScript ayrıca {{jsxref("Infinity")}} (sonsuz) ve<code>-Infinity</code> (- sonsuz) gibi özel değerlere sahiptir:</p>

<pre><code>1 / 0; //  Infinity
-1 / 0; // -Infinity</code>
</pre>

<p> <code>Infinity</code>, <code>-Infinity</code> ve <code>NaN</code> değerlerini gömme fonksiyon  {{jsxref("Global_Objects/isFinite", "isFinite()")}} ile test edebilirsiniz: </p>

<pre class="brush: js">isFinite(1/0); // false
isFinite(-Infinite); //false
isFinite(NaN); // false
</pre>

<div class="note"><strong>Not:</strong> {{jsxref("Global_Objects/parseInt", "parseInt()")}} ve {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} fonksiyonları, belirtilen sayı biçimi için geçerli olmayan bir karaktere ulaşıncaya kadar bir dizeyi ayrıştırır, ardından bu noktaya kadar ayrıştırılan sayıyı döndürür. Ancak "+" operatörü, içinde geçersiz bir karakter varsa dizeyi  <code>NaN</code> 'a dönüştürür. Bahsettiğimiz yöntemleri kullanarak"10.2abc" dizesini konsolda kendiniz ayrıştırmayı denerseniz farklarını daha iyi anlayabilirsiniz.</div>

<h2 id="Stringler">Stringler</h2>

<p>JavaScript'teki stringler, karakter dizileridir. Daha doğrusu her karakter 16 bitlik bir sayı ile temsil edilen Unicode karakter dizisidir. Bu, uluslararasılaşma ile uğraşmak zorunda kalmış herkese iyi bir haber diyebiliriz.</p>

<p>Tek bir karakteri temsil etmek istiyorsanız, sadece 1 uzunluğunda bir string kullanmanız yeterlidir.</p>

<p>Bir string'in uzunluğunu bulmak istiyorsanız <code><a href="/en/JavaScript/Reference/Global_Objects/String/length" title="en/Core_JavaScript_1.5_Reference/Global_Objects/String/length">length</a></code> özelliğini kullanabilirsiniz:</p>

<pre class="brush: js">"merhaba".length; // 7
</pre>

<p>Böylelikle Javascript nesnelerine ilk adımımızı atmış olduk! Stringlerin de nesne olduğundan bahsetmiş miydik? Onların da stringleri manipüle etmek ve stringlerden bilgi almak için kullanılabilecek metodları vardır:</p>

<pre class="brush: js">&gt; 'merhaba'.charAt(0); // "m"
&gt; 'merhaba, dünya'.replace('merhaba', 'elveda'); // "elveda, dünya"
&gt; 'merhaba'.toUpperCase(); // MERHABA
</pre>

<h2 id="Diğer_Türler">Diğer Türler</h2>

<p>JavaScript, bir değer sayılmayan (ve sadece <code>null</code>  anahtar kelimesi ile erişilebilen) {{jsxref ("null")}} ve atanmamış değer olduğunu belirten {{jsxref ("undefined")}} arasındaki farkı ayırt edebilir. Daha sonra değişkenlerden bahsedeceğiz, ancak şimdiden belirtmeliyiz ki JavaScript'te değer atamadan da değişken tanımlamak mümkündür. Bunu yaparsanız, değişkenin türü <code>undefined</code> olur, bu da bize <code>undefined</code> türünün aslında bir sabit olduğunu gösterir.</p>

<p>Javascript, <code>true</code> (doğru) ve <code>false</code> (yanlış) değerlerini alabilen bir boolean türüne sahiptir. Aşağıdaki kurallar dahilinde her değer boolean'e çevrilebilir:</p>

<ol>
 <li> <code>false</code>, <code>0</code>, boş stringler (<code>""</code>), <code>NaN</code>, ve <code>undefined </code>değerlerinin tamamı <code>false</code>,</li>
 <li>Kalan tüm değerler <code>true</code> olur.</li>
</ol>

<p>Bu dönüşümü, <code>Boolean()</code> fonksiyonunu kullanarak kolayca gerçekleştirebilirsiniz:</p>

<pre class="brush: js"><code>Boolean('');  // false
Boolean(234); // true</code></pre>

<p>Ancak bu dönüşüm çoğu zaman gereksizdir çünkü Javascript bir boolean -bir if else ifadesi gibi (aşağıda görebilirsiniz)- beklediğinde bu dönüşümü sessizce gerçekleştirir. Bu nedenle "doğru değerler" ve "yanlış değerler"den bahsederken aslında  <code>true</code> ve <code>false</code> haline gelen değerlerden bahsediyoruz. Bu sizin true ve false değerleri yerine "truthy" ve "falsy" gibi sözcükler de kullanabileceğiniz anlamına gelir.</p>

<p><code>&amp;&amp;</code> (ve), <code>||</code> (veya), ve <code>!</code> (değil) gibi mantıksal boolean işlemleri desteklenmektedir; aşağıda daha fazla bilgi bulabilirsiniz.</p>

<h2 id="Değişkenler">Değişkenler</h2>

<p>Javascript'de yeni değişkenler <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let">let</a></code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const">const</a></code>, veya <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var" title="/en/JavaScript/Reference/Statements/var">var</a></code> anahtar kelimeleri ile tanımlanır.</p>

<p><code>let</code>, blok-düzeyinde değişkenleri tanımlamaya yarar. Tanımlanan değişken sadece kapsadığı blok dahilinde geçerlidir.</p>

<pre class="brush: js">let a;
let isim = "eren";
</pre>

<p>Aşağıda <code><strong>let</strong></code> ile tanımlanmış bir değişken örneği görebilirsiniz:</p>

<pre class="brush: js">// letDegiskenim burada kullanılabilir *değil*

for (let letDegiskenim = 0; letDegiskenim &lt; 5; letDegiskenim++) {
    // letDegiskenim sadece burada kullanılabilir
}

// letDegiskenim burada kullanılabilir *değil*
</pre>

<p><code><strong>const</strong></code> ile ileride değiştirme amacınız olmayan değişkenler tanımlayabilirsiniz. Değişken sadece içinde tanımlandığı <em>blokta </em>kullanılabilir.</p>

<pre class="brush: js">const Pi = 3.14;
Pi = 1; // const değişkenlerine yeni değerler atanamayacağı için hata verecektir.</pre>

<p><code><strong>var</strong></code><strong> </strong>en çok kullanılan tanımlayıcı anahtar sözcüktür. <code>let</code> ve <code>const</code>'daki kısıtlamalar bu anahtar sözcükte geçerli değildir. Bunun nedeni Javascript'de geçmişten beri bir değişken tanımlamak için <strong><code>var</code> </strong>kullanılmasıdır. Bu anahtar sözcükle tanımlanan değişkenler, tanımlandığı <em>fonksiyon</em> içerisinde kullanılabilir.</p>

<pre class="brush: js">var a;
var isim = 'eren';</pre>

<p>Aşağıda <strong><code>var</code></strong> ile tanımlanmış bir değişken örneği görebilirsiniz:</p>

<pre class="brush: js">// varDegiskenim burada kullanılabilir

for (let varDegiskenim = 0; varDegiskenim &lt; 5; varDegiskenim++) {
    // varDegiskenim tüm fonksiyon için kullanılabilir
}

// varDegiskenim burada kullanılabilir</pre>

<p>Eğer bir değişkeni değer atamadan tanımlarsanız, türü <code>undefined</code> olur.</p>

<p>Javascript ve Java gibi diller arasındaki önemli bir fark, Javascript'de blokların değil sadece fonksiyonların kapsama alanınından bahsedebilmemizdir. Yani bileşik bir ifade (örneğin bir <code>if</code> kontrol yapısı gibi) içerisinde <code>var</code> ile tanımlanan değişken, tüm fonksiyon içerisinde kullanılabilir. Ancak, ESMAScript 2015'den beri, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let">let</a></code> ve <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const">const</a></code> tanımlayıcıları size blok-düzeyinde değişkenler oluşturmanıza yarar.</p>

<h2 id="Operatörler">Operatörler</h2>

<p>Javascript'de <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> ve <code>%</code> gibi sayısal operatörler bulunur. (%: "kalan" operatörüdür ve modülüs ile aynı değildir.). Değerler <code>=</code> ile atanır, ayrıca <code>+=</code> ve <code>-=</code> gibi bileşke atama ifadeleri de kullanılabilir.</p>

<pre class="brush: js">x += 5;
x = x + 5;
</pre>

<p> <code>++</code> and <code>--</code> operatörlerini sırasıyla arttırmak ve azaltmak için kullanabilirsiniz.  Bu operatörler, değerden önce veya sonra yazılabilir (++deger ve deger++ gibi).</p>

<p><a href="/en/JavaScript/Reference/Operators/String_Operators" title="en/Core_JavaScript_1.5_Reference/Operators/String_Operators"><code>+</code> operator</a>ü stringleri birbirine bağlamak için de kullanılabilir:</p>

<pre class="brush: js">&gt; "merhaba" + " dünya"
merhaba dünya
</pre>

<p>Eğer bir sayıya (veya herhangi bir değere) string eklerseniz, her şey stringe dönüştürülür. Aşağıdaki örneğe bir göz atın:</p>

<pre class="brush: js">&gt; '3' + 4 + 5 // "345"
&gt; 3 + 4 + '5' // "75"
</pre>

<p>Bir değere boş string ekleyerek onu stringe dönüştürmek pratik bir yoldur.</p>

<p>Javascript'de <a href="/en/JavaScript/Reference/Operators/Comparison_Operators">karşılaştırmalar</a> <code>&lt;</code><code>&gt;</code><code>&lt;=</code> ve <code>&gt;=</code> ile yapılır. Bu operatörleri hem string hem de sayı değerleri için kullanabilirsiniz. Eşitlik ise bundan biraz daha karmaşık bir konudur. Çift-eşitlik operatörü, aşağıda görebileceğiniz gibi farklı türleri karşılaştırdığınızda düşündüğünüzden farklı sonuçlar verebilir:</p>

<pre class="brush: js">123 == '123' // true
1 == true;   // true
</pre>

<p>Farklı türlerle çalışırken bu tarz karışıklıklarlardan kaçınmak için üçlü-eşitlik operatörünü kullanın:</p>

<pre class="brush: js">123 === '123'; // false
1 === true;   // false
</pre>

<p>Javascript'de ayrıca <code>!=</code> ve <code>!==</code> operatörleri de vardır.</p>

<p>Eğer bit-dizeyinde işlemlerle ilgileniyorsanız <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">buraya </a>tıklayarak referans belgelerinden daha ayrıntılı bilgi alabilirsiniz.</p>

<h2 id="Kontrol_yapıları">Kontrol yapıları</h2>

<p>Javascript, C ailesine benzer nitelikte kontrol yapılarına sahiptir. Koşullu ifadeler <code>if</code> ve <code>else</code> ile desteklenir; isterseniz onları aşağıda göreceğiniz gibi birlikte kullanabilirsiniz:</p>

<pre class="brush: js">var isim = 'kediler';
if (isim  == 'köpekler') {
    isim += 'havlar';
} else if (isim == 'kediler') {
    isim += 'miyavlar';
} else {
    isim += '!';
}
isim == 'kediler miyavlar';</pre>

<p>JavaScript'de iki tür döngü (loop) vardır: <code>while</code> ve <code>do-while</code> . İlki basit döngüler için idealken; ikincisi, döngünün gövdesinin en az bir kez yürütüldüğünden emin olmak istediğiniz döngüler içindir:</p>

<pre class="brush: js">while (true) {
  // sonsuz döngü!
}

var input;
do {
  input = get_input();
} while (inputIsNotValid(input))
</pre>

<p>JavaScript'de <code>for</code> döngüsü aynı C ve Java'daki gibidir, döngünün kontrol bilgisini tek bir satıra yazmanıza olanak sağlar.</p>

<pre class="brush: js">for (var i = 0; i &lt; 5; i++) {
  // 5 kez yürütülecektir
}
</pre>

<p>JavaScript'de ayrıca döngüler için iki önemli ifade vardır: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code>for</code>...<code>of</code></a></p>

<pre class="brush: js"><code>for (let value of array) {
  // value değeri ile ilgili bir şey yap
}</code></pre>

<p>ve <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in"><code>for</code>...<code>in</code></a>:</p>

<pre class="brush: js"><code>for (let property in object) {
  // object'e ait property değeri ile ilgili bir şey yap
}</code>​​​
</pre>

<p><code>&amp;&amp;</code> ve <code>||</code> kısa devre mantığı ile çalışır, ikinci işlenecek olan işlenen (operand), ilkine bağlıdır. Bu şekilde <code>null</code> nesnelerinin niteliklerine erişmeden önce kontrol etmek için kullanılabilir:</p>

<pre class="brush: js">var name = o &amp;&amp; o.getName();
</pre>

<p>Veya değerleri önbelleğe almak için (falsy değerleri geçersiz olduğunda):</p>

<pre class="brush: js"><code>var name = cachedName || (cachedName = getName());</code></pre>

<p>JavaScript koşullu ifadeler için üçlü bir operatöre sahiptir:</p>

<pre class="brush: js"><code>var giriş_izni = (yaş &gt; 18) ? 'evet' : 'hayır';</code></pre>

<p><code>switch</code> ifadesi bir sayıya veya string'e bağlı olarak birden fazla kolda kullanılabilir:</p>

<pre class="brush: js"><code>switch (eylem) {
  case 'çiz':
    Çizim();
    break;
  case 'ye':
    Yemek();
    break;
  default:
    birSeyYapma();
}</code></pre>

<p><code>break</code> ifadesini eklemezseniz yürütme esnasında kod bir sonraki seviyeye "atlayacaktır". Bu çoğu zaman isteyeceğiniz bir durum değildir  — ancak eğer amacınız fallthrough ( açıkça yeniden yönlendirilmedikçe, yürütme işleminin bir listede sonraki duruma geçtiği durum)  yapmak ise yorum eklemeniz debug sürecini kolaylaştıracaktır:</p>

<pre class="brush: js"><code>switch (a) {
  case 1: // fallthrough
  case 2:
    Yemek();
    break;
  default:
    birSeyYapma();
}</code></pre>

<p><code>default</code> maddesi tamamen isteğe bağlıdır.  İsterseniz hem <code>switch</code> kısmında hem de <code>case</code> kısmında ifade kullanabilirsiniz. </p>

<pre class="brush: js"><code>switch (1 + 3) {
  case 2 + 2:
    yaşasın();
    break;
  default:
    aslaGerceklesmez();
}</code>
</pre>

<h2 id="Nesneler">Nesneler</h2>

<p>Javascript nesneleri (objects), basit isim-değer çiftleri olarak düşünülebilir. Bu açıdan diğer dillerdeki karşılıkları aşağıdaki gibidir:</p>

<ul>
 <li>Python'da kütüphane</li>
 <li>Perl ve Ruby'de Hash</li>
 <li>C and C++'da Hash tabloları</li>
 <li>Java'da HashMap</li>
 <li>PHP'de İlişkili Diziler</li>
</ul>

<p>Bu veri yapısının çok yaygın kullanıldığı gerçeği, çok yönlülüğünün bir kanıtıdır. JavaScript'teki her şey bir nesneden oluştuğu için, her JavaScript programı doğal olarak çok sayıda komut çizelgesi (hash table) aramaları içerir.</p>

<p>"İsim" kısmı bir Javascript string'i iken, değer olarak herhangi bir Javascript değeri yazabilirsiniz — diğer nesneler de dahil. Bu şekilde istediğiniz kadar komplike veri yapıları oluşturabilirsiniz.</p>

<p>Boş nesne oluşturmanın iki temel yolu vardır:</p>

<pre class="brush: js"><code>var nesne = new Object();</code></pre>

<p>Ve:</p>

<pre class="brush: js"><code>var nesne = {};</code></pre>

<p>Bunlar semantik olarak eşdeğerdir; ikinci nesne örneğine değişmez sözdizimi (literal syntax) denir ve daha kullanışlıdır. Bu sözdizimi aynı zamanda JSON formatının özüdür ve her zaman tercih edilmelidir.</p>

<p>Değişmez sözdizimi ile bir nesneyi tamamen tanımlayabilirsiniz:</p>

<pre class="brush: js"><code>var nesne = {
  isim: 'Havuç',
  kime: 'Max',
  detaylar: {
    renk: 'turuncu',
    boyut: 12
  }
};</code></pre>

<p>Özelliklere erişmek için aşağıda gördüğünüz iki yolu da kullanabilirsiniz:</p>

<pre class="brush: js"><code>nesne.detaylar.renk; // turuncu
nesne['detaylar']['boyut']; // 12</code></pre>

<p>Aşağıdaki örnekte bir nesne prototipi (<code>Kişi</code>) ve bu prototipin bir örneğini (<code>sen</code>) oluşturacağız:</p>

<pre class="brush: js"><code>function Kişi(isim, yaş) {
  this.isim= isim;
  this.yaş = yaş;
}

// Bir nesne tanımlayalım
var sen = new Kişi('Sen', 24);
// Adı "Sen" olan 24 yaşında bir kişi yaratmış olduk.</code></pre>

<p><strong>Bir kere oluşturulduktan sonra</strong>, nesnenin değerlerine erişebilmenin iki yolu vardır: </p>

<pre class="brush: js"><code>// nokta notasyonu
nesne.isim = 'Ayşe';
</code>var isim = nesne.isim;</pre>

<p>Ve...</p>

<pre class="brush: js"><code>// parantez notasyonu
nesne['isim'] = 'Ayşe';
var isim = nesne['isim'];
// Anahtar (key) tanımlamak için değişken kullanabilirsiniz.
var kullanıcı = prompt('Anahtar değeriniz nedir?')
obj[kullanıcı] = prompt('Anahtarın değeri nedir?')</code>
</pre>

<p>Yukarıda gördüğünüz örnekler de semantik olarak eşdeğerdir. İkinci metodun avantajı, özelliğin ismi string olarak sunulduğu için, yükleme zamanı (run-time) içerisinde hesaplanmasıdır. Ancak bu yöntemin kullanılması bazı Javascript motoru ve sıkıştırma optimizasyonlarının (minifier optimizations) çalışmasına engel olabilir.  Ayrıca parantez notasyonu ile <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords">rezerve sözcükler</a>i kullanarak özellik atama ve çağırma işlemleri yapabilirsiniz:</p>

<pre class="brush: js"><code>obj.for = 'Simon'; // Sözdizimi hatası verecektir çünkü 'for' rezerve sözcüklerden
obj['for'] = 'Simon'; // düzgün çalışır</code></pre>

<div class="note">
<p>ECMAScript 5'den itibaren, rezerve sözcükler nesne özelliği olarak kullanılabiliyor. Daha fazla bilgi için: <a href="http://es5.github.io/#x7.6.1">ES5 Spesifikasyonu</a></p>
</div>

<p>Nesneler ve prototipleri hakkında daha fazla bilgi için <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype">Object.prototype</a> adresini ziyaret edebilirsiniz. Nesne prototipleri  ve nesne prototip zincirleri için daha detaylı öğrenmek için: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">Kalıtım ve prototip zinciri</a>.</p>

<div class="note">
<p>ECMAScript 5'den itibaren, nesne anahtarları parantez notasyonuyla oluşturulmuş değişkenler ile tanımlanabilir. Yani<code><font face="x-locale-heading-primary, zillaslab, Palatino, Palatino Linotype, x-locale-heading-secondary, serif"><span style="background-color: #fff3d4; font-size: 18px;"> </span></font>var telKullanıcı = {}; telKullanıcı[telNum] = 12345</code>yerine sadece <code>{[telNum]: 12345}</code> ifadesini kullanmak mümkündür.</p>
</div>

<h2 id="Diziler">Diziler</h2>

<p>Javascript'de diziler (arrays) aslında özel birer nesneden ibarettir. Çoğu açıdan sıradan nesneler gibi çalışırlar (sayısal özelliklere doğal olarak yalnızca <code>[]</code> ile erişilebilir) ancak onları nesnelerden ayıran sihirli bir özellik vardır: '<code>length</code>'. Bu değer her zaman en yüksek index değerinden bir fazladır.</p>

<p>Dizi oluşturmanın bir yolu aşağıdaki gibidir:</p>

<pre class="brush: js"><code>var a = new Array();
a[0] = 'köpek';
a[1] = 'kedi';
a[2] = 'tavuk';
a.length; // 3</code></pre>

<p>Bir diğer yol ise değişmez dizi (literal array) oluşturmaktır:</p>

<pre class="brush: js"><code>var a = ['köpek', 'kedi', 'tavuk'];
a.length; // 3</code></pre>

<p>Fark edebileceğiniz gibi <code>array.length</code> her zaman dizideki öğe sayısı anlamına gelmez. Aşağıdaki örneğe dikkat edin:</p>

<pre class="brush: js"><code>var a = ['köpek', 'kedi', 'tavuk'];
a[100] = 'tilki';
a.length; // 101</code></pre>

<p>Unutmayın — dizinin uzunluğu en yüksek index'den bir fazladır.</p>

<p>Eğer varolmayan bir dizi index'ini sorgularsanız, <code>undefined</code> sonucunu alırsınız:</p>

<pre class="brush: js"><code>typeof a[90]; // undefined</code></pre>

<p>Yukarıda gördüğünüz <code>[]</code> ve <code>length</code> unsurları ile istediğiniz her dizi üzerinden <code>for</code> döngüsü ile geçebilirsiniz:</p>

<pre class="brush: js"><code>for (var i = 0; i &lt; a.length; i++) {
  //  a[i] kere ... yap
}</code></pre>

<p>ES2015, diziler gibi yinelenen nesneler için daha kullanışlı bir <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code>for</code>...<code>of</code></a> döngüsünü tanıttı:</p>

<pre class="brush: js"><code>for (const currentValue of a) {
  // currentValue kadar ... yap
}</code></pre>

<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in" title="/en/JavaScript/Reference/Statements/for...in"><code>for</code>...<code>in</code></a> döngüsü kullanarak da bir dizi üzerinden geçebilirsiniz ancak bu işlem dizi elemanları üzerinden değil, dizi index'i üzerinden işlenir. Ayrıca <code>Array.prototype</code> 'a yeni özellikler eklendiği takdirde, onlar da döngüde yer alacaktır. Bu nedenle bu döngü türü diziler için önerilmez. </p>

<p>Bir dizi üzerinden geçmenin bir diğer yolu ECMAScript 5 ile eklenen <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">forEach()</a></code> yöntemidir:</p>

<pre class="brush: js"><code>['köpek', 'kedi', 'tavuk'].forEach(function(currentValue, index, array) {
  // currentValue veya array[index] ile ... yap
});</code></pre>

<p>Bir diziye yeni bir eleman eklemek istiyorsanız aşağıdaki basit metodu uygulamanız yeterli olacaktır:</p>

<pre><code>a.push(item);</code></pre>

<p>Diziler için birçok metod mevcuttur. Tam dokümantasyon için <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">buraya </a>tıklayabilirsiniz.</p>

<table>
 <thead>
  <tr>
   <th scope="col">Metod ismi</th>
   <th scope="col">Açıklama</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>a.toString()</code></td>
   <td> <code>toString()</code> içerisine virgülle ayırarak yazılan her öğeyi string şeklinde <code>return</code> eder.</td>
  </tr>
  <tr>
   <td><code>a.toLocaleString()</code></td>
   <td> <code>toLocaleString()</code> içerisine virgülle ayırarak yazılan her öğeyi string şeklinde <code>return</code> eder.</td>
  </tr>
  <tr>
   <td><code>a.concat(item1[, item2[, ...[, itemN]]])</code></td>
   <td>Seçilen öğeler eklenmiş bir biçimde yeni bir dizi <code>return</code> eder.</td>
  </tr>
  <tr>
   <td><code>a.join(sep)</code></td>
   <td>Diziyi string'e dönüştürür. — öğeleri <code>sep</code> ile ayırarak</td>
  </tr>
  <tr>
   <td><code>a.pop()</code></td>
   <td>Son öğeyi siler ve <code>return</code> eder.</td>
  </tr>
  <tr>
   <td><code>a.push(item1, ..., itemN)</code></td>
   <td>Öğeleri dizinin sonuna ekler.</td>
  </tr>
  <tr>
   <td><code>a.reverse()</code></td>
   <td>Diziyi ters çevirir.</td>
  </tr>
  <tr>
   <td><code>a.shift()</code></td>
   <td>İlk değeri siler ve <code>return</code> eder</td>
  </tr>
  <tr>
   <td><code>a.slice(start[, end])</code></td>
   <td>Bir alt dizi oluşturur.</td>
  </tr>
  <tr>
   <td><code>a.sort([cmpfn])</code></td>
   <td>İsteğe bağlı bir karşılaştırma fonksiyonu alır.</td>
  </tr>
  <tr>
   <td><code>a.splice(start, delcount[, item1[, ...[, itemN]]])</code></td>
   <td>Bir bölümü silerek ve yerine daha fazla öğe ile ekleyerek bir diziyi modife etmenizi sağlar.</td>
  </tr>
  <tr>
   <td><code>a.unshift(item1[, item2[, ...[, itemN]]])</code></td>
   <td>Öğeleri dizinin başlangıcına ekler.</td>
  </tr>
 </tbody>
</table>

<h2 id="Fonksiyonlar">Fonksiyonlar</h2>

<p>Nesnelerle gibi fonksiyonlar da Javascript'i anlamak için öğrenmeniz gereken ana bileşenlerden biridir. En temel fonksiyon aşağıda görebileceğiniz gibi oldukça kolaydır:</p>

<pre class="brush: js"><code>function topla(x, y) {
  var toplam = x + y;
  return toplam;
}</code></pre>

<p>Javascript fonksiyonları birden fazla adlandırılmış parametre alabileceği gibi, parametresiz de oluşturulabilir. Fonksiyon gövdesi istediğiniz kadar ifade içerebilir ve o fonksiyonda yer alan yerel değişkenler de tanımlayabilir. <code>return</code> ifadesi ile birlikte istediğiniz değer getirilir ve fonksiyon sonlandırılır. Eğer hiçbir return ifadesi kullanılmamışsa (veya değer girilmemiş boş bir <code>return</code> kullanılmışsa) Javascript <code>undefined</code> sonucunu verir.</p>

<p>Adlandırılmış parametreler tam bir kılavuz niteliğindedir. Fonksiyonun beklediği parametreleri girmeden de çağırabilirsiniz, sonuç olarak karşınıza <code>undefined</code> çıkacaktır.</p>

<pre class="brush: js"><code>topla(); // NaN
// undefined bir değerle toplama işlemi gerçekleştiremezsiniz.</code></pre>

<p>Ayrıca fonksiyonun beklediğinden fazla argüman da ekleyebilirsiniz:</p>

<pre class="brush: js"><code>topla(2, 3, 4); // 5
// İlk iki değerle işlem yapıp 4'ü ihmal edecektir</code></pre>

<p>Biraz saçma gelebilir; ama fonksiyonlar, gövdelerinde ek bir değişken olarak bulunan <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">argümanlara</a></code> erişebilir. Argümanlar, fonksiyonlara verilen tüm değerleri kaydeden dizi-benzeri nesnelerdir. Hadi toplama fonksiyonumuzu istediğimiz kadar değer alabileceği şekilde yeniden yazalım:</p>

<pre class="brush: js"><code>function topla() {
  var toplam = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    toplam += arguments[i];
  }
  return toplam;
}

topla(2, 3, 4, 5); // 14</code></pre>

<p>Yine de bu fonksiyonu kullanmak yerine <code>2 + 3 + 4 + 5</code>  yazmak daha mantıklı duruyor. O yüzden bir de ortalama alan bir fonksiyon yazalım:</p>

<pre class="brush: js"><code>function ort() {
  var toplam = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    toplam += arguments[i];
  }
  return toplam / arguments.length;
}

ort(2, 3, 4, 5); // 3.5</code></pre>

<p>Oldukça kullanışlı, ancak gereksiz ifadeler olması gerekenden fazla kullanılmış gibi. Yazdığımız kodu kısaltmak için argüman dizimizin yerine <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest parameter syntax</a> yolunu kullanabiliriz. Bu yöntem hem istediğimiz sayıda argümanı fonksiyonumuzda kullanıp hem de kod uzunluğunu minimum seviyede tutmanıza yarar. <strong>Rest parametre operatörü </strong>şu şekilde listeleme yapar: <strong>...değişken,</strong> ve bu değişkenle beraber, fonksiyonla beraber çağrılan tüm argümanların bir listesi. Ayrıca <strong>for </strong>döngüsü yerine<strong> for..of </strong>döngüsünü kullanmamız daha mantıklı olacaktır.</p>

<pre class="brush: js"><code>function ort(...args) {
  var toplam = 0;
  for (let value of args) {
    toplam += value;
  }
  return toplam / args.length;
}

ort(2, 3, 4, 5); // 3.5</code></pre>

<div class="note">
<p>Yukarıdaki kodda <strong>args </strong>değişkeni, fonksiyona verilen tüm değerleri tutar.</p>

<p>Unutmamanız gereken önemli bir ayrıntı: <strong>rest parametre operatörü </strong>nerede tanımlandıysa, tanımladığı satırdan <em>sonraki </em>argümanları belleğe alacaktır. Bir diğer deyişle, fonksiyona verilen ilk değer <strong>firstValue</strong> değişkeninde, kalan argümanlar ise <strong>args</strong>'da saklanacaktır. Bu yararlı bir dil özelliği olsa da bizi yeni bir sorunla başbaşa bırakıyor. <code>avg()</code> fonksiyonu virgülle ayrılan argüman listesini alabilir — ancak eğer dizinin ortalamasını bulmak istersek ne yapmamız gerekir? Fonksiyonu aşağıdaki gibi yazmak iyi bir çözüm olabilir:</p>
</div>

<pre class="brush: js"><code>function avgArray(arr) {
  var toplam = 0;
  for (var i = 0, j = arr.length; i &lt; j; i++) {
    toplam += arr[i];
  }
  return toplam / arr.length;
}

avgArray([2, 3, 4, 5]); // 3.5</code></pre>

<p>Yine de önceden oluşturduğumuz fonksiyonu kullanabilmek daha iyi olurdu. Neyseki Javascript, size isteğe bağlı bir dizi argümana sahip bir fonksiyon çağırmanıza olanak sağlıyor. Bunun için tek yapmanız gereken {{jsxref("Function.apply", "apply()")}} metodunu kullanmak.</p>

<pre class="brush: js"><code>avg.apply(null, [2, 3, 4, 5]); // 3.5</code></pre>

<p> Bir diğer <code>apply()</code> yöntemi ise argüman olarak dizi kullanmaktır. Bu bilgi dahilinde, fonksiyonların da birer nesne olduğunu tekrardan hatırlamış olalım.</p>

<div class="note">
<p>Aynı sonucu <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operatörü</a>nü çağırarak da elde edebilirsiniz.</p>

<p>Örneğin: <code>avg(...numbers)</code></p>
</div>

<p>JavaScript ile anonim fonksiyonlar oluşturabilirsiniz.</p>

<pre class="brush: js"><code>var avg = function() {
  var toplam = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    toplam += arguments[i];
  }
  return toplam / arguments.length;
};</code></pre>

<p>Yukarıda gördüğünüz yöntem semantik olarak <code>function avg()</code> ifadesine eşdeğerdir. Oldukça güçlü olan bu yöntem ile normalde ifade yazabileceğiniz her yere fonksiyon tanımı koyabilirsiniz. Bu şekilde zekice hilelere başvurabilirsiniz. Aşağıda gördüğünüz yerel değişken "saklama" yöntemi bunlardan sadece biri:</p>

<pre class="brush: js"><code>var a = 1;
var b = 2;

(function() {
  var b = 3;
  a += b;
})();

a; // 4
b; // 2</code></pre>

<p>JavaScript, fonksiyonları özyinelemeli (recursively) çağırmanıza olanak sağlar. Bu, özellikle tarayıcı DOM'larında rastlayacağınız ağaç yapıları (tree structures) ile çalışırken oldukça faydalıdır.</p>

<pre class="brush: js"><code>function countChars(elm) {
  if (elm.nodeType == 3) { // TEXT_NODE
    return elm.nodeValue.length;
  }
  var count = 0;
  for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += countChars(child);
  }
  return count;
}</code></pre>

<p>Bu anonim fonksiyonlarda olası bir sorunu işaret eder. Eğer bu fonksiyonların bir adı yoksa, onları nasıl özyinelemeli çağırabiliriz? Javascript bunun için fonksiyon ifadelerini adlandırmanıza olanak sağlar. Aşağıda görebileceğiniz gibi <a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE">IAIFEs (Immediately Invoked Function Expressions)</a> özelliğini kullanabilirsiniz:</p>

<pre class="brush: js"><code>var charsInBody = (function counter(elm) {
  if (elm.nodeType == 3) { // TEXT_NODE
    return elm.nodeValue.length;
  }
  var count = 0;
  for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += counter(child);
  }
  return count;
})(document.body);</code></pre>

<p>Yukarıdaki fonksiyona verilen isme sadece fonksiyonun kendi kapsamında erişilebilir. Bu şekilde Javascript motorunun daha fazla optimizasyon yapmasına olanak sağlamış olursunuz, böylelikle kodunuz daha okunur hale gelir. Ayrıca, hata ayıklama yaparken zamandan tasarruf edebilirsiniz.</p>

<p>Fark ettiyseniz Javascript'de -diğer her şey gibi- fonksiyonlar da birer nesnedir. Böylelikle daha önceki bölümlerde öğrendiğiniz nesnelerdeki gibi, özellik ekleme ve değiştirmeniz mümkündür.</p>

<h2 id="Özel_nesneler">Özel nesneler</h2>

<div class="note">
<p>JavaScript'te nesne yönelimli programlama hakkında daha ayrıntılı bilgiler için <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects">Nesne Yönelimli Javascript'e Giriş</a> sayfasına göz atabilirsiniz.</p>
</div>

<p>Nesne yönelimli programlamada; nesneler, yine aynı veriler üzerinde işlem yapan veri ve metod koleksiyonlarıdır. Javascript prototip tabanlı bir dil olduğu için, C++ ve Java'nın aksine sınıf (class) kavramına sahip değildir. Javascript'de sınıf yerine fonksiyonlar kullanılır. Ad ve soyad alanları olan bir Kişi fonksiyonu düşünelim. Tam adı görüntülemenin iki yolu olabilir: "ad, soyad" ve "soyad, ad". Fonksiyonları ve nesneleri kullanarak veriyi aşağıda göreceğiniz gibi ekrana yansıtabiliriz:</p>

<pre class="brush: js"><code>function Kişi(ad, soyad) {
  return {
    ad: ad,
    soyad: soyad
  };
}
function tamİsim(a) {
  return a.ad + ' ' + a.soyad;
}
function tamİsimTers(a) {
  return a.soyad + ', ' + a.ad;
}

s = Kişi('Simon', 'Willison');
tamİsim(s); // "Simon Willison"
tamİsimTers(s); // "Willison, Simon"</code>
</pre>

<p>Yukarıda gördüğünüz kod çalışacaktır ama oldukça çirkin gözüküyor. Çünkü yapmak istediğiniz işlemler arttıkça global ad alanı (namespace) onlarca fonksiyon ile dolabilir. Bu nedenle yapmamız gereken şey nesnemize fonksiyon eklemek. Fonksiyonlar da birer nesne olduğu için işimiz oldukça kolay:</p>

<pre class="brush: js"><code>function Kişi(ad, soyad) {
  return {
    ad: ad,
    soyad: soyad,
    tamİsim: function() {
      return this.ad + ' ' + this.soyad;
    },
    tamİsimTers: function() {
      return this.soyad + ', ' + this.ad;
    }
  };
}

s = Kişi('Simon', 'Willison');
s.tamİsim(); // "Simon Willison"
s.tamİsimTers(); // "Willison, Simon"</code></pre>

<p>Fark ettiyseniz burada yeni bir anahtar kelime kullandık: <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" title="/en/JavaScript/Reference/Operators/this">this</a></code>. Fonksiyonun içinde kullanıldığında <code>this</code>, geçerli nesneyi ifade eder. Ne anlama geleceği fonksiyonu çağırma yöntemine göre belirlenir. Örneğin; bir nesne üzerinde, fonksiyonu <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Accessing_properties">nokta notasyonu veya parantez notasyonu</a> ile çağırırsanız, o nesne <code>this</code> olur. Eğer nokta notasyonu çağrı işleminde kullanılmadıysa <code>this</code> global nesneyi ifade eder.</p>

<p><code>this</code> anahtar sözcüğü birçok hataya sebep olabilir. Aşağıdaki örneğe bir göz atın:</p>

<pre class="brush: js"><code>s = Kişi('Simon', 'Willison');
var tamİsim = s.tamİsim;
fullName(); // undefined undefined </code></pre>

<p><code>tamİsim()</code> fonksiyonunu  <code>s.tamİsim()</code>'i kullanmadan tek başına çağırdığımızda, <code>this</code> global nesneye bağlıdır. <code>ad</code> ve <code>soyad</code> gibi global değişkenler olmadığı için ekrana her biri için <code>undefined</code> sonucu yansıyacaktır.</p>

<p>Şimdi <code>Kişi</code> fonksiyonumuzu geliştirmek için <code>this</code> anahtar kelimesini kullanalım:</p>

<pre class="brush: js"><code>function Kişi(ad, soyad) {
  this.ad = ad;
  this.soyad = soyad;
  this.tamİsim = function() {
    return this.ad + ' ' + this.soyad;
  };
  this.tamİsimTers = function() {
    return this.soyad + ', ' + this.ad;
  };
}
var s = new Kişi('Simon', 'Willison');</code></pre>

<p>Yeni bir anahtar kelimeden bahsetmenin vakti geldi: <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new">new</a></code>. <code>new</code>, <code>this</code> ile doğrudan bağlantılıdır. Tamamen yeni bir boş nesne yaratır ve belirtilen fonksiyonu yeni nesnenin <code>this</code> değeriyle güncelleyerek çağırır. Fark ettiyseniz <code>this</code>, sadece <code>this</code> nesnesinde değişiklik yapar. Bir değeri <code>return</code> eden <code>new</code> anahtar kelimesidir. <code>new</code> tarafından çağırılacak fonksiyonlara kurucu (constructor) fonksiyon denir. Bu fonksiyonları <code>new</code> ile çağırmayı unutmamak için büyük harfle isimlendirmek yaygın bir yöntemdir.</p>

<p>Geliştirdiğimiz fonksiyon hala <code>tamİsim()</code>'i tek başına çağırdığımızda istediğimiz sonucu vermeyecek.</p>

<p>Kişi nesnelerimiz artık eskisinden daha iyi, ancak hala kötü tarafları mevcut. Her kişi nesnesi oluşturduğumuzda, iki yepyeni fonksiyon yaratmış oluyoruz — peki bu kod paylaşılsaydı daha iyi olmaz mıydı?</p>

<pre class="brush: js"><code>function tamİsim() {
  return this.ad + ' ' + this.soyad;
}
function tamİsimTers() {
  return this.soyad + ', ' + this.ad;
}
function Kişi(ad, soyad) {
  this.ad = ad;
  this.soyad = soyad;
  this.tamİsim= tamİsim;
  this.tamİsimTers = tamİsimTers;
}</code></pre>

<p>Çok daha iyi. Artık metod fonksyionlarını bir defa oluşturuyoruz ve referansları kurucu fonksiyonun içinde atıyoruz. Bundan daha iyisini de yapabilir miyiz? Cevap evet:</p>

<pre class="brush: js"><code>function Kişi(ad, soyad) {
  this.ad = ad;
  this.soyad = soyad;
}
Kişi.prototype.tamİsim = function() {
  return this.ad+ ' ' + this.soyad;
};
Kişi.prototype.tamİsimTers = function() {
  return this.soyad + ', ' + this.ad;
};</code></pre>

<p><code>Kişi.prototype</code><font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">Kişi</span></font>'nin tüm özelliklerinin paylaşıldığı bir nesnedir. Bir diğer adı "prototip zinciri" olan bu nesne, bir arama zincirinin parçasını oluşturur. <code>Kişi</code>'ye ait ayarlanmamış bir özelliğe erişmek istediğinizde, Javascript bu özelliğin var olup olmadığını <code>Kişi.prototype</code> öğesinde arayacaktır. Böylelikle <code>Kişi.prototype</code>'a atanan her şey, <code>this</code> nesnesi kullanılarak kurucu fonksiyonda da geçerli hale gelecektir.</p>

<p>Bu, oldukça güçlü bir özellik. Javascript, size istediğiniz zaman, herhangi bir şeyin prototipini modifiye etmenize olanak tanır. Bu şekilde önceden oluşturduğunuz nesnelere yeni metodlar ekleyebilirsiniz:</p>

<pre class="brush: js"><code>s = new Kişi('Simon', 'Willison');
s.isimCaps(); // 1. satırda TypeError: s.isimCaps bir fonksiyon değil

Kişi.prototype.isimCaps = function() {
  return this.first.toUpperCase();
};
s.isimCaps(); // "SIMON"</code></pre>

<p>İlginç bir şekilde gömülü Javascript nesnelerinin prototiplerine de bir şeyler ekleyebilirsiniz. Hadi <code>String</code>  nesnesine sözcükleri ters çevirmeye yarayan bir metod ekleyelim:</p>

<pre class="brush: js"><code>var s = 'Simon';
s.ters(); // 1. satırda TypeError: s.ters bir fonksiyon değil

String.prototype.ters = function() {
  var r = '';
  for (var i = this.length - 1; i &gt;= 0; i--) {
    r += this[i];
  }
  return r;
};

s.ters(); // nomiS</code></pre>

<p>Yeni metodumuz aşağıda görebileceğiniz durumlarda bile çalışıyor:</p>

<pre class="brush: js"><code>'Ters çevir'.ters(); // riveç sreT</code></pre>

<p>Daha önce de bahsettiğimiz gibi; prototip, zincirin bir kısmını oluşturur. Bu zincirin kökü <code>Object.prototype</code>, içerdiği metodlardan biri ise <code>toString()</code>'dir. — hatırlarsanız bu metodu bir nesneyi string'e çevirmek için çağırıyorduk. Bu yöntem <code>Kişi</code> nesnelerimizin hata ayıklama sürecinde yardımcı olacaktır.</p>

<pre class="brush: js"><code>var s = new Kişi('Simon', 'Willison');
s.toString(); // [object Object]

Kişi.prototype.toString = function() {
  return '&lt;Kişi: ' + this.isim() + '&gt;';
}

s.toString(); // "&lt;Kişi: Simon Willison&gt;"</code></pre>

<p>Hatırlarsanız <code>avg.apply()</code> metodu yeni bir boş argüman oluşturuyordu. Şimdi o konuya geri dönebiliriz.  <code>apply()</code> kullanacağımız ilk argüman, '<code>this</code>' ile ele alınacak bir nesne olmalıdır. Aşağıda <code>new</code> anahtar kelimesinin kullanıldığı küçük bir uygulama görebilirsiniz:</p>

<pre class="brush: js"><code>function Deneme(constructor, ...args) {
  var o = {}; // Nesne yaratır
  constructor.apply(o, args);
  return o;
}</code></pre>

<p>Bu, prototip zincirini oluşturmadığı için <code>new</code> ifadesinin tam anlamıyla karşılığı sayılmaz (bu durumu anlatması biraz zor) ve çok sık kullanacağınız bir şey değil, ancak yine de bilmek faydalı olacaktır. Bu örnekte <code>...args</code>, "<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest arguments</a>" olarak da geçer. — adından da anlayacağınız üzere geriye kalan tüm argümanları temsil eder.</p>

<p>Bu nedenle bu satır,</p>

<pre class="brush: js"><code>var bill = Deneme(Kişi, 'William', 'Orange');</code></pre>

<p>hemen hemen bu satır ile aynıdır:</p>

<pre class="brush: js"><code>var bill = new Kişi('William', 'Orange');</code></pre>

<p><code>apply()</code> metodunun kardeşi sayabileceğimiz <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call" title="/en/JavaScript/Reference/Global_Objects/Function/call"><code>call</code></a>, <code>apply()</code>'dan farklı olarak genişletilmiş bir argüman listesi alır.</p>

<pre class="brush: js"><code>function soyadCaps() {
  return this.last.toUpperCase();
}
var s = new Kişi('Simon', 'Willison');
soyadCaps.call(s);
// Veya aşağıdaki yöntemi kullanabilirsiniz:
s.soyadCaps = soyadCaps;
s.soyadCaps(); // WILLISON</code></pre>

<h3 id="İç_fonksiyonlar">İç fonksiyonlar</h3>

<p>JavaScript fonksiyonların içinde başka fonksiyonlar tanımlayabilirsiniz. Bu durumu  <code>Kişi()</code> fonksiyonumuzun önceki versiyonlarında görmüştük. İç içe oluşturulan fonksiyonlara dair önemli bir detay, içteki fonksiyonun içinde bulunduğu "parent" fonksiyon kapsamında kullanılan değişkenlere erişebilmesidir:</p>

<pre class="brush: js"><code>function parentFonk() {
  var a = 1;

  function içFonk() {
    var b = 4; // parentFonk bunu kullanamaz.
    return a + b;
  }
  return içFonk(); // 5
}</code></pre>

<p>Bu, daha sürdürülebilir bir kod yazmanızda büyük yarar sağlar. Eğer bir fonksiyonunuz, başka kısımlarda işinize yaramayacak bir veya daha fazla fonksiyona bağlıysa; bu fonksiyonları başka bir yerde çağıracağınız fonksiyonun içine yazabilirsiniz. Bu şekilde global düzeyde kullanılan değişken sayısını azaltacağınız için, daha güvenli bir koda sahip olursunuz.</p>

<p>Yazdığınız kod karmaşık bir hal aldıkça birden çok fonksiyon arasında değer paylaşmak yerine global değişkenler kullanmak daha cazip gelebilir — ki bu sebeple sürdürülmesi zor bir kod yaratmış olursunuz. İç içe fonksiyonlar dış fonksiyon ile değişken paylaşabildiği için global isim alanınızı (global namespace) kirletmeden, sadece ilgili fonksiyonları bir araya getirerek bu mekanizmayı kullanabilirsiniz.  —  bu şekilde kullanacağınız değişkenlere "yerel global" bile diyebiliriz. Ne kadar kullanışlı da olsa bu mekanizmayı dikkatli kullanmanız gerekir.</p>

<h2 id="Kaplamlar">Kaplamlar</h2>

<p>Sıra geldi Javascript'in en güçlü -bir yandan da en kafa karıştırıcı-  soyutlamalarından birine. Peki kaplamlar (closures) tam olarak ne yapar?</p>

<pre class="brush: js"><code>function ekle(a) {
  return function(b) {
    return a + b;
  };
}
var x = ekle(5);
var y = ekle(20);
x(6); // ?
y(7); // ?</code></pre>

<p><code>ekle()</code> fonksiyonun işlevini anlamışsınızdır; yeni bir "toplama" fonksiyonu oluşturur ve tek bir argümanla çağrıldığında, oluşturulduğu argümana o değeri ekler.</p>

<p>Burada gördüğünüz olayın gerçekleşme şekli, daha önce bahsettiğimiz iç fonksiyonların çalışma prensibiyle hemen hemen aynı: içeride tanımlanmış fonksiyon, dış fonksiyonun değişkenlerine erişim hakkı vardır. Buradaki tek fark ise şu; dış fonksiyon <code>return</code> edildiğinde yerel değişkenleri artık yok olacak gibi düşünürüz, ancak <em>hala bellektedirler </em>— aksi takdirde fonksiyonlarımız çalışmazdı. Dahası, <code>ekle()</code> fonksiyonunun yerel değişkenlerinin iki farklı "kopyası" bulunuyor. — bir 5 olan <code>a</code> ve bir de 20 olan <code>a</code>. Bu yüzden yukarıdaki kodun sonucu böyle olacaktır:</p>

<pre class="brush: js"><code>x(6); //  11
y(7); //  27</code></pre>

<p>Şimdi arkaplanda ne olup bittiğini yazalım. Javascript ne zaman bir fonksiyonu yürütse, fonksiyon içerisindeki yerel değişkenleri tutma amaçlı bir 'kapsama alanı' oluşturur. Bu alan, fonksiyon parametresi olarak gönderilen tüm değişkenler üzerinden tanımlanır. Bahsettiğimiz durum tüm global değişken ve fonksiyonları içeren global nesneye benzese de, birkaç önemli farklılık taşır: ilk olarak, fonksiyon her yürütüldüğünde yepyeni bir kapsam nesnesi oluşturulur, ve ikinci olarak, kapsam nesneleri global nesnelerin aksine Javascript kodu üzerinden doğrudan erişilebilir değildir. Örneğin, geçerli kapsam nesnesinin özellikleri üzerinde yineleme yapmak için bir mekanizma yoktur.</p>

<p>Özetlemek gerekirse; <code>ekle()</code> çağırıldığında, fonksiyona geçen argüman, yani tek bir özelliğe sahip (<code>a</code>) bir kapsam nesnesi oluşturulur. Ardından <code>ekle()</code> fonksiyonu yeni bir fonksiyon <code>return</code> eder. Normal koşullarda Javascript'in çöp toplayıcısının <code>ekle()</code> için oluşturulan bu yeni fonksiyonu temizlemesi gerekirken, <code>return</code> edilen fonksiyon yine de kapsam fonksiyonu için referans konumunda durur. Bu nedenle <code>ekle()</code>'nin oluşturduğu fonksiyon nesnesine herhangi bir referans kalmayana dek bu kapsamda hiç bir öğe silinmeyecektir.</p>

<p>Kapsam nesneleri, JavaScript'in nesne sisteminde kullanılan prototip zincirine benzer şekilde, kapsam zinciri adı verilen bir zinciri oluşturur.</p>

<p><strong>Kaplam</strong>, bir fonksiyon ile, o fonksiyon beraberinde oluşturulan kapsam nesnesinin bir kombinasyonudur. Kaplamlar durum (state) kaydetmenize olanak sağlar — böylelikle nesnelerin yerine kullanılabilirler. Kaplamlar hakkında bazı muhteşem bilgiler için buraya <a href="http://stackoverflow.com/questions/111102/how-do-javascript-closures-work">tıklayabilirsiniz.</a></p>

<div class="originaldocinfo">
<h2 id="Original_Document_Information" name="Original_Document_Information">Orijinal Belge Bilgileri</h2>

<ul>
 <li>Yazar: <a class="external" href="http://simon.incutio.com/">Simon Willison</a></li>
 <li>Son güncellenme tarihi: March 7, 2006</li>
 <li>Copyright: © 2006 Simon Willison, contributed under the Creative Commons: Attribute-Sharealike 2.0 license.</li>
 <li>Daha fazla bilgi: Bu ders ile ilgili daha fazla bilgi (ve orijinal sunuma ait slaytlar) için, <a class="external" href="http://simon.incutio.com/archive/2006/03/07/etech">Etech weblog post</a> adresine girebilirsiniz.</li>
</ul>
</div>

<pre class="script" style="font-size: 16px;">wiki.languages({
  "fr": "fr/Une_r\u00e9introduction_\u00e0_JavaScript",
  "it": "it/Una_re-introduzione_a_Javascript",
  "ja": "ja/A_re-introduction_to_JavaScript",
  "ko": "ko/A_re-introduction_to_JavaScript",
  "pl": "pl/JavaScript/Na_pocz\u0105tek",
  "ru": "ru/\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435_\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435_\u0432_JavaScript",
  "zh-cn": "cn/A_re-introduction_to_JavaScript",
  "zh-tw": "zh_tw/\u91cd\u65b0\u4ecb\u7d39_JavaScript",
  "es": "es/JavaScript/Una_nueva_introducción_a_JavaScript"});
</pre>