|
| 1 | +## Prototip |
| 2 | + |
| 3 | +JavaScript klasik bir kalıtım modeli değil *prototip* modeli kullanır. |
| 4 | + |
| 5 | +Çoğu zaman bu modelin JavaScript'in zayıf yönlerinden biri olduğu söylense de, |
| 6 | +aslında prototip model klasik modelden daha güçlüdür. Mesela prototip model |
| 7 | +temel alınarak klasik kalıtım modeli oluşturulabilir, fakat bunun tersini yapmak |
| 8 | +çok daha zordur. |
| 9 | + |
| 10 | +Prototip kalıtım modeli kullanan tek popüler dil JavaScript olduğu için iki |
| 11 | +model arasındaki farklılıklara alışmak biraz zaman alır. |
| 12 | + |
| 13 | +İlk büyük farklılık JavaScript'te kalıtımın *prototip zincirleri* ile |
| 14 | +yapılmasıdır. |
| 15 | + |
| 16 | +> **Not:** `Bar.prototype = Foo.prototype` gibi basit bir atama yapmak her iki |
| 17 | +> nesnenin de **aynı** prototipe sahip olmasına neden olacaktır. Bu yüzden bir |
| 18 | +> nesnenin prototipinde yapılacak değişiklikler diğer nesnenin prototipini de |
| 19 | +> etkileyecektir, ki çoğu zaman istenen etki bu değildir. |
| 20 | + |
| 21 | + function Foo() { |
| 22 | + this.value = 42; |
| 23 | + } |
| 24 | + Foo.prototype = { |
| 25 | + method: function() {} |
| 26 | + }; |
| 27 | + |
| 28 | + function Bar() {} |
| 29 | + |
| 30 | + // Bar nesnesinin prototipi olarak yeni bir Foo nesnesini ata |
| 31 | + Bar.prototype = new Foo(); |
| 32 | + Bar.prototype.foo = 'Hello World'; |
| 33 | + |
| 34 | + // Nesne oluşturucusunun Bar olmasını sağla |
| 35 | + Bar.prototype.constructor = Bar; |
| 36 | + |
| 37 | + var test = new Bar() // yeni bir Bar oluştur |
| 38 | + |
| 39 | + // Sonuçta ortaya çıkan prototip zinciri |
| 40 | + test [bir Bar sınıfı nesnesi] |
| 41 | + Bar.prototype [bir Foo sınıfı nesnesi] |
| 42 | + { foo: 'Hello World' } |
| 43 | + Foo.prototype |
| 44 | + { method: ... } |
| 45 | + Object.prototype |
| 46 | + { toString: ... /* vs. */ } |
| 47 | + |
| 48 | +Yukarıda, `test` nesnesi hem `Bar.prototype` hem de `Foo.prototype` 'dan |
| 49 | +türeyecektir; bu nedenle `Foo` 'da tanımlanmış olan `method` fonksiyonuna |
| 50 | +da erişebilir. Ayrıca, prototipi olan **tek** `Foo` nesnesinin `value` |
| 51 | +özelliğine de erişebilir. Dikkat edilmesi gereken bir nokta, `new Bar()` |
| 52 | +ifadesinin yeni bir `Foo` nesnesi **yaratmayıp**, prototipine atanmış olan |
| 53 | +nesneyi kullanmasıdır; bu nedenle, tüm `Bar` nesneleri **aynı** `value` |
| 54 | +özelliğine sahip olacaktır. |
| 55 | + |
| 56 | +> **Not:** `Bar.prototype = Foo` gibi bir ifade **kullanmayın**, çünkü `Foo` |
| 57 | +> 'nun prototipine değil fonksiyon nesnesine işaret edecektir. Yani |
| 58 | +> prototip zinciri `Foo.prototype` değil `Function.prototype` üzerinden |
| 59 | +> gidecektir; ve bu yüzden, `method` prototip zincirinden bulunmayacaktır. |
| 60 | +
|
| 61 | +### Özelliklere bulmak |
| 62 | + |
| 63 | +Bir nesnenin özelliklerine erişildiğinde, JavaScript, istenen isimdeki özelliği |
| 64 | +bulana kadar prototip zincirinde **yukarı** doğru dolaşır. |
| 65 | + |
| 66 | +Zincirin en üstüne ulaştığında (yani `Object.protype`) ve hala istenen özelliği |
| 67 | +bulamamışsa sonuç olarak [undefined](#core.undefined) verecektir. |
| 68 | + |
| 69 | +### prototype özelliği |
| 70 | + |
| 71 | +`prototype` özelliği dil tarafından prototip zincirleri oluşturmak için |
| 72 | +kullanılsa da, bu özelliğe **herhangi** bir değer atamak mümkündür. Fakat |
| 73 | +prototip olarak atanan ilkel nesne türleri göz ardı edilecektir. |
| 74 | + |
| 75 | + function Foo() {} |
| 76 | + Foo.prototype = 1; // hiç bir etkisi olmaz |
| 77 | + |
| 78 | +Bir önceki örnekte gösterildiği gibi, prototip olarak nesneler atanabilir, bu da |
| 79 | +prototip zincirlerinin dinamik olarak oluşturulabilmesini sağlar. |
| 80 | + |
| 81 | +### Performans |
| 82 | + |
| 83 | +Prototip zincirinin yukarısındaki özellikleri aramanın performansı kritik olan |
| 84 | +programlarda olumsuz etkileri olabilir. Ek olarak, mevcut olmayan özelliklere |
| 85 | +erişmeye çalışmak da tüm prototip zincirinin baştan sona taranmasına neden |
| 86 | +olacaktır. |
| 87 | + |
| 88 | +Ayrıca, bir nesnenin özellikleri üzerinde [iterasyon](#object.forinloop) |
| 89 | +yapıldığında da prototip zinciri üzerindeki **tüm** özelliklere bakılacaktır. |
| 90 | + |
| 91 | +### Temel prototiplerin genişletilmesi |
| 92 | + |
| 93 | +Sıklıkla yapılan bir hata `Object.protype` 'ı veya diğer baz prototipleri |
| 94 | +genişletmektir. |
| 95 | + |
| 96 | +Bu tekniğe [monkey patching][1] denir ve *kapsüllemeyi* bozar. Bu teknik |
| 97 | +[Prototype][2] gibi bazı popüler sistemlerde kullanılsa bile, temel nesne |
| 98 | +türlerine *standart olmayan* özellikler eklenmesinin geçerli iyi bir nedeni |
| 99 | +yoktur. |
| 100 | + |
| 101 | +Temel prototipleri genişletmenin **tek bir** geçerli nedeni vardır, o da daha |
| 102 | +yeni JavaScript motorlarında bulunan özelliklerin eski motorlara getirilmesidir; |
| 103 | +mesela [`Array.forEach`][3]. |
| 104 | + |
| 105 | +### Sonuç |
| 106 | + |
| 107 | +Prototip kalıtım modeli kullanan karmaşık programlar yazmadan önce bu modelin |
| 108 | +tamamen anlaşılması **şarttır**. Ayrıca, prototip zincirinin uzunluğuna dikkat |
| 109 | +edilmeli ve çok uzaması durumunda performans sorunları yaşamamak için parçalara |
| 110 | +bölünmelidir. Bundan başka, temel prototipler yeni JavaScript motorları ile |
| 111 | +uyumluluk sağlamak dışında bir nedenle **asla** genişletilmemelidir. |
| 112 | + |
| 113 | +[1]: http://en.wikipedia.org/wiki/Monkey_patch |
| 114 | +[2]: http://prototypejs.org/ |
| 115 | +[3]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach |
| 116 | + |
0 commit comments