diff --git a/00_intro.md b/00_intro.md index 35055bc4..e57a693e 100644 --- a/00_intro.md +++ b/00_intro.md @@ -1,78 +1,79 @@ {{meta {load_files: ["code/intro.js"]}}} -# Introduction +# Giriş -{{quote {author: "Ellen Ullman", title: "Close to the Machine: Technophilia and its Discontents", chapter: true} +{{quote {author: "Ellen Ullman", title: "Close to the Machine: Technophilia and Its Discontents", chapter: true} -We think we are creating the system for our own purposes. We believe we are making it in our own image... But the computer is not really like us. It is a projection of a very slim part of ourselves: that portion devoted to logic, order, rule, and clarity. +Sistemleri kendi amaçlarımız için oluşturduğumuzu düşünüyoruz. Onu kendi görüntümüzde yapıyor olduğumuza inanıyoruz... Ancak bilgisayar gerçekten bizim gibi değil. Aslında, çok ince bir kısmımızın yansımasıdır: mantık, düzen, kural ve netliğe adanmış kısmın bir yansımasıdır. quote}} {{figure {url: "img/chapter_picture_00.jpg", alt: "Illustration of a screwdriver next to a circuit board of about the same size", chapter: "framed"}}} -This is a book about instructing ((computer))s. Computers are about as common as screwdrivers today, but they are quite a bit more complex, and making them do what you want them to do isn't always easy. +Bu bir bilgisayarlara talimat verme kitabıdır. Bilgisayarlar bugün tornavida kadar yaygın olsa da, oldukça karmaşıklar ve onları istediğiniz şekilde hareket ettirmek her zaman kolay değildir. -If the task you have for your computer is a common, well-understood one, such as showing you your email or acting like a calculator, you can open the appropriate ((application)) and get to work. But for unique or open-ended tasks, there often is no appropriate application. +Bilgisayarınız için göreviniz yaygın, iyi anlaşılmış bir görevse, örneğin e-postanızı göstermek veya bir hesap makinesi gibi davranmak gibi, uygun uygulamayı açabilir ve işe koyulabilirsiniz. Ancak benzersiz veya açık uçlu görevler için muhtemelen bir uygulama yoktur. -That is where ((programming)) may come in. _Programming_ is the act of constructing a _program_—a set of precise instructions telling a computer what to do. Because computers are dumb, pedantic beasts, programming is fundamentally tedious and frustrating. +İşte programlamaya girilen yer burası olabilir. _Programlama_, bir programı oluşturma eylemidir - bir bilgisayara ne yapması gerektiğini söyleyen kesin talimatlar kümesi. Çünkü bilgisayarlar aptal, pedantik yaratıklardır, programlama temelde sıkıcı ve sinir bozucudur. {{index [programming, "joy of"], speed}} -Fortunately, if you can get over that fact—and maybe even enjoy the rigor of thinking in terms that dumb machines can deal with—programming can be rewarding. It allows you to do things in seconds that would take _forever_ by hand. It is a way to make your computer tool do things that it couldn't do before. On top of that, it makes for a wonderful game of puzzle solving and abstract thinking. +Neyse ki, eğer bu gerçeği aşabilir ve hatta aptal makinelerin anlayabileceği terimlerle düşünmenin titizliğinden zevk alırsanız, programlama ödüllendirici olabilir. Size _saatler_ sürecek şeyleri anında yapma olanağı sağlar. Bilgisayar aracınızın önce yapamadığı şeyleri yapmasını sağlar. Ve soyut düşünme için harika bir egzersiz sunar. -Most programming is done with ((programming language))s. A _programming language_ is an artificially constructed language used to instruct computers. It is interesting that the most effective way we've found to communicate with a computer borrows so heavily from the way we communicate with each other. Like human languages, computer languages allow words and phrases to be combined in new ways, making it possible to express ever new concepts. +Çoğu programlama, programlama dilleri ile yapılır. Bir _programlama dili_, bilgisayarlara talimat vermek için kullanılan yapay bir dil. Bir bilgisayarla iletişim kurmanın en etkili yolunun, birbirimizle iletişim kurma şeklimizden ağır şekilde ödünç alınması ilginçtir. İnsan dilleri gibi, bilgisayar dilleri de kelimelerin ve ifadelerin yeni yollarla birleştirilmesine izin verir, böylece her zaman yeni kavramları ifade etmek mümkün olur. {{index [JavaScript, "availability of"], "casual computing"}} -At one point, language-based interfaces, such as the BASIC and DOS prompts of the 1980s and 1990s, were the main method of interacting with computers. For routine computer use, these have largely been replaced with visual interfaces, which are easier to learn but offer less freedom. But if you know where to look, the languages are still there. One of them, _JavaScript_, is built into every modern web ((browser))—and is thus available on almost every device. +Bir zamanlar BASIC ve DOS gibi dil tabanlı arayüzler, 1980'lerin ve 1990'ların ana bilgisayarlarla etkileşim yöntemiydi. Daha rutin bilgisayar kullanımı için bunlar genel olarak kullanımı öğrenmesi kolay olan ancak özgürlüğünüzü sınırlandıran görsel arayüzlerle değiştirildi. Ancak bilgisayar dilleri hala orada, tabii nereye bakacağınızı bilirseniz. O dillerden bir tanesi olan JavaScript, her modern web tarayıcısına yerleştirilmiştir ve böylece neredeyse her cihazda bulunur. {{indexsee "web browser", browser}} -This book will try to make you familiar enough with this language to do useful and amusing things with it. +Bu kitap, bu dili yararlı ve eğlenceli şeyler yapmak için yeterince tanımanıza yardımcı olmaya çalışacaktır. -## On programming +## Programlama hakkında {{index [programming, "difficulty of"]}} -Besides explaining JavaScript, I will introduce the basic principles of programming. Programming, it turns out, is hard. The fundamental rules are simple and clear, but programs built on top of these rules tend to become complex enough to introduce their own rules and complexity. You're building your own maze, in a way, and you can easily get lost in it. +JavaScript'i açıklamanın yanı sıra, programlamanın temel prensiplerini de tanıtacağım. Programlama, anlaşıldığı kadarıyla zor bir iştir. Temel kurallar basit ve net olsa da, bu kuralların üzerine inşa edilen programlar kendi kurallarını ve karmaşıklıklarını tanıtmaya yeterince karmaşık hale gelir. Bir bakıma kendi labirentinizi oluşturuyorsunuz ve bundan ötürü içinde kolayca kaybolabilirsiniz. {{index learning}} -There will be times when reading this book feels terribly frustrating. If you are new to programming, there will be a lot of new material to digest. Much of this material will then be _combined_ in ways that require you to make additional connections. +Bu kitabı okurken bazen son derece sinir bozucu hissedeceğiniz zamanlar olacak. Eğer programlamaya yeni başlayan biriyseniz, sindirmeniz gereken çok yeni malzeme olacak. Bu materyalin büyük bir kısmı daha sonra ek bağlantılar kurmanızı gerektiren şekillerde _birleştirilecek_. -It is up to you to make the necessary effort. When you are struggling to follow the book, do not jump to any conclusions about your own capabilities. You are fine—you just need to keep at it. Take a break, reread some material, and make sure you read and understand the example programs and ((exercises)). Learning is hard work, but everything you learn is yours and will make further learning easier. +Gereken çabayı göstermek size bağlıdır. Kitabı takip etmekte zorlandığınızda, kendi yeteneklerinizle ilgili herhangi bir sonuca varmayın. Sorun yok, sadece devam etmeniz gerekiyor. Ara verin, bazı materyalleri tekrar okuyun, örnek programları ve ((alıştırmaları)) okuyup anladığınızdan emin olun. Öğrenmek zor bir iş olabilir, ancak öğrendiğiniz her şey sizindir ve daha sonraki öğrenmeyi kolaylaştıracaktır. {{quote {author: "Ursula K. Le Guin", title: "The Left Hand of Darkness"} {{index "Le Guin, Ursula K."}} -When action grows unprofitable, gather information; when information grows unprofitable, sleep. +Eylem faydasız hale geldiğinde, bilgi toplayın; bilgi faydasız hale geldiğinde, uyuyun. quote}} {{index [program, "nature of"], data}} -A program is many things. It is a piece of text typed by a programmer, it is the directing force that makes the computer do what it does, it is data in the computer's memory, and at the same time it controls the actions performed on this memory. Analogies that try to compare programs to familiar objects tend to fall short. A superficially fitting one is to compare a program to a machine—lots of separate parts tend to be involved, and to make the whole thing tick, we have to consider the ways in which these parts interconnect and contribute to the operation of the whole. +Bir program birçok şeydir. Bir programcı tarafından yazılan bir metindir, bilgisayarın yaptığı işi yapan yönlendirici güçtür, bilgisayarın belleğindeki veridir ve aynı zamanda bu bellekte gerçekleştirilen eylemleri kontrol eder. Programları tanıdık nesnelerle karşılaştırmaya çalışan benzetmeler genellikle eksik kalır. Yüzeysel olarak uygun olanlardan biri, bir programı bir makineye benzetmektir - genellikle birçok ayrı parça içerir ve tümünün çalışmasını sağlamak için bu parçaların nasıl birbirine bağlandığını ve tümünün işleyişine nasıl katkıda bulunduğunu düşünmemiz gerekir. -A ((computer)) is a physical machine that acts as a host for these immaterial machines. Computers themselves can do only stupidly straightforward things. The reason they are so useful is that they do these things at an incredibly high ((speed)). A program can ingeniously combine an enormous number of these simple actions to do very complicated things. +Bir bilgisayar, bu soyut makinelerin barındırıcısı olarak işlev gören fiziksel bir makinadır. Bilgisayarlar kendileri sadece aptalca basit şeyler yapabilir. Onların bu kadar faydalı olmasının nedeni, bu işleri inanılmaz derecede yüksek bir hızda yapmalarıdır. Bir program, çok karmaşık şeyler yapmak için birçok bu tür basit eylemi ustaca birleştirebilir. {{index [programming, "joy of"]}} -A program is a building of thought. It is costless to build, it is weightless, and it grows easily under our typing hands. But as a program grows, so does its ((complexity)). The skill of programming is the skill of building programs that don't confuse yourself. The best programs are those that manage to do something interesting while still being easy to understand. +Bir program bir düşünce binasıdır. İnşa etmek bedelsizdir, ağırlıksızdır ve yazarak ellerimizin altında kolayca büyür. Ancak bir program büyüdükçe, karmaşıklığı da artar. Programlamanın becerisi, kendinizi kafanızı karıştırmayan programlar oluşturma becerisidir. En iyi programlar, anlaşılması kolay olmasına rağmen ilginç bir şey yapmayı başaranlardır. {{index "programming style", "best practices"}} Some programmers believe that this complexity is best managed by using only a small set of well-understood techniques in their programs. They have composed strict rules ("best practices") prescribing the form programs should have and carefully stay within their safe little zone. +Bazı programcılar, bu karmaşıklığın programlarında yalnızca iyi anlaşılan birkaç teknik kullanılarak en iyi şekilde yönetildiğine inanırlar. Programların hangi formda olması ve küçük güvenli alanlarında dikkatlice kalmaları gerektiğini düşündükleri katı kurallar ("en iyi pratikler") oluşturdular. {{index experiment}} -This is not only boring, it is ineffective. New problems often require new solutions. The field of programming is young and still developing rapidly, and it is varied enough to have room for wildly different approaches. There are many terrible mistakes to make in program design, and you should go ahead and make them at least once so that you understand them. A sense of what a good program looks like is developed with practice, not learned from a list of rules. +Bu sadece sıkıcı değil, etkisizdir de. Yeni sorunlar genellikle yeni çözümler gerektirir. Programlama alanı genç ve hala hızla gelişmekte olup, oldukça farklı yaklaşımlar için yer bulacak kadar çeşitlidir. Program tasarımında yapılacak pek çok korkunç hata vardır ve onları anlamanız için en azından bir kez yapmalısınız. İyi bir programın nasıl göründüğüne dair bir anlayış, pratikle geliştirilir, kurallar listesinden öğrenilmez. -## Why language matters +## Dil neden önemlidir {{index "programming language", "machine code", "binary data"}} -In the beginning, at the birth of computing, there were no programming languages. Programs looked something like this: +Başta, bilgisayarların doğuşunda herhangi bir programlama dili yoktu. Programlar şu şekilde gözüküyordu: ```{lang: null} 00110001 00000000 00000000 @@ -88,49 +89,49 @@ In the beginning, at the birth of computing, there were no programming languages {{index [programming, "history of"], "punch card", complexity}} -This is a program to add the numbers from 1 to 10 together and print the result: `1 + 2 + ... + 10 = 55`. It could run on a simple hypothetical machine. To program early computers, it was necessary to set large arrays of switches in the right position or punch holes in strips of cardboard and feed them to the computer. You can imagine how tedious and error-prone this procedure was. Even writing simple programs required much cleverness and discipline. Complex ones were nearly inconceivable. +Bu, sayıları 1'den 10'a kadar toplayıp sonucu yazdıran bir programdır: 1 + 2 + ... + 10 = 55. Basit bir varsayımsal makinede çalışabilirdi. Erken bilgisayarları programlamak için, büyük anahtar dizilerini doğru konuma ayarlamak veya karton şeritlere delikler açmak ve bunları bilgisayara beslemek gerekiyordu. Bu prosedürün ne kadar sıkıcı ve hata yapmaya açık olduğunu hayal edebilirsiniz. Basit programları yazmak bile çok zeka ve disiplin gerektirirdi. Karmaşık olanlar neredeyse hayal edilemezdi. {{index bit, "wizard (mighty)"}} -Of course, manually entering these arcane patterns of bits (the ones and zeros) did give the programmer a profound sense of being a mighty wizard. And that has to be worth something in terms of job satisfaction. +Tabii ki, bu gizemli desenlerin (birler ve sıfırlar) el ile girilmesi, programcıya güçlü bir büyücü hissi veriyordu. Ve bu, iş tatmini açısından bir şeylere değer olmalı. {{index memory, instruction}} -Each line of the previous program contains a single instruction. It could be written in English like this: +Önceki programın her satırı yalnızca bir talimat içerir. Bu İngilizce olarak şöyle yazılabilir: - 1. Store the number 0 in memory location 0. - 2. Store the number 1 in memory location 1. - 3. Store the value of memory location 1 in memory location 2. - 4. Subtract the number 11 from the value in memory location 2. - 5. If the value in memory location 2 is the number 0, continue with instruction 9. - 6. Add the value of memory location 1 to memory location 0. - 7. Add the number 1 to the value of memory location 1. - 8. Continue with instruction 3. - 9. Output the value of memory location 0. +1. Bellek konumu 0'da 0 sayısını saklayın. +2. Bellek konumu 1'de 1 sayısını saklayın. +3. Bellek konumu 1'in değerini bellek konumu 2'ye saklayın. +4. Bellek konumu 2'deki değerden 11'i çıkarın. +5. Bellek konumu 2'deki değer 0 ise, talimat 9 ile devam edin. +6. Bellek konumu 0'ın değerine bellek konumu 1'in değerini ekleyin. +7. Bellek konumu 1'in değerine 1 sayısını ekleyin. +8. Talimat 3 ile devam edin. +9. Bellek konumu 0'ın değerini sonuç olarak çıkarın. {{index readability, naming, binding}} -Although that is already more readable than the soup of bits, it is still rather obscure. Using names instead of numbers for the instructions and memory locations helps: +Bu, artık bitlerin karışımından daha okunabilir olsa da, hala oldukça belirsizdir. Talimatlar ve bellek konumları için sayılar yerine isimler kullanmak çok daha yardımcı olur. ```{lang: "null"} - Set “total” to 0. - Set “count” to 1. -[loop] - Set “compare” to “count”. - Subtract 11 from “compare”. - If “compare” is zero, continue at [end]. - Add “count” to “total”. - Add 1 to “count”. - Continue at [loop]. + “total” değerini 0 yap. + “count” değerini 1 yap. +[while] + “compare” değerini “count” değerine ata. + “compare” değerinden 11 çıkar. + Eğer “compare” sıfırsa şuradan devam et: [end]. + “count” değerini “total” değerine ekle. + “count” değerine 1 ekle. + Şuradan devam et: [loop]. [end] - Output “total”. + Sonuç “total”. ``` {{index loop, jump, "summing example"}} -Can you see how the program works at this point? The first two lines give two memory locations their starting values: `total` will be used to build up the result of the computation, and `count` will keep track of the number that we are currently looking at. The lines using `compare` are probably the most confusing ones. The program wants to see whether `count` is equal to 11 to decide whether it can stop running. Because our hypothetical machine is rather primitive, it can only test whether a number is zero and make a decision based on that. It therefore uses the memory location labeled `compare` to compute the value of `count - 11` and makes a decision based on that value. The next two lines add the value of `count` to the result and increment `count` by 1 every time the program decides that `count` is not 11 yet. +Artık programın nasıl çalıştığını görebiliyor musunuz? İlk iki satır, iki bellek konumuna başlangıç değerlerini verir: `total`, hesaplamanın sonucunu oluşturmak için kullanılacak ve `count`, şu anda baktığımız sayıyı takip edecek. `compare` değerini kullanan satırlar muhtemelen en karışık olanlardır. Program, çalışmayı durdurup durduramayacağını belirlemek için `count` değerinin 11'e eşit olup olmadığını görmek istiyor. Varsayımsal makinemiz oldukça ilkel olduğundan, yalnızca bir sayının sıfır olup olmadığını test edebip buna dayanarak bir karar verebiliyor. Bu nedenle, `compare` olarak etiketlenmiş bellek konumunu kullanarak `count - 11` değerini hesaplar ve bu değere dayanarak bir karar verir. Bir sonraki iki satır, `count` değerini `total` değerine ekler ve `count` değerninin 11 olmadığına karar verdiğinde `count` değerini bir artırır. -Here is the same program in JavaScript: +Aynı programın JavaScript'teki hali: ``` let total = 0, count = 1; @@ -144,15 +145,16 @@ console.log(total); {{index "while loop", loop, [braces, block]}} -This version gives us a few more improvements. Most importantly, there is no need to specify the way we want the program to jump back and forth anymore—the `while` construct takes care of that. It continues executing the block (wrapped in braces) below it as long as the condition it was given holds. That condition is `count <= 10`, which means “the count is less than or equal to 10”. We no longer have to create a temporary value and compare that to zero, which was just an uninteresting detail. Part of the power of programming languages is that they can take care of uninteresting details for us. +Bu versiyon bize birkaç iyileştirme sağlar. En önemlisi, artık programa ileri geri nasıl atlamak istediğimizi belirtmemize gerek yoktur - `while` yapısı bununla ilgilenir. Verilen koşul geçerli olduğu sürece, onun altında (süslü parantezlerle sarılı) bloğu devam ettirir. Bu koşul `sayac <= 10`dur, yani "sayım 10'a eşit veya daha azdır" anlamına gelir. Artık geçici bir değer oluşturup bunu sıfır ile karşılaştırmamıza gerek yoktur, bu sadece ilgisiz bir ayrıntıydı. Programlama dillerinin gücünün bir kısmıysa bizim için o tür ilgisiz ayrıntıları ele alabilmeleridir. {{index "console.log"}} -At the end of the program, after the `while` construct has finished, the `console.log` operation is used to write out the result. +Programın sonunda, `while` yapısı bitirdikten sonra, sonucu yazmak için `console.log` işlemi kullanılır. {{index "sum function", "range function", abstraction, function}} Finally, here is what the program could look like if we happened to have the convenient operations `range` and `sum` available, which respectively create a ((collection)) of numbers within a range and compute the sum of a collection of numbers: +Son olarak, `range` ve `sum` adlı belirli değerler arasında sayılar koleksiyonu oluşturup onların toplamını bulan kullanışlı fonksiyonlarımızın mevcut olduğu bir durumda programımızın nasıl görünebileceğine dair: ```{startCode: true} console.log(sum(range(1, 10))); @@ -161,13 +163,13 @@ console.log(sum(range(1, 10))); {{index readability}} -The moral of this story is that the same program can be expressed in both long and short, unreadable and readable ways. The first version of the program was extremely obscure, whereas this last one is almost English: `log` the `sum` of the `range` of numbers from 1 to 10. (We will see in [later chapters](data) how to define operations like `sum` and `range`.) +Bu hikayenin özü, aynı programın uzun ve kısa, okunaksız ve okunabilir yollarla ifade edilebileceğidir. Programın ilk versiyonu son derece belirsizken, bu son versiyon neredeyse İngilizce gibidir: 1'den 10'a kadar olan sayıların aralığının(`range(10)`) toplamını(`sum`) konsolda görüntüleyin(`console.log`). (Sonraki bölümlerde toplam ve aralık gibi işlemleri nasıl tanımlayacağımızı göreceğiz.) {{index ["programming language", "power of"], composability}} -A good programming language helps the programmer by allowing them to talk about the actions that the computer has to perform on a higher level. It helps omit details, provides convenient building blocks (such as `while` and `console.log`), allows you to define your own building blocks (such as `sum` and `range`), and makes those blocks easy to compose. +İyi bir programlama dili, programcının daha yüksek bir seviyede bilgisayarın gerçekleştirmesi gereken eylemler hakkında konuşmasına izin vererek ona yardımcı olur. Detayları atlamasına yardımcı olur, uygun yapı taşları sağlar (`while` ve `console.log` gibi), kendi yapı taşlarınızı tanımlamanıza izin verir (`sum` ve `range` gibi) ve bu blokları kolayca birleştirmenizi sağlar. -## What is JavaScript? +## JavaScript nedir? {{index history, Netscape, browser, "web application", JavaScript, [JavaScript, "history of"], "World Wide Web"}} @@ -175,47 +177,48 @@ A good programming language helps the programmer by allowing them to talk about {{indexsee Web, "World Wide Web"}} -JavaScript was introduced in 1995 as a way to add programs to web pages in the Netscape Navigator browser. The language has since been adopted by all other major graphical web browsers. It has made modern web applications possible—that is, applications with which you can interact directly without doing a page reload for every action. JavaScript is also used in more traditional websites to provide various forms of interactivity and cleverness. +JavaScript is also used in more traditional websites to provide various forms of interactivity and cleverness. +JavaScript, 1995 yılında Netscape Navigator tarayıcısına websitelere interaktif programlar oluşturmanın bir yolu olarak eklendi. O zamandan beri, dil diğer tüm önemli grafiksel web tarayıcıları tarafından benimsendi. JavaScript, bugünkü her eylem için sayfanın yeniden yüklenmesine gerek kalmadan doğrudan etkileşimde bulunabileceğiniz modern web uygulamalarını mümkün kıldı, ayrıca daha geleneksel web sitelerinde de çeşitli etkileşim sağlamak için kullanıldı. {{index Java, naming}} -It is important to note that JavaScript has almost nothing to do with the programming language named Java. The similar name was inspired by marketing considerations rather than good judgment. When JavaScript was being introduced, the Java language was being heavily marketed and was gaining popularity. Someone thought it was a good idea to try to ride along on this success. Now we are stuck with the name. +JavaScript'in Java adındaki programlama diliyle neredeyse hiçbir ilgisi olmadığını belirtmek önemlidir. Benzer ad, iyi bir değerlendirme yerine pazarlama düşüncelerinden esinlenmiştir. JavaScript tanıtıldığında, Java dili yoğun bir şekilde pazarlanıyor ve popülerlik kazanıyordu. Birisi bu başarıya eşlik etmeyi denemek için iyi bir fikir olduğunu düşündü. Şimdi ise isimle sıkışıp kaldık. {{index ECMAScript, compatibility}} -After its adoption outside of Netscape, a ((standard)) document was written to describe the way the JavaScript language should work so that the various pieces of software that claimed to support JavaScript could make sure they actually provided the same language. This is called the ECMAScript standard, after the Ecma International organization that conducted the standardization. In practice, the terms ECMAScript and JavaScript can be used interchangeably—they are two names for the same language. +Netscape dışında benimsenmesinin ardından, JavaScript dilini desteklendiğini iddia eden çeşitli yazılımların aslında aynı dili desteklediklerini garanti edebilemek adına bir standart belgesi yazıldı. Bu, standardizasyonu gerçekleştiren Ecma International organizasyonunun adından ECMAScript standardı olarak adlandırıldı. Uygulamada, ECMAScript ve JavaScript terimleri değiştirilebilir şekilde kullanılabilir— bu iki isim aynı programlama diline hitap etmektedir. {{index [JavaScript, "weaknesses of"], debugging}} -There are those who will say _terrible_ things about JavaScript. Many of these things are true. When I was required to write something in JavaScript for the first time, I quickly came to despise it. It would accept almost anything I typed but interpret it in a way that was completely different from what I meant. This had a lot to do with the fact that I did not have a clue what I was doing, of course, but there is a real issue here: JavaScript is ridiculously liberal in what it allows. The idea behind this design was that it would make programming in JavaScript easier for beginners. In actuality, it mostly makes finding problems in your programs harder because the system will not point them out to you. +JavaScript hakkında _korkunç_ şeyler söyleyenler vardır ve söylenen bu şeylerin pek çoğu doğrudur. İlk kez JavaScript'te bir şeyler yazmam gerektiğinde, ondan nefret etmeye hızlıca başladım çünkü JavaScript neredeyse yazdığım her şeyi kabul eder, ancak yazdıkalrımı hep istediğimden başka bir şekilde yorumlardı. Bu durum, tabii ki ne yaptığımı bilmediğim gerçeğiyle çok ilgiliydi, ancak burada gerçek bir sorun var: JavaScript, maalesef izin verdiği şeylerde son derece cömerttir. Bu tasarımın arkasındaki fikir, JavaScript'te programlamanın yeni başlayanlar için daha kolay olmasını sağlamaktı ama aslında bu, programlarınızdaki sorunları bulmayı çoğunlukla daha zor hale getirir çünkü sistem size bunları işaret etmez. {{index [JavaScript, "flexibility of"], flexibility}} -This flexibility also has its advantages, though. It leaves room for techniques that are impossible in more rigid languages and makes for a pleasant, informal style of programming. After ((learning)) the language properly and working with it for a while, I have come to actually _like_ JavaScript. +Ancak bu esnekliğin avantajları da vardır. Daha katı dillerde mümkün olmayan tekniklere olanak tanır ve hoş, gayri resmi bir programlama tarzı sunar. Dilin düzgün bir şekilde öğrendikten ve bir süre kendisiyle çalıştıktan sonra JavaScript'i aslında _sevmeye_ başladım. {{index future, [JavaScript, "versions of"], ECMAScript, "ECMAScript 6"}} -There have been several versions of JavaScript. ECMAScript version 3 was the widely supported version during JavaScript's ascent to dominance, roughly between 2000 and 2010. During this time, work was underway on an ambitious version 4, which planned a number of radical improvements and extensions to the language. Changing a living, widely used language in such a radical way turned out to be politically difficult, and work on the version 4 was abandoned in 2008. A much less ambitious version 5, which made only some uncontroversial improvements, came out in 2009. In 2015, version 6 came out, a major update that included some of the ideas planned for version 4. Since then we've had new, small updates every year. +JavaScript'in birkaç versiyonu olmuştur. ECMAScript sürüm 3, yaklaşık olarak 2000 ile 2010 arasında JavaScript'in hakimiyetinin arttığı dönemde yaygın olarak desteklenen sürümdü. Bu dönemde, dili radikal bir şekilde iyileştirmeyi ve genişletmeyi planlayan cesur bir sürüm 4 üzerinde çalışmalar devam ediyordu. Ancak, geniş kullanılan bir dilin bu kadar radikal bir şekilde değiştirilmesi politik olarak zorlu çıktı ve sürüm 4 üzerindeki çalışmalar 2008'de terkedildi. Yalnızca bazı tartışmasız iyileştirmeler getiren çok daha iddiasız bir sürüm olan 5. sürüm, 2009'da piyasaya çıktı. 2015'te, sürüm 6, sürüm 4 için planlanan bazı fikirleri içeren önemli bir güncelleme olarak yayınlandı. O zamandan beri her yıl yeni, küçük güncellemeler yapılmaktadır. -The fact that JavaScript is evolving means that browsers have to constantly keep up. If you're using an older browser, it may not support every feature. The language designers are careful to not make any changes that could break existing programs, so new browsers can still run old programs. In this book, I'm using the 2023 version of JavaScript. +JavaScript'in gelişmekte olması, tarayıcıların sürekli olarak ayak uydurması gerektiği anlamına gelir. Eski bir tarayıcı kullanıyorsanız, JavaScript'in her özelliğini desteklemeyebilir. Dil tasarımcıları, mevcut programları bozabilecek herhangi bir değişiklik yapmamaya dikkat eder, bu nedenle yeni tarayıcılar hala eski programları çalıştırabilir. Bu kitapta, 2023 sürümünü kullanıyorum. {{index [JavaScript, "uses of"]}} -Web browsers are not the only platforms on which JavaScript is used. Some databases, such as MongoDB and CouchDB, use JavaScript as their scripting and query language. Several platforms for desktop and server programming, most notably the ((Node.js)) project (the subject of [Chapter ?](node)), provide an environment for programming JavaScript outside of the browser. +Web tarayıcıları, JavaScript'in kullanıldığı tek platformlar değildir. MongoDB ve CouchDB gibi bazı veritabanları JavaScript'i scripting ve sorgu dili olarak kullanır. Masaüstü ve sunucu programlama için birçok platform, özellikle Node.js projesi tarayıcı dışında JavaScript kullanabilmek için bir ortam sağlar. -## Code, and what to do with it +## Kod ve onunla ne yapılacağı {{index "reading code", "writing code"}} -_Code_ is the text that makes up programs. Most chapters in this book contain quite a lot of code. I believe reading code and writing ((code)) are indispensable parts of ((learning)) to program. Try to not just glance over the examples—read them attentively and understand them. This may be slow and confusing at first, but I promise that you'll quickly get the hang of it. The same goes for the ((exercises)). Don't assume you understand them until you've actually written a working solution. +_Kod_, programları oluşturan metindir. Bu kitaptaki çoğu bölüm oldukça fazla kod içerir. Kod okumak ve kod yazmak, programlamayı öğrenmenin vazgeçilmez parçaları olduğuna inanıyorum. Örnekleri sadece gözden geçirmeyin ve onları dikkatlice okuyup anlamaya çalışın. Başlangıçta bu yavaş ve kafa karıştırıcı olabilir, ancak hızlıca alışacaksınıza söz veriyorum. Aynı şey ((alıştırmalar)) için de geçerlidir, lütfen bir çalışan çözüm yazmadan önce onları anladığınızı varsaymayın. {{index interpretation}} -I recommend you try your solutions to exercises in an actual JavaScript interpreter. That way, you'll get immediate feedback on whether what you are doing is working, and, I hope, you'll be tempted to ((experiment)) and go beyond the exercises. +Çözümlerinizi gerçek bir JavaScript yorumlayıcısında denemenizi öneririm. Böylece, yaptıklarınızın çalışıp çalışmadığı konusunda hemen geri bildirim alırsınız ve umarım, ((deney yapmaya)) ve alıştırmaların ötesine geçmeye teşvik edilirsiniz. {{if interactive -When reading this book in your browser, you can edit (and run) all example programs by clicking them. +Bu kitabı tarayıcınızda okurken, tüm örnek programları düzenleyip çalıştırabilir ve üzerlerine tıklayarak çalıştırabilirsiniz. if}} @@ -223,37 +226,37 @@ if}} {{index download, sandbox, "running code"}} -The easiest way to run the example code in the book—and to experiment with it—is to look it up in the online version of the book at [_https://eloquentjavascript.net_](https://eloquentjavascript.net/). There, you can click any code example to edit and run it and to see the output it produces. To work on the exercises, go to [_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code), which provides starting code for each coding exercise and allows you to look at the solutions. +Kitaptaki örnek kodları çalıştırmanın ve bunlarla deney yapmanın en kolay yolu, kitabın çevrimiçi sürümünü [_https://eloquentjavascript.net_](https://eloquentjavascript.net/) adresinden bulmaktır. Orada, herhangi bir kod örneğine tıklayarak onu düzenleyebilir, çalıştırabilir ve ürettiği çıktıyı görebilirsiniz. Alıştırmalar üzerinde çalışmak için, [_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code) adresine gidin, bu adres her programlama alıştırması için başlangıç kodu sağlar ve çözümleri görebilmenize olanak tanır. if}} {{index "developer tools", "JavaScript console"}} -Running the programs defined in this book outside of the book's website requires some care. Many examples stand on their own and should work in any JavaScript environment. But code in later chapters is often written for a specific environment (the browser or Node.js) and can run only there. In addition, many chapters define bigger programs, and the pieces of code that appear in them depend on each other or on external files. The [sandbox](https://eloquentjavascript.net/code) on the website provides links to ZIP files containing all the scripts and data files necessary to run the code for a given chapter. +Bu kitapta tanımlanan programları kitabın web sitesinin dışında çalıştırmak biraz dikkat gerektirir. Birçok örnek kendi başına durur ve herhangi bir JavaScript ortamında normal çalışabilmelidir. Ancak, daha sonraki bölümlerdeki kodlar genellikle belirli bir ortam için yazılmıştır (tarayıcı veya Node.js) ve yalnızca orada çalışabilir. Ayrıca, birçok bölüm daha büyük programlar tanımlar ve onlarda görünen kod parçaları birbirlerine veya dış dosyalara bağlıdır. Web sitesindeki [dijital kum havuzu](https://eloquentjavascript.net/code), belirli bir bölüm için kodu çalıştırmak için gerekli tüm betikleri ve veri dosyalarını içeren ZIP dosyalarına bağlantılar sağlar. -## Overview of this book +## Kitaba genel bakış -This book contains roughly three parts. The first 12 chapters discuss the JavaScript language. The next seven chapters are about web ((browsers)) and the way JavaScript is used to program them. Finally, two chapters are devoted to ((Node.js)), another environment to program JavaScript in. There are five _project chapters_ in the book that describe larger example programs to give you a taste of actual programming. +Bu kitap yaklaşık üç bölüm içerir. İlk 12 bölüm JavaScript dilini tartışır. Sonraki yedi bölüm web ((tarayıcıları)) ve JavaScript'in onları programlamak için kullanımı hakkındadır. Son olarak, iki bölüm, JavaScript programlamak için başka bir ortam olan ((Node.js))'e adanmıştır. Kitapta, gerçek programlamaya bir tat vermek için daha büyük örnek programları açıklayan beş _proje bölümü_ bulunmaktadır. -The language part of the book starts with four chapters that introduce the basic structure of the JavaScript language. They discuss [control structures](program_structure) (such as the `while` word you saw in this introduction), [functions](functions) (writing your own building blocks), and [data structures](data). After these, you will be able to write basic programs. Next, Chapters [?](higher_order) and [?](object) introduce techniques to use functions and objects to write more _abstract_ code and keep complexity under control. +Kitabın dil kısmı, JavaScript dilinin temel yapısını tanıtan dört bölümle başlar. Bunlar [kontrol yapıları](program_structure) (bu girişte gördüğünüz while kelimesi gibi), [fonksiyonlar](functions) (kendi yapı taşlarınızı yazma), ve veri [yapıları'nı](data) tartışır. Bunlardan sonra, temel programlar yazabilir duruma geleceksiniz. Ardından, [?](higher_order) ve [?](object) numaralı bölümler, daha _soyut_ kod yazmak ve karmaşıklığı kontrol altında tutmak için fonksiyonlar ve nesneleri kullanma tekniklerini tanıtır. -After a [first project chapter](robot) that builds a crude delivery robot, the language part of the book continues with chapters on [error handling and bug fixing](error), [regular expressions](regexp) (an important tool for working with text), [modularity](modules) (another defense against complexity), and [asynchronous programming](async) (dealing with events that take time). The [second project chapter](language), where we implement a programming language, concludes the first part of the book. +[İlk bir proje bölümü](robot) olan robot adlı bölümün ardından, kitabın dil kısmı, [hata işleme ve hata düzeltme](error), [düzenli ifadeler](regexp) (metinle çalışmak için önemli bir araç), [modülerlik](modules) (karmaşıklığa karşı bir diğer savunma) ve [asenkron programlama](async) (zaman alan olaylarla başa çıkma) üzerine bölümlerle devam eder. Bir programlama dilini uyguladığımız [ikinci proje bölümü](language), kitabın ilk bölümünü tamamlar. -The second part of the book, Chapters [?](browser) to [?](paint), describes the tools that browser JavaScript has access to. You'll learn to display things on the screen (Chapters [?](dom) and [?](canvas)), respond to user input ([Chapter ?](event)), and communicate over the network ([Chapter ?](http)). There are again two project chapters in this part, building a [platform game](game) and a [pixel paint program](paint). +Kitabın ikinci bölümü, [?](browser) ile [?](paint) arasındaki bölümler, tarayıcı içindeki JavaScript'in erişebileceği araçları tanımlar. Ekran üzerinde şeyler görüntülemeyi ([?](dom) ve [?](canvas) numaralı bölümler), kullanıcı girişlerine yanıt vermeyi ([?](event) numaralı bölüm), ve ağ üzerinden iletişim kurmayı ([?](http) numaralı bölüm) öğreneceksiniz. Bu bölümde yine iki proje bölümü bulunmaktadır, biri [platform oyunu](game) ve diğeri [piksel boya programı](paint) oluşturur. -[Chapter ?](node) describes Node.js, and [Chapter ?](skillsharing) builds a small website using that tool. +[?](node) numaralı bölüm Node.js'yi tanımlarken, [?](skillsharing) numaralı bölüm bu aracı kullanarak küçük bir web sitesi oluşturur. {{if commercial -Finally, [Chapter ?](fast) describes some of the considerations that come up when optimizing JavaScript programs for speed. +Son olarak, [?](fast) numaralı bölüm, JavaScript programlarını hız için optimize etmesi adına dikkate alınması gereken bazı hususlar hakkında bilgi verir. if}} -## Typographic conventions +## Tipografik kurallar {{index "factorial function"}} -In this book, text written in a `monospaced` font will represent elements of programs. Sometimes these are self-sufficient fragments, and sometimes they just refer to part of a nearby program. Programs (of which you have already seen a few) are written as follows: +Bu kitapta, `monospace` fontuyla yazılmış metinler program öğelerini temsil edecektir. Bazı durumlarda bunlar kendi başına yeterli parçalar olabilir, bazen ise yalnızca yanındaki bir programın bir parçasına atıfta bulunabilirler. Programlar (birkaçını zaten gördünüz) şu şekilde yazılır: ``` function factorial(n) { @@ -267,11 +270,11 @@ function factorial(n) { {{index "console.log"}} -Sometimes, to show the output that a program produces, the expected output is written after it, with two slashes and an arrow in front. +Bazen, bir programın ürettiği çıktıyı göstermek için, beklenen çıktı programın sonrasına, iki eğik çizgi ve bir ok ile yazılır. ``` console.log(factorial(8)); // → 40320 ``` -Good luck! +İyi şanslar! diff --git a/01_values.md b/01_values.md index 843a47e0..63b6acde 100644 --- a/01_values.md +++ b/01_values.md @@ -1,10 +1,10 @@ {{meta {docid: values}}} -# Values, Types, and Operators +# Değerler, Tipler ve Operatörler {{quote {author: "Master Yuan-Ma", title: "The Book of Programming", chapter: true} -Below the surface of the machine, the program moves. Without effort, it expands and contracts. In great harmony, electrons scatter and regroup. The forms on the monitor are but ripples on the water. The essence stays invisibly below. +Makinenin yüzeyinin altında, program hareket eder. Çaba sarf etmeden genişler ve daralır. Büyük bir uyum içinde, elektronlar dağılır ve yeniden gruplanır. Monitördeki formlar sadece suyun üstünde dalgalar gibiyken öz ise görünmez bir şekilde altta kalır. quote}} @@ -14,42 +14,42 @@ quote}} {{index "binary data", data, bit, memory}} -In the computer's world, there is only data. You can read data, modify data, create new data—but that which isn't data cannot be mentioned. All this data is stored as long sequences of bits and is thus fundamentally alike. +Bilgisayarın dünyasında, sadece veri vardır. Veriyi okuyabilir, değiştirebilir, yeni veri oluşturabilirsiniz - ancak veri olmayan şeylerden bahsedilemez. Tüm bu veriler, sıfır ve birlerden oluşan bitlerin bir araya geldiği uzun diziler olarak depolanır ve bu nedenle temel olarak birbirlerine benzerler. {{index CD, signal}} -_Bits_ are any kind of two-valued things, usually described as zeros and ones. Inside the computer, they take forms such as a high or low electrical charge, a strong or weak signal, or a shiny or dull spot on the surface of a CD. Any piece of discrete information can be reduced to a sequence of zeros and ones and thus represented in bits. +_Bitler_, genellikle sıfırlar ve birler olarak tanımlanan her türlü iki değerli şeydir. Bilgisayarın içinde, yüksek veya düşük bir elektrik yükü, güçlü veya zayıf bir sinyal veya bir CD'nin yüzeyinde parlak veya mat bir leke gibi şekiller alırlar. Herhangi bir soyut bilgi parçası, sıfırların ve birlerin bir dizisine indirgenebilir ve bu şekilde bitlerle temsil edilebilir. -{{index "binary number", radix, "decimal number"}} +{{index "binary number", "decimal number"}} -For example, we can express the number 13 in bits. This works the same way as a decimal number, but instead of 10 different ((digit))s, we have only 2, and the weight of each increases by a factor of 2 from right to left. Here are the bits that make up the number 13, with the weights of the digits shown below them: +Örneğin, sayı 13'ü bitlerle ifade edebiliriz. Bu, ondalık bir sayıyla aynı çalışır, ancak 10 farklı ((rakam)) yerine yalnızca 2 tane vardır ve her birinin ağırlığı sağdan sola doğru bir faktörle artar. İşte 13'ü oluşturan bitler ve rakamların ağırlıkları aşağıda gösterilmiştir: ```{lang: null} 0 0 0 0 1 1 0 1 128 64 32 16 8 4 2 1 ``` -That's the binary number 00001101. Its non-zero digits stand for 8, 4, and 1, and add up to 13. +Bu, ikili sayı 00001101. Sıfır olmayan rakamlar, 8, 4 ve 1'i temsil eder ve toplamda 13'e eşittir. -## Values +## Değerler {{index [memory, organization], "volatile data storage", "hard drive"}} -Imagine a sea of bits—an ocean of them. A typical modern computer has more than 100 billion bits in its volatile data storage (working memory). Nonvolatile storage (the hard disk or equivalent) tends to have yet a few orders of magnitude more. +Bitlerden oluşan bir denizi, bir okyanusu hayal edin. Tipik bir modern bilgisayarın, geçici veri depolama alanında (çalışma belleği) 100 milyarın üzerinde biti vardır. Kalıcı depolamaysa(sabit disk veya benzeri) genellikle birkaç kat daha fazla sayıda bit barındırır. -To be able to work with such quantities of bits without getting lost, we separate them into chunks that represent pieces of information. In a JavaScript environment, those chunks are called _((value))s_. Though all values are made of bits, they play different roles. Every value has a ((type)) that determines its role. Some values are numbers, some values are pieces of text, some values are functions, and so on. +Bu miktardaki bitlerle kaybolmadan çalışabilmek için, onları bilgi parçalarını temsil eden parçalara ayırırız. Bir JavaScript ortamında, bu parçalara ((_değer_))ler denir. Tüm değerler bitlerden oluşsa da, farklı roller üstlenirler. Her değerin rolünü belirleyen bir ((_tür_))ü vardır. Bazı değerler sayıdır, bazıları metin parçalarıdır, bazıları fonksiyonlardır ve benzeri. {{index "garbage collection"}} -To create a value, you must merely invoke its name. This is convenient. You don't have to gather building material for your values or pay for them. You just call for one, and _whoosh_, you have it. Of course, values are not really created from thin air. Each one has to be stored somewhere, and if you want to use a gigantic number of them at the same time, you might run out of computer memory. Fortunately, this is a problem only if you need them all simultaneously. As soon as you no longer use a value, it will dissipate, leaving behind its bits to be recycled as building material for the next generation of values. +Bir değer oluşturmak için, yalnızca adını çağırmanız gerekir. Bu kullanışlıdır. Değerleriniz için yapı malzemesini toplamanıza veya ödeme yapmanıza gerek yoktur. Sadece bir tane çağırırsınız ve _şup_, ona sahip olursunuz. Tabii ki, değerler gerçekten birdenbire hiçlikten yaratılmaz. Her biri bir yerde depolanmalıdır ve eğer hepsini aynı anda kullanmak isterseniz, bilgisayar belleği tükenebilir. Neyse ki, bu sadece hepsine aynı anda ihtiyacınız varsa bir problem olur. Bir değeri artık kullanmadığınızda, o dağılır ve arkasında bitlerini bırakır, böylece bir sonraki nesil değerler için yapı malzemesi olarak geri dönüştürülebilir. -The remainder of this chapter introduces the atomic elements of JavaScript programs, that is, the simple value types and the operators that can act on such values. +Bu bölümün geri kalanı, JavaScript programlarının atomik unsurlarını, yani basit değer tiplerini ve bu tür değerler üzerinde işlem yapabilen operatörleri tanıtır. -## Numbers +## Sayılar {{index [syntax, number], number, [number, notation]}} -Values of the _number_ type are, unsurprisingly, numeric values. In a JavaScript program, they are written as follows: +_Sayı_ türündeki değerler, beklenildiği gibi, sayısal değerlerdir. Bir JavaScript programında, şu şekilde yazılırlar: ``` 13 @@ -57,21 +57,22 @@ Values of the _number_ type are, unsurprisingly, numeric values. In a JavaScript {{index "binary number"}} -Using that in a program will cause the bit pattern for the number 13 to come into existence inside the computer's memory. +Bunu bir programda kullanmak, bilgisayar belleğinde sayı 13 için bit deseninin varlığını ortaya çıkarır. {{index [number, representation], bit}} -JavaScript uses a fixed number of bits, 64 of them, to store a single number value. There are only so many patterns you can make with 64 bits, which limits the number of different numbers that can be represented. With _N_ decimal ((digit))s, you can represent 10^N^ numbers. Similarly, given 64 binary digits, you can represent 2^64^ different numbers, which is about 18 quintillion (an 18 with 18 zeros after it). That's a lot. +JavaScript, bir adet sayı değeri saklamak için sabit olarak 64 bit kullanır. 64 bit ile yapabileceğiniz sadece belirli bir sayıda desen vardır, bu da temsil edilebilecek farklı sayıların sayısını sınırlar. _N_ ondalık ((basamak)) ile 10^N^ adet farklı sayıyı temsil edebilirsiniz. Benzer şekilde, 64 adet ikilik sayı basamakları ile 2^64^ farklı sayıyı temsil edebilirsiniz, bu da yaklaşık olarak 18 katrilyon (18'in arkasında 18 sıfır olan bir sayı), yani çok fazla. -Computer memory used to be much smaller, and people tended to use groups of 8 or 16 bits to represent their numbers. It was easy to accidentally _((overflow))_ such small numbers—to end up with a number that did not fit into the given number of bits. Today, even computers that fit in your pocket have plenty of memory, so you are free to use 64-bit chunks, and you need to worry about overflow only when dealing with truly astronomical numbers. +Bilgisayar belleği eskiden çok daha küçüktü ve insanlar sayılarını temsil etmek için 8 veya 16 bitlik gruplar kullanma eğilimindeydi. Bu tür küçük sayılarla işlemler yaparken kazara ((taşma)) durumuyla karşılaşmak, yani verilen bit sayısını aşan bir sayıya yanlışlıkla ulaşmak kolaydı. Bugün, cebinizdeki telefon adlı bilgisayarlar bile yeterince belleğe sahiptir, bu yüzden 64 bitlik parçaları özgürce kullanabilirsiniz ve gerçekten astronomik sayılarla uğraşmadığınız sürece taşma sorunuyla ilgilenmeniz gerekmez. {{index sign, "floating-point number", "sign bit"}} -Not all whole numbers less than 18 quintillion fit in a JavaScript number, though. Those bits also store negative numbers, so one bit indicates the sign of the number. A bigger issue is representing nonwhole numbers. To do this, some of the bits are used to store the position of the decimal point. The actual maximum whole number that can be stored is more in the range of 9 quadrillion (15 zeros)—which is still pleasantly huge. +The actual maximum whole number that can be stored is more in the range of 9 quadrillion (15 zeros)—which is still pleasantly huge. +Ancak, 18 katrilyonun altında kalan tüm tam sayılar bir JavaScript sayısına sığmaz. Bu bitler ayrıca negatif sayıları da saklar, bu nedenle bir bit sayının artı veya eksi olup olmadığını gösterir. Daha büyük bir sorunsa tam olmayan sayıları temsil etmektir. Bunun için, sayı bitlerinin bazıları ondalık noktanın konumunu saklamak için kullanılır. Depolanabilen asıl maksimum tam sayı, 9 katrilyon aralığındadır (15 sıfır). {{index [number, notation], "fractional number"}} -Fractional numbers are written using a dot: +Kesirli sayılar bir nokta kullanılarak yazılır: ``` 9.81 @@ -80,22 +81,23 @@ Fractional numbers are written using a dot: {{index exponent, "scientific notation", [number, notation]}} For very big or very small numbers, you may also use scientific notation by adding an _e_ (for _exponent_), followed by the exponent of the number: +Çok büyük veya çok küçük sayılar için, sayının üssünü belirten bir e (((_üs/exponent_)) için) ekleyerek bilimsel gösterim de kullanabilirsiniz: ``` 2.998e8 ``` -That's 2.998 × 10^8^ = 299,800,000. +Bu, 2.998 × 10^8^ = 299,800,000'dir. {{index pi, [number, "precision of"], "floating-point number"}} -Calculations with whole numbers (also called _((integer))s_) that are smaller than the aforementioned 9 quadrillion are guaranteed to always be precise. Unfortunately, calculations with fractional numbers are generally not. Just as π (pi) cannot be precisely expressed by a finite number of decimal digits, many numbers lose some precision when only 64 bits are available to store them. This is a shame, but it causes practical problems only in specific situations. The important thing is to be aware of it and treat fractional digital numbers as approximations, not as precise values. +Yukarıda bahsedilen 9 katrilyonun altındaki tüm tam sayılarla yapılan hesaplamalar her zaman kesindir. Ne yazık ki, tam olmayan sayılarla yapılan hesaplamalarsa genellikle kesin değildir. Pi (π) gibi birçok sayı, yalnızca 64 bit kullanılarak saklandığında bazı hassasiyetlerini kaybeder. Bu bir dezavantaj olsa da yalnızca belirli durumlarda yalnızca pratik problemlere neden olur. Önemli olan bunun farkında olmak ve tam olmayan sayıları kesin değerler olarak değil, yaklaşımlar olarak ele almaktır. -### Arithmetic +### Aritmetik {{index [syntax, operator], operator, "binary operator", arithmetic, addition, multiplication}} -The main thing to do with numbers is arithmetic. Arithmetic operations such as addition or multiplication take two number values and produce a new number from them. Here is what they look like in JavaScript: +Sayılarla yapılan temel işlem aritmetiktir. Toplama veya çarpma gibi aritmetik işlemler iki sayı değerini alır ve bunlardan yeni bir sayı üretir. JavaScript'te bunlar şu şekildedir: ```{meta: "expr"} 100 + 4 * 11 @@ -103,11 +105,11 @@ The main thing to do with numbers is arithmetic. Arithmetic operations such as a {{index [operator, application], asterisk, "plus character", "* operator", "+ operator"}} -The `+` and `*` symbols are called _operators_. The first stands for addition and the second stands for multiplication. Putting an operator between two values will apply it to those values and produce a new value. +`+` ve `*` sembolleri ((_operatör_)) olarak adlandırılır. İlk sembol toplamayı temsil eder ve ikincisi çarpma işlemini temsil eder. İki değer arasına bir operatör koymak işlemin bu değerlere uygulanmasına ve yeni bir değer üretmesine sebep olur. {{index grouping, parentheses, precedence}} -Does this example mean "Add 4 and 100, and multiply the result by 11", or is the multiplication done before the adding? As you might have guessed, the multiplication happens first. As in mathematics, you can change this by wrapping the addition in parentheses: +Bu örnek, "4'e 100'ü ekle ve sonucu 11 ile çarp" mı demektir, yoksa çarpma işlemi eklemeden önce mi yapılır? Tahmin ettiğiniz gibi, çarpma önce gerçekleşir. Matematikte olduğu gibi, bunu parantez içine alarak değiştirebilirsiniz: ```{meta: "expr"} (100 + 4) * 11 @@ -115,33 +117,32 @@ Does this example mean "Add 4 and 100, and multiply the result by 11", or is the {{index "hyphen character", "slash character", division, subtraction, minus, "- operator", "/ operator"}} -For subtraction, there is the `-` operator. Division can be done with the `/` operator. +Çıkarma için `-` operatörü bulunur. Bölme işlemi `/` operatörü ile yapılır. -When operators appear together without parentheses, the order in which they are applied is determined by the _((precedence))_ of the operators. The example shows that multiplication comes before addition. The `/` operator has the same precedence as `*`. Likewise, `+` and `-` have the same precedence. When multiple operators with the same precedence appear next to each other, as in `1 - 2 + 1`, they are applied left to right: `(1 - 2) + 1`. +Operatörler parantez olmadan bir araya geldiğinde, uygulanma sırası operatörlerin ((_önceliği_)) tarafından belirlenir. Örnek, çarpmanın toplamadan önce geldiğini gösterir. `/` operatörünün önceliği `*` ile aynıdır. Benzer şekilde, `+` ve `-` aynı önceliğe sahiptir. Aynı önceliğe sahip birden çok operatör yan yana geldiğinde, örneğin `1 - 2 + 1`, soldan sağa uygulanır: `(1 - 2) + 1`. -Don't worry too much about these precedence rules. When in doubt, just add parentheses. +Bu öncelik kuralları hakkında çok fazla endişelenmeyin. Şüphede kaldığınızda, sadece parantez ekleyin. {{index "modulo operator", division, "remainder operator", "% operator"}} -There is one more arithmetic operator, which you might not immediately recognize. The `%` symbol is used to represent the _remainder_ operation. `X % Y` is the remainder of dividing `X` by `Y`. For example, `314 % 100` produces `14`, and `144 % 12` gives `0`. The remainder operator's precedence is the same as that of multiplication and division. You'll also often see this operator referred to as _modulo_. +Hemen tanıyamayabileceğiniz biraz farklı olan bir aritmetik operatör daha var. `%` sembolü _kalan_ işlemi temsil etmek için kullanılır. `X % Y`, `X`'i `Y` ile böldüğünüzde kalanı verir. Örneğin, `314 % 100` `14` üretir ve `144 % 12` ise `0` verir. Kalan operatörünün önceliği, çarpma ve bölme işlemiyle aynıdır. Bu operatör aynı zamanda _modülo_ olarak da adlandırılır. -### Special numbers +### Özel sayılar {{index [number, "special values"], infinity}} -There are three special values in JavaScript that are considered numbers but don't behave like normal numbers. The first two are `Infinity` and `-Infinity`, which represent the positive and negative infinities. `Infinity - 1` is still `Infinity`, and so on. Don't put too much trust in infinity-based computation, though. It isn't mathematically sound, and it will quickly lead to the next special number: `NaN`. - +JavaScript'te normal sayılar gibi davranmayan ancak sayı olarak değerlendirilen üç adet özel değer vardır. İlk ikisi `Infinity` ve `-Infinity`, pozitif ve negatif sonsuzlukları temsil eder. `Infinity - 1` hala `Infinity`'dir ve benzeri. Ancak sonsuzluk tabanlı hesaplara fazla güvenmeyin. Matematiksel olarak sağlam değildir ve hızla bir sonraki özel sayıya yol açacaktır: `NaN`. {{index NaN, "not a number", "division by zero"}} -`NaN` stands for "not a number", even though it _is_ a value of the number type. You'll get this result when you, for example, try to calculate `0 / 0` (zero divided by zero), `Infinity - Infinity`, or any number of other numeric operations that don't yield a meaningful result. +`NaN`, "sayı değil" anlamına gelir, ancak _sayı türünden bir değerdir_. Örneğin `0 / 0` (sıfır bölü sıfır), `Infinity - Infinity` veya anlamlı bir sonuç vermeyen diğer sayısal işlemleri hesaplamaya çalıştığınızda da bu sonucu alırsınız. -## Strings +## Dizeler {{indexsee "grave accent", backtick}} {{index [syntax, string], text, character, [string, notation], "single-quote character", "double-quote character", "quotation mark", backtick}} -The next basic data type is the _((string))_. Strings are used to represent text. They are written by enclosing their content in quotes. +Sonraki temel veri türü _((dize))_ dir. Dizeler metni temsil etmek için kullanılır. İçeriklerini tırnak işaretleri içine alarak yazılırlar. ``` `Down on the sea` @@ -149,28 +150,29 @@ The next basic data type is the _((string))_. Strings are used to represent text 'Float on the ocean' ``` -You can use single quotes, double quotes, or backticks to mark strings, as long as the quotes at the start and the end of the string match. +Dizeleri işaretlemek için başlangıç ve sonundaki tırnaklar eşleştiği sürece tek tırnak, çift tırnak veya ters tırnaklar kullanabilirsiniz. {{index "line break", "newline character"}} -You can put almost anything between quotes to have JavaScript make a string value out of it. But a few characters are more difficult. You can imagine how putting quotes between quotes might be hard, since they will look like the end of the string. _Newlines_ (the characters you get when you press [enter]{keyname}) can be included only when the string is quoted with backticks (`` ` ``). +JavaScript'te neredeyse her şeyi tırnaklar arasına koyarak dize değeri yapmasını sağlayabilirsiniz. Ancak birkaç karakter daha zordur. Tırnakların arasına tırnak koymak zor olabilir, çünkü bunlar dizenin sonu gibi görünecektir. _Satır sonları_ (klavyede [enter]{keyname} tuşuna basarak elde edilen karakter) yalnızca ters tırnaklarla (`` ` ``) alıntılanmış dizelerde dahil edilebilir. {{index [escaping, "in strings"], ["backslash character", "in strings"]}} -To make it possible to include such characters in a string, the following notation is used: a backslash (`\`) inside quoted text indicates that the character after it has a special meaning. This is called _escaping_ the character. A quote that is preceded by a backslash will not end the string but be part of it. When an `n` character occurs after a backslash, it is interpreted as a newline. Similarly, a `t` after a backslash means a ((tab character)). Take the following string: +Bu tür karakterleri bir dizeye dahil etmeyi mümkün kılmak için ters bölü çubuğu (`\`) gösterimi kullanılır ve tırnak içindeki metin içinde onun sonrasındaki karakterin özel bir anlamı olduğunu belirtir. Bu, karakterin _kaçırılması_ olarak adlandırılır. Bir ters bölü çubuğundan sonra gelen bir tırnak dizeyi sonlandırmaz, ancak onun bir parçası olur. Bir ters bölü çubuğu (`\`) sonrasında bir `n` karakteri varsa, bu bir satır sonu olarak yorumlanır. Benzer şekilde, bir ters bölü çubuğu (`\`) sonrasında bir `t` karakteri, bir ((tab karakteri)) anlamına gelir. Aşağıdaki dizeyi düşünün: ``` "This is the first line\nAnd this is the second" ``` -This is the actual text is that string: +Bu, dizenin gerçek metni: ```{lang: null} This is the first line And this is the second ``` -There are, of course, situations where you want a backslash in a string to be just a backslash, not a special code. If two backslashes follow each other, they will collapse together, and only one will be left in the resulting string value. This is how the string "_A newline character is written like `"`\n`"`._" can be expressed: +This is how the string "_A newline character is written like `"`\n`"`._" can be expressed: +Elbette, bir dizeye bir ters bölü çubuğunun özel bir kod değil yalnızca bir ters bölü çubuğu olmasını istediğiniz durumlar da vardır. Ardışık olarak iki ters bölü çubuğu takip ederse, bunlar birleşir ve sonuçta değer dizesinde yalnızca bir tane kalır. Aşağıdaki dize "_A newline character is written like `"`\n`"`._" olarak ifade edilebilir: ``` "A newline character is written like \"\\n\"." @@ -180,37 +182,40 @@ There are, of course, situations where you want a backslash in a string to be ju {{index [string, representation], Unicode, character}} -Strings, too, have to be modeled as a series of bits to be able to exist inside the computer. The way JavaScript does this is based on the _((Unicode))_ standard. This standard assigns a number to virtually every character you would ever need, including characters from Greek, Arabic, Japanese, Armenian, and so on. If we have a number for every character, a string can be described by a sequence of numbers. And that's what JavaScript does. +Dizeler de bilgisayarın içinde var olabilmek için bir dizi bitler olarak modellenmelidir. JavaScript'in bunu yapmasının yolu _((Unicode))_ standardına dayanmaktadır. Bu standart, Yunanca, Arapça, Japonca, Ermenice ve diğer diller de dahil olmak üzere ihtiyacınız olan hemen hemen her karaktere bir spesifik bir numara atar. Her karakter için bir sayımız olduğuna göre, bir dize bir dizi numara ile açıklanabilir. Ve işte JavaScript bunu yapıyor. {{index "UTF-16", emoji}} -There's a complication though: JavaScript's representation uses 16 bits per string element, which can describe up to 2^16^ different characters. However, Unicode defines more characters than that—about twice as many, at this point. So some characters, such as many emoji, take up two "character positions" in JavaScript strings. We'll come back to this in [Chapter ?](higher_order#code_units). +Ancak bir karmaşıklık var: JavaScript dize temsilinde dizenin her karakterini temsil etmek için ancak 16 bit yani 2^16^ değerine kadar farklı karakteri açıklayabiliyor. Ancak Unicode, bu noktada, bunun yaklaşık iki katı kadar daha fazla karakteri tanımlar. Bu nedenle, birçok emoji gibi bazı karakterler, JavaScript dizelerinde iki "karakter konumu" kaplar. Buna [bölüm ?'da](higher_order#code_units)'da geri döneceğiz. {{index "+ operator", concatenation}} Strings cannot be divided, multiplied, or subtracted. The `+` operator _can_ be used on them, not to add, but to _concatenate_—to glue two strings together. The following line will produce the string `"concatenate"`: +Dizeler bölünemez, çarpılamaz veya çıkarılamaz. `+` operatörü onlar üzerinde _kullanılabilir_, ancak ekleme değil iki diziyi _birleştirmek_, yani yapıştırmak için. Aşağıdaki satır `"concatenate"` dizesini üretecektir: ```{meta: "expr"} "con" + "cat" + "e" + "nate" ``` -String values have a number of associated functions (_methods_) that can be used to perform other operations on them. I'll say more about these in [Chapter ?](data#methods). +String values have a number of associated functions (_methods_) that can be used to perform other operations on them. I'll say more about these in . +Dize değerleri üzerinde, onlarla diğer işlemleri gerçekleştirmek için kullanılabilecek bir dizi ilgili fonksiyonlar(_metodlar_) bulunur. Bunlar hakkında daha fazla bilgiyi [bölüm ?'da](data#methods) vereceğim. {{index interpolation, backtick}} -Strings written with single or double quotes behave very much the same—the only difference lies in which type of quote you need to escape inside of them. Backtick-quoted strings, usually called _((template literals))_, can do a few more tricks. Apart from being able to span lines, they can also embed other values. +Tek tırnak veya çift tırnakla yazılan dizeler çok benzer şekilde davranır—tek fark, içlerinde hangi tür tırnak karakterini kaçırmanız gerektiğindedir. Geri tırnakla oluşturulmuş dizeler, genellikle _((template literals))_ olarak adlandırılır ve birkaç daha iyi şeyler vardır. Satır soru karakterlerini içlerinde yazabilmenizin yanı sıra, dizenizin içerisine başka dinamik değerler de gömmenizi sağlarlar. ```{meta: "expr"} `half of 100 is ${100 / 2}` ``` When you write something inside `${}` in a template literal, its result will be computed, converted to a string, and included at that position. This example produces "_half of 100 is 50_". +Bir şablon literalde `${}` içine bir şey yazarsanız, sonucu hesaplanır, bir dizeye dönüştürülür ve dizenin içerisinde yazdığınız o konumda dahil edilir. Bu örnek "_half of 100 is 50_" dizesini üretir. -## Unary operators +## Tekil operatörler {{index operator, "typeof operator", type}} -Not all operators are symbols. Some are written as words. One example is the `typeof` operator, which produces a string value naming the type of the value you give it. +Tüm operatörler semboller olarak yazılmaz, bazıları kelimeler olarak yazılır. Bu operatörlere bir örnek `typeof` operatörüdür. Bu operatör verdiğiniz değerin türünün adını içeren bir dize değeri üretir. ``` console.log(typeof 4.5) @@ -223,28 +228,28 @@ console.log(typeof "x") {{id "console.log"}} -We will use `console.log` in example code to indicate that we want to see the result of evaluating something. More about that in the [next chapter](program_structure). +Örnek kodlarda değerlendirmek istediğimiz kodun sonucunu görebilmek için `console.log` kullanacağız. Bununla ilgili daha fazla bilgiye [sonraki bölümde](program_structure) ulaşabilirsiniz. {{index negation, "- operator", "binary operator", "unary operator"}} -The other operators shown so far in this chapter all operated on two values, but `typeof` takes only one. Operators that use two values are called _binary_ operators, while those that take one are called _unary_ operators. The minus operator can be used both as a binary operator and as a unary operator. +Bu bölümde şimdiye kadar gösterilen diğer operatörlerin hepsi iki değer üzerinde işlem yaparken, typeof sadece bir değer alır. İki değer kullanan operatörler _ikili operatörler_ olarak adlandırılırken, bir tane alanlar _tekil operatörler_ olarak adlandırılır. Eksi operatörü hem ikili operatör olarak hem de tekil operatör olarak kullanılabilir. ``` console.log(- (10 - 2)) // → -8 ``` -## Boolean values +## Boolean değerleri {{index Boolean, operator, true, false, bit}} -It is often useful to have a value that distinguishes between only two possibilities, like "yes" and "no" or "on" and "off". For this purpose, JavaScript has a _Boolean_ type, which has just two values, true and false, written as those words. +"Evet" ve "hayır" veya "açık" ve "kapalı" gibi yalnızca iki olasılığı birbirinden ayıran bir değere sahip olmak genellikle faydalıdır. Bu amaçla JavaScript'te, birebir bu kelimelerle `true` ve `false` olarak yazılan ve yalnızca iki değere sahip olan bir _Boolean_ türü vardır. -### Comparison +### Karşılaştırma {{index comparison}} -Here is one way to produce Boolean values: +İşte Boolean değerlerini üretmenin bir yolu: ``` console.log(3 > 2) @@ -255,9 +260,9 @@ console.log(3 < 2) {{index [comparison, "of numbers"], "> operator", "< operator", "greater than", "less than"}} -The `>` and `<` signs are the traditional symbols for "is greater than" and "is less than", respectively. They are binary operators. Applying them results in a Boolean value that indicates whether they hold true in this case. +`>` ve `<` işaretleri, sırasıyla "büyüktür" ve "küçüktür" için geleneksel sembollerdir. Bunlar ikili operatörlerdir. Bu operatörleri kullanmak, bu durumda doğru olup olmadığını gösteren bir Boolean değeri üretir. -Strings can be compared in the same way: +Dizeler de aynı şekilde karşılaştırılabilir: ``` console.log("Aardvark" < "Zoroaster") @@ -266,11 +271,11 @@ console.log("Aardvark" < "Zoroaster") {{index [comparison, "of strings"]}} -The way strings are ordered is roughly alphabetic but not really what you'd expect to see in a dictionary: uppercase letters are always "less" than lowercase ones, so `"Z" < "a"`, and nonalphabetic characters (!, -, and so on) are also included in the ordering. When comparing strings, JavaScript goes over the characters from left to right, comparing the ((Unicode)) codes one by one. +Dizelerin sıralanma şekli yaklaşık olarak alfabetiktir, ancak bir sözlükte görmeyi beklediğiniz gibi değildir: büyük harfler her zaman küçük harflerden "daha azdır", bu nedenle "Z" < "a" ifadesi doğrudur ve alfabetik olmayan karakterler (!, -, ve benzeri) de sıralamaya dahildir. Dizeler karşılaştırıldığında, JavaScript karakterleri soldan sağa doğru geçer ve onlara atanmış sayısal değerlerden oluşan Unicode kodlarını bir birine karşı karşılaştırır. {{index equality, ">= operator", "<= operator", "== operator", "!= operator"}} -Other similar operators are `>=` (greater than or equal to), `<=` (less than or equal to), `==` (equal to), and `!=` (not equal to). +Diğer benzer operatörler `>=` (büyük eşittir), `<=` (küçük eşittir), `==` (eşittir) ve `!=` (eşit değildir). ``` console.log("Garnet" != "Ruby") @@ -281,24 +286,24 @@ console.log("Pearl" == "Amethyst") {{index [comparison, "of NaN"], NaN}} -There is only one value in JavaScript that is not equal to itself, and that is `NaN` ("not a number"). +JavaScript'te kendine eşit olmayan yalnızca bir değer vardır, o da NaN ("not a number"). ``` console.log(NaN == NaN) // → false ``` -`NaN` is supposed to denote the result of a nonsensical computation, and as such, it isn't equal to the result of any _other_ nonsensical computations. +`NaN`, anlamsız bir hesaplamanın sonucunu belirtmek için kullanılır ve bu nedenle, başka anlamsız hesaplamaların sonucuyla da eşit değildir. -### Logical operators +### Mantıksal operatörler {{index reasoning, "logical operators"}} -There are also some operations that can be applied to Boolean values themselves. JavaScript supports three logical operators: _and_, _or_, and _not_. These can be used to "reason" about Booleans. +Boolean değerlere kendilerine uygulanabilen bazı işlemler de vardır. JavaScript, üç mantıksal operatörü destekler: _ve_, _veya_ ve _değil_. Bunlar, Boolean değerleri hakkında "akıl yürütmek" için kullanılabilir. {{index "&& operator", "logical and"}} -The `&&` operator represents logical _and_. It is a binary operator, and its result is true only if both the values given to it are true. +`&&` operatörü mantıksal _ve_'yi temsil eder. Bu, ikili bir operatördür ve verilen değerlerin her ikisi de doğruysa sonucu `true` değeri olur. ``` console.log(true && false) @@ -309,7 +314,7 @@ console.log(true && true) {{index "|| operator", "logical or"}} -The `||` operator denotes logical _or_. It produces true if either of the values given to it is true. +`||` operatörü, mantıksal _veya_'yı gösterir. Verilen değerlerden herhangi biri doğru ise `true` değerini üretir. ``` console.log(false || true) @@ -321,10 +326,11 @@ console.log(false || false) {{index negation, "! operator"}} _Not_ is written as an exclamation mark (`!`). It is a unary operator that flips the value given to it—`!true` produces `false` and `!false` gives `true`. +_Değil operatörü_, bir tekil operatör olarak ünlem işareti (`!`) ile yazılır. Verilen değeri ters çeviren bir operatördür — `!true`, `false` değerini üretir ve `!false` ise `true` değerini üretir. {{index precedence}} -When mixing these Boolean operators with arithmetic and other operators, it is not always obvious when parentheses are needed. In practice, you can usually get by with knowing that of the operators we have seen so far, `||` has the lowest precedence, then comes `&&`, then the comparison operators (`>`, `==`, and so on), and then the rest. This order has been chosen such that, in typical expressions like the following one, as few parentheses as possible are necessary: +Bu Boolean operatörlerini aritmetik ve diğer operatörlerle karıştırdığınızda, parantezlere ne zaman ihtiyaç duyacağımız her zaman çok da belli değildir. Uygulamada, şimdiye kadar gördüğümüz operatörlerden, `||` operatörünün en düşük önceliğe sahip olduğunu, sonra `&&` operatörünün daha öncelikli olduğunu, ardından karşılaştırma operatörlerinin (`>`, `==`, vb.) ve sonra geri kalanın daha öncelikli olduğunu bilerek işleri genellikle yürütebilirsiniz. Bu sıra, aşağıdaki gibi tipik ifadelerde mümkün olduğunca az parantez gerektirecek şekilde seçilmiştir: ```{meta: "expr"} 1 + 1 == 2 && 10 * 10 > 50 @@ -332,7 +338,7 @@ When mixing these Boolean operators with arithmetic and other operators, it is n {{index "conditional execution", "ternary operator", "?: operator", "conditional operator", "colon character", "question mark"}} -The last logical operator we will look at is not unary, not binary, but _ternary_, operating on three values. It is written with a question mark and a colon, like this: +Bakacağımız son mantıksal operatör, tekil değil, ikili değil, ancak üç değere işlem yapan üçlü operatördür. Soru işareti ve iki nokta üst üste ile şu şekilde yazılır: ``` console.log(true ? 1 : 2); @@ -341,23 +347,23 @@ console.log(false ? 1 : 2); // → 2 ``` -This one is called the _conditional_ operator (or sometimes just _the ternary operator_ since it is the only such operator in the language). The operator uses the value to the left of the question mark to decide which of the two other values to "pick". If you write `a ? b : c`, the result will be `b` when `a` is true and `c` otherwise. +Bu, _koşullu_ operatör olarak adlandırılır (veya bazen sadece _üçlü operatör_ olarak adlandırılır, çünkü dildeki bu türde var olan tek operatördür). Operatör, soru işaretinin solundaki değeri iki diğer değerden hangisini "seçeceğine" karar vermek için kullanır. `a ? b : c` yazarsanız, `a` değeri `true` olduğunda sonuç `b` veya `a` değeri `false`olduğu takdirde sonuç `c` olur. -## Empty values +## Boş değerler {{index undefined, null}} -There are two special values, written `null` and `undefined`, that are used to denote the absence of a _meaningful_ value. They are themselves values, but they carry no information. +_Anlamlı_ bir değerin yokluğunu belirtmek için kullanılan `null` ve `undefined` olarak yazılan iki özel değer vardır. Kendileri, kendi başlarına birer değerdirler ancak hiçbir bilgi taşımazlar. -Many operations in the language that don't produce a meaningful value yield `undefined` simply because they have to yield _some_ value. +Dil içinde herhangi bir değer üretmeyen bir işlem, _herhangi bir_ değeri üretmek zorunda olduğundan ötürü sadece `undefined` değerini üretir. -The difference in meaning between `undefined` and `null` is an accident of JavaScript's design, and it doesn't matter most of the time. In cases where you actually have to concern yourself with these values, I recommend treating them as mostly interchangeable. +`undefined` ve `null` arasındaki anlam farkı, JavaScript'in tasarımının bir kazasıdır ve çoğu zaman önemli değildir. Bu değerlerle gerçekten ilgilenmeniz gereken durumlarda, onları genellikle birbirinin yerine kullanılabilir olarak ele almanızı öneririm. -## Automatic type conversion +## Otomatik tür dönüşümü {{index NaN, "type coercion"}} -In the Introduction, I mentioned that JavaScript goes out of its way to accept almost any program you give it, even programs that do odd things. This is nicely demonstrated by the following expressions: +Giriş bölümünde, JavaScript'in hemen hemen her türde programı kabul etmeye çalıştığını, hatta garip şeyler yapan programları bile kabul ettiğini belirttim. Bunun güzel bir örneği aşağıdaki ifadelerle gösterilmiştir: ``` console.log(8 * null) @@ -374,15 +380,15 @@ console.log(false == 0) {{index "+ operator", arithmetic, "* operator", "- operator"}} -When an operator is applied to the "wrong" type of value, JavaScript will quietly convert that value to the type it needs, using a set of rules that often aren't what you want or expect. This is called _((type coercion))_. The `null` in the first expression becomes `0` and the `"5"` in the second expression becomes `5` (from string to number). Yet in the third expression, `+` tries string concatenation before numeric addition, so the `1` is converted to `"1"` (from number to string). +Bir operatörün "yanlış" türdeki bir değere uygulandığında, JavaScript o değeri sessizce ihtiyaç duyduğu türe dönüştürür, ancak bunu genellikle istemediğiniz veya beklemediğiniz kurallar kullanarak yapar. Buna _((tür dönüşümü))_ denir. İlk ifadedeki `null` `0` olur ve ikinci ifadedeki `"5"` değeri `5`'e dönüşür olur (dize türünden sayıya). Ancak üçüncü ifadede `+`, sayısal eklemeye geçmeden önce dize birleştirme denemesi yapar, bu nedenle `1` değeri "1" değerine dönüştürülür (sayıdan dizeye). {{index "type coercion", [number, "conversion to"]}} -When something that doesn't map to a number in an obvious way (such as `"five"` or `undefined`) is converted to a number, you get the value `NaN`. Further arithmetic operations on `NaN` keep producing `NaN`, so if you find yourself getting one of those in an unexpected place, look for accidental type conversions. +Açık bir şekilde bir sayıya eşlenmeyen bir şey (örneğin, `"five"` veya `undefined`) sayıya dönüştürüldüğünde, `NaN` değerini elde edersiniz. `NaN` üzerinde yapılan daha fazla aritmetik işlemler, sürekli olarak `NaN` üretir, bu nedenle beklenmedik bir yerde bunlardan birini bulursanız, kazara oluşma ihtimali olan tür dönüşümlerini arayın. {{index null, undefined, [comparison, "of undefined values"], "== operator"}} -When comparing values of the same type using the `==` operator, the outcome is easy to predict: you should get true when both values are the same, except in the case of `NaN`. But when the types differ, JavaScript uses a complicated and confusing set of rules to determine what to do. In most cases, it just tries to convert one of the values to the other value's type. However, when `null` or `undefined` occurs on either side of the operator, it produces true only if both sides are one of `null` or `undefined`. +`==` operatörünü kullanarak aynı türdeki değerleri karşılaştırdığınızda, sonucu tahmin etmek kolaydır: her iki değer de aynı olduğunda `true` değerini almalısınız, tabii `NaN` durumunda hariç. Ancak türler farklı olduğunda, JavaScript ne yapacağını belirlemek ve bir değeri diğer değerin türüne çevirip işlemi devam ettirebilmek için karmaşık ve kafa karıştırıcı bir kural seti kullanır. Çoğu durumda, sadece değerlerden birini diğer değerin türüne dönüştürmeye çalışır. Ancak, operatörün herhangi bir tarafında `null` veya `undefined` göründüğünde, yalnızca her iki tarafın da `null` veya `undefined` değerlerinden biri olduğunda `true` değerini üretir. ``` console.log(null == undefined); @@ -391,23 +397,24 @@ console.log(null == 0); // → false ``` -That behavior is often useful. When you want to test whether a value has a real value instead of `null` or `undefined`, you can compare it to `null` with the `==` or `!=` operator. +Bu davranış genellikle yararlıdır. Bir değerin `null` veya `undefined` yerine gerçek bir değer olup olmadığını test etmek istediğinizde, onu `==` veya `!=` operatörü ile null ile karşılaştırabilirsiniz. {{index "type coercion", [Boolean, "conversion to"], "=== operator", "!== operator", comparison}} -What if you want to test whether something refers to the precise value `false`? Expressions like `0 == false` and `"" == false` are also true because of automatic type conversion. When you do _not_ want any type conversions to happen, there are two additional operators: `===` and `!==`. The first tests whether a value is _precisely_ equal to the other, and the second tests whether it is not precisely equal. Thus `"" === false` is false as expected. +The first tests whether a value is _precisely_ equal to the other, and the second tests whether it is not precisely equal. Thus `"" === false` is false as expected. +Peki ya bir şeyin tam olarak `false` değeri olup olmadığını test etmek istiyorsanız ne olacak? `0 == false` ve `"" == false` gibi ifadeler, otomatik tür dönüşümünden ötürü aynı şekilde `true` değerine çözümlenirler. Herhangi bir tür dönüşümü olmasını _istemiyorsanız_, iki ek operatör vardır: `===` ve `!==`. İlk, bir değerin tam olarak diğerine eşit olup olmadığını test eder ve ikincisi, _tam olarak_ eşit olup olmadığını test eder. Bu nedenle, `"" === false`, ifadesi beklenildiği gibi `false` değerine çözümlenir. -I recommend using the three-character comparison operators defensively to prevent unexpected type conversions from tripping you up. But when you're certain the types on both sides will be the same, there is no problem with using the shorter operators. +Beklenmedik tür dönüşümlerinin sizi zorlamasını önlemek adına üç karakterli karşılaştırma operatörlerini kullanmanızı öneririm. Ancak eğer her iki taraftaki türlerin aynı olacağından eminseniz, kısa operatörleri kullanmakta da bir sorun yoktur. -### Short-circuiting of logical operators +### Mantıksal operatörlerin kısa devre davranışı {{index "type coercion", [Boolean, "conversion to"], operator}} -The logical operators `&&` and `||` handle values of different types in a peculiar way. They will convert the value on their left side to Boolean type in order to decide what to do, but depending on the operator and the result of that conversion, they will return either the _original_ left-hand value or the right-hand value. +`&&` ve `||` mantıksal operatörler, farklı türlerdeki değerleri ilginç bir şekilde işlemektedirler. Ne yapacaklarına karar vermek için sol taraftaki değeri Boolean türüne dönüştürürler, ancak operatöre ve bu dönüşümün sonucuna bağlı olarak, ya _orijinal_ sol taraf değerini ya da sağ taraf değerini döndürürler. {{index "|| operator"}} -The `||` operator, for example, will return the value to its left when that value can be converted to true and will return the value on its right otherwise. This has the expected effect when the values are Boolean and does something analogous for values of other types. +Örneğin, `||` operatörü, sol taraftaki değeri `true` değerine dönüştürebiliyorsa o değeri döndürür, aksi takdirde sağ taraftaki değeri döndürür. Bu, değerlerin Boolean olduğunda beklenen etkiyi yapar ve diğer türlerdeki değerler için de benzer bir şey yapar. ``` console.log(null || "user") @@ -418,11 +425,11 @@ console.log("Agnes" || "user") {{index "default value"}} -We can use this functionality as a way to fall back on a default value. If you have a value that might be empty, you can put `||` after it with a replacement value. If the initial value can be converted to false, you'll get the replacement instead. The rules for converting strings and numbers to Boolean values state that `0`, `NaN`, and the empty string (`""`) count as `false`, while all the other values count as `true`. That means `0 || -1` produces `-1`, and `"" || "!?"` yields `"!?"`. +Bu işlevselliği bir varsayılan değere yedek olarak düşmek adına kullanabiliriz. Boş olabilecek bir değeriniz varsa sonrasına `||` operatörünü yazıp yerine varsayılan bir değer olarak gelmesini istediğiniz diğer değeri yazabilirsiniz. Başlangıç değeri eğer `false` değerine dönüştürülebiliyorsa, operatör sonrasına yazdığınız değeri varsayılan değer olarak alırsınız. Dizeleri ve sayıları Boolean değerlere dönüştürme kuralları, `0`, `NaN` ve boş dize (`""`) değerlerinin `false` değeri olarak sayıldığını, diğer tüm değerlerinse `true`değeri olarak sayıldığını belirtir. Bu, `0 || -1` ifadesinin `-1` değerini üreteceğini ve `"" || "!?"` ifadesinin `"!?"`değerini vereceği anlamına gelir. {{index "?? operator", null, undefined}} -The `??` operator resembles `||`, but returns the value on the right only if the one on the left is null or undefined, not if it is some other value that can be converted to `false`. Often, this is preferable to the behavior of `||`. +`??` operatörü, `||` operatörüne benzer şekilde çalışır ancak soldaki değer yalnızca `null` veya `undefined` değerlerinden biri olduğunda sağdaki değeri döndürür. Genel olarak `??` operatörün davranışı `||` operatörün davranışı yerine tercih edilir. ``` console.log(0 || 100); @@ -435,18 +442,18 @@ console.log(null ?? 100); {{index "&& operator"}} -The `&&` operator works similarly but the other way around. When the value to its left is something that converts to false, it returns that value, and otherwise it returns the value on its right. +`&&` operatörü de benzer şekilde çalışır ancak tam tersi şekildedir. Soldaki ifade `false` değerine dönüştürülebilecek bir şey ise, o değeri döndürür ve aksi takdirde sağdaki değeri döndürür. -Another important property of these two operators is that the part to their right is evaluated only when necessary. In the case of `true || X`, no matter what `X` is—even if it's a piece of program that does something _terrible_—the result will be true, and `X` is never evaluated. The same goes for `false && X`, which is false and will ignore `X`. This is called _((short-circuit evaluation))_. +Bu iki operatörün bir başka önemli özelliği de, operatörün sağ tarafında kalan ifadeleri yalnızca gerekli olduğunda değerlendirmeleridir. `true || X` durumunda, `X` ne olursa olsun - hatta o bir program parçasıysa ve korkunç bir şey yapsa bile - sonuç `true` değeri olacaktır ve `X` asla değerlendirilmeyecektir. Aynı şey, false && X için de geçerlidir, bu false'tur ve X göz ardı edilir. Buna _((kısa devre değerlendirme))_ denir. {{index "ternary operator", "?: operator", "conditional operator"}} -The conditional operator works in a similar way. Of the second and third values, only the one that is selected is evaluated. +Koşullu operatör de benzer bir şekilde çalışır. İkinci ve üçüncü değerlerden yalnızca seçilen değer değerlendirilecektir. -## Summary +## Özet -We looked at four types of JavaScript values in this chapter: numbers, strings, Booleans, and undefined values. Such values are created by typing in their name (`true`, `null`) or value (`13`, `"abc"`). +Bu bölümde dört tür JavaScript değerine baktık: sayılar, dizeler, Booleans ve tanımsız değerler. Bu tür değerler, adlarını (`true`, `null`) veya değerlerini (`13`, `"abc"`) yazarak oluşturulur. -You can combine and transform values with operators. We saw binary operators for arithmetic (`+`, `-`, `*`, `/`, and `%`), string concatenation (`+`), comparison (`==`, `!=`, `===`, `!==`, `<`, `>`, `<=`, `>=`), and logic (`&&`, `||`, `??`), as well as several unary operators (`-` to negate a number, `!` to negate logically, and `typeof` to find a value's type) and a ternary operator (`?:`) to pick one of two values based on a third value. +Operatörlerle değerleri birleştirebilir ve dönüştürebilirsiniz. Aritmetik (`+`, `-`, `*`, `/`, ve `%`), dize birleştirme (`+`), karşılaştırma (`==`, `!=`, `===`, `!==`, `<`, `>`, `<=`, `>=`) ve mantık (`&&`, `||`, `??`) için ikili operatörler, tekil operatörler (bir sayıyı negatif yapmak için `-`, mantıksal olarak olumsuzlamak için `!` ve bir değerin türünü bulmak için `typeof`) ve bir üçüncü bir değere göre diğer iki değerden birisini seçmek adına var olan tek üçlü operatörü (`?:`) gördük. -This gives you enough information to use JavaScript as a pocket calculator but not much more. The [next chapter](program_structure) will start tying these expressions together into basic programs. +Bu, JavaScript'i bir cep hesap makinesi olarak kullanmanız için yeterli bilgiyi verir, ancak çok daha fazlası değil. [Sonraki bölüm](program_structure), bu ifadeleri temel programlara bağlamamıza yardımcı olacak. diff --git a/02_program_structure.md b/02_program_structure.md index 9e729694..8b250096 100644 --- a/02_program_structure.md +++ b/02_program_structure.md @@ -1,8 +1,8 @@ -# Program Structure +# Program Yapısı -{{quote {author: "_why", title: "Why's (Poignant) Guide to Ruby", chapter: true} +{{quote {author: "\_why", title: "Why's (Poignant) Guide to Ruby", chapter: true} -And my heart glows bright red under my filmy, translucent skin and they have to administer 10cc of JavaScript to get me to come back. (I respond well to toxins in the blood.) Man, that stuff will kick the peaches right out your gills! +Ve kalbim, bulanık, saydam cildimin altında parlak kırmızı yanarken beni geri getirmek için 10cc JavaScript uygulamak zorunda kalırlar. (Kandaki toksinlere iyi tepki veririm.) Vay be, o madde doğrudan soluğu keser! quote}} @@ -10,47 +10,47 @@ quote}} {{figure {url: "img/chapter_picture_2.jpg", alt: "Illustration showing a number of tentacles holding chess pieces", chapter: framed}}} -In this chapter, we will start to do things that can actually be called _programming_. We will expand our command of the JavaScript language beyond the nouns and sentence fragments we've seen so far to the point where we can express meaningful prose. +Bu bölümde, gerçek anlamda _programlama_ olarak adlandırılabilecek şeyler yapmaya başlayacağız. Şimdiye kadar gördüğümüz isimler ve cümle parçaları ötesinde JavaScript dilini anlamamızı sağlayacağız, böylece anlamlı bir yazılar ifade edebileceğiz. -## Expressions and statements +## İfade ve beyanlar {{index grammar, [syntax, expression], [code, "structure of"], grammar, [JavaScript, syntax]}} -In [Chapter ?](values), we made values and applied operators to them to get new values. Creating values like this is the main substance of any JavaScript program. But that substance has to be framed in a larger structure to be useful. That's what we'll cover in this chapter. +[?](values) Bölümünde, değerler oluşturduk ve bunlara operatörler uygulayarak yeni değerler elde ettik. Bu şekilde değer oluşturmak, herhangi bir JavaScript programının ana maddesidir. Ancak bu maddenin faydalı olabilmesi için daha büyük bir yapı içerisinde çerçevelenmelidir. İşte bu bölümde ele alacağımız şey budur. {{index "literal expression", [parentheses, expression]}} -A fragment of code that produces a value is called an _((expression))_. Every value that is written literally (such as `22` or `"psychoanalysis"`) is an expression. An expression between parentheses is also an expression, as is a ((binary operator)) applied to two expressions or a ((unary operator)) applied to one. +Bir değer üreten kod parçasına _((ifade))_ denir. Yazılmış olan her değer (örneğin `22` veya `"psikanaliz"`) bir ifadedir. Parantezler arasındaki bir ifade de bir ifade olarak kabul edilir, iki ifadeye uygulanan ((ikili operatör)) veya bir ifadeye uygulanan ((tekli operatör)) de ifadedir. {{index [nesting, "of expressions"], "human language"}} -This shows part of the beauty of a language-based interface. Expressions can contain other expressions in a way similar to how subsentences in human languages are nested—a subsentence can contain its own subsentences, and so on. This allows us to build expressions that describe arbitrarily complex computations. +Bu, dil tabanlı bir arabirimin güzelliğinin bir kısmını gösterir. İfadeler, insan dillerindeki yan cümlelerin iç içe geçmiş olduğu şekilde diğer ifadeleri içerebilir - bir yan cümle kendi yan cümlelerini içerebilir ve böyle devam eder. Bu, istediğimiz şekilde karmaşık hesaplamaları tanımlayan ifadeler oluşturmamıza izin verir. {{index statement, semicolon, program}} -If an expression corresponds to a sentence fragment, a JavaScript _statement_ corresponds to a full sentence. A program is a list of statements. +Bir JavaScript ifadesi bir cümle parçasına karşılık geliyorsa, bir JavaScript beyanı tam bir cümleye karşılık gelir. Bir program, bir beyanlar listesidir. {{index [syntax, statement]}} -The simplest kind of statement is an expression with a semicolon after it. This is a program: +En basit türde bir beyan, ardından bir noktalı virgül bulunan bir ifadedir. Bu bir programdır: ``` 1; !false; ``` -It is a useless program, though. An ((expression)) can be content to just produce a value, which can then be used by the enclosing code. However, a ((statement)) stands on its own, so if it doesn't affect the world, it's useless. It may display something on the screen, as with `console.log`, or change the state of the machine in a way that will affect the statements that come after it. These changes are called _((side effect))s_. The statements in the previous example just produce the values `1` and `true` and then immediately throw them away. This leaves no impression on the world at all. When you run this program, nothing observable happens. +Ancak bu işe yaramaz bir programdır. Bir ((ifade)), sadece bir değer üretmekle yetinebilir, ardından bu değer çevreleyen kod tarafından kullanılabilir. Ancak, bir ((beyan)) kendi başına durur, bu nedenle dünyayı etkilemiyorsa, işe yaramazdır. `console.log` ile olduğu gibi ekranın bir şeyler görüntülemesi veya makinenin durumunu bunlar ardından gelen beyanları etkileyecek şekilde değiştirmesi de olabilir. Bu değişikliklere _((yan etki))_ denir. Önceki örnekteki deyimler sadece `1` ve `true` değerlerini üretir ve hemen sonra onları yok eder. Bu, dünyada hiçbir iz bırakmaz. Bu programı çalıştırdığınızda, gözlemlenebilir hiçbir şey olmaz. {{index "programming style", "automatic semicolon insertion", semicolon}} -In some cases, JavaScript allows you to omit the semicolon at the end of a statement. In other cases, it has to be there, or the next ((line)) will be treated as part of the same statement. The rules for when it can be safely omitted are somewhat complex and error-prone. So in this book, every statement that needs a semicolon will always get one. I recommend you do the same, at least until you've learned more about the subtleties of missing semicolons. +Bazı durumlarda, JavaScript bir beyanın sonundaki noktalı virgülü atlayabilmenize izin verir ancak bazı durumlarda, orada olmalıdır çünkü aksi takdirde bir sonraki ((satır)), aynı beyanın bir parçası olarak işlenebilir. Ne zaman güvenle atlanabileceğine dair kurallar biraz karmaşıktır ve hata yapmaya müsaittir. Bu yüzden bu kitapta, noktalı virgül gerektiren her beyan her zaman bir noktalı virgül ile bitecek. En azından noktalı virgüllerin eksikliği hakkındaki incelikleri daha fazla öğrenene kadar aynısını yapmanızı öneririm. -## Bindings +## Bağlantılar {{indexsee variable, binding}} {{index [syntax, statement], [binding, definition], "side effect", [memory, organization], [state, in binding]}} -How does a program keep an internal state? How does it remember things? We have seen how to produce new values from old values, but this does not change the old values, and the new value must be used immediately or it will dissipate again. To catch and hold values, JavaScript provides a thing called a _binding_, or _variable_: +Bir program nasıl içsel bir durum tutar? Nasıl şeyleri hatırlar? Eski değerlerden yeni değerler üretmeyi gördük, ancak bu eski değerleri değiştirmez ve yeni değer hemen kullanılmalıdır, aksi takdirde tekrar kaybolur. Değerleri yakalamak ve tutmak için JavaScript, bir _bağlantı_ veya _değişken_ adı verilen bir şey sağlar: ``` let caught = 5 * 5; @@ -58,11 +58,11 @@ let caught = 5 * 5; {{index "let keyword"}} -That gives us a second kind of ((statement)). The special word (_((keyword))_) `let` indicates that this sentence is going to define a binding. It is followed by the name of the binding and, if we want to immediately give it a value, by an `=` operator and an expression. +Bu bize bir ikinci tür ((beyan)) verir. Özel bir kelime (((anahtar kelime))) olan `let`, bu cümlenin bir bağlantıyı tanımlayacağını gösterir. Ondan hemen sonra bağlantının adı ve eğer hemen bağlantı tanımlama sırasınfa bir değer vermek istiyorsak, bir `=` operatörü ve bir ifade bulunur. -The example creates a binding called `caught` and uses it to grab hold of the number that is produced by multiplying 5 by 5. +Örnekte, `caught` adında bir bağlantı oluşturulur ve 5'in 5 ile çarpılmasıyla üretilen sayıyı tutmak için kullanılır. -After a binding has been defined, its name can be used as an ((expression)). The value of such an expression is the value the binding currently holds. Here's an example: +Bir bağlantı tanımlanıp oluşturulduktan sonra, adı bir ((ifade)) olarak kullanılabilir. Böyle bir ifadenin değeri, bağlantının o anda tuttuğu değerdir. İşte bir örnek: ``` let ten = 10; @@ -72,7 +72,7 @@ console.log(ten * ten); {{index "= operator", assignment, [binding, assignment]}} -When a binding points at a value, that does not mean it is tied to that value forever. The `=` operator can be used at any time on existing bindings to disconnect them from their current value and have them point to a new one: +Bir bağlantı bir değere işaret ettiğinde, bu onun sonsuza dek o değere bağlı olduğu anlamına gelmez. Mevcut bağlantılar üzerinde istendiğinde `=` operatörü kullanılarak bunları mevcut değerlerinden ayırabilir ve onları yeni bir değere işaret etmesini sağlayabilirsiniz: ``` let mood = "light"; @@ -85,9 +85,9 @@ console.log(mood); {{index [binding, "model of"], "tentacle (analogy)"}} -You should imagine bindings as tentacles rather than boxes. They do not _contain_ values; they _grasp_ them—two bindings can refer to the same value. A program can access only the values to which it still has a reference. When you need to remember something, you either grow a tentacle to hold on to it or reattach one of your existing tentacles to it. +Bağlantıları kutular yerine bir ahtapotun dokunaçları olarak hayal etmelisiniz. Değerleri _içermezler_; onları _kavrarlar_ - iki bağlantı aynı değere atıfta bulunabilir. Bir program sadece hala bir referansı olan değerlere erişebilir. Bir şeyi hatırlamanız gerektiğinde, onu tutmak için bir ahtapot dokunaçı büyütür veya mevcut ahtapot dokunaçlarınızdan birini ona takarsınız. -Let's look at another example. To remember the number of dollars that Luigi still owes you, you create a binding. When he pays back $35, you give this binding a new value: +Başka bir örneğe bakalım. Luigi'nin size hala borçlu olduğu dolar miktarını hatırlamak için bir bağlantı oluşturursunuz. 35 doları size geri ödediğinde, bu bağlantıya yeni bir değer verirsiniz: ``` let luigisDebt = 140; @@ -98,11 +98,11 @@ console.log(luigisDebt); {{index undefined}} -When you define a binding without giving it a value, the tentacle has nothing to grasp, so it ends in thin air. If you ask for the value of an empty binding, you'll get the value `undefined`. +Bir değer vermeden bir bağlantı tanımladığınızda, ahtapot dokungacının kavrayacağı hiçbir şey yoktur, bu yüzden boş havada biter. Boş bir bağlantının değerini isterseniz, `undefined` değerini alırsınız. {{index "let keyword"}} -A single `let` statement may define multiple bindings. The definitions must be separated by commas: +Tek bir `let` beyanı birden fazla bağlantı tanımlayabilir ancak her spesifik isime tanımlanan bağlantılar virgülle ayrılmalıdır: ``` let one = 1, two = 2; @@ -110,7 +110,7 @@ console.log(one + two); // → 3 ``` -The words `var` and `const` can also be used to create bindings, in a similar fashion to `let`: +`var` ve `const` kelimeleri de, `let` ile benzer bir şekilde belirli isimlere bağlantı oluşturmak için kullanılabilir: ``` var name = "Ayda"; @@ -122,20 +122,21 @@ console.log(greeting + name); {{index "var keyword"}} The first of these, `var` (short for "variable"), is the way bindings were declared in pre-2015 JavaScript, when `let` didn't exist yet. I'll get back to the precise way it differs from `let` in the [next chapter](functions). For now, remember that it mostly does the same thing, but we'll rarely use it in this book because it behaves oddly in some situations. +Bunlardan ilki, `var` (kısaltma olarak "variable" - değişken anlamına gelir), 2015 öncesi JavaScript'te bağlantıların nasıl bildirildiğidir, o zamanlarda `let` henüz mevcut değildi. [Sonraki bölümde](functions) `var` bağlantılarının `let` bağlantılarından nasıl farklılık gösterdiğine dair ayrıntılı bilgilere göstereceğim ancak şimdilik, çoğunlukla aynı işi yaptığını hatırlayın. Bu kitapta `var` bağlantılarını nadiren kullanacağız çünkü bazı durumlarda garip davranışları bulunmakta. {{index "const keyword", naming}} -The word `const` stands for _((constant))_. It defines a constant binding, which points at the same value for as long as it lives. This is useful for bindings that just give a name to a value so that you can easily refer to it later. +`const` kelimesi _((constant))_ için kullanılır. Bu, yaşadığı sürece aynı değere işaret eden sabit bir bağlantı tanımlar. Bu, bir değere ad veren ve daha sonra kolayca başvurabileceğiniz bağlantılar için kullanışlıdır. -## Binding names +## Bağlantı isimleri {{index "underscore character", "dollar sign", [binding, naming]}} -Binding names can be any sequence of one or more letters. Digits can be part of binding names—`catch22` is a valid name, for example—but the name must not start with a digit. A binding name may include dollar signs (`$`) or underscores (`_`) but no other punctuation or special characters. +Bağlantı adları bir veya daha fazla harf dizisi olabilir. Rakamlar bağlantı adlarının bir parçası olabilir - örneğin, `catch22` geçerli bir addır - ancak ad bir rakamla başlamamalıdır. Bir bağlantı adı, dolar işaretleri (`$`) veya alt çizgiler (`_`) içerebilir, ancak başka noktalama işaretleri veya özel karakterler içeremez. {{index [syntax, identifier], "implements (reserved word)", "interface (reserved word)", "package (reserved word)", "private (reserved word)", "protected (reserved word)", "public (reserved word)", "static (reserved word)", "void operator", "yield (reserved word)", "enum (reserved word)", "reserved word", [binding, naming]}} -Words with a special meaning, such as `let`, are _((keyword))s_, and may not be used as binding names. There are also a number of words that are "reserved for use" in ((future)) versions of JavaScript, which also can't be used as binding names. The full list of keywords and reserved words is rather long: +`let` gibi özel anlamlı kelimeler _((anahtar kelimeler))_ olarak adlandırılır ve bağlantı adları olarak kullanılamazlar. Ayrıca, bağlantı adları olarak kullanılamayan ((gelecek)) JavaScript sürümlerinde "kullanım için saklanmış" birkaç kelime daha vardır. Tüm anahtar kelimelerin ve saklanmış kelimelerin tam listesi oldukça uzundur: ```{lang: "null"} break case catch class const continue debugger default @@ -147,22 +148,22 @@ switch this throw true try typeof var void while with yield {{index [syntax, error]}} -Don't worry about memorizing this list. When creating a binding produces an unexpected syntax error, check whether you're trying to define a reserved word. +Merak etmeyin, bu listeyi ezberlemenize gerek yok. Bir bağlantı oluştururken beklenmeyen bir sözdizimi hatası oluşturursanız, kullanmaya çalıştığınızın bir saklanmış kelime olup olmadığını kontrol edin. -## The environment +## Çevre {{index "standard environment", [browser, environment]}} -The collection of bindings and their values that exist at a given time is called the _((environment))_. When a program starts up, this environment is not empty. It always contains bindings that are part of the language ((standard)), and most of the time, it also has bindings that provide ways to interact with the surrounding system. For example, in a browser, there are functions to interact with the currently loaded website and to read ((mouse)) and ((keyboard)) input. +Belirli bir zamanda var olan bağlantılar ve bu bağlantıların işaret ettiği değerler topluluğuna _((çevre))_ denir. Bir program başladığında, bu ortam artık boş değildir. Her zaman programlama dilinin bir parçası olan ((standart)) bağlantıları içerir ve çoğu zaman, çevrenin içinde bulunduğu çevre sistemle etkileşim sağlayan bağlantıları da içerir. Örneğin, bir web tarayıcısında, şu anda yüklenmiş web sitesi ile etkileşimde bulunmak ve ((mouse)) ve ((keyboard)) girişini okumak için işlevler vardır. -## Functions +## Fonksiyonlar {{indexsee "application (of functions)", [function, application]}} {{indexsee "invoking (of functions)", [function, application]}} {{indexsee "calling (of functions)", [function, application]}} {{index output, function, [function, application], [browser, environment]}} -A lot of the values provided in the default environment have the type _((function))_. A function is a piece of program wrapped in a value. Such values can be _applied_ in order to run the wrapped program. For example, in a browser environment, the binding `prompt` holds a function that shows a little ((dialog box)) asking for user input. It is used like this: +Ortamda sağlanan varsayılan değerlerin çoğu _((fonksiyon))_ türündedir. Bir fonksiyon, bir değerle sarılmış bir program parçasıdır. Bu tür değerler, sarılmış programı çalıştırmak için _çalıştırılabilir_. Örneğin, bir web tarayıcı ortamında, `prompt` bağlantısı, kullanıcı girişi isteyen küçük bir ((diyalog kutusu)) gösteren bir işleve işaret eder. Bunu şu şekilde kullanırız: ``` prompt("Enter passcode"); @@ -172,19 +173,20 @@ prompt("Enter passcode"); {{index parameter, [function, application], [parentheses, arguments]}} -Executing a function is called _invoking_, _calling_, or _applying_ it. You can call a function by putting parentheses after an expression that produces a function value. Usually you'll directly use the name of the binding that holds the function. The values between the parentheses are given to the program inside the function. In the example, the `prompt` function uses the string that we give it as the text to show in the dialog box. Values given to functions are called _((argument))s_. Different functions might need a different number or different types of arguments. +Bir fonksiyonu çalıştırmak, onu _çağırmak_ veya _uygulamak_ veya _uygulamak_ olarak adlandırılır. Bir fonksiyonu değeri üreten bir ifadeye parantez ekleyerek bir fonksiyonu çağırabilirsiniz. Bunun için, genellikle fonksiyonu tutan bağlantının adını doğrudan kullanırsınız. Fonksiyonu çağırırkenki kullandığınız parantezler arasında verdiğiniz değerler _((argümanlar))_ olarak adlandırılır. Farklı fonksiyonların farklı sayıda veya farklı türde argümanlara ihtiyacı olabilir. -The `prompt` function isn't used much in modern web programming, mostly because you have no control over the way the resulting dialog looks, but it can be helpful in toy programs and experiments. +`prompt` fonksiyonu, modern web programlamasında pek kullanılmaz, çoğunlukla sonuç olarak oluşan iletişim kutusunun görünümü üzerinde kontrol sahibi olmadığınızdan dolayı, ancak oyuncak programlar ve deneylerde faydalı olabilir. -## The console.log function +## console.log fonksiyonu {{index "JavaScript console", "developer tools", "Node.js", "console.log", output, [browser, environment]}} -In the examples, I used `console.log` to output values. Most JavaScript systems (including all modern web browsers and Node.js) provide a `console.log` function that writes out its arguments to _some_ text output device. In browsers, the output lands in the ((JavaScript console)). This part of the browser interface is hidden by default, but most browsers open it when you press F12 or, on a Mac, [command]{keyname}-[option]{keyname}-I. If that does not work, search through the menus for an item named Developer Tools or similar. +Örneklerde, değerleri çıktı olarak göstermek için `console.log` kullandım. Tüm modern web tarayıcıları ve Node.js dahil olmak üzere çoğu JavaScript sistemleri, argüman olarak verilen metinleri çıkış ortamına yazan bir `console.log` fonksiyonunu size sağlar. Tarayıcılarda yazılan bu çıktı, ((JavaScript konsolu))nda yer alır. Bu bölüm, varsayılan olarak gizlidir, ancak çoğu tarayıcı, genelde F12'ye veya bir Mac'te [command]{keyname}-[option]{keyname}-I tuşlarına bastığınızda açar. Bu çalışmazsa, Geliştirici Araçlar veya buna benzer bir öğe arayarak menüler arasında gezinin. {{if interactive When running the examples (or your own code) on the pages of this book, `console.log` output will be shown after the example, instead of in the browser's JavaScript console. +Bu kitabın sayfalarında örnekleri (veya kendi kodlarınızı) çalıştırırken, `console.log` çıktısı, tarayıcının JavaScript konsolu yerine, örneğin altında gösterilir. ``` let x = 30; @@ -196,14 +198,15 @@ if}} {{index [object, property], [property, access]}} -Though binding names cannot contain ((period character))s, `console.log` does have one. This is because `console.log` isn't a simple binding, but an expression that retrieves the `log` property from the value held by the `console` binding. We'll find out exactly what this means in [Chapter ?](data#properties). +Bağlama isimleri ((nokta karakteri)) içeremez, ancak `console.log`'ta bir tane vardır. Bu, `console.log`'un basit bir bağlantı olmadığı, ancak `console` bağlantısında tutulan değerden `log` özelliği alınan bir ifade olduğu içindir. Bunun ne anlama geldiğini [Bölüm ?](data#properties)'da öğreneceğiz. {{id return_values}} -## Return values + +## Döndürülen değerler {{index [comparison, "of numbers"], "return value", "Math.max function", maximum}} -Showing a dialog box or writing text to the screen is a _((side effect))_. Many functions are useful because of the side effects they produce. Functions may also produce values, in which case they don't need to have a side effect to be useful. For example, the function `Math.max` takes any amount of number arguments and gives back the greatest: +Bir iletişim kutusu göstermek veya ekrana metin yazmak, bir \_((yan etki))\_dir. Birçok fonksiyon, ürettikleri yan etkiler nedeniyle yararlıdır. Fonksiyonlar ayrıca değerler üretebilir, bu durumda yararlı olmak için bir yan etkiye ihtiyaçları yoktur. Örneğin, `Math.max` fonksiyonu, herhangi bir miktarda sayı argümanları alır ve bu verilen sayı argümanlar arasından en büyük olanını geri verir: ``` console.log(Math.max(2, 4)); @@ -212,20 +215,20 @@ console.log(Math.max(2, 4)); {{index [function, application], minimum, "Math.min function"}} -When a function produces a value, it is said to _return_ that value. Anything that produces a value is an ((expression)) in JavaScript, which means that function calls can be used within larger expressions. In the following code, a call to `Math.min`, which is the opposite of `Math.max`, is used as part of a plus expression: +Bir fonksiyon bir değer ürettiğinde, o değeri _döndürdüğü_ söylenir. Bir değer üreten her şey, JavaScript'te bir ((ifade)) olduğundan, fonksiyon çağrıları daha büyük ifadelerin içinde kullanılabilir. Aşağıdaki kodda, Math.max'in tam tersi olan Math.min bir artı ifadesinin parçası olarak kullanılmıştır: ``` console.log(Math.min(2, 4) + 100); // → 102 ``` -[Chapter ?](functions) will explain how to write your own functions. +[Bölüm ?](functions), kendi fonksiyonlarınızı nasıl yazacağınızı açıklayacaktır. -## Control flow +## Kontrol akışı {{index "execution order", program, "control flow"}} -When your program contains more than one ((statement)), the statements are executed as though they were a story, from top to bottom. For example, the following program has two statements. The first asks the user for a number, and the second, which is executed after the first, shows the ((square)) of that number: +Programınız birden fazla ((beyan)) içeriyorsa, beyanlar, bir hikaye gibi, üstten alta doğru çalıştırılır. Örneğin, aşağıdaki programda iki ifade bulunmaktadır. İlk olarak, kullanıcıdan bir sayı istenir ve ilk ifadenin ardından yürütülen ikinci beyan o sayının ((kare))sini gösterir: ``` let theNumber = Number(prompt("Pick a number")); @@ -235,23 +238,23 @@ console.log("Your number is the square root of " + {{index [number, "conversion to"], "type coercion", "Number function", "String function", "Boolean function", [Boolean, "conversion to"]}} -The function `Number` converts a value to a number. We need that conversion because the result of `prompt` is a string value, and we want a number. There are similar functions called `String` and `Boolean` that convert values to those types. +Number fonksiyonu, bir değeri bir sayıya dönüştürür. Bu dönüşüme ihtiyacımız var çünkü `prompt`'un sonucu bir dize değeri ve biz bir sayı istiyoruz. Benzer şekilde, bu türlerdeki değerleri dönüştüren `String` ve `Boolean` adında diğer fonksiyonlar da bulunmaktadır. -Here is the rather trivial schematic representation of straight-line control flow: +İşte oldukça basit doğrusal kontrol akışının şematik temsili: {{figure {url: "img/controlflow-straight.svg", alt: "Diagram showing a straight arrow", width: "4cm"}}} -## Conditional execution +## Koşullu çalıştırma {{index Boolean, ["control flow", conditional]}} -Not all programs are straight roads. We may, for example, want to create a branching road where the program takes the proper branch based on the situation at hand. This is called _((conditional execution))_. +Tüm programlar düz yollar değildir. Örneğin, elimizdeki ana yoldan sapan başka yollar oluşturmak isteyebilir ve programımızın belirli durumlarda bu yollardan gitmesini sağlayabiliriz. Buna _((koşullu çalıştırma))_ denir. {{figure {url: "img/controlflow-if.svg", alt: "Diagram of an arrow that splits in two, and then rejoins again",width: "4cm"}}} {{index [syntax, statement], "Number function", "if keyword"}} -Conditional execution is created with the `if` keyword in JavaScript. In the simple case, we want some code to be executed if, and only if, a certain condition holds. We might, for example, want to show the square of the input only if the input is actually a number: +Koşullu çalıştırma, JavaScript'te `if` anahtar kelimesiyle oluşturulur. Basit bir durumda, belirli bir koşulun geçerli olduğu durumda yalnızca bazı kodların yürütülmesini istiyoruz. Örneğin, yalnızca girdinin gerçekten bir sayı olduğu durumda karesini göstermek isteyebiliriz: ```{test: wrap} let theNumber = Number(prompt("Pick a number")); @@ -261,19 +264,19 @@ if (!Number.isNaN(theNumber)) { } ``` -With this modification, if you enter "parrot", no output is shown. +Bu değişiklikle, girdi olarak programa `"parrot"` dize değerini verirseniz, hiçbir çıktı gösterilmez. {{index [parentheses, statement]}} -The `if` keyword executes or skips a statement depending on the value of a Boolean expression. The deciding expression is written after the keyword, between parentheses, followed by the statement to execute. +`if` anahtar kelimesi, bir Boolean ifadesinin değerine bağlı olarak bir beyanı yürütür veya atlar. Karar vermek için kullanılan ifade anahtar kelimenin ardından, parantezler arasına, ardından da yürütülecek beyan veya beyanlar yazılır. {{index "Number.isNaN function"}} -The `Number.isNaN` function is a standard JavaScript function that returns `true` only if the argument it is given is `NaN`. The `Number` function happens to return `NaN` when you give it a string that doesn't represent a valid number. Thus, the condition translates to "unless `theNumber` is not-a-number, do this". +`Number.isNaN` işlevi, yalnızca ona verilen argüman `NaN` ise `true` değerini döndüren standart bir JavaScript fonksiyonudur. `Number` işlevi, geçerli bir sayıyı temsil etmeyen bir dize argüman olarak verildiğinde `NaN` değerini döndürür. Bu nedenle, koşul "eğer `theNumber` bir sayıysa, bunu yap" şeklinde çevrilir. {{index grouping, "{} (block)", [braces, "block"]}} -The statement after the `if` is wrapped in braces (`{` and `}`) in this example. The braces can be used to group any number of statements into a single statement, called a _((block))_. You could also have omitted them in this case, since they hold only a single statement, but to avoid having to think about whether they are needed, most JavaScript programmers use them in every wrapped statement like this. We'll mostly follow that convention in this book, except for the occasional one-liner. +`if`'den sonraki ifade bu örnekte süslü parantezlerle (`{` ve `}`) sarılmıştır. Süslü parantezler, herhangi bir sayıda beyanı tek bir beyana, yani bir _((blok))_'a gruplamak için kullanılabilir. Bu durumda onları kullanmayabilirdiniz çünkü yalnızca tek bir satır beyan içibde bulundurmaktalar, ancak ihtiyaç duyulup duyulmadığı konusunda düşünmekten kaçınmak için çoğu JavaScript programcısı bunları bu şekilde yine de sarar. Bu kitapta çoğunlukla bu kurala uymaya devam edeceğiz, tek satırlık ifadeler hariç. ``` if (1 + 1 == 2) console.log("It's true"); @@ -282,7 +285,7 @@ if (1 + 1 == 2) console.log("It's true"); {{index "else keyword"}} -You often won't just have code that executes when a condition holds true, but also code that handles the other case. This alternate path is represented by the second arrow in the diagram. You can use the `else` keyword, together with `if`, to create two separate, alternative execution paths: +Genellikle sadece bir koşul doğru olduğunda yürütülen kodunuz olmayacak, aynı zamanda doğru olmayan diğer durumu da ele alan kodunuz olacak. Bu alternatif yol, şemadaki ikinci okla temsil edilmiştir. İki ayrı, alternatif çalıştırma yolu oluşturmak için `else` anahtar kelimesini, `if` ile birlikte kullanabilirsiniz: ```{test: wrap} let theNumber = Number(prompt("Pick a number")); @@ -296,7 +299,7 @@ if (!Number.isNaN(theNumber)) { {{index ["if keyword", chaining]}} -If you have more than two paths to choose from, you can "chain" multiple `if`/`else` pairs together. Here's an example: +Birden fazla seçenekli yolu varsa, birden çok `if`/`else` çiftini birbirine "zincirleyebilirsiniz". İşte bir örnek: ``` let num = Number(prompt("Pick a number")); @@ -310,16 +313,17 @@ if (num < 10) { } ``` -The program will first check whether `num` is less than 10. If it is, it chooses that branch, shows `"Small"`, and is done. If it isn't, it takes the `else` branch, which itself contains a second `if`. If the second condition (`< 100`) holds, that means the number is at least 10 but below 100, and `"Medium"` is shown. If it doesn't, the second and last `else` branch is chosen. +Program önce `num`'un 10'dan küçük olup olmadığını kontrol edecek. Eğer öyleyse, o dalı seçer, `"Small"` dize değerini gösterir ve biter. Eğer değilse, `else` dalını alır, ki bu da kendi içinde ikinci bir `if` içerir. İkinci koşul `(< 100)` geçerliyse, bu, sayının en az 10 ancak 100'den küçük olduğu anlamına gelir ve `"Medium"` dize değeri gösterilir. Eğer geçerli değilse, ikinci ve son `else` dalı seçilir, `"Large"` dize değeri gösterilir. -The schema for this program looks something like this: +Bu program için şema şöyle görünebilir: {{figure {url: "img/controlflow-nested-if.svg", alt: "Diagram showing arrow that splits in two, with on the branches splitting again, before all branches rejoin again", width: "4cm"}}} {{id loops}} -## while and do loops -Consider a program that outputs all ((even number))s from 0 to 12. One way to write this is as follows: +## while ve do döngüleri + +0 ile 12 arasındaki tüm ((çift sayı))ları çıkaran bir programı düşünün. Bunu yazmanın bir yolu şu şekildedir: ``` console.log(0); @@ -333,13 +337,13 @@ console.log(12); {{index ["control flow", loop]}} -That works, but the idea of writing a program is to make something _less_ work, not more. If we needed all even numbers less than 1,000, this approach would be unworkable. What we need is a way to run a piece of code multiple times. This form of control flow is called a _((loop))_. +Bu çalışır, ancak bir program yazmanın fikri daha _az_ iş yapmaktır, daha fazla iş yapmak değil. Eğer 1.000'den küçük tüm çift sayılara ihtiyacımız olsaydı, bu yaklaşım işe yaramaz olurdu. İhtiyacımız olan şey, bir kod parçasını birden çok kez çalıştıracak bir yol. Bu kontrol akış biçimi bir ((döngü/loop)) olarak adlandırılır. {{figure {url: "img/controlflow-loop.svg", alt: "Diagram showing an arrow to a point which has a cyclic arrow going back to itself and another arrow going further", width: "4cm"}}} {{index [syntax, statement], "counter variable"}} -Looping control flow allows us to go back to some point in the program where we were before and repeat it with our current program state. If we combine this with a binding that counts, we can do something like this: +Döngü kontrol akışı, programın daha önce bulunduğumuz bir noktaya geri dönmesine ve mevcut program durumu ile tekrar etmesine izin verir. Bunu sayabilen bir bağlantı ile birleştirirsek, şunu yapabiliriz: ``` let number = 0; @@ -354,15 +358,15 @@ while (number <= 12) { {{index "while loop", Boolean, [parentheses, statement]}} -A ((statement)) starting with the keyword `while` creates a loop. The word `while` is followed by an ((expression)) in parentheses and then a statement, much like `if`. The loop keeps entering that statement as long as the expression produces a value that gives `true` when converted to Boolean. +`while` anahtar kelimesiyle başlayan bir ((beyan)), bir döngü oluşturur. `while` kelimesinin ardından parantez içinde bir ((ifade)) ve ardından bir beyan, sanki `if` gibi bir şekilde yazılır. Döngü, verilen ifade Boolean'a dönüştürüldüğünde `true` değerini ürettiği sürece, o beyanı tekrar eder. {{index [state, in binding], [binding, as state]}} -The `number` binding demonstrates the way a ((binding)) can track the progress of a program. Every time the loop repeats, `number` gets a value that is 2 more than its previous value. At the beginning of every repetition, it is compared with the number 12 to decide whether the program's work is finished. +`number` adlı bağlantı, bir programın ilerlemesini bir bağlantı aracılığıyla izlemenin bir yolunu gösterir. Her döngü tekrarı tekrarlandığında, `number` adlı bağlantı önceki değerinden 2 fazla bir değer alır. Her tekrarın başlangıcında, programın işinin bitip bitmediğini anlaması için 12 sayısı ile karşılaştırılır. {{index exponentiation}} -As an example that actually does something useful, we can now write a program that calculates and shows the value of 2^10^ (2 to the 10th power). We use two bindings: one to keep track of our result and one to count how often we have multiplied this result by 2. The loop tests whether the second binding has reached 10 yet and, if not, updates both bindings. +Bu sefer herhangi bir işe yarayan bir örnek olarak, artık 2^10^ (2'nin 10. kuvvetinin) değerini hesaplayan ve gösteren bir program yazabiliriz. İki bağlantıya ihtiyacımız var: sonucumuzu takip etmek için bir tane ve bu sonucu 2 ile kaç kez çarptığımızı saymak için bir tane. Döngü, ikinci bağlantının henüz 10 değerine ulaşıp ulaşmadığını test eder ve eğer ulaşmamışsa, her iki bağlantıyı da günceller. ``` let result = 1; @@ -376,14 +380,15 @@ console.log(result); ``` The counter could also have started at `1` and checked for `<= 10`, but for reasons that will become apparent in [Chapter ?](data#array_indexing), it is a good idea to get used to counting from 0. +`counter` bağlantısı `1` ile başlayabilir ve `<= 10` için kontrol edebilirdi, ancak [Bölüm ?](data#array_indexing)'da anlatılacak sebeplerden ötürü, 0'dan saymayı alışkanlık haline getirmek iyi bir fikirdir. {{index "** operator"}} -Note that JavaScript also has an operator for exponentiation (`2 ** 10`), which you would use to compute this in real code—but that would have ruined the example. +Unutmayın ki JavaScript'in de bir üs operatörü vardır (`2 ** 10`), bunu kodda hesaplamak için kullanabilirdiniz - ancak bu örneğin amacını bozardı. {{index "loop body", "do loop", ["control flow", loop]}} -A `do` loop is a control structure similar to a `while` loop. It differs only on one point: a `do` loop always executes its body at least once, and it starts testing whether it should stop only after that first execution. To reflect this, the test appears after the body of the loop: +`do` döngüsü, `while` döngüsüne benzer bir kontrol yapısıdır. Tek farkı: bir `do` döngüsü daima gövdesini en az bir kez çalıştırır ve yalnızca bu ilk yürütmeden sonra durması gerekip gerekmediğini test eder. Bunu yansıtmak için test koşul ifadesi, döngünün gövdesinden sonra gelir: ``` let yourName; @@ -395,15 +400,15 @@ console.log("Hello " + yourName); {{index [Boolean, "conversion to"], "! operator"}} -This program will force you to enter a name. It will ask again and again until it gets something that is not an empty string. Applying the `!` operator will convert a value to Boolean type before negating it, and all strings except `""` convert to `true`. This means the loop continues going round until you provide a non-empty name. +Bu program, bir isim girmenizi zorlayacak. Girdi olarak boş olmayan bir dize alana kadar tekrar ve tekrar sormaya devam edecek. `!` operatörünü uygulamak, bir değeri Boolean türüne dönüştürdükten sonra bu değeri tersine çevirecektir ve buradaki `""` dışında tüm dizeler `true` değerine dönüşecektir. Bu, döngünün boş olmayan bir dize girdisi verilene kadar devam etmesi anlamına gelir. -## Indenting Code +## Kod girintileme {{index [code, "structure of"], [whitespace, indentation], "programming style"}} -In the examples, I've been adding spaces in front of statements that are part of some larger statement. These spaces are not required—the computer will accept the program just fine without them. In fact, even the ((line)) breaks in programs are optional. You could write a program as a single long line if you felt like it. +Örneklerde, bazı daha büyük ifadelerin bir parçası olan ifadelerin önüne boşluklar ekliyorum. Bu boşluklar gerekli değildir - bilgisayar bunlarsız da programı kabul eder. Aslında, JavaScript programlarında hatta ((yeni satır karakterleri)) bile opsiyoneldir. Eğer isterseniz, tüm programınızı uzun bir satır olarak da yazabilirsiniz. -The role of this ((indentation)) inside ((block))s is to make the structure of the code stand out to human readers. In code where new blocks are opened inside other blocks, it can become hard to see where one block ends and another begins. With proper indentation, the visual shape of a program corresponds to the shape of the blocks inside it. I like to use two spaces for every open block, but tastes differ—some people use four spaces, and some people use ((tab character))s. The important thing is that each new block adds the same amount of space. +Bu ((blok)) içindeki bu ((girinti))lerin rolü, kodun yapısını insan okuyucuların dikkatine varabilmesi içinde. Yeni blokların diğer blokların içinde açıldığı kodlarda, bir bloğun nerede bittiğini ve diğerinin nerede başladığını görmek zor olabilir. Uygun girinti kullanımıyla, bir programın görsel şekli, içindeki blokların şekline karşılık gelir. Ben her açık blok için iki boşluk kullanmayı tercih ediyorum, ancak zevkler değişir - bazı insanlar dört boşluk kullanırken, bazıları ((tab karakter))lerini kullanır. Önemli olan, her yeni bloğun aynı miktarda boşluk eklemesidir. ``` if (false != true) { @@ -414,17 +419,18 @@ if (false != true) { } ``` -Most code ((editor)) programs[ (including the one in this book)]{if interactive} will help by automatically indenting new lines the proper amount. +Çoğu kod ((düzenleyici)) programı[ (bu kitaptaki gibi)]{if interactive} yeni satırları otomatik olarak uygun miktarda girintileme yaparak size yardımcı olacaktır. -## for loops +## for döngüleri {{index [syntax, statement], "while loop", "counter variable"}} Many loops follow the pattern shown in the `while` examples. First a "counter" binding is created to track the progress of the loop. Then comes a `while` loop, usually with a test expression that checks whether the counter has reached its end value. At the end of the loop body, the counter is updated to track progress. +Birçok döngü, `while` örneklerinde gösterilen deseni takip eder. İlk olarak, döngünün ilerlemesini takip etmek için bir `"counter"` bağlantısı oluşturulur. Ardından, genellikle `"counter"` bağlantısının hedef değerine ulaşıp ulaşmadığını kontrol eden bir test ifadesiyle birlikte bir `while` döngüsü gelir. Döngü gövdesinin sonunda, ilerlemeyi izlemek için `"counter"` bağlantısı güncellenir. {{index "for loop", loop}} -Because this pattern is so common, JavaScript and similar languages provide a slightly shorter and more comprehensive form, the `for` loop: +Bu desen o kadar yaygındır ki, JavaScript ve benzer diller bunun için biraz daha kısa ve kapsamlı bir form sağlar, `for` döngüsü: ``` for (let number = 0; number <= 12; number = number + 2) { @@ -438,14 +444,16 @@ for (let number = 0; number <= 12; number = number + 2) { {{index ["control flow", loop], state}} This program is exactly equivalent to the [earlier](program_structure#loops) even-number-printing example. The only change is that all the ((statement))s that are related to the "state" of the loop are grouped together after `for`. +Bu program, daha [önceki](program_structure#loops) çift sayıları yazdırma örneğine tam olarak eşdeğerdir. Tek fark, döngünün "durumu" ile ilgili olan tüm ((beyan))ların for'dan sonra gruplandırılmış olmasıdır. {{index [binding, as state], [parentheses, statement]}} The parentheses after a `for` keyword must contain two ((semicolon))s. The part before the first semicolon _initializes_ the loop, usually by defining a binding. The second part is the ((expression)) that _checks_ whether the loop must continue. The final part _updates_ the state of the loop after every iteration. In most cases, this is shorter and clearer than a `while` construct. +`for` anahtar kelimesinden sonra parantezlerin içinde iki ((noktalı virgül)) bulunmalıdır. İlk noktalı virgülden önceki kısım, genellikle bir bağlantı tanımlayarak döngüyü başlatır. İkinci kısım, döngünün devam edip etmemesini gerektiğini her seferinde kontrol eden ((ifade))dir. Son kısım, her iterasyondan sonra döngünün durumunu _günceller_. Çoğu durumda, bu, `while` yapısından daha kısa ve daha açıklayıcıdır. {{index exponentiation}} -This is the code that computes 2^10^ using `for` instead of `while`: +Bu, `while` kullanmak yerine `for` döngüsü yapısını kullanarak 2^10^ hesaplayan koddur: ```{test: wrap} let result = 1; @@ -456,11 +464,11 @@ console.log(result); // → 1024 ``` -## Breaking Out of a Loop +## Döngü içerisinden çıkmak {{index [loop, "termination of"], "break keyword"}} -Having the looping condition produce `false` is not the only way a loop can finish. The `break` statement has the effect of immediately jumping out of the enclosing loop. Its use is demonstrated in the following program, which finds the first number that is both greater than or equal to 20 and divisible by 7: +Döngü koşulunun `false` değerini üretmesini sağlamak bir döngünün bitmesi için tek yol değildir. `break` beyanı, dışındaki döngüden anında çıkmak etkisine sahiptir. Kullanımı aşağıdaki programda gösterilmiştir, bu program, hem 20'den büyük veya eşit olan ve hem de 7'ye bölünebilen ilk sayıyı bulur: ``` for (let current = 20; ; current = current + 1) { @@ -474,43 +482,43 @@ for (let current = 20; ; current = current + 1) { {{index "remainder operator", "% operator"}} -Using the remainder (`%`) operator is an easy way to test whether a number is divisible by another number. If it is, the remainder of their division is zero. +Modülo(%) operatörünü kullanmak, bir sayının başka bir sayıya bölünebilir olup olmadığını test etmenin kolay bir yoludur çünkü eğer öyleyse bölme işleminin kalanı sıfırdır. {{index "for loop"}} -The `for` construct in the example does not have a part that checks for the end of the loop. This means that the loop will never stop unless the `break` statement inside is executed. +Örnekteki `for` yapısı döngünün sona gelip gelmediğini kontrol eden bir parça içermez. Bu, döngünün içerisinde bir `break` ifadesi çalıştırılmadıkça döngünün hiçbir zaman durmayacağı anlamına gelir. -If you were to remove that `break` statement or you accidentally write an end condition that always produces `true`, your program would get stuck in an _((infinite loop))_. A program stuck in an infinite loop will never finish running, which is usually a bad thing. +Eğer o `break` ifadesini kaldırırsanız veya yanlışlıkla her zaman `true` değerini üreten bir bitiş koşulu yazarsanız, programınız bir _((sonsuz döngü))_'ye takılacaktır. Bir sonsuz döngüye takılan bir program asla çalışmayı bitiremez, bu genellikle kötü bir şeydir. {{if interactive -If you create an infinite loop in one of the examples on these pages, you'll usually be asked whether you want to stop the script after a few seconds. If that fails, you will have to close the tab that you're working in to recover. +Bu sayfalardaki örneklerden birinde sonsuz bir döngü oluşturursanız, genellikle birkaç saniye sonra scripti durdurmak isteyip istemediğiniz sorulur. Eğer bu başarısız olursa, kurtarmak için çalıştığınız sekmeyi kapatmanız zorunda kalırsınız. if}} {{index "continue keyword"}} -The `continue` keyword is similar to `break` in that it influences the progress of a loop. When `continue` is encountered in a loop body, control jumps out of the body and continues with the loop's next iteration. +`continue` anahtar kelimesi, `break` gibi bir döngünün ilerleyişini etkiler. Bir döngü gövdesinde `continue` bulunduğunda, kontrol gövdeden çıkar ve döngünün bir sonraki tekrarından devam eder. -## Updating bindings succinctly +## Kısa ve öz şekilde bağlantıları güncelleme {{index assignment, "+= operator", "-= operator", "/= operator", "*= operator", [state, in binding], "side effect"}} -Especially when looping, a program often needs to "update" a binding to hold a value based on that binding's previous value. +Özellikle döngü yapılırken, bir program genellikle bir bağlantının değerini o bağlantını önceki değerine dayalı olarak başka bir değerle "güncellemeye" ihtiyaç duyar. ```{test: no} counter = counter + 1; ``` -JavaScript provides a shortcut for this: +JavaScript, bunun için bir kısayol sağlar: ```{test: no} counter += 1; ``` -Similar shortcuts work for many other operators, such as `result *= 2` to double `result` or `counter -= 1` to count downward. +Benzer kısayollar, `result *= 2` ile `result` bağlantısının değerini iki katına çıkarmak veya `counter -= 1` ile geriye doğru saymak gibi birçok diğer aritmetik operatörle de çalışır. -This allows us to further shorten our counting example: +Bu, sayım örneğimizi daha da kısaltmamıza olanak tanır: ``` for (let number = 0; number <= 12; number += 2) { @@ -520,13 +528,13 @@ for (let number = 0; number <= 12; number += 2) { {{index "++ operator", "-- operator"}} -For `counter += 1` and `counter -= 1`, there are even shorter equivalents: `counter++` and `counter--`. +`counter += 1` ve `counter -= 1` için daha kısa aynı şeye denk gelen yazım şekilleri de mevcuttur: counter++ ve counter--. -## Dispatching on a value with switch +## switch aracılığıyla bir değere göre çalıştırmak {{index [syntax, statement], "conditional execution", dispatch, ["if keyword", chaining]}} -It is not uncommon for code to look like this: +Kodun şu şekilde görünmesi yaygındır: ```{test: no} if (x == "value1") action1(); @@ -537,7 +545,7 @@ else defaultAction(); {{index "colon character", "switch keyword"}} -There is a construct called `switch` that is intended to express such a "dispatch" in a more direct way. Unfortunately, the syntax JavaScript uses for this (which it inherited from the C/Java line of programming languages) is somewhat awkward—a chain of `if` statements may look better. Here is an example: +Buna benzer ancak daha doğrudan bir şekilde kod "çalıştırmayı" ifade etmek için tasarlanmış `switch` adında bir yapı vardır. Ne yazık ki, bu yapı için JavaScript'in kullandığı sözdizimi (C/Java programlama dillerinden miras aldığı) biraz garip gözükebilir ve bundan ötürü bir dizi `if` ifadesi daha iyi görünebilir. İşte bir örnek: ``` switch (prompt("What is the weather like?")) { @@ -557,13 +565,13 @@ switch (prompt("What is the weather like?")) { {{index fallthrough, "break keyword", "case keyword", "default keyword"}} -You may put any number of `case` labels inside the block opened by `switch`. The program will start executing at the label that corresponds to the value that `switch` was given, or at `default` if no matching value is found. It will continue executing, even across other labels, until it reaches a `break` statement. In some cases, such as the `"sunny"` case in the example, this can be used to share some code between cases (it recommends going outside for both sunny and cloudy weather). Be careful, though—it is easy to forget such a `break`, which will cause the program to execute code you do not want executed. +`switch` tarafından açılan bloğun içine istediğiniz sayıda `case` koyabilirsiniz. Program, `switch`'e verilen değere karşılık gelen etiketteki kodu veya eşleşen bir değer bulunamazsa `default` etiketindeki kodu çalıştırır. `break` ifadesine ulaşana kadar diğer etiketler de dahil olmak üzere karşılaştığı kodları çalıştırmaya devam eder. Örnekteki `"sunny"` durumunda olduğu gibi bazı durumlarda, bu kodu durumlar arasında paylaşmak için kullanılabilir (hem güneşli hem de bulutlu hava için dışarı çıkmanızı önerir). Ancak dikkatli olun - bu şekilde bir `break` ifadesini unutmak kolaydır ve istenmeyen şekilde kodun yürütülmesine sebep olmak kolaydır. -## Capitalization +## Büyük harf kullanımı {{index capitalization, [binding, naming], [whitespace, syntax]}} -Binding names may not contain spaces, yet it is often helpful to use multiple words to clearly describe what the binding represents. These are pretty much your choices for writing a binding name with several words in it: +Bağlantı adları arasında boşluk olmamalıdır, ancak bağlantının temsil ettiği şeyi açıkça tanımlamak için birden fazla kelime kullanmak faydalı olabilir. Birden fazla kelime içeren bir bağlantı adı yazmak için şu seçenekleriniz var: ```{lang: null} fuzzylittleturtle @@ -574,21 +582,21 @@ fuzzyLittleTurtle {{index "camel case", "programming style", "underscore character"}} -The first style can be hard to read. I rather like the look of the underscores, though that style is a little painful to type. The ((standard)) JavaScript functions, and most JavaScript programmers, follow the final style—they capitalize every word except the first. It is not hard to get used to little things like that, and code with mixed naming styles can be jarring to read, so we follow this ((convention)). +İlk stili okumak zor olabilir. Ben alt çizgilerin görünümünü oldukça beğeniyorum, ancak bu stili yazmak biraz zor olabilir. ((Standart)) JavaScript fonksiyonları ve çoğu JavaScript programcısı, sondaki stili takip eder - ilk kelime haricindeki her kelimenin ilk harfini büyük harfle yazarlar. Böyle küçük detaylara alışmak zor değildir ve karışık isimlendirme stilleri olan kodlar okunması zor olabilir, bu yüzden bu ((kuralı)) kullanıyoruz. {{index "Number function", constructor}} -In a few cases, such as the `Number` function, the first letter of a binding is also capitalized. This was done to mark this function as a constructor. It will become clear what a constructor is in [Chapter ?](object#constructors). For now, the important thing is not to be bothered by this apparent lack of ((consistency)). +Bazı durumlarda, `Number` fonksiyonu gibi, bağlantı isminin ilk harfi de büyük yazılır. Bu, bu fonskiyonu bir yapılandırıcı olarak işaretlemek içindir. Bir yapılandırıcının ne olduğu [Bölüm ?](object#constructors)'da netleşecektir. Şu anda, önemli olan bu belirgin ((tutarlılık)) eksikliğinden rahatsız olmamaktır. -## Comments +## Yorum satırları {{index readability}} -Often, raw code does not convey all the information you want a program to convey to human readers, or it conveys it in such a cryptic way that people might not understand it. At other times, you might just want to include some related thoughts as part of your program. This is what _((comment))s_ are for. +Sıklıkla, ham kod, bir programın insan okuyucularına iletmek istediğiniz tüm bilgileri iletemez veya bilgiyi anlaşılması zor veya kriptik bir şekilde iletebilir. Bazı zamanlarda, programınızın bir parçası olarak ilgili düşünceleri dahil etmek isteyebilirsiniz. \_((Yorum))\_lar bunun için vardır. {{index "slash character", "line comment"}} -A comment is a piece of text that is part of a program but is completely ignored by the computer. JavaScript has two ways of writing comments. To write a single-line comment, you can use two slash characters (`//`) and then the comment text after it: +Yorum, bir programın bir parçası olan ancak bilgisayar tarafından tamamen görmezden gelinen bir metin parçasıdır. JavaScript'in iki yorum yazma yöntemi vardır. Tek satırlık bir yorum yazmak için iki eğik çizgi karakteri (`//`) kullanabilir ve ardından yorum metnini ekleyebilirsiniz: ```{test: no} let accountBalance = calculateBalance(account); @@ -603,7 +611,7 @@ addToReport(accountBalance, report); {{index "block comment"}} -A `//` comment goes only to the end of the line. A section of text between `/*` and `*/` will be ignored in its entirety, regardless of whether it contains line breaks. This is useful for adding blocks of information about a file or a chunk of program: +`//` ile başlayan bir yorum yalnızca satırın sonuna kadar gider. `/*` ve `*/` arasındaki bir metin bölümü, yeni satır karakterlerini içinde barındırıp barındırmadığına bakılmaksızın tamamen görmezden gelinir. Bu, bir dosya veya program parçası hakkında satırlar yerine bloklar halinde bilgi eklemek için kullanışlıdır: ``` /* @@ -615,29 +623,29 @@ A `//` comment goes only to the end of the line. A section of text between `/*` const myNumber = 11213; ``` -## Summary +## Özet -You now know that a program is built out of statements, which themselves sometimes contain more statements. Statements tend to contain expressions, which themselves can be built out of smaller expressions. +Şimdi bir programın bazen içerisinde beyanlar barındıran beyanlardan oluştuğunu biliyorsunuz. Beyanlar da genellikle ifadeler barındıran ifadelerden oluşurlar. -Putting statements after one another gives you a program that is executed from top to bottom. You can introduce disturbances in the flow of control by using conditional (`if`, `else`, and `switch`) and looping (`while`, `do`, and `for`) statements. +İfadeleri ardışık olarak bir araya getirmek, üstten alta çalıştırılan bir program elde etmenizi sağlar. Koşullu (`if`, `else` ve `switch`) ve döngü (`while`, `do` ve `for`) ifadelerini kullanarak kontrol akışına farklı şekillerde değişiklikler ekleyebilirsiniz. -Bindings can be used to file pieces of data under a name, and they are useful for tracking state in your program. The environment is the set of bindings that are defined. JavaScript systems always put a number of useful standard bindings into your environment. +Bağlanlar, bir parça bilgiyi bir isim altında saklamak için kullanılabilir ve programınızdaki durumu takip etmek için de kullanışlıdır. Ortam, tanımlanan bağlantıların kümesidir. JavaScript sistemleri, ortamınıza birçok kullanışlı standart bağlantıları otomatik olarak yerleştirir. -Functions are special values that encapsulate a piece of program. You can invoke them by writing `functionName(argument1, argument2)`. Such a function call is an expression and may produce a value. +Fonksiyonlar, bir program parçasını kapsayan özel değerlerdir. Onları `fonksiyonAdı(argüman1, argüman2)` şeklinde yazarak çağırabilirsiniz. Böyle bir fonksiyon çağrısı bir ifade olup ayrıca bir değer üretebilir. -## Exercises +## Egzersizler {{index exercises}} -If you are unsure how to test your solutions to the exercises, refer to the [Introduction](intro). +Egzersiz çözümlerinizi nasıl test edeceğinizden emin değilseniz, [Giriş](intro)'e başvurun. -Each exercise starts with a problem description. Read this description and try to solve the exercise. If you run into problems, consider reading the hints [after the exercise]{if interactive}[at the [end of the book](hints)]{if book}. You can find full solutions to the exercises online at [_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code#2). If you want to learn something from the exercises, I recommend looking at the solutions only after you've solved the exercise, or at least after you've attacked it long and hard enough to have a slight headache. +Her egzersiz bir problem açıklaması ile başlar, bu açıklamayı okuyun ve egzersizi çözmeye çalışın. Sorunlarla karşılaşırsanız, [egzersizden sonra]{if interactive} [[kitabın sonundaki](hints)]{if book} ipuçlarını'ı okuyabilirsiniz. Egzersizlerin tam çözümlerini [_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code#2)'da çevrimiçi olarak bulabilirsiniz. Egzersizlerden bir şeyler öğrenmek istiyorsanız, egzersizi çözdükten sonra çözümlere bakmayı veya en azından biraz baş ağrısı yaşayana kadar çözüme saldırmanızı öneririm. -### Looping a triangle +### Bir üçgeni döngüye almak {{index "triangle (exercise)"}} -Write a ((loop)) that makes seven calls to `console.log` to output the following triangle: +Aşağıdaki üçgeni çıktıya yazdırmak için `console.log`'u yedi kere çağıran bir ((döngü)) yazın: ```{lang: null} # @@ -651,7 +659,7 @@ Write a ((loop)) that makes seven calls to `console.log` to output the following {{index [string, length]}} -It may be useful to know that you can find the length of a string by writing `.length` after it. +Bir dizinin uzunluğunu `.length` yazarak bulabileceğinizi bilmek faydalı olabilir. ``` let abc = "abc"; @@ -661,20 +669,21 @@ console.log(abc.length); {{if interactive -Most exercises contain a piece of code that you can modify to solve the exercise. Remember that you can click code blocks to edit them. +Çoğu egzersiz, egzersizi çözmek için değiştirebileceğiniz bir kod parçası içerir. Kod bloklarını düzenlemek için üzerlerine tıklayabileceğinizi unutmayın. ``` -// Your code here. +// Kodunuz buraya. ``` + if}} {{hint {{index "triangle (exercise)"}} -You can start with a program that prints out the numbers 1 to 7, which you can derive by making a few modifications to the [even number printing example](program_structure#loops) given earlier in the chapter, where the `for` loop was introduced. +1'den 7'ye kadar olan sayıları yazdıran bir programla başlayabilirsiniz. Bunun için, [bu bölümden önce tanıtılan `for` döngüsü örneğine](program_structure#loops) birkaç değişiklik yaparak türetebilirsiniz. -Now consider the equivalence between numbers and strings of hash characters. You can go from 1 to 2 by adding 1 (`+= 1`). You can go from `"#"` to `"##"` by adding a character (`+= "#"`). Thus, your solution can closely follow the number-printing program. +Şimdi, sayıların ve # karakterlerinden oluşan dizelerinin arasındaki bağlantıyı düşünün. 1'den 2'ye gitmek için 1 ekleyebilirsiniz (`+= 1`). "#" den "##" e gitmek için bir karakter ekleyebilirsiniz (`+= "#"`). Bu nedenle, çözümünüz yakından sayı yazdırma programını takip edebilir. hint}} @@ -682,73 +691,79 @@ hint}} {{index "FizzBuzz (exercise)", loop, "conditional execution"}} -Write a program that uses `console.log` to print all the numbers from 1 to 100, with two exceptions. For numbers divisible by 3, print `"Fizz"` instead of the number, and for numbers divisible by 5 (and not 3), print `"Buzz"` instead. +1'den 100'e kadar olan değerleri çıktı olarak `console.log` fonksiyonunu aracılığıyla yazdıracak ancak iki adet istisna sağlayacak bir program yaz. 3 sayısı ile bölünebilecek sayılar için sayıyı yazdırmak yerine `"Fizz"` ve 5 sayısı ile bölünüp 3 sayısı ile bölünmeyen sayılar için de sayı yerine `"Buzz"` yazdır. When you have that working, modify your program to print `"FizzBuzz"` for numbers that are divisible by both 3 and 5 (and still print `"Fizz"` or `"Buzz"` for numbers divisible by only one of those). +Çalışan bir şey elde ettiğinde gerektikçe değişiklikler yap ve programının `"FizzBuzz"` çıktısını 3 ve 5 ile bölünebilir sayılar için yazdırmasını sağla, ayrıca güncel sayı sadece 3 veya 5'e bölünebiliyorsa sadece `"Fizz"` veya `"Buzz"` çıktısını yazdırdığına emin ol. -(This is actually an ((interview question)) that has been claimed to weed out a significant percentage of programmer candidates. So if you solved it, your labor market value just went up.) +(Bu aslında bir ((mülakat sorusu)) ve iddia edildiğine göre programcı adaylarının önemli bir yüzdesini elemek için kullanılıyor. Dolayısıyla, eğer çözdüyseniz, bu sizin işgücü piyasası değerinizin arttığı anlamına geliyor.) {{if interactive + ``` -// Your code here. +// Kodunuz buraya. ``` + if}} {{hint {{index "FizzBuzz (exercise)", "remainder operator", "% operator"}} -Going over the numbers is clearly a looping job, and selecting what to print is a matter of conditional execution. Remember the trick of using the remainder (`%`) operator for checking whether a number is divisible by another number (has a remainder of zero). +Sayıları geçmek açıkça bir döngü işidir ve neyi yazdıracağını seçmek bir koşullu ifade meselesidir. Bir sayının başka bir sayıya bölünebilir olup olmadığını (kalanının sıfır olup olmadığını) kontrol etmek için modülo (%) operatörünü kullanmayı unutmayın. -In the first version, there are three possible outcomes for every number, so you'll have to create an `if`/`else if`/`else` chain. +İlk versiyonda, her sayı için üç olası sonuç vardır, bu nedenle bir `if`/`else if`/`else` zinciri oluşturmanız gerekecek. {{index "|| operator", ["if keyword", chaining]}} -The second version of the program has a straightforward solution and a clever one. The simple solution is to add another conditional "branch" to precisely test the given condition. For the clever solution, build up a string containing the word or words to output and print either this word or the number if there is no word, potentially by making good use of the `||` operator. +Programın ikinci versiyonunun basit bir çözümü ve zekice bir çözümü vardır. Basit çözüm, verilen koşulu kesin olarak test etmek için başka bir koşullu "dal" eklemektir. Zeki çözüm için, çıktılanacak kelime veya kelimeleri içeren bir dize oluşturun ve bu kelimeyi veya numarayı yazdırın eğer kelime yoksa potansiyel olarak || operatörünü iyi kullanarak sadece sayıyı yazdırın. hint}} -### Chessboard +### Satranç tahtası {{index "chessboard (exercise)", loop, [nesting, "of loops"], "newline character"}} -Write a program that creates a string that represents an 8×8 grid, using newline characters to separate lines. At each position of the grid there is either a space or a "#" character. The characters should form a chessboard. +Bir satır başına yeni satır karakterleri kullanarak satırları ayıran bir 8x8 ızgarayı temsil edecek dizeyi oluşturan bir program yazın. Izgaranın her bir konumunda ya bir boşluk ya da "#" karakteri bulunmalıdır. Karakterler bir satranç tahtası oluşturmalıdır. -Passing this string to `console.log` should show something like this: +Bu diziyi `console.log`'a verirseniz şuna benzer bir şey görüntülemelisiniz: ```{lang: null} # # # # -# # # # +# # # # # # # # -# # # # +# # # # # # # # -# # # # +# # # # # # # # -# # # # +# # # # ``` -When you have a program that generates this pattern, define a binding `size = 8` and change the program so that it works for any `size`, outputting a grid of the given width and height. +Bu deseni üreten bir programa sahip olduğunuzda, bir bağlantı `size = 8` tanımlayın ve programı verilen genişlik ve yükseklikteki bir ızgarayı çıkaracak şekilde değiştirin. {{if interactive + ``` -// Your code here. +// Kodunuz buraya. ``` + if}} {{hint {{index "chess board (exercise)"}} -You can build the string by starting with an empty one (`""`) and repeatedly adding characters. A newline character is written `"\n"`. +Dizeyi başlangıçta boş bir dize (`""`) ile başlayarak ve ardından karakterleri tekrar tekrar ekleyerek oluşturabilirsiniz. Bir satır sonu karakteri `"\n"` olarak yazılır. {{index [nesting, "of loops"], [braces, "block"]}} -To work with two ((dimensions)), you will need a ((loop)) inside of a loop. Put braces around the bodies of both loops to make it easy to see where they start and end. Try to properly indent these bodies. The order of the loops must follow the order in which we build up the string (line by line, left to right, top to bottom). So the outer loop handles the lines, and the inner loop handles the characters on a line. +İki ((boyut)) ile çalışmak için iç içe olan iki ((döngü))'ye ihtiyacınız olacak. Her iki döngünün vücutlarını görmeyi kolaylaştırmak için her iki döngünün de etrafına parantezler koyun. Bu vücutları uygun şekilde girintileyin. Döngülerin sırası, diziyi nasıl oluşturduğumuzun sırasını izlemelidir (satır satır, soldan sağa, yukarıdan aşağıya). Bu nedenle, dış döngü satırları ele alır ve iç içe döngü bir satırdaki karakterleri ele alır. {{index "counter variable", "remainder operator", "% operator"}} You'll need two bindings to track your progress. To know whether to put a space or a hash sign at a given position, you could test whether the sum of the two counters is even (`% 2`). +İlerlemenizi izlemek için iki farklı bağlantıya ihtiyacınız olacak. Belirli bir konumda bir boşluk mu yoksa bir "#" işareti mi ekleyeceğinizi belirlemeniz için, iki farklı sayaç olarak kullandığınız bağlantıların değerlerinin toplamı çift mi yoksa tek mi olduğunu test edebilirsiniz (`% 2`). -Terminating a line by adding a newline character must happen after the line has been built up, so do this after the inner loop but inside the outer loop. +Bir satırı sonlandırmak için yeni bir satır karakteri eklemeyi dış döngü içinde ancak iç içe olan döngünün dışında yapmalısınız. hint}} diff --git a/03_functions.md b/03_functions.md index ab8622ae..1e63fb02 100644 --- a/03_functions.md +++ b/03_functions.md @@ -1,8 +1,8 @@ -# Functions +# Fonksiyonlar {{quote {author: "Donald Knuth", chapter: true} -People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones. +İnsanlar bilgisayar biliminin sadece dahilerin ortaya koyabileceği bir sanat olduğunu düşünüyorlar ancak durum tam olarak öyle değil, sadece birbirini takip eden birçok insanın küçük taşlarla bir duvar oluşturması gibi. quote}} @@ -12,19 +12,19 @@ quote}} {{index function, [code, "structure of"]}} -Functions are one of the most central tools in JavaScript programming. The concept of wrapping a piece of program in a value has many uses. It gives us a way to structure larger programs, to reduce repetition, to associate names with subprograms, and to isolate these subprograms from each other. +Fonksiyonlar, JavaScript programlamasındaki en merkezi araçlardan biridir. Bir program parçasını bir değere sarma kavramının birçok yararlı kullanımı vardır. Daha büyük programları yapılandırmanın, tekrarı azaltmanın, alt programları isimlendirmenin ve bu alt programları birbirinden izole etmenin bir yolunu sağlar. -The most obvious application of functions is defining new ((vocabulary)). Creating new words in prose is usually bad style, but in programming, it is indispensable. +Fonksiyonların en açık uygulamalarından biri yeni ((kelime dağarcığı)) tanımlamaktır. Konuşma dilinde yeni kelimeler oluşturmak genellikle kötü bir stildir ancak programlamada bu bir vazgeçilmezdir. {{index abstraction, vocabulary}} -Typical adult English speakers have some 20,000 words in their vocabulary. Few programming languages come with 20,000 commands built in. And the vocabulary that _is_ available tends to be more precisely defined, and thus less flexible, than in human language. Therefore, we _have_ to introduce new words to avoid excessive verbosity. +Tipik yetişkin İngilizce konuşanların kelime dağarcığında yaklaşık 20.000 kelime bulunmaktadır ancak muhtemelen hiç bir programlama dili 20.000 komutla beraber gelmez. Ayrıca, mevcut olan kelime dağarcığı da daha kesin bir şekilde tanımlanmıştır ve bundan ötürü insan dilindeki kadar esnek olmaz. Bu nedenle, aşırı ayrıntıdan kaçınmak için yeni kelimeler tanıtmamız gerekmektedir. -## Defining a function +## Fonksiyonlar tanımlamak {{index "square example", [function, definition], [binding, definition]}} -A function definition is a regular binding where the value of the binding is a function. For example, this code defines `square` to refer to a function that produces the square of a given number: +Bir fonksiyon tanımı, değeri bir fonksiyon olan basit bir bağlantıdır. Örneğin, bu kod, `square` bağlantısını bir sayının karesini üreten bir fonksiyona atayacak sağlayacak şekilde tanımlar: ``` const square = function(x) { @@ -38,11 +38,11 @@ console.log(square(12)); {{indexsee "curly braces", braces}} {{index [braces, "function body"], block, [syntax, function], "function keyword", [function, body], [function, "as value"], [parentheses, arguments]}} -A function is created with an expression that starts with the keyword `function`. Functions have a set of _((parameter))s_ (in this case, only `x`) and a _body_, which contains the statements that are to be executed when the function is called. The body of a function created this way must always be wrapped in braces, even when it consists of only a single ((statement)). +Bir fonksiyon, `function` anahtar kelimesiyle başlayan bir ifade ile oluşturulur. Fonksiyonların bir dizi _((parametre))leri_ (bu durumda sadece `x`) ve çağrıldığında yürütülecek ((ifade))leri içeren bir _gövdesi_ vardır. Bu şekilde oluşturulan bir fonksiyonun gövdesi yalnızca tek bir ((beyan)) içerse bile her zaman süslü parantezlerle sarılmalıdır. {{index "roundTo example"}} -A function can have multiple parameters or no parameters at all. In the following example, `makeNoise` does not list any parameter names, whereas `roundTo` (which rounds `n` to the nearest multiple of `step`) lists two: +Bir fonksiyon birden fazla parametreye sahip olabilirken ayrıca hiç parametreye sahip olmayabilir. Aşağıdaki örnekte, `makeNoise` hiçbir parametre adı listelemezken (`n`'yi `step`'in en yakın katına yuvarlayan) `roundTo` iki parametre listeler: ``` const makeNoise = function() { @@ -63,26 +63,26 @@ console.log(roundTo(23, 10)); {{index "return value", "return keyword", undefined}} -Some functions, such as `roundTo` and `square`, produce a value, and some don't, such as `makeNoise`, whose only result is a ((side effect)). A `return` statement determines the value the function returns. When control comes across such a statement, it immediately jumps out of the current function and gives the returned value to the code that called the function. A `return` keyword without an expression after it will cause the function to return `undefined`. Functions that don't have a `return` statement at all, such as `makeNoise`, similarly return `undefined`. +Bazı `roundTo` ve `square` gibi fonksiyonlar bir değer üretirken bazılarıysa `makeNoise` gibi sadece bir ((yan etki))ye sebep olur. Bir `return` beyanı, fonksiyonun çalıştırıldığında döndüreceği değeri belirler. Program kontrolü böyle bir beyanla karşılaştığında, derhal mevcut fonksiyondan çıkar ve fonksiyonu çağıran koda o beyanda belirtilen değeri verir. Bir ifade verilmeden yazılan `return` anahtar kelimesi, fonksiyonun `undefined` değerini döndürmesine neden olur. `makeNoise` gibi hiçbir `return` beyanı olmayan fonksiyonlar da benzer şekilde `undefined` döndürürler. {{index parameter, [function, application], [binding, "from parameter"]}} -Parameters to a function behave like regular bindings, but their initial values are given by the _caller_ of the function, not the code in the function itself. +Bir fonksiyona gelen parametreler sıradan değişkenlerde olan bağlantılar gibi davranırlar ancak kendilerinin başlangıç değerlerini fonksiyon içindeki kod tarafından değil, fonksiyonun çağırıcısı tarafından alırlar. -## Bindings and scopes +## Bağlantılar ve kapsamlar {{indexsee "top-level scope", "global scope"}} {{index "var keyword", "global scope", [binding, global], [binding, "scope of"]}} -Each binding has a _((scope))_, which is the part of the program in which the binding is visible. For bindings defined outside of any function, block, or module (see [Chapter ?](modules)), the scope is the whole program—you can refer to such bindings wherever you want. These are called _global_. +Her bağlantının bir *((kapsam))*ı vardır ve belirli bağlantılar belirli kapsamların içinde görünürdürler. Herhangi bir fonksiyon, blok veya modül(bkz. [Bölüm ?](modules)) içinde olmayacak şekilde tanımlanmış bağlantılar için kapsam tüm programdır - bu tür bağlantılara istediğiniz yerden ulaşabilirsiniz. Bunlara _global_ denir. {{index "local scope", [binding, local]}} -Bindings created for function ((parameter))s or declared inside a function can be referenced only in that function, so they are known as _local_ bindings. Every time the function is called, new instances of these bindings are created. This provides some isolation between functions—each function call acts in its own little world (its local environment) and can often be understood without knowing a lot about what's going on in the global environment. +Ancak bir fonksiyon parametreleri için oluşturulan bağlantılar veya bir fonksiyon içinde oluşturulan bağlantılar yalnızca o fonksiyon içerisinden ulaşılabilir, bu yüzden _yerel_ bağlantılar olarak bilinirler. Her fonksiyon çağrıldığında, bu bağlamaların yeni kopyaları oluşturulur. Bu, fonksiyonlar arasında bir izolasyon sağlar - her fonksiyon çağrısı kendi küçük dünyasında (yerel ortamında) hareket eder ve genellikle global ortamda neler olduğunu çok fazla bilmeden anlaşılabilir. {{index "let keyword", "const keyword", "var keyword"}} -Bindings declared with `let` and `const` are in fact local to the _((block))_ in which they are declared, so if you create one of those inside of a loop, the code before and after the loop cannot "see" it. In pre-2015 JavaScript, only functions created new scopes, so old-style bindings, created with the `var` keyword, are visible throughout the whole function in which they appear—or throughout the global scope, if they are not in a function. +`let` ve `const` ile oluşturulan bağlantılar aslında oluşturuldukları _((blok))_ için yereldirler, bundan ötürü döngü içinde bir bağlantı oluşturursanız, döngüden önceki ve sonraki kod onu "göremez". 2015 öncesi JavaScript'te, fonksiyonlar yeni kapsam oluşturabilen tek yapı oldukları için, `var` anahtar kelimesiyle oluşturulan eski tarz bağlantılar, bulundukları fonksiyonun tamamında - veya bir fonksiyon içinde değillerse, global kapsamda görünürlerdi. ``` let x = 10; // global @@ -94,7 +94,7 @@ if (true) { {{index [binding, visibility]}} -Each ((scope)) can "look out" into the scope around it, so `x` is visible inside the block in the example. The exception is when multiple bindings have the same name—in that case, code can see only the innermost one. For example, when the code inside the `halve` function refers to `n`, it is seeing its _own_ `n`, not the global `n`. +Her ((kapsam)), çevresindeki kapsamlara "bakabilir", bu yüzden örnekteki bloğun içinde `x` görülebilir durumdadır. Tek istisna, birden fazla aynı isimli bağlantının durumda, kod yalnızca en içteki bağlantıyı görebilir. Örneğin, `halve` fonksiyonu içindeki kod `n`'ye atıfta bulunduğunda, global kapsamdaki `n` değerini değil, kendi `n` değerini görür. Buna içerideki aynı isimdeki bir bağlantının dışarıdaki aynı isimdeki bir bağlantıyı gölgelemesinden ötürü "gölgeleme" denir ve kafa karışıklığına sebep olabileceğinden ötürü önlenilmeye çalışılmalıdır. ``` const halve = function(n) { @@ -110,15 +110,15 @@ console.log(n); {{id scoping}} -## Nested scope +### Gömülü kapsamlar {{index [nesting, "of functions"], [nesting, "of scope"], scope, "inner function", "lexical scoping"}} -JavaScript distinguishes not just global and local bindings. Blocks and functions can be created inside other blocks and functions, producing multiple degrees of locality. +JavaScript, sadece _global_ ve _yerel_ bağlantıları ayırt etmez. Bloklar ve fonksiyonlar diğer bloklar ve fonksiyonlar içinde oluşturulabilir, böylece çoklu kapsamlar oluştururlar. {{index "landscape example"}} -For example, this function—which outputs the ingredients needed to make a batch of hummus—has another function inside it: +Örneğin, humus yapmak için gerekli malzemeleri çıkaran bu fonksiyon, içinde başka bir fonksiyona sahiptir: ``` const hummus = function(factor) { @@ -140,19 +140,19 @@ const hummus = function(factor) { {{index [function, scope], scope}} -The code inside the `ingredient` function can see the `factor` binding from the outer function, but its local bindings, such as `unit` or `ingredientAmount`, are not visible in the outer function. +`ingredient` fonksiyonunun içindeki kod, dış fonksiyon `factor` bağlantısını görebilir. Ancak, `unit` veya `ingredientAmount` gibi içerisinde barındırdığı yerel bağlantılar dış fonksiyondan görülemez. -The set of bindings visible inside a block is determined by the place of that block in the program text. Each local scope can also see all the local scopes that contain it, and all scopes can see the global scope. This approach to binding visibility is called _((lexical scoping))_. +Bir bloğun içinde görünür olan bağlantılar kümesi, o bloğun program metnindeki konumuna göre belirlenir. Her yerel kapsam, kendisini içeren tüm yerel kapsamları görebilir ve tüm kapsamlar da global kapsamı görebilir. Bu bağlantılardaki bu görünürlük yaklaşımına ((lexical scoping(sözcüksel kapsam belirleme))) denir. -## Functions as values +## Değer olarak fonksiyonlar {{index [function, "as value"], [binding, definition]}} -A function binding usually simply acts as a name for a specific piece of the program. Such a binding is defined once and never changed. This makes it easy to confuse the function and its name. +Bir fonksiyon bağlantısı genellikle basitçe programın belirli bir parçası için bir isim olarak işlev görür ve bu tür bir bağlantılar bir kez tanımlanıp asla tekrardan değiştirilmezler. Bu, fonksiyonu ve adını karıştırmayı kolaylaştırır. {{index [binding, assignment]}} -But the two are different. A function value can do all the things that other values can do—you can use it in arbitrary ((expression))s, not just call it. It is possible to store a function value in a new binding, pass it as an argument to a function, and so on. Similarly, a binding that holds a function is still just a regular binding and can, if not constant, be assigned a new value, like so: +Ancak, ikisi farklıdır. Bir fonksiyon değeri, diğer değerlerin yapabileceği tüm işleri yapabilir - onu sadece çağırmakla kalmaz, istediğiniz yerde kullanabilirsiniz. Bir fonksiyon değerini yeni bir bağlantıya depolamak ve bir fonksiyona bir argüman olarak iletmek vb. mümkündür. Benzer şekilde, fonksiyon tutan bir bağlantı, hala yalnızca sıradan bir bağlantıdır ve eğer sabit bir şekilde oluşturulmadıysa(`const`) kendisine şu şekilde yeni bir değer atanabilir: ```{test: no} let launchMissiles = function() { @@ -165,13 +165,13 @@ if (safeMode) { {{index [function, "higher-order"]}} -In [Chapter ?](higher_order), we'll discuss the interesting things that we can do by passing around function values to other functions. +[Bölüm ?](higher_order)'da, fonksiyon değerlerini diğer fonksiyonlara argüman olarak vererek yapılabilen ilginç şeyleri tartışacağız. -## Declaration notation +## Beyan notasyonu {{index [syntax, function], "function keyword", "square example", [function, definition], [function, declaration]}} -There is a slightly shorter way to create a function binding. When the `function` keyword is used at the start of a statement, it works differently: +Bir işlev bağlantısı oluşturmanın biraz daha kısa bir yolu vardır. `function` anahtar kelimesi bir ifadenin başında kullanıldığında, farklı şekilde çalışır. ```{test: wrap} function square(x) { @@ -181,9 +181,9 @@ function square(x) { {{index future, "execution order"}} -This is a function _declaration_. The statement defines the binding `square` and points it at the given function. It is slightly easier to write and doesn't require a semicolon after the function. +Bu bir fonksiyon _beyanıdır_. Beyan, `square` bağlantısını tanımlar ve onu verilen fonksiyona işaret eder. Yazması biraz daha kolaydır ve işlevden sonra noktalı virgül gerektirmez. -There is one subtlety with this form of function definition. +Bu fonksiyon tanımlama formuyla alakalı bir nüans vardır. ``` console.log("The future says:", future()); @@ -193,13 +193,13 @@ function future() { } ``` -The preceding code works, even though the function is defined _below_ the code that uses it. Function declarations are not part of the regular top-to-bottom flow of control. They are conceptually moved to the top of their scope and can be used by all the code in that scope. This is sometimes useful because it offers the freedom to order code in a way that seems the clearest, without worrying about having to define all functions before they are used. +Fonksiyon, kullanıldığı kodun _altında_ tanımlanmış olsa bile önceki kod çalışır. Fonksiyon bildirimleri, düzenli olarak yukarıdan aşağıya kontrol akışının bir parçası değildir. Kavramsal olarak içinde bulundukları kapsamın en üstüne taşınır ve bu kapsamdaki tüm kod tarafından kullanılabilir. Bu bazen yararlı olabilir çünkü tüm fonksiyonların kullanılmadan önce tanımlanması gerekmeksizin kodu en net sayılan şekilde düzenleme özgürlüğü sunar. -## Arrow functions +## Ok notasyonu {{index function, "arrow function"}} -There's a third notation for functions, which looks very different from the others. Instead of the `function` keyword, it uses an arrow (`=>`) made up of an equal sign and a greater-than character (not to be confused with the greater-than-or-equal operator, which is written `>=`): +Fonksiyonlar için diğerlerinden çok farklı görünen üçüncü bir gösterim var. `function` anahtar kelimesi yerine, büyük eşittir operatörüyle(`>=`) karıştırılmaması gereken eşitlik ve büyüktür işaretlerinden oluşan bir ok (`=>`) kullanır. ```{test: wrap} const roundTo = (n, step) => { @@ -210,11 +210,11 @@ const roundTo = (n, step) => { {{index [function, body]}} -The arrow comes _after_ the list of parameters and is followed by the function's body. It expresses something like "this input (the ((parameter))s) produces this result (the body)". +Ok, parametre listesinin ardından gelir ve işlevin gövdesi takip eder. "Bu giriş (parametreler) bu sonucu (gövdeyi) üretir" gibi bir şey ifade eder. {{index [braces, "function body"], "square example", [parentheses, arguments]}} -When there is only one parameter name, you can omit the parentheses around the parameter list. If the body is a single expression, rather than a ((block)) in braces, that expression will be returned from the function. So, these two definitions of `square` do the same thing: +Tek bir parametre adı olduğunda, parametre listesinin etrafındaki parantezleri yazmanıza gerek yoktur. Gövde, süslü parantezlerle oluşturulmuş bir blok yerine, tek satırlık bir ifade ise bu ifade fonksiyondan `return` anahtar kelimesini kullanmadan kullanmışçasına döndürmenizi sağlar. Bu nedenle, bu iki square tanımı aynı şeyi yapar: ``` const square1 = (x) => { return x * x; }; @@ -223,7 +223,7 @@ const square2 = x => x * x; {{index [parentheses, arguments]}} -When an arrow function has no parameters at all, its parameter list is just an empty set of parentheses. +Bir ok işlevinin hiç parametresi olmadığında, parametre listesi yalnızca boş bir parantez kümesidir. ``` const horn = () => { @@ -233,16 +233,16 @@ const horn = () => { {{index verbosity}} -There's no deep reason to have both arrow functions and `function` expressions in the language. Apart from a minor detail, which we'll discuss in [Chapter ?](object), they do the same thing. Arrow functions were added in 2015, mostly to make it possible to write small function expressions in a less verbose way. We'll use them often in [Chapter ?](higher_order). +Dilin bir fonksiyonu hem ok fonksiyonlarıyla hem de `function` anahtar kelimesiyle oluşturulma olasılığını sağlamasının derin bir nedeni yoktur. Küçük bir ayrıntı dışında, [Bölüm ?](object)'da da konuşacağımız gibi bunlar aynı işi yaparlar. Ok fonksiyonları 2015 yılında daha rahat bir şekilde küçük fonksiyon ifadelerini yazmayı mümkün kılmak adına eklendi. [Bölüm ?](higher_order)'da çokça kullanacağız. {{id stack}} -## The call stack +## Çağrı yığını {{indexsee stack, "call stack"}} {{index "call stack", [function, application]}} -The way control flows through functions is somewhat involved. Let's take a closer look at it. Here is a simple program that makes a few function calls: +Kontrolün fonksiyonlar arasında nasıl akış gösterdiği biraz karmaşıktır, hadi buna daha yakından bakalım. İşte birkaç fonksiyon çağrısı yapan basit bir program: ``` function greet(who) { @@ -254,29 +254,29 @@ console.log("Bye"); {{index ["control flow", functions], "execution order", "console.log"}} -A run through this program goes roughly like this: the call to `greet` causes control to jump to the start of that function (line 2). The function calls `console.log`, which takes control, does its job, and then returns control to line 2. There, it reaches the end of the `greet` function, so it returns to the place that called it—line 4. The line after that calls `console.log` again. After that returns, the program reaches its end. +Bu programın çalışması yaklaşık olarak şöyle gider: `greet` fonksiyonuna yapılan çağrı, kontrolün o fonksiyonun başına (2. satır) atlamasına neden olur. Fonksiyon, `console.log`'u çağırır, kontrolü alır, işini yapar ve ardından kontrolü 2. satıra geri verir. Orada `greet` fonksiyonunun sonuna ulaşır, bu nedenle onu çağıran yere geri döner, ki bu da 4. satırdır. Bundan sonra bir sonraki satır tekrar `console.log` çağrısı yapar. Dönüş yaptıktan sonra, program sonuna ulaşır. -We could show the flow of control schematically like this: +Kontrol akışını şematik olarak şöyle gösterebiliriz: ```{lang: null} not in function - in greet - in console.log - in greet + in greet + in console.log + in greet not in function - in console.log + in console.log not in function ``` {{index "return keyword", [memory, call stack]}} -Because a function has to jump back to the place that called it when it returns, the computer must remember the context from which the call happened. In one case, `console.log` has to return to the `greet` function when it is done. In the other case, it returns to the end of the program. +Bir fonksiyona dönüş yapıldığında çağrıldığı yere geri kontrol akışının geri dönebilmesi için, bilgisayarın, çağrının nereden yapıldığı bağlamını hatırlaması gerekir. Bir durumda, `console.log`, işi bittiğinde `greet` fonksiyonuna dönmelidir. Diğer bir durumdaysa programın sonuna dönmelidir. -The place where the computer stores this context is the _((call stack))_. Every time a function is called, the current context is stored on top of this stack. When a function returns, it removes the top context from the stack and uses that context to continue execution. +Bilgisayarın bu bağlamı sakladığı yer _((çağrı yığını))_ dır. Bir fonksiyon çağrıldığında, mevcut bağlam bu yığının üstüne depolanır. Bir işlev döndüğünde, yığının üstündeki bağlamı kaldırır ve kaldırdığı bu bağlamı programı yürütmeye devam etmek için kullanır. {{index "infinite loop", "stack overflow", recursion}} -Storing this stack requires space in the computer's memory. When the stack grows too big, the computer will fail with a message like "out of stack space" or "too much recursion". The following code illustrates this by asking the computer a really hard question that causes an infinite back-and-forth between two functions. Or rather, it _would_ be infinite, if the computer had an infinite stack. As it is, we will run out of space, or "blow the stack". +Bu yığını saklamak, bilgisayarın belleğinde yer gerektirir. Yığın çok büyük hale geldiğinde, bilgisayar "yığın depolama alanı kalmadı" veya "çok fazla özyineleme yapıldı" gibi bir hata mesajıyla başarısız olacaktır. Aşağıdaki kod, bilgisayara sonsuz geriye doğru gidip gelme gerektiren gerçekten zor bir soru sorarak bunu gösterir. Aslında, bilgisayarın gerçekten sonsuz bir yığını olsaydı _sonsuz olurdu_ ancak şu anki durumda alanı tüketir ve "yığı taşarız". ```{test: no} function chicken() { @@ -289,11 +289,11 @@ console.log(chicken() + " came first."); // → ?? ``` -## Optional Arguments +## Opsiyonel argümanlar {{index argument, [function, application]}} -The following code is allowed and executes without any problem: +Aşağıdaki koda izin verilir ve herhangi bir sorun olmaksızın çalışır: ``` function square(x) { return x * x; } @@ -301,13 +301,15 @@ console.log(square(4, true, "hedgehog")); // → 16 ``` -We defined `square` with only one ((parameter)). Yet when we call it with three, the language doesn't complain. It ignores the extra arguments and computes the square of the first one. +`square`'i yalnızca bir ((parametre)) ile tanımladık. Ancak üç adet argümanla çağırdığımızda JavaScript'in şikayet etmediğini ve ek argümanları yok sayıp ilk argümanın karesini hesapladığını gözlemliyoruz. {{index undefined}} -JavaScript is extremely broad-minded about the number of arguments you can pass to a function. If you pass too many, the extra ones are ignored. If you pass too few, the missing parameters are assigned the value `undefined`. +JavaScript, bir işleve kaç argüman geçirdiğiniz konusunda son derece açık fikirlidir. Çok fazla argüman verirseniz, fazladan olanlar yok sayılır. Çok az argüman verirseniz, eksik parametreler `undefined` değerine otomatik olarak atanır. -The downside of this is that it is possible—likely, even—that you'll accidentally pass the wrong number of arguments to functions. And no one will tell you about it. The upside is that you can use this behavior to allow a function to be called with different numbers of arguments. For example, this `minus` function tries to imitate the `-` operator by acting on either one or two arguments: +Bunun dezavantajı, fonksiyonlara olası olarak yanlış sayıda argüman verecek olursanız size kimsenin bundan haber vermeyecek olmasıdır. + +Avantajı ise, bu davranışın bir fonksiyonun farklı sayılarda argümanlarla çağrılmasına izin vermek için kullanılabilmesidir. Örneğin, bu `minus` fonksiyonu, bir veya iki argümanla etkileşime girerek `-` operatörünü taklit etmeye çalışır: ``` function minus(a, b) { @@ -324,7 +326,11 @@ console.log(minus(10, 5)); {{id roundTo}} {{index "optional argument", "default value", parameter, ["= operator", "for default value"] "roundTo example"}} -If you write an `=` operator after a parameter, followed by an expression, the value of that expression will replace the argument when it is not given. For example, this version of `roundTo` makes its second argument optional. If you don't provide it or pass the value `undefined`, it will default to one: +Bir parametrenin ardından `=` operatörünü yazar ve onu bir ifade ile takip ederseniz, o parametre için bir argüman değeri verilmediğinde o verdiğiniz ifade, parametrenin varsayılan argüman değeri haline gelir. + +{{index "roundTo example"}} + +Örneğin, bu versiyon `roundTo` fonksiyonunun ikinci argümanını opsiyonel hale getirir. Eğer `undefined` değerini argüman olarak vermezseniz, o ikinci parametrenin varsayılan argüman değeri 1 olacaktır. ```{test: wrap} function roundTo(n, step = 1) { @@ -340,20 +346,20 @@ console.log(roundTo(4.5, 2)); {{index "console.log"}} -The [next chapter](data#rest_parameters) will introduce a way in which a function body can get at the whole list of arguments it was passed. This is helpful because it allows a function to accept any number of arguments. For example, `console.log` does this, outputting all the values it is given: +[Sonraki bölümde](data#rest_parameters), bir fonksiyon gövdesinin aldığı tüm argüman listesine nasıl erişebileceğimizi göreceğiz. Bu, bir fonksiyonun herhangi bir sayıda argümanı kabul etmesini mümkün kılar. Örneğin, `console.log` bunu yapar ve kendisine verilen tüm değerleri çıktı olarak gösterir. ``` console.log("C", "O", 2); // → C O 2 ``` -## Closure +## Kapama {{index "call stack", "local binding", [function, "as value"], scope}} -The ability to treat functions as values, combined with the fact that local bindings are recreated every time a function is called, brings up an interesting question: what happens to local bindings when the function call that created them is no longer active? +Fonksiyonları herhangi bir değer olarak ele alabilme yeteneği ve fonksiyonların her çağrıldığında yerel bağlantılarının yeniden oluşturulması özellikleri ortaya ilginç bir soru çıkarır. Yerel bağlara onları oluşturan fonksiyon çağrısı artık etkin değilken ne olur? -The following code shows an example of this. It defines a function, `wrapValue`, that creates a local binding. It then returns a function that accesses and returns this local binding: +Aşağıdaki kod, bunun bir örneğini gösterir. Bir yerel bağlantı oluşturan `wrapValue` adında bir fonksiyon tanımlar. Ardından bu yerel bağlantıya erişen ve bunu döndüren bir fonksiyon döndürür. ``` function wrapValue(n) { @@ -369,13 +375,13 @@ console.log(wrap2()); // → 2 ``` -This is allowed and works as you'd hope—both instances of the binding can still be accessed. This situation is a good demonstration of the fact that local bindings are created anew for every call, and different calls don't affect each other's local bindings. +Bu izin verilir ve umduğunuz gibi çalışır - her iki ayrı yaratılmış bağlam hala erişilebilir. Bu durum, yerel bağlantıların her çağrı için yeniden oluşturulduğunu ve farklı çağrıların birbirlerinin yerel bağlantılarını etkilemediğini iyi bir şekilde gösterir. -This feature—being able to reference a specific instance of a local binding in an enclosing scope—is called _((closure))_. A function that references bindings from local scopes around it is called _a_ closure. This behavior not only frees you from having to worry about the lifetimes of bindings but also makes it possible to use function values in some creative ways. +Kapsayan bir kapsamdaki belirli bir yerel bağlantının yaratılmış spesifik bir değerine başvurabilmeyi sağlayan bu özellik _((kapama))_ olarak adlandırılır. Etrafındaki kapsamlardan yerel bağlantı veya bağlantılarını kullanan bir fonksiyonun kullandığı özelliğe kapama denir. Bu davranış, bağlantıların yaşam süreleri hakkında endişelenmenize gerek olmadığı için sizi serbest bırakmakla kalmaz, aynı zamanda fonksiyon değerlerini bazı yaratıcı şekillerde kullanmanızı mümkün kılar. {{index "multiplier function"}} -With a slight change, we can turn the previous example into a way to create functions that multiply by an arbitrary amount: +Önceki örneği hafif bir değişiklikle vereceğimiz herhangi bir miktarı istediğimiz herhangi bir miktarla çarpan fonksiyonlar oluştucak bir haline getirebiliriz. ``` function multiplier(factor) { @@ -389,19 +395,19 @@ console.log(twice(5)); {{index [binding, "from parameter"]}} -The explicit `local` binding from the `wrapValue` example isn't really needed, since a parameter is itself a local binding. +`wrapValue` örneğindeki `local` bağlantısı bir parametre zaten kendisi de yerel bir bağlantı olduğundan ötürü gerekli değildir. {{index [function, "model of"]}} -Thinking about programs like this takes some practice. A good mental model is to think of function values as containing both the code in their body and the environment in which they are created. When called, the function body sees the environment in which it was created, not the environment in which it is called. +Bu tür programları düşünmek biraz pratik gerektirir. İyi bir zihinsel model, fonksiyon değerlerininin hem içindeki kodu ve hem de oluşturuldukları ortamı içerdiklerini düşünmektir. Çağrıldığında, fonksiyon gövdesi oluşturulduğu ortamı görür, çağrıldığı yerin ortamını değil. -In the previous example, `multiplier` is called and creates an environment in which its `factor` parameter is bound to 2. The function value it returns, which is stored in `twice`, remembers this environment so that when that is called, it multiplies its argument by 2. +Örnekte, `multiplier` çağrılır ve `factor` parametresinin 2'ye bağlı olduğu bir ortam oluşturur. `twice` bağlantısı içinde depolanan bu döndürülen fonksiyon değeri, o ortamı hatırlar ki çağrıldığında argümanını 2 ile çarpar. -## Recursion +## Özyineleme {{index "power example", "stack overflow", recursion, [function, application]}} -It is perfectly okay for a function to call itself, as long as it doesn't do it so often that it overflows the stack. A function that calls itself is called _recursive_. Recursion allows some functions to be written in a different style. Take, for example, this `power` function, which does the same as the `**` (exponentiation) operator: +Bir fonksiyonun yığını taşırmadığı sürece kendini çağırması tamamen normaldir. Kendini çağıran bir fonskiyon _özyineleyici_ bir fonksiyon olarak adlandırılır. Özyineleyicilik, bazı işlevlerin farklı bir tarzda yazılmasına olanak tanır. Örneğin, `**` (üs alma) operatörü ile aynı işi yapan bu `power` adlı fonksiyona bakın: ```{test: wrap} function power(base, exponent) { @@ -418,36 +424,39 @@ console.log(power(2, 3)); {{index loop, readability, mathematics}} -This is rather close to the way mathematicians define exponentiation and arguably describes the concept more clearly than the loop we used in [Chapter ?](program_structure). The function calls itself multiple times with ever smaller exponents to achieve the repeated multiplication. +Bu, matematikçilerin üs alma işlemini tanımlama şekline oldukça yakındır ve tartışmaya açık bir şekilde [Bölüm ?](program_structure)'da kullandığımız döngüden daha açık bir şekilde kavramı tanımlar. Tekrarlı çarpma işlemini gerçekleştirmek için her seferinde daha küçük üslerle kendini birden çok kez çağırır. {{index [function, application], efficiency}} -This implementation has one problem, however: in typical JavaScript implementations, it's about three times slower than a version using a `for` loop. Running through a simple loop is generally cheaper than calling a function multiple times. +Ancak bu uygulamanın bir sorunu var: tipik JavaScript uygulamalarında, döngü kullanan bir versiyondan yaklaşık üç kat daha yavaştır. Basit bir döngüden geçmek, bir fonksiyonu birden çok kez çağırmaktan genellikle performans bakımından daha ucuzdur. {{index optimization}} -The dilemma of speed versus ((elegance)) is an interesting one. You can see it as a kind of continuum between human-friendliness and machine-friendliness. Almost any program can be made faster by making it bigger and more convoluted. The programmer has to find an appropriate balance. +Hızlılıkla ((zarafet)) arasındaki ikilem ilginçtir. Bu, insan dostu ve makine dostu olmak arasında bir tür devam eden bir durum olarak görülebilir. Neredeyse her program, onu daha büyük ve daha karmaşık hale getirerek daha hızlı hale getirilebilir. Programcının burada uygun bir dengeyi kendisinin belirlemesi gerekmektedir. -In the case of the `power` function, an inelegant (looping) version is still fairly simple and easy to read. It doesn't make much sense to replace it with a recursive function. Often, though, a program deals with such complex concepts that giving up some efficiency in order to make the program more straightforward is helpful. +Often, though, a program deals with such complex concepts that giving up some efficiency in order to make the program more straightforward is helpful. +`power` fonksiyonunun durumunda, zarif olmayan (döngü kullanan) bir versiyon hala oldukça basit ve okunması kolaydır. Onu özyinelemeli bir fonksiyonla değiştirmenin pek mantıklı değildir. Ancak, bir program genellikle öyle kompleks durumlarla ilgilenir ki programı daha anlaşılır hale getirmek için bazen verimliliğinden vazgeçmek daha mantıklıdır. {{index profiling}} -Worrying about efficiency can be a distraction. It's yet another factor that complicates program design, and when you're doing something that's already difficult, that extra thing to worry about can be paralyzing. +Verimlilik hakkında endişelenmek dikkati dağıtabilir. Bu, program tasarımını karmaşıklaştıran başka bir faktördür ve zaten zor olan bir şey yaparken, bu ekstra düşünme nedeniyle felç olabilirsiniz. {{index "premature optimization"}} -Therefore, you should generally start by writing something that's correct and easy to understand. If you're worried that it's too slow—which it usually isn't, since most code simply isn't executed often enough to take any significant amount of time—you can measure afterward and improve it if necessary. +Bu nedenle, genellikle doğru ve anlaşılması kolay olan bir şey yazarak başlamalısınız. Genellikle çoğu kod önemli miktarda çalıştırılmadığından ötürü aldığı zaman hakkında çok da endişelenmenize gerek yoktur, sonradan ölçebilir ve gerektiğinde iyileştirebilirsiniz. {{index "branching recursion"}} -Recursion is not always just an inefficient alternative to looping. Some problems really are easier to solve with recursion than with loops. Most often these are problems that require exploring or processing several "branches", each of which might branch out again into even more branches. +Özyineleme, sadece döngülerin verimsiz bir alternatifi değildir. Bazı problemler gerçekten özyineleme aracılığıyla döngülerden daha kolay bir şekilde çözülebilir. Çoğunlukla bunlar, birden çok "dal" keşfetmeyi veya işlemeyi gerektiren problemlerdir, her bir dal daha fazla dala ayrılabilir. {{id recursive_puzzle}} {{index recursion, "number puzzle example"}} -Consider this puzzle: by starting from the number 1 and repeatedly either adding 5 or multiplying by 3, an infinite set of numbers can be produced. How would you write a function that, given a number, tries to find a sequence of such additions and multiplications that produces that number? For example, the number 13 could be reached by first multiplying by 3 and then adding 5 twice, whereas the number 15 cannot be reached at all. +Bu bulmacayı düşünün: Sayı 1'den başlayarak ve tekrarlanarak ya 5 eklenerek ya da 3 ile çarpılarak, sonsuz bir sayı kümesi üretilebilir. Verilen bir sayıyı üreten böyle bir toplama ve çarpma dizisi bulmaya çalışan bir fonksiyonu nasıl yazarsınız? -Here is a recursive solution: +Örneğin, sayı 13'e, önce 3 ile çarpılarak ve ardından 5 iki kez eklenerek ulaşılabilirken, sayı 15 hiçbir şekilde ulaşılamaz. + +İşte bir özyinelemeli bir çözüm: ``` function findSolution(target) { @@ -468,19 +477,19 @@ console.log(findSolution(24)); // → (((1 * 3) + 5) * 3) ``` -Note that this program doesn't necessarily find the _shortest_ sequence of operations. It is satisfied when it finds any sequence at all. +Bu programın _en kısa_ işlem dizisini bulması gerekmediğini lütfen unutmayın, kendisi herhangi bir diziyi bulduğunda memnun olur. -It's okay if you don't see how this code works right away. Let's work through it, since it makes for a great exercise in recursive thinking. +Hemen nasıl çalıştığını görmüyorsanız endişelenmeyin. Bunun üzerinde çalışalım, çünkü bu, özyinelemeli düşünme pratiği için harika bir alıştırmadır. -The inner function `find` does the actual recursing. It takes two ((argument))s: the current number and a string that records how we reached this number. If it finds a solution, it returns a string that shows how to get to the target. If it can find no solution starting from this number, it returns `null`. +İçeride bulunan `find`, gerçek özyinelemeli işlemi yapmaktadır. İki ((argüman)) alır: mevcut sayı ve bu sayıya nasıl ulaştığımızı kaydeden bir dize. Bir çözüm bulursa, hedefe nasıl ulaşılacağını gösteren bir dize döndürür. Bu sayıdan başlayarak bir çözüm bulunamazsa, `null` döndürür. {{index null, "?? operator", "short-circuit evaluation"}} -To do this, the function performs one of three actions. If the current number is the target number, the current history is a way to reach that target, so it is returned. If the current number is greater than the target, there's no sense in further exploring this branch because both adding and multiplying will only make the number bigger, so it returns `null`. Finally, if we're still below the target number, the function tries both possible paths that start from the current number by calling itself twice, once for addition and once for multiplication. If the first call returns something that is not `null`, it is returned. Otherwise, the second call is returned, regardless of whether it produces a string or `null`. +Bunu yapmak için işlev üç eylemden birini gerçekleştirir. Eğer mevcut sayı hedef sayı ise, mevcut geçmiş, hedefe ulaşmanın bir yoludur, bu yüzden döndürülür. Eğer mevcut sayı hedeften büyükse, bu dalı daha fazla keşfetmenin bir anlamı yoktur çünkü hem eklemek hem de çarpmak sayıyı sadece daha büyük yapar, bu yüzden `null` döndürür. Son olarak, hala hedef sayıdan daha düşükse, fonksiyon mevcut sayıdan başlayan her iki olası yolu da denemek için kendisini iki kez çağırır, bir kez toplama ve bir kez çarpma için. İlk çağrı `null` döndürmeyen bir şey döndürürse, bu döndürülür. Aksi takdirde, ikinci çağrı, dize veya `null` üretip üretmediğine bakılmasızın döndürülür. {{index "call stack"}} -To better understand how this function produces the effect we're looking for, let's look at all the calls to `find` that are made when searching for a solution for the number 13: +Bu fonksiyonun istediğimiz etkiyi nasıl ürettiğini daha iyi anlamak için, 13 sayısı için bir çözüm ararken yapılan tüm `find` çağrılarına bakalım. ```{lang: null} find(1, "1") @@ -498,34 +507,34 @@ find(1, "1") found! ``` -The indentation indicates the depth of the call stack. The first time `find` is called, the function starts by calling itself to explore the solution that starts with `(1 + 5)`. That call will further recurse to explore _every_ continued solution that yields a number less than or equal to the target number. Since it doesn't find one that hits the target, it returns `null` back to the first call. There the `??` operator causes the call that explores `(1 * 3)` to happen. This search has more luck—its first recursive call, through yet _another_ recursive call, hits upon the target number. That innermost call returns a string, and each of the `??` operators in the intermediate calls passes that string along, ultimately returning the solution. +Girinti, çağrı yığınının derinliğini gösterir. `find` ilk kez çağrıldığında, `(1 + 5)` ile başlayan çözümü keşfetmek için kendisini çağırarak başlar. Bu çağrı, hedef sayıya eşit veya daha küçük bir sayı üreten _her_ çözümü keşfetmek için fonksiyonu tekrar eder. Hedefe ulaşan bir çözüm bulamadığından ötürü ilk çağrıya `null` döner. İlk çağrıda, `??` operatörü `(1 * 3)` ile keşfeden çağrının olmasını sağlar. Bu aramanın şansı yaver gider - ilk özyineleyici çağrısı, henüz başka bir özyineleyici çağrı aracılığıyla hedef sayıya ulaşır. En içteki çağrı bir dize döndürür, ve ara çağrılardaki her `??` operatörü bu diziyi çıktı olarak vererek sonunda çözümü döndürür. -## Growing functions +## Büyüyen fonksiyonlar {{index [function, definition]}} -There are two more or less natural ways for functions to be introduced into programs. +Programlara fonksiyonların tanıtılması için az buçuk doğal olan iki yol vardır. {{index repetition}} -The first occurs when you find yourself writing similar code multiple times. You'd prefer not to do that, as having more code means more space for mistakes to hide and more material to read for people trying to understand the program. So you take the repeated functionality, find a good name for it, and put it into a function. +İlk olarak, benzer kodları birden çok kez yazdığınızı fark edersiniz. Bunu yapmak istemezsiniz. Daha fazla kod, hataların saklanabileceği daha fazla alan ve programı anlamaya çalışan insanlar için okunacak daha fazla materyal demektir. Bu nedenle, tekrarlanan kodu alır, ona iyi bir isim bulur ve bir fonksiyon içine koyarsınız. -The second way is that you find you need some functionality that you haven't written yet and that sounds like it deserves its own function. You start by naming the function, then write its body. You might even start writing code that uses the function before you actually define the function itself. +İkinci yol, henüz yazmadığınız ancak kendi fonksiyonunu hak eden bazı koda ihtiyacınız olduğunu fark ettiğinizdir. Fonksiyonu adlandırmakla başlayacak ve ardından gövdesini yazacaksınız. Hatta fonksiyonu tanımlamadan önce fonksiyonu kullanan kodu yazmaya bile başlayabilirsiniz. {{index [function, naming], [binding, naming]}} -How difficult it is to find a good name for a function is a good indication of how clear a concept it is that you're trying to wrap. Let's go through an example. +Bir fonksiyon için iyi bir ad bulmanın ne kadar zor olduğu, kod yazmaya çalıştığınız kavramın ne kadar net olduğunun iyi bir göstergesidir. Bir örnek üzerinden geçelim. {{index "farm example"}} -We want to write a program that prints two numbers: the numbers of cows and chickens on a farm, with the words `Cows` and `Chickens` after them and zeros padded before both numbers so that they are always three digits long: +Bir çiftlikteki ineklerin ve tavukların sayısını, ardından her iki sayının yanına `Cows` ve `Chickens` kelimelerini ve her iki sayının da her zaman üç basamaklı olacak şekilde önceden doldurulmuş sıfırlarını yazdıran bir program yazmak istiyoruz. ```{lang: null} 007 Cows 011 Chickens ``` -This asks for a function of two arguments—the number of cows and the number of chickens. Let's get coding. +Bu, iki argümanlı bir fonksiyon gerektirir - ineklerin sayısı ve tavukların sayısı. Hadi kodlamaya başlayalım. ``` function printFarmInventory(cows, chickens) { @@ -545,13 +554,13 @@ printFarmInventory(7, 11); {{index ["length property", "for string"], "while loop"}} -Writing `.length` after a string expression will give us the length of that string. Thus, the `while` loops keep adding zeros in front of the number strings until they are at least three characters long. +Bir dize ifadesinin sonuna `.length` yazmak bize o dizenin uzunluğunu verecektir. Bu nedenle, `while` döngüleri, sayı dizelerinin en az üç karakter uzunluğunda olana kadar önüne sıfırlar eklemeye devam eder. -Mission accomplished! But just as we are about to send the farmer the code (along with a hefty invoice), she calls and tells us she's also started keeping pigs, and couldn't we please extend the software to also print pigs? +Görev tamamlandı! Ancak, çiftlik sahibine kodu (birlikte ciddi bir fatura ile) gönderecekken, bizi arar ve ayrıca domuzları da yazdırmak için yazılımı genişletemeyiz mi diye bize sorar. {{index "copy-paste programming"}} -We sure can. But just as we're in the process of copying and pasting those four lines one more time, we stop and reconsider. There has to be a better way. Here's a first attempt: +Tabii ki yapabiliriz. Ancak, o dört satırı bir kez daha kopyalayıp yapıştırma sürecindeyken durur ve yeniden düşünürüz. Daha iyi bir yol olmalı. İşte bu bizim ilk denememiz: ``` function printZeroPaddedWithLabel(number, label) { @@ -573,11 +582,11 @@ printFarmInventory(7, 11, 3); {{index [function, naming]}} -It works! But that name, `printZeroPaddedWithLabel`, is a little awkward. It conflates three things—printing, zero-padding, and adding a label—into a single function. +İşe yarıyor! Ancak, `printZeroPaddedWithLabel` adı biraz garip. Üç şeyi - yazdırma, sıfır dolgusu ve bir etiket ekleme - tek bir işlevde birleştiriyor gibi görünüyor. {{index "zeroPad function"}} -Instead of lifting out the repeated part of our program wholesale, let's try to pick out a single _concept_: +Programımızın tekrar eden kısmını toptan dışarı çıkarmak yerine, tek bir _kavram_ seçmeye çalışalım. ``` function zeroPad(number, width) { @@ -599,36 +608,38 @@ printFarmInventory(7, 16, 3); {{index readability, "pure function"}} -A function with a nice, obvious name like `zeroPad` makes it easier for someone who reads the code to figure out what it does. Such a function is also useful in more situations than just this specific program. For example, you could use it to help print nicely aligned tables of numbers. +`zeroPad` gibi güzel, açık bir adı olan bir fonksiyon, kodu okuyan birinin ne yaptığını anlamasını kolaylaştırır. Ve böyle bir fonksiyon, sadece bu belirli program için değil, daha fazla durumda da kullanışlıdır. Örneğin, sayıların güzelce hizalanmış tablolarını konsola yazdırmaya yardımcı olmak için de kullanabilirsiniz. {{index [interface, design]}} -How smart and versatile _should_ our function be? We could write anything, from a terribly simple function that can only pad a number to be three characters wide to a complicated generalized number-formatting system that handles fractional numbers, negative numbers, alignment of decimal dots, padding with different characters, and so on. +İşlevimiz ne kadar zeki ve çok yönlü olmalıdır? Çok basit sadece üç karakter genişliğinde bir sayı dolgusunu yapabilen bir fonksiyondan karmaşık genelleştirilmiş tam olmayan sayıları, negatif satıları, tam olmayan sayılardaki noktaları, farklı karakterlerle dolgu yapmayı da halledebilen bir sayı biçimlendirme sistemi oluşturmaya kadar her şeyi yazabiliriz. -A useful principle is to refrain from adding cleverness unless you are absolutely sure you're going to need it. It can be tempting to write general "((framework))s" for every bit of functionality you come across. Resist that urge. You won't get any real work done—you'll be too busy writing code that you never use. +Kullanışlı bir prensip, kesinlikle ihtiyacınız olduğundan emin olmadıkça, zekiğe girmemektir. Karşılaştığınız her işlev için genel "((çerçeve))ler" yazma dürtüsüne karşı koyun. Eğer bu prensipi takip etmezseniz gerçekten bir iş yapamayıp - sadece hiç kullanmayacağınız kod yazacaksınız. {{id pure}} -## Functions and side effects + +## Fonksiyonlar ve yan etkiler {{index "side effect", "pure function", [function, purity]}} -Functions can be roughly divided into those that are called for their side effects and those that are called for their return value (though it is also possible to both have side effects and return a value). +Fonksiyonlar, yan etkileri için çağrılanlar ve dönüş değeri için çağrılanlar olarak kabaca ikiye ayrılabilir. (Ancak hem yan etkilere sahip olmak ve hem de bir değer döndürmek kesinlikle mümkündür.) {{index reuse}} -The first helper function in the ((farm example)), `printZeroPaddedWithLabel`, is called for its side effect: it prints a line. The second version, `zeroPad`, is called for its return value. It is no coincidence that the second is useful in more situations than the first. Functions that create values are easier to combine in new ways than functions that directly perform side effects. +((Çiftlik örneğinde))ki ilk yardımcı fonksiyon olan `printZeroPaddedWithLabel`, yan etkisi için çağrılır: bir satır yazdırır. İkinci sürüm olan zeroPad`, dönüş değeri için çağrılır. İkincisinin birinciden daha fazla durumda kullanışlı olması tesadüf değildir. Değerler üreten fonksiyonlar, doğrudan yan etki yapan fonksiyonlardan daha kolay yeni şekillerde birleştirilebilmektedirler. {{index substitution}} -A _pure_ function is a specific kind of value-producing function that not only has no side effects but also doesn't rely on side effects from other code—for example, it doesn't read global bindings whose value might change. A pure function has the pleasant property that, when called with the same arguments, it always produces the same value (and doesn't do anything else). A call to such a function can be substituted by its return value without changing the meaning of the code. When you are not sure that a pure function is working correctly, you can test it by simply calling it and know that if it works in that context, it will work in any context. Nonpure functions tend to require more scaffolding to test. +Bir _saf_ fonksiyon, yalnızca yan etkisi olmayan belirli bir türde bir değer üreten bir fonksiyon değil, ayrıca diğer kodlardan yan etkileri de almayan bir işlevdir - örneğin, değeri değişebilecek global bağlantıları okumaz. Saflık fonksiyonu, aynı argümanlarla çağrıldığında her zaman aynı değeri üreten (ve başka bir şey yapmayan) hoş bir özelliğe sahiptir. Böyle bir fonksiyonun çağrısı, kodun anlamını değiştirmeden döndürdüğü değeri kullanarak değiştirilebilir. Bir saf fonksiyonun doğru çalışıp çalışmadığından emin değilseniz, onu sadece çağırarak test edebilir ve eğer bu bağlamda çalışıyorsa, herhangi bir bağlamda da çalışacağını bilirsiniz. Saf olmayan fonksiyonların test edilmesi daha fazla destekleme gerektirir. {{index optimization, "console.log"}} -Still, there's no need to feel bad when writing functions that are not pure. Side effects are often useful. There's no way to write a pure version of `console.log`, for example, and `console.log` is good to have. Some operations are also easier to express in an efficient way when we use side effects. +Yine de, saf olmayan fonksiyonlar yazdığınızda kötü hissetmenize gerek yok. Yan etkiler genellikle yararlıdır. Örneğin, `console.log`'un saf bir versiyonunu yazmanın bir yolu yoktur ve `console.log`'un olması iyidir. Bazı işlemler, yan etkileri kullanarak daha verimli bir şekilde ifade edilebilir. -## Summary +## Özet -This chapter taught you how to write your own functions. The `function` keyword, when used as an expression, can create a function value. When used as a statement, it can be used to declare a binding and give it a function as its value. Arrow functions are yet another way to create functions. +The `function` keyword, when used as an expression, can create a function value. When used as a statement, it can be used to declare a binding and give it a function as its value. Arrow functions are yet another way to create functions. +Bu bölüm, size kendi fonksiyonlarınızı yazmayı öğretti. `function` anahtar kelimesi, bir ifade olarak kullanıldığında bir fonksiyon değeri oluşturabilir. Bir beyan olarak kullanıldığında, bir bağlantıyı bildirmek ve ona bir fonksiyon değeri olarak vermek için kullanılabilir. Ok fonksiyonlarıysa fonksiyon oluşturmanın başka bir yoludur. ``` // Define f to hold a function value @@ -645,64 +656,65 @@ function g(a, b) { let h = a => a % 3; ``` -A key part of understanding functions is understanding scopes. Each block creates a new scope. Parameters and bindings declared in a given scope are local and not visible from the outside. Bindings declared with `var` behave differently—they end up in the nearest function scope or the global scope. +İşlevleri anlamanın temel yönlerinden biri kapsamları anlamaktır. Her blok yeni bir kapsam oluşturur. Bir kapsam içindeki parametreler ve bağlantılar yerel olup dışarıdan görünmez. `var` ile bildirilen bağlantılar farklı davranır - bunlar en yakın fonksiyon kapsamına veya global kapsama yerleşirler. -Separating the tasks your program performs into different functions is helpful. You won't have to repeat yourself as much, and functions can help organize a program by grouping code into pieces that do specific things. +Programınızın yaptığı görevleri farklı fonksiyonlara ayırmak yararlıdır. Kendinizi tekrar etmek zorunda kalmazsınız ve fonksiyonlar, kodu belirli şeyler yapan parçalara gruplayarak bir programı düzenlemenize yardımcı olabilir. -## Exercises +## Egzersizler ### Minimum {{index "Math object", "minimum (exercise)", "Math.min function", minimum}} -The [previous chapter](program_structure#return_values) introduced the standard function `Math.min` that returns its smallest argument. We can write a function like that ourselves now. Define the function `min` that takes two arguments and returns their minimum. +[Önceki bölüm](program_structure#return_values), en küçük verilen argümanını döndüren standart `Math.min` işlevini tanıttı. Şimdi buna benzer bir şey yapabiliriz. İki argüman alan ve bunların minimumunu döndüren `min` adında bir fonksiyon yazın. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(min(0, 10)); // → 0 console.log(min(0, -10)); // → -10 ``` + if}} {{hint {{index "minimum (exercise)"}} -If you have trouble putting braces and parentheses in the right place to get a valid function definition, start by copying one of the examples in this chapter and modifying it. +Eğer süslü parantezleri ve normal parantezleri doğru yerlere koyarak bir geçerli fonksiyon tanımı elde etmekte zorlanıyorsanız, bir önceki bölümdeki örneklerden birini kopyalayıp onu değiştirerek başlayabilirsiniz. {{index "return keyword"}} -A function may contain multiple `return` statements. +Bir fonksiyon birden fazla `return` beyanını içinde bulundurabilir. hint}} -### Recursion +### Özyineleme {{index recursion, "isEven (exercise)", "even number"}} -We've seen that we can use `%` (the remainder operator) to test whether a number is even or odd by using `% 2` to see whether it's divisible by two. Here's another way to define whether a positive whole number is even or odd: +`%` (kalan işlemcisi) operatörünün bir sayının çift mi yoksa tek mi olduğunu test etmek için 2'ye bölünüp bölünmediğini anlamak adına `% 2` kullanılabileceğini gördük. İşte bir pozitif tam sayının çift veya tek olup olmadığını tanımlamanın başka bir yolu: -- Zero is even. +- Sıfır çifttir. -- One is odd. +- Bir tektir. -- For any other number _N_, its evenness is the same as _N_ - 2. +- Herhangi bir _N_ sayısı için _N_ - 2 çifttir. -Define a recursive function `isEven` corresponding to this description. The function should accept a single parameter (a positive, whole number) and return a Boolean. +Bu tanıma karşılık gelen özyinelemeli bir fonksiyon olan `isEven` fonksiyonunu tanımlayın. Fonksiyon tek bir parametre kabul etmeli (pozitif, tam sayı) ve Bir Boole değeri döndürmelidir. {{index "stack overflow"}} -Test it on 50 and 75. See how it behaves on -1. Why? Can you think of a way to fix this? +Fonksiyonu 50 ve 75 üzerinde test edin. -1'de nasıl davrandığını görün. Neden? Bunun nasıl düzeltilebileceğini düşünebilir misiniz? {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(isEven(50)); // → true @@ -718,28 +730,28 @@ if}} {{index "isEven (exercise)", ["if keyword", chaining], recursion}} -Your function will likely look somewhat similar to the inner `find` function in the recursive `findSolution` [example](functions#recursive_puzzle) in this chapter, with an `if`/`else if`/`else` chain that tests which of the three cases applies. The final `else`, corresponding to the third case, makes the recursive call. Each of the branches should contain a `return` statement or in some other way arrange for a specific value to be returned. +Fonksiyonunuz muhtemelen bu bölümdeki özyinelemeli `findSolution` [örneğindeki](functions#recursive_puzzle) iç `find` fonksiyona oldukça benzer görünecek ve üç durumdan hangisinin uygulandığını test eden bir `if/else` `if/else` zinciri ile olacak. Üçüncü duruma karşılık gelen son `else`, özyinelemeli çağrıyı yapar. Her bir dal, belirli bir değerin döndürülmesini sağlamak için bir `return` beyanı içermelidir veya başka bir şekilde düzenlenmelidir. {{index "stack overflow"}} -When given a negative number, the function will recurse again and again, passing itself an ever more negative number, thus getting further and further away from returning a result. It will eventually run out of stack space and abort. +Negatif bir sayı verildiğinde, fonksiyon kendisine negatif bir sayı vererek tekrar tekrar özyinelemeye girecek, böylece sonuç döndürmekten giderek daha uzaklaşacaktır. Sonunda, yığın alanı tükenecek ve işlem iptal edilecektir. hint}} -### Bean counting +### Fasulye sayımı {{index "bean counting (exercise)", [string, indexing], "zero-based counting", ["length property", "for string"]}} -You can get the *N*th character, or letter, from a string by writing `[N]` after the string (for example, `string[2]`). The resulting value will be a string containing only one character (for example, `"b"`). The first character has position 0, which causes the last one to be found at position `string.length - 1`. In other words, a two-character string has length 2, and its characters have positions 0 and 1. +Bir diziden (örneğin `string[2]` olarak) N'inci karakterini veya harfini alabilirsiniz. Elde edilen değer, yalnızca bir karakter içeren bir dizedir (örneğin, `"b"`). İlk karakterin konumu 0 olduğu için, son karakterin konumu `string.length - 1` pozisyonunda bulunur. Başka bir deyişle, iki karakterlik bir dizenin uzunluğu 2'dir ve karakterleri 0 ve 1 konumunda bulunur. -Write a function `countBs` that takes a string as its only argument and returns a number that indicates how many uppercase B characters there are in the string. +Tek bir argüman olarak bir dize alan ve dizide kaç büyük `"B"` karakteri olduğunu gösteren bir sayı döndüren `countBs` adında bir fonksiyon yazın. -Next, write a function called `countChar` that behaves like `countBs`, except it takes a second argument that indicates the character that is to be counted (rather than counting only uppercase B characters). Rewrite `countBs` to make use of this new function. +Sonraki adımda, `countBs` gibi davranan ancak sadece bütük "B" dizesini saymak yerine sayılacak karakteri de belirtecek ikinci bir argüman alan `countChar` adında bir fonksiyon yazın. `countBs` işlevini bu yeni işlevi kullanacak şekilde tekrar yazın. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(countBs("BOB")); // → 2 @@ -753,10 +765,10 @@ if}} {{index "bean counting (exercise)", ["length property", "for string"], "counter variable"}} -Your function will need a ((loop)) that looks at every character in the string. It can run an index from zero to one below its length (`< string.length`). If the character at the current position is the same as the one the function is looking for, it adds 1 to a counter variable. Once the loop has finished, the counter can be returned. +İşleviniz, dizedeki her karaktere bakan bir ((döngü)) gerektirecektir. Döngü, sıfırdan dizenin uzunluğunun bir altına kadar bir dizini çalıştırabilir (`< string.length`). Mevcut konumdaki karakter fonksiyonun aradığı karakterle aynıysa, sayaç bağlantısındaki değeri 1 artırır. Döngü tamamlandığında, sayaç sonuç olarak `return` beyanı aracılığıyla döndürülebilir. {{index "local binding"}} -Take care to make all the bindings used in the function _local_ to the function by properly declaring them with the `let` or `const` keyword. +Fonksiyonda kullanılan tüm bağlantıların `let` veya `const` anahtar kelimelerini kullanarak düzgün bir şekilde fonksiyon içerisinde yerel halde olmasını sağlayın. hint}} diff --git a/04_data.md b/04_data.md index 54e19c81..01fe2642 100644 --- a/04_data.md +++ b/04_data.md @@ -1,10 +1,10 @@ {{meta {load_files: ["code/journal.js", "code/chapter/04_data.js"], zip: "node/html"}}} -# Data Structures: Objects and Arrays +# Veri Yapıları: Objeler ve Diziler {{quote {author: "Charles Babbage", title: "Passages from the Life of a Philosopher (1864)", chapter: true} -On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' [...] I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. +İki kez bana şu soruyu sordular, 'Eğer makineye yanlış rakamlar girerseniz, doğru cevaplar çıkar mı?' [...] Böyle bir sorunun sorulmasına sebep olan kafa karışıklığı dolu fikirleri anlayamıyorum. quote}} @@ -14,47 +14,47 @@ quote}} {{index object, "data structure"}} -Numbers, Booleans, and strings are the atoms from which ((data)) structures are built. Many types of information require more than one atom, though. _Objects_ allow us to group values—including other objects—to build more complex structures. +Sayılar, Boole değerleri ve dizeler, ((veri)) yapılarının oluşturulduğu atomlardır. Ancak, birçok bilgi türü, birden fazla atom gerektirir. _Objeler_ bize, daha karmaşık yapılar oluşturmak için obje değerleri de dahil olmak üzere değerleri gruplamamıza olanak sağlar. -The programs we have built so far have been limited by the fact that they were operating only on simple data types. After learning the basics of data structures in this chapter, you'll know enough to start writing useful programs. +Şimdiye kadar oluşturduğumuz programlar, yalnızca basit veri türleri üzerinde çalıştıkları için sınırlıydı. Bu bölüm, temel veri yapılarını tanıtacaktır. Sonunda, yararlı programlar yazmaya başlamak için yeterli bilgiye sahip olacaksınız. -The chapter will work through a more or less realistic programming example, introducing concepts as they apply to the problem at hand. The example code will often build on functions and bindings introduced earlier in the book. +Bölüm, bir miktar gerçekçi bir programlama örneği üzerinden çalışacak ve kavramları uygulandıkları sorunla ilişkilendirecektir. Örnek kodlar genellikle metinde daha önce tanıtılan fonksiyonlar ve bağlantılar üzerine kurulacaktır. {{if book -The online coding ((sandbox)) for the book ([_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code)) provides a way to run code in the context of a particular chapter. If you decide to work through the examples in another environment, be sure to first download the full code for this chapter from the sandbox page. +Kitabın çevrimiçi kodlama ((kum havuzu)) ([_https://eloquentjavascript.net/code_](https://eloquentjavascript.net/code)) belirli bir bölüm bağlamında kodu çalıştırmanın bir yolunu sağlar. Örnekleri başka bir ortamda çalıştırmaya karar verirseniz, önce bu bölüm için tam kodu kum havuzu sayfasından indirmeyi unutmayın. if}} -## The weresquirrel +## Sincap {{index "weresquirrel example", lycanthropy}} -Every now and then, usually between 8 p.m. and 10 p.m., ((Jacques)) finds himself transforming into a small furry rodent with a bushy tail. +Arada sırada, genellikle akşam 8 ile 10 arasında, ((Jacques)) kendisini tüylü kuyruklu küçük bir kemirgen haline dönüşürken bulur. -On one hand, Jacques is quite glad that he doesn't have classic lycanthropy. Turning into a squirrel does cause fewer problems than turning into a wolf. Instead of having to worry about accidentally eating the neighbor (_that_ would be awkward), he worries about being eaten by the neighbor's cat. After two occasions of waking up on a precariously thin branch in the crown of an oak, naked and disoriented, he has taken to locking the doors and windows of his room at night and putting a few walnuts on the floor to keep himself busy. +Bir yandan, Jacques klasik kurt adamlığına sahip olmadığına oldukça sevinir. Bir sincapa dönüşmek, bir kurt adama dönüşmekten daha az soruna neden olur. Komşuyu yanlışlıkla yemekten endişe etmek yerine (bu garip olurdu), komşunun kedisi tarafından yenilmekten endişe eder. Meşe ağacının tacındaki tehlikeli derecede ince bir dalda, çıplak ve oryantasyonunu yitirmiş olarak uyanmış ve gece odasının kapılarını, pencerelerini kapatmaya ve kendisini meşgul etmeyi birkaç ceviz koyarak başarmıştır. -But Jacques would prefer to get rid of his condition entirely. The irregular occurrences of the transformation make him suspect that they might be triggered by something. For a while, he believed that it happened only on days when he had been near oak trees. However, avoiding oak trees did not solve the problem. +Ancak Jacques, durumunu tamamen ortadan kaldırmayı tercih ederdi. Dönüşümün düzensiz oluşları, onları tetikleyen bir şeyin olabileceğini düşündürmektedir. Bir süre, sadece meşe ağaçlarına yaklaştığı günlerde olduğuna inandı. Ancak meşe ağaçlarından kaçınmak sorunu durdurmadı. {{index journal}} -Switching to a more scientific approach, Jacques has started keeping a daily log of everything he does on a given day and whether he changed form. With this data he hopes to narrow down the conditions that trigger the transformations. +Daha bilimsel bir yaklaşıma geçiş yaparak, Jacques, belirli bir günde yaptığı her şeyi ve dönüşüp dönüşmediğini günlük olarak kaydetmeye başladı. Bu verilerle dönüşümleri tetikleyen koşulları daraltmayı umuyor. -The first thing he needs is a data structure to store this information. +İhtiyacı olan ilk şey, bu bilgileri depolamak için bir veri yapısıdır. -## Data sets +## Veri setleri {{index ["data structure", collection], [memory, organization]}} -To work with a chunk of digital data, we first have to find a way to represent it in our machine's memory. Say, for example, that we want to represent a ((collection)) of the numbers 2, 3, 5, 7, and 11. +Dijital veri parçalarıyla çalışabilmek için, onu öncelikle makinenin belleğinde temsil etmenin bir yolunu bulmamız gerekecek. Örneğin, 2, 3, 5, 7 ve 11 sayılar ((koleksiyon))unu temsil etmek istediğimizi varsayalım. {{index string}} -We could get creative with strings—after all, strings can have any length, so we can put a lot of data into them—and use `"2 3 5 7 11"` as our representation. But this is awkward. We'd have to somehow extract the digits and convert them back to numbers to access them. +Dizelerle yaratıcı olabiliriz—sonuçta, dizelerin herhangi bir uzunluğu olabilir, bu yüzden içine çok fazla veri koyabiliriz—ve `"2 3 5 7 11"` değerini temsilimiz olarak kullanabiliriz. Ancak bu garip bir yaklaşım. Sayıları dizeden çıkarıp tekrar erişmek için onları sayı türü değerlere dönüştürmeniz gerekir. {{index [array, creation], "[] (array)"}} -Fortunately, JavaScript provides a data type specifically for storing sequences of values. It is called an _array_ and is written as a list of values between ((square brackets)), separated by commas: +Neyse ki, JavaScript, değer dizilerini depolamak için özel bir veri türü sağlar. Buna _dizi_ denir ve virgüllerle ayrılmış bir değer listesi olarak yazılır, ((köşeli parantezler)) arasında bulunur. ``` let listOfNumbers = [2, 3, 5, 7, 11]; @@ -68,24 +68,24 @@ console.log(listOfNumbers[2 - 1]); {{index "[] (subscript)", [array, indexing]}} -The notation for getting at the elements inside an array also uses ((square brackets)). A pair of square brackets immediately after an expression, with another expression inside of them, will look up the element in the left-hand expression that corresponds to the _((index))_ given by the expression in the brackets. +Bir dizideki elemanlara erişim için kullanılan gösterim için ((köşeli parantezler)) kullanılır. İfadeyi takip eden bir çift köşeli parantez ve bu köşeli parantezler içinde başka bir ifade ile dizi içerisindeki \_((index))\_e denk gelen elementi arayacaktır. {{id array_indexing}} {{index "zero-based counting"}} -The first index of an array is zero, not one, so the first element is retrieved with `listOfNumbers[0]`. Zero-based counting has a long tradition in technology and in certain ways makes a lot of sense, but it takes some getting used to. Think of the index as the number of items to skip, counting from the start of the array. +Bir dizinin ilk dizini sıfırdır, bir değil. Bu nedenle, ilk eleman `listOfNumbers[0]` ile alınır. Sıfır tabanlı sayma, teknolojide uzun bir geleneğe sahiptir ve belirli yönlerden oldukça mantıklıdır, ancak alışması biraz zaman alır. İndeksi, dizinin başlangıcından itibaren atlama miktarı olarak düşünün. {{id properties}} -## Properties +## Özellikler {{index "Math object", "Math.max function", ["length property", "for string"], [object, property], "period character", [property, access]}} -We've seen a few expressions like `myString.length` (to get the length of a string) and `Math.max` (the maximum function) in past chapters. These expressions access a _property_ of some value. In the first case, we access the `length` property of the value in `myString`. In the second, we access the property named `max` in the `Math` object (which is a collection of mathematics-related constants and functions). +Geçmiş bölümlerde `myString.length` (bir dizgenin uzunluğunu almak için) ve `Math.max` (maksimum fonksiyonu) gibi şüpheli görünen bazı ifadeler gördük. Bunlar, bir değerin _özelliğine_ erişen ifadelerdir. İlk durumda, `myString` değeri içindeki `length` özelliğine erişiriz. İkincisinde, matematikle ilgili sabitler ve fonksiyonlardan oluşan bir koleksiyon olan `Math` nesnesindeki `max` adlı özelliğe erişiriz. {{index [property, access], null, undefined}} -Almost all JavaScript values have properties. The exceptions are `null` and `undefined`. If you try to access a property on one of these nonvalues, you get an error: +Hemen hemen tüm JavaScript değerlerinin özellikleri vardır. İstisnalar `null` ve `undefined` değerleridir. Bu değer olmayan değerlerden birinde bir özelliğe erişmeye çalışırsanız, bir hata alırsınız. ```{test: no} null.length; @@ -95,23 +95,23 @@ null.length; {{indexsee "dot character", "period character"}} {{index "[] (subscript)", "period character", "square brackets", "computed property", [property, access]}} -The two main ways to access properties in JavaScript are with a dot and with square brackets. Both `value.x` and `value[x]` access a property on `value`—but not necessarily the same property. The difference is in how `x` is interpreted. When using a dot, the word after the dot is the literal name of the property. When using square brackets, the expression between the brackets is _evaluated_ to get the property name. Whereas `value.x` fetches the property of `value` named "x", `value[x]` takes the value of the variable named `x` and uses that, converted to a string, as the property name. +JavaScript'te özelliklere erişmenin iki temel yolu vardır: bir nokta ile ve köşeli parantezlerle. Hem `value.x` hem de `value[x]`, değer üzerinde bir özelliğe erişir—ancak erişilen özellik tam olarak aynı özellik olmayabilir. Fark, `x`'in nasıl yorumlandığındadır. Nokta kullanırken, noktanın sonrasındaki kelime, erişilmek istenen özelliğin adıdır. Köşeli parantezler kullanırken, parantezler arasındaki ifade, erişilmek istenen özelliğin adını almak için _değerlendirilir_. Nokta kullanılırken, `value.x` ifadesi `value` objesinin "x" adlı özelliğini alırken, köşeli parantezler kullanılan `value[x]` ifadesinde, `x` adındaki değişkenin değerini alır ve bunu bir dizeye dönüştürerek özellik adı olarak kullanır. -If you know that the property in which you are interested is called _color_, you say `value.color`. If you want to extract the property named by the value held in the binding `i`, you say `value[i]`. Property names are strings. They can be any string, but the dot notation works only with names that look like valid binding names—starting with a letter or underscore, and containing only letters, numbers, and underscores. If you want to access a property named _2_ or _John Doe_, you must use square brackets: `value[2]` or `value["John Doe"]`. +Yani eğer ilgilendiğiniz özelliğin adının _color_ olduğunu biliyorsanız, `value.color` yazarsınır. Eğer `i` adlı bağlantının sahip olduğunu değerin adını taşıyan özelliği çıkarmak istiyorsanız, `value[i]` yazarsınız. Özellik adları dizelerdir. Herhangi bir dize olabilirler, ancak nokta notasyonu yalnızca geçerli bağlantı adları gibi görünen adlarla çalışır. Dolayısıyla _2_ veya _John Doe_ adında bir özelliğe erişmek istiyorsanız, köşeli parantezleri kullanmanız gerekir: `value[2]` veya `value["John Doe"]`. -The elements in an ((array)) are stored as the array's properties, using numbers as property names. Because you can't use the dot notation with numbers and usually want to use a binding that holds the index anyway, you have to use the bracket notation to get at them. +Bir ((dizideki)) öğeler, dizi özelliklerinin bir parçasıdır ve sayıları özellik adları olarak kullanarak saklanır. Sayılarla nokta notasyonunu kullanamazsınız ve genellikle zaten index değerini tutan bir bağlantı kullanmak istersiniz, bu nedenle onlara erişmek için köşeli parantez notasyonunu kullanmanız gerekir. {{index ["length property", "for array"], [array, "length of"]}} -Just like strings, arrays have a `length` property that tells us how many elements the array has. +Dizilerin, dizelerin de sahip olduğu gibi kaç öğe olduğunu söyleyen bir `length` özelliği vardır. {{id methods}} -## Methods +## Metodlar {{index [function, "as property"], method, string}} -Both string and array values contain, in addition to the `length` property, a number of properties that hold function values. +Dizelerin ve dizilerin `length` özelliği ötesinde fonksiyon değerleri tutan bir dizi özelliklere de sahiptirler. ``` let doh = "Doh"; @@ -123,17 +123,17 @@ console.log(doh.toUpperCase()); {{index "case conversion", "toUpperCase method", "toLowerCase method"}} -Every string has a `toUpperCase` property. When called, it will return a copy of the string in which all letters have been converted to uppercase. There is also `toLowerCase`, going the other way. +Her dizenin bir `toUpperCase` özelliği vardır. Çağrıldığında, tüm harflerin büyük harfe dönüştürüldüğü bir dize kopyası döndürür. Ayrıca, tersi olan `toLowerCase` özelliği de vardır. {{index "this binding"}} -Interestingly, even though the call to `toUpperCase` does not pass any arguments, the function somehow has access to the string `"Doh"`, the value whose property we called. You'll find out how this works in [Chapter ?](object#obj_methods). +İlginç bir şekilde, `toUpperCase` özelliğine yapılan çağrıya herhangi bir argüman vermediğimiz halde fonksiyonunu çağırdığımız `"Doh"` dize değerine erişebilmektedir. Bunun nasıl çalıştığı, [Bölüm ?](object#obj_methods)'da açıklanmıştır. -Properties that contain functions are generally called _methods_ of the value they belong to, as in "`toUpperCase` is a method of a string". +Fonksiyonları içeren özellikler genellikle ait oldukları değerin _metodları_ olarak adlandırılır, örneğin `toUpperCase` bir dize değerinin yöntemidir. {{id array_methods}} -This example demonstrates two methods you can use to manipulate arrays: +Bu örnek dizileri manipüle etmek için kullanabileceğiniz iki metodu göstermektedir: ``` let sequence = [1, 2, 3]; @@ -149,21 +149,21 @@ console.log(sequence); {{index collection, array, "push method", "pop method"}} -The `push` method adds values to the end of an array. The `pop` method does the opposite, removing the last value in the array and returning it. +`push` metodu dizinin sonuna değerler eklerken `pop` metoduysa tam tersi yapar, yani sonundan bir değer çıkarıp bunu değer olarak döndürür. {{index ["data structure", stack]}} -These somewhat silly names are the traditional terms for operations on a _((stack))_. A stack, in programming, is a data structure that allows you to push values into it and pop them out again in the opposite order so that the thing that was added last is removed first. Stacks are common in programming—you might remember the function ((call stack)) from [the previous chapter](functions#stack), which is an instance of the same idea. +Bu biraz komik isimler, bir ((yığın)) üzerinde yapılan işlemler için geleneksel terimlerdir. Bir yığın, programlamada, değerleri yığına iterken ve sonra onları ters sırayla geri çekerken, en son eklenen şeyin ilk önce çıkarılmasına izin veren bir veri yapısıdır. Bunlar programlamada yaygındır—[önceki bölümden](functions#stack) hatırlayabileceğiniz gibi, buna bir örnek olan ((çağrı yığını))nı ele almıştık. -## Objects +## Objeler {{index journal, "weresquirrel example", array, record}} -Back to the weresquirrel. A set of daily log entries can be represented as an array, but the entries do not consist of just a number or a string—each entry needs to store a list of activities and a Boolean value that indicates whether Jacques turned into a squirrel or not. Ideally, we would like to group these together into a single value and then put those grouped values into an array of log entries. +Sincap hikayesine geri dönelim. Günlük yaşanan olayların bir küme olarak temsil edilmesi için dizi veri yapısı kullanılabilir. Ancak, girişler sadece bir sayı veya dize değildir—her girişin bir dizi etkinliği depolaması ve Jacques'nın bir sincapa dönüşüp dönüşmediğini gösteren bir Boolean değerini barındırması gerekir. İdeal olarak, bunları tek bir değere gruplamak ve sonra bu gruplanmış değerleri bir diziye teker teker koymaktır. {{index [syntax, object], [property, definition], [braces, object], "{} (object)"}} -Values of the type _((object))_ are arbitrary collections of properties. One way to create an object is by using braces as an expression: +_((Obje))_ türündeki değerler, farklı özelliklerden koleksiyonlarıdır. Nesne oluşturmanın bir yolu, süslü parantezler ifadesini kullanmaktır. ``` let day1 = { @@ -181,7 +181,7 @@ console.log(day1.wolf); {{index [quoting, "of object properties"], "colon character"}} -Inside the braces, you write a list of properties separated by commas. Each property has a name followed by a colon and a value. When an object is written over multiple lines, indenting it as shown in this example helps with readability. Properties whose names aren't valid binding names or valid numbers must be quoted: +Parantezlerin içinde, virgüllerle ayrılmış bir özellik listesi bulunur. Her özelliğin bir adı ve ardından iki nokta üst üste ve bir değeri vardır. Bir obje yazıldığında, örnekte olduğu gibi girintili yapmak, okunabilirlik konusunda yardımcı olur. Adları geçerli bağlantı adı olmayan veya geçerli olmayan bir sayı olan özellikler tırnak içine alınmalıdır. ``` let descriptions = { @@ -192,23 +192,23 @@ let descriptions = { {{index [braces, object]}} -This means that braces have _two_ meanings in JavaScript. At the start of a ((statement)), they begin a ((block)) of statements. In any other position, they describe an object. Fortunately, it is rarely useful to start a statement with an object in braces, so the ambiguity between these two is not much of a problem. The one case where this does come up is when you want to return an object from a short-hand arrow function—you can't write `n => {prop: n}`, since the braces will be interpreted as a function body. Instead, you have to put a set of parentheses around the object to make it clear that it is an expression. +Bu, parantezlerin JavaScript'te _iki_ anlama geldiği anlamına gelir. Bir ((beyan))ın başında olduklarında, bir beyanlar ((bloğunu)) başlatırlar. Herhangi bir başka konumda, bir nesnenin oluşturulmasını sağlarlar. Neyse ki, bir beyanı süslü parantezle başlatmak pek nadiren kullanışlıdır, bu yüzden bu ikisi arasındaki belirsizlik pek bir problem değildir. Bu iki durumun çakıştığı tek durum, bir kısayol ok fonksiyonundan değer olarak bir nesne döndürmek istediğinizde ortaya çıkar—`n => {prop: n}` yazamazsınız çünkü süslü parantezler fonksiyon gövdesi olarak yorumlanacaktır, obje olduğunu belirtmek için nesnenin etrafına bir parantez kümesi koymak zorundasınız. {{index undefined}} -Reading a property that doesn't exist will give you the value `undefined`. +Mevcut olmayan bir özelliği okumak size `undefined` değerini verecektir. {{index [property, assignment], mutability, "= operator"}} -It is possible to assign a value to a property expression with the `=` operator. This will replace the property's value if it already existed or create a new property on the object if it didn't. +Bir özellik ifadesine bir değer atamak mümkündür. Bu, özellik zaten varsa değerini değiştirir, eğer yoksa da verilend değeri barındıran yeni bir özellik oluşturur. {{index "tentacle (analogy)", [property, "model of"], [binding, "model of"]}} -To briefly return to our tentacle model of ((binding))s—property bindings are similar. They _grasp_ values, but other bindings and properties might be holding onto those same values. You can think of objects as octopuses with any number of tentacles, each of which has a name written on it. +Kısaca ((bağlantı))larımızın ahtapot dokungaç modeline geri dönersek—özellik bağlantılarının da onlara benzer olduğunu görürüz. Değerleri kavrarlar ve kavradıkları değerler diğer bağlantı ve özellikler tarafından da sahip olunabilirdir. Nesneleri herhangi bir sayıda üzerine isimler dövmelenmiş dokungaçları olan bir ahtapot olarak düşünebilirsiniz. {{index "delete operator", [property, deletion]}} -The `delete` operator cuts off a tentacle from such an octopus. It is a unary operator that, when applied to an object property, will remove the named property from the object. This is not a common thing to do, but it is possible. +`delete` operatörü, böyle bir ahtapotun dokungaçlarından birini keser. Bu tekil bir operatördür ve herhangi bir nesne özelliğine uygulandığında, adı verilen özelliği nesneden kaldırır. Bu yaygın bir şey değildir, ancak mümkündür. ``` let anObject = {left: 1, right: 2}; @@ -225,18 +225,18 @@ console.log("right" in anObject); {{index "in operator", [property, "testing for"], object}} -The binary `in` operator, when applied to a string and an object, tells you whether that object has a property with that name. The difference between setting a property to `undefined` and actually deleting it is that in the first case, the object still _has_ the property (it just doesn't have a very interesting value), whereas in the second case the property is no longer present and `in` will return `false`. +İkili `in` operatörü, bir dizeye veya bir nesneye uygulandığında, bu nesnenin o ada sahip bir özelliği olup olmadığını size söyler. Bir özelliği `undefined` değerini vermek ve gerçekten silmek arasındaki fark, ilk durumda nesnenin _hala özelliğe sahip olmasıdır_ (sadece çok ilginç bir değere sahip değil), ikinci durumda ise özelliğin artık mevcut olmaması ve `in` ikili operatörünün `false` değerini döndürmesidir. {{index "Object.keys function"}} -To find out what properties an object has, you can use the `Object.keys` function. Give the function an object and it will return an array of strings—the object's property names: +Bir nesnenin hangi özelliklere sahip olduğunu öğrenmek için `Object.keys` fonksiyonunu kullanabilirsiniz. Bu fonksiyona argüman olarak nesne verirsiniz ve size nesnenin özellik adlarını içnide barındıran bir dizi döndürür. ``` console.log(Object.keys({x: 0, y: 0, z: 2})); // → ["x", "y", "z"] ``` -There's an `Object.assign` function that copies all properties from one object into another: +Bir nesneden başka bir nesneye tüm özellikleri kopyalayan bir `Object.assign` fonksiyonu vardır. ``` let objectA = {a: 1, b: 2}; @@ -247,11 +247,11 @@ console.log(objectA); {{index array, collection}} -Arrays, then, are just a kind of object specialized for storing sequences of things. If you evaluate `typeof []`, it produces `"object"`. You can visualize arrays as long, flat octopuses with all their tentacles in a neat row, labeled with numbers. +Öyleyse dizileri belirli bir sırada olan şeylerin dizilerini depolamak için özelleştirilmiş bir nesne türü olarak düşünebiliriz. `typeof []` ifadesini değerlendirirseniz, `"object"` değerini ürettiğini gözlemlersiniz. Onları, uzun, tüm tentakülleri düzenli bir sırayla ve sayılarla dövmelenmiş düz ahtapotlar olarak da düşünebilirsiniz. {{index journal, "weresquirrel example"}} -Jacques will represent the journal that Jacques keeps as an array of objects: +Jacques'ın tuttuğu günlüğü, nesnelerden oluşan bir dizi olarak temsil edeceğiz. ```{test: wrap} let journal = [ @@ -264,23 +264,23 @@ let journal = [ {events: ["weekend", "cycling", "break", "peanuts", "beer"], squirrel: true}, - /* and so on... */ + /* And so on... */ ]; ``` -## Mutability +## Değiştirilebilirlik -We will get to actual programming soon, but first, there's one more piece of theory to understand. +Çok yakında _gerçek_ programlamaya geçeceğiz. İlk olarak, anlaşılması gereken biraz daha teori var. {{index mutability, "side effect", number, string, Boolean, [object, mutability]}} -We saw that object values can be modified. The types of values discussed in earlier chapters, such as numbers, strings, and Booleans, are all _((immutable))_—it is impossible to change values of those types. You can combine them and derive new values from them, but when you take a specific string value, that value will always remain the same. The text inside it cannot be changed. If you have a string that contains `"cat"`, it is not possible for other code to change a character in your string to make it spell `"rat"`. +Önceki bölümlerde tartışılan değer sayılar, dizeler ve Booleans gibi türlerinin tümü ((_değiştirilemezdir_)). Onları birleştirebilir ve onlardan yeni değerler türetebilirsiniz, ancak belirli bir dize değeri aldığınızda, o değer her zaman aynı kalacaktır. İçindeki metin değiştirilemez. İçinde `"cat"` yazan bir dizeniz olduğunda, başka bir kodun dizenizdeki bir karakteri değiştirerek `"rat"` şeklinde yazmasına izin verilmez. -Objects work differently. You _can_ change their properties, causing a single object value to have different content at different times. +Nesneler farklı çalışır. Özelliklerini _değiştirebilirsiniz_, böylece tek bir nesne değeri farklı zamanlarda farklı içeriğe sahip olabilir. {{index [object, identity], identity, [memory, organization], mutability}} -When we have two numbers, 120 and 120, we can consider them precisely the same number, whether or not they refer to the same physical bits. With objects, there is a difference between having two references to the same object and having two different objects that contain the same properties. Consider the following code: +120 ve 120 gibi iki sayımız olduğunda, onları depolandıkları fiziksel bitlerin yerlerinin aynı olup olmadığına bakmaksızın tam olarak aynı sayı olarak düşünebiliriz. Objelerde, aynı nesnenin depolandığı alana olan iki referansa sahip olmanın ve aynı özelliklere sahip iki farklı nesnenin bir farkı vardır. Aşağıdaki kodu düşünün: ``` let object1 = {value: 10}; @@ -301,11 +301,11 @@ console.log(object3.value); {{index "tentacle (analogy)", [binding, "model of"]}} -The `object1` and `object2` bindings grasp the _same_ object, which is why changing `object1` also changes the value of `object2`. They are said to have the same _identity_. The binding `object3` points to a different object, which initially contains the same properties as `object1` but lives a separate life. +`object1` ve `object2` bağlantıları aynı nesneyi tutar, bu yüzden `object1i` değiştirmek `object2` bağlantısının değerini değiştirir. Bunların aynı _kimliğe_ sahip oldukları söylenir. `object3` bağlantısı, başlangıçta `object1` ile aynı özellik ve değerlere sahip ancak ayrı bir yaşama sahip farklı bir objeye işaret eder. {{index "const keyword", "let keyword", [binding, "as state"]}} -Bindings can also be changeable or constant, but this is separate from the way their values behave. Even though number values don't change, you can use a `let` binding to keep track of a changing number by changing the value at which the binding points. Similarly, though a `const` binding to an object can itself not be changed and will continue to point at the same object, the _contents_ of that object might change. +Bağlantılar ayrıca değiştirilebilir veya sabit olabilir, ancak bu, değerlerinin nasıl davrandığından ayrıdır. Sayı değerleri değişmese de, bir `let` bağlantısını, bağlantının işaret ettiği değeri değiştirerek değişen bir sayıyı takip etmek için kullanabilirsiniz. Benzer şekilde, bir nesneye yapılan bir `const` bağlantısı kendisi değiştirilemeyip sadece aynı nesneye işaret etmeye devam etse de, o nesnenin içerisindeki özellikler değişebilir, bu durumda nesne aynı nesnedir ve kimliği değişmemiştir ancak aynı kimliğe sahip bu nesnenin içerisindeki özellikler değişmiştir gibi düşünebilirsiniz. ```{test: no} const score = {visitors: 0, home: 0}; @@ -317,13 +317,13 @@ score = {visitors: 1, home: 1}; {{index "== operator", [comparison, "of objects"], "deep comparison"}} -When you compare objects with JavaScript's `==` operator, it compares by identity: it will produce `true` only if both objects are precisely the same value. Comparing different objects will return `false`, even if they have identical properties. There is no "deep" comparison operation built into JavaScript that compares objects by contents, but it is possible to write it yourself (which is one of the [exercises](data#exercise_deep_compare) at the end of this chapter). +JavaScript'in `==` operatörüyle nesneleri karşılaştırdığınızda, kimliğe göre karşılaştırır: Yalnızca her iki nesne de tam olarak aynı değerse `true` değerini üretecektir. Farklı nesneleri karşılaştırmak içeriklerinin tamamen aynı özellik ve değerlerden oluşsa dahil `false` değerinin döndürülmesine sebep olur. JavaScript'e objeleri o objelerin içeriklerine göre karşılaştıran yerleşik "derin" bir karşılaştırma işlemi bulunmamaktadır, ancak içeriklerine göre nesneleri karşılaştıracak bir fonksiyonu kenidiniz yazmanız mümlündür(bu, bu bölümün sonundaki [alıştırmalardan](data#exercise_deep_compare) biridir). -## The lycanthrope's log +## Sincap kurtadamının günlüğü {{index "weresquirrel example", lycanthropy, "addEntry function"}} -Jacques starts up his JavaScript interpreter and sets up the environment he needs to keep his ((journal)): +Bu arada, Jacques JavaScript yorumlayıcısını başlatır ve ((günlüğünü)) tutması için gereken ortamı kurar. ```{includeCode: true} let journal = []; @@ -335,9 +335,9 @@ function addEntry(events, squirrel) { {{index [braces, object], "{} (object)", [property, definition]}} -Note that the object added to the journal looks a little odd. Instead of declaring properties like `events: events`, it just gives a property name: `events`. This is shorthand that means the same thing—if a property name in brace notation isn't followed by a value, its value is taken from the binding with the same name. +Günlüğe eklenen nesne biraz garip görünüyor. Özelliklerin `events: events` gibi bildirilmesi yerine, sadece bir özellik adı verilmiştir. Bu, aynı anlama gelir- eğer parantez notasyonundaki bir özellik adı bir değerle takip edilmiyorsa, değeri o özellik adıyla aynı adda olan bir bağlantının değerinden alınır. -Every evening at 10 p.m.—or sometimes the next morning, after climbing down from the top shelf of his bookcase—Jacques records the day: +Böylelikle, her akşam saat 10.00'da—veya bazen ertesi sabah, kitaplığının en üst rafından indikten sonra—Jacques günü kaydeder. ``` addEntry(["work", "touched tree", "pizza", "running", @@ -348,21 +348,21 @@ addEntry(["weekend", "cycling", "break", "peanuts", "beer"], true); ``` -Once he has enough data points, he intends to use statistics to find out which of these events may be related to the squirrelifications. +Yeterince veri noktasına sahip olduktan sonra, bu olaylardan hangilerinin sincaplaşmayla ilişkili olabileceğini bulmak için istatistikleri kullanmayı amaçlıyor. {{index correlation}} -_Correlation_ is a measure of ((dependence)) between statistical variables. A statistical variable is not quite the same as a programming variable. In statistics you typically have a set of _measurements_, and each variable is measured for every measurement. Correlation between variables is usually expressed as a value that ranges from -1 to 1. Zero correlation means the variables are not related. A correlation of 1 indicates that the two are perfectly related—if you know one, you also know the other. Negative 1 also means that the variables are perfectly related but are opposites—when one is true, the other is false. +_Korelasyon_, istatistiksel değişkenler arasındaki ((bağımlılık)) ölçüsüdür ve istatistiksel değişken programlamadaki değişkenle tam olarak aynı değildir. İstatistikte genelde belirli ölçümler vardır ve her değişken bu ölçümlerle ölçülmektedir. Değişkenler arasındaki korelasyon genellikle -1 ile 1 arasında değişen bir değer olarak ifade edilir. Sıfır korelasyon, değişkenlerin ilişkili olmadığı anlamına gelir. Değeri bir olan bir korelasyon, iki değişkenin mükemmel bir şekilde ilişkili olduğunu gösterir - birini bildiğinizde, diğerini de bilmenizi sağlar. Değeri eksi bir olan bir korelasyon, değişkenlerin mükemmel bir şekilde ilişkili olduğunu ancak bunların zıt olduğunu gösterir - biri doğru olduğunda, diğerinin olmadığını bilmenizi sağlar. {{index "phi coefficient"}} -To compute the measure of correlation between two Boolean variables, we can use the _phi coefficient_ (_ϕ_). This is a formula whose input is a ((frequency table)) containing the number of times the different combinations of the variables were observed. The output of the formula is a number between -1 and 1 that describes the correlation. +İki Boolean değişken arasındaki korelasyon ölçümünü hesaplamak için _fi katsayısını_ (_ϕ_) kullanabiliriz. Bu, girdisi değişkenlerin kaç kere gözlemlendiğini içinde barındıran bir ((frekans tablosu)) olan bir formüldür. Formülün çıktısı, korelasyonu açıklayan -1 ile 1 arasında bir sayıdır. -We could take the event of eating ((pizza)) and put that in a frequency table like this, where each number indicates the number of times that combination occurred in our measurements. +Yeme olayını içindeki her sayı ölçülerimizde o kombinasyonun kaç kez meydana geldiğini gösteren bir pizza frekans tablosuna yerleştirebiliriz: {{figure {url: "img/pizza-squirrel.svg", alt: "A two-by-two table showing the pizza variable on the horizontal, and the squirrel variable on the vertical axis. Each cell show how many time that combination occurred. In 76 cases, neither happened. In 9 cases, only pizza was true. In 4 cases only squirrel was true. And in one case both occurred.", width: "7cm"}}} -If we call that table _n_, we can compute _ϕ_ using the following formula: +Eğer o tabloya _n_ dersek, _ϕ_ değerini aşağıdaki formülle hesaplayabiliriz: {{if html @@ -376,27 +376,27 @@ if}} if}} -(If at this point you're putting the book down to focus on a terrible flashback to 10th grade math class—hold on! I do not intend to torture you with endless pages of cryptic notation—it's just this one formula for now. And even with this one, all we do is turn it into JavaScript.) +(Eğer bu noktada kitabı bırakıp 10. sınıf matematik dersine yoğunlaşmaya başladıysanız—bekleyin! Sizi anlaşılmaz işaretlerle dolu sonsuz sayfalık bir işkenceye tabi tutmak niyetinde değilim—şimdilik sadece bu formül. Ve bu formülle yapacağımız tek şey onu sadece JavaScript'e dönüştürmek.) -The notation [_n_~01~]{if html}[[$n_{01}$]{latex}]{if tex} indicates the number of measurements where the first variable (squirrelness) is false (0) and the second variable (pizza) is true (1). In the pizza table, [_n_~01~]{if html}[[$n_{01}$]{latex}]{if tex} is 9. +Notasyon [_n_~01~]{if html}[[$n_{01}$]{latex}]{if tex}, ilk değişkenin (sincaplık) yanlış (0) ve ikinci değişkenin (pizza) doğru (1) olduğu ölçümlerin sayısını gösterir. Pizza tablosunda, [_n_~01~]{if html}[[$n_{01}$]{latex}]{if tex} 9'dur. -The value [_n_~1•~]{if html}[[$n_{1\bullet}$]{latex}]{if tex} refers to the sum of all measurements where the first variable is true, which is 5 in the example table. Likewise, [_n_~•0~]{if html}[[$n_{\bullet0}$]{latex}]{if tex} refers to the sum of the measurements where the second variable is false. +Değer [_n_~1•~]{if html}[[$n_{1\bullet}$]{latex}]{if tex}, ilk değişkenin doğru olduğu tüm ölçümlerin toplamını ifade eder, örneğin tabloda 5'tir. Benzer şekilde, [_n_~•0~]{if html}[[$n_{\bullet0}$]{latex}]{if tex} değeri, ikinci değişkenin yanlış olduğu ölçümlerin toplamını ifade eder. {{index correlation, "phi coefficient"}} -So for the pizza table, the part above the division line (the dividend) would be 1×76−4×9 = 40, and the part below it (the divisor) would be the square root of 5×85×10×80, or [√340,000]{if html}[[$\sqrt{340,000}$]{latex}]{if tex}. This comes out to _ϕ_ ≈ 0.069, which is tiny. Eating ((pizza)) does not appear to have influence on the transformations. +Dolayısıyla pizza tablosu için, bölümün üst kısmı (pay) 1×76−4×9 = 40 olur ve alt kısmı (payda) 5×85×10×80'ın karekökü, veya [√340000]{if html}[[$\sqrt{340000}$]{latex}]{if tex}. Bu, ϕ ≈ 0.069 olur, yani çok küçüktür. Pizza yemenin dönüşümler üzerinde bir etkisi olmadığı görünmektedir. -## Computing correlation +## Korelasyonu hesaplama {{index [array, "as table"], [nesting, "of arrays"]}} -We can represent a two-by-two ((table)) in JavaScript with a four-element array (`[76, 9, 4, 1]`). We could also use other representations, such as an array containing two two-element arrays (`[[76, 9], [4, 1]]`) or an object with property names like `"11"` and `"01"`, but the flat array is simple and makes the expressions that access the table pleasantly short. We'll interpret the indices to the array as two-((bit)) ((binary number))s, where the leftmost (most significant) digit refers to the squirrel variable and the rightmost (least significant) digit refers to the event variable. For example, the binary number `10` refers to the case where Jacques did turn into a squirrel, but the event (say, "pizza") didn't occur. This happened four times. And since binary `10` is 2 in decimal notation, we will store this number at index 2 of the array. +JavaScript'te iki satır iki sütun ((tablo))'yu dört elemanlı bir dizi ile temsil edebiliriz (`[76, 9, 4, 1]`). Ayrıca, diğer temsilleri kullanabiliriz, örneğin, iki iki elemanlı dizi içeren bir dizi (`[[76, 9], [4, 1]]`) veya `"11"` ve `"01"` gibi özellik adlarına sahip bir nesne, ancak düz dizi basittir ve tabloya erişimi kolaylaştırır. Dizinin index değerlerini iki bitlik ((ikili sayı))lar olarak yorumlayacak, soldaki (en önemli) basamak sincap değişkenine ve sağdaki (en önemsiz) basamak olay değişkenine atıfta bulunmasını sağlayacağız. Örneğin, ikili sayı `10`, Jacques'nin bir sincap haline geldiği ancak olayın (örneğin, "pizza") gerçekleşmediği durumu ifade eder. Bu dört kez oldu. Ve iki gösterimdeki `10` sayısı ondalık gösterimde 2 olduğundan ötürü bu sayıyı dizinin 2. index değer pozisyonuna kaydedeceğiz. {{index "phi coefficient", "phi function"}} {{id phi_function}} -This is the function that computes the _ϕ_ coefficient from such an array: +Böyle bir diziyle ϕ katsayısını hesaplayan fonksiyon budur: ```{includeCode: strip_log, test: clip} function phi(table) { @@ -413,15 +413,15 @@ console.log(phi([76, 9, 4, 1])); {{index "square root", "Math.sqrt function"}} -This is a direct translation of the _ϕ_ formula into JavaScript. `Math.sqrt` is the square root function, as provided by the `Math` object in a standard JavaScript environment. We have to add two fields from the table to get fields like [n~1•~]{if html}[[$n_{1\bullet}$]{latex}]{if tex} because the sums of rows or columns are not stored directly in our data structure. +Bu, _ϕ_ formülünün JavaScript'e doğrudan çevirisidir. `Math.sqrt`, standart bir JavaScript ortamında `Math` nesnesi tarafından sağlanan karekök işlemidir. [n~1•~]{if html}[[$n_{1\bullet}$]{latex}]{if tex} gibi alanları elde etmek için tablodan iki alan eklememiz gerekmektedir çünkü satır veya sütunların toplamları doğrudan veri yapımızda saklanmamaktadır. -{{index "JOURNAL data set"}} +{{index "JOURNAL dataset"}} -Jacques keeps his journal for three months. The resulting ((data set)) is available in the [coding sandbox](https://eloquentjavascript.net/code#4) for this chapter[ ([_https://eloquentjavascript.net/code#4_](https://eloquentjavascript.net/code#4))]{if book}, where it is stored in the `JOURNAL` binding, and in a downloadable [file](https://eloquentjavascript.net/code/journal.js). +Jacques günlüğünü üç ay boyunca tuttu. Ortaya çıkan ((veri seti)), bu bölüm için[ ([_https://eloquentjavascript.net/code#4_](https://eloquentjavascript.net/code#4))]{if book} kod [kum havuzunda](https://eloquentjavascript.net/code#4) mevcuttur, burada `JOURNAL` bağlantısında saklanır ve bir [dosya](https://eloquentjavascript.net/code/journal.js) halinde indirilebilir. {{index "tableFor function"}} -To extract a two-by-two ((table)) for a specific event from the journal, we must loop over all the entries and tally how many times the event occurs in relation to squirrel transformations: +Günlükten belirli bir olay için iki satır iki sütun bir ((tablo)) çıkarmak adına tüm girişler üzerinde döngü yapıp olayın sincap dönüşümlerine göre kaç kere yaşandığını saymalıyız. ```{includeCode: strip_log} function tableFor(event, journal) { @@ -441,21 +441,21 @@ console.log(tableFor("pizza", JOURNAL)); {{index [array, searching], "includes method"}} -Arrays have an `includes` method that checks whether a given value exists in the array. The function uses that to determine whether the event name it is interested in is part of the event list for a given day. +Dizilerin `includes` metodu, verilen bir değerin dizide var olup olmadığını kontrol eder. Fonksiyon, bunu kullanır ilgilendiği olayın o günkü olay listesinin bir parçası olup olmadığını belirlemek için kullanır. {{index [array, indexing]}} -The body of the loop in `tableFor` figures out which box in the table each journal entry falls into by checking whether the entry contains the specific event it's interested in and whether the event happens alongside a squirrel incident. The loop then adds one to the correct box in the table. +`tableFor` içindeki döngünün gövdesi, her günlük girişinin özel olarak ilgilenilen olayı içerip içermediğini ve olayın bir sincap olayıyla aynı anda gerçekleşip gerçekleşmediğini kontrol ederek tablodaki hangi kutuya düştüğünü belirler. Döngü daha sonra tablodaki doğru kutuya bir ekler. -We now have the tools we need to compute individual ((correlation))s. The only step remaining is to find a correlation for every type of event that was recorded and see whether anything stands out. +Şimdi, bireysel ((korelasyon))ları hesaplamak için ihtiyacımız olan araçlara sahibiz. Kalan tek adım, kaydedilen her tür olay için bir korelasyon bulmak ve herhangi bir şeyin dikkat çekip çekmediğini görmektir. {{id for_of_loop}} -## Array loops +## Dizi döngüleri {{index "for loop", loop, [array, iteration]}} -In the `tableFor` function, there's a loop like this: +`tableFor` fonksiyonunda şöyle bir döngü var: ``` for (let i = 0; i < JOURNAL.length; i++) { @@ -464,9 +464,9 @@ for (let i = 0; i < JOURNAL.length; i++) { } ``` -This kind of loop is common in classical JavaScript—going over arrays one element at a time is something that comes up a lot, and to do that you'd run a counter over the length of the array and pick out each element in turn. +Bu tür bir döngü, klasik JavaScript'te yaygındır—dizilerin her bir elemanını tek tek geçmek sık sık karşılaşılan bir durumdur ve bunu yapmak için dizinin uzunluğu üzerinde bir sayaç çalıştırarak sırayla her elemanı seçersiniz. -There is a simpler way to write such loops in modern JavaScript: +Modern JavaScript'te böyle döngüleri daha basit bir şekilde yazmanın bir yolu var. ``` for (let entry of JOURNAL) { @@ -476,15 +476,15 @@ for (let entry of JOURNAL) { {{index "for/of loop"}} -When a `for` loop uses the word `of` after its variable definition, it will loop over the elements of the value given after `of`. This works not only for arrays but also for strings and some other data structures. We'll discuss _how_ it works in [Chapter ?](object). +Bir `for` döngüsü şu şekilde görünüyorsa, bir değişken tanımından sonra `of` kelimesi varsa, `of` kelimesinden sonra verilen değerin öğeleri üzerinde döngüyü başlatır. Bu yalnızca diziler için değil dizeler ve bazı diğer veri yapıları için de çalışır. Nasıl çalıştığını [Bölüm ?](object)’de tartışacağız. {{id analysis}} -## The final analysis +## Son analiz {{index journal, "weresquirrel example", "journalEvents function"}} -We need to compute a correlation for every type of event that occurs in the data set. To do that, we first need to _find_ every type of event. +Veri setinde bulunan her tür olay için bir korelasyon hesaplamamız gerekiyor. Bunun için önce her tür olayı _bulmalıyız_. {{index "includes method", "push method"}} @@ -505,9 +505,9 @@ console.log(journalEvents(JOURNAL)); // → ["carrot", "exercise", "weekend", "bread", …] ``` -By adding any event names that aren't already in it to the `events` array, the function collects every type of event. +Tüm olayların üzerinden geçerek, içinde var olmayanları olayları `events` dizisine ekleyerek, fonksiyon her tür olayı toplar. -Using that function, we can see all the ((correlation))s: +Bunu kullanarak, tüm ((korelasyon))ları görebiliriz. ```{test: no} for (let event of journalEvents(JOURNAL)) { @@ -518,10 +518,10 @@ for (let event of journalEvents(JOURNAL)) { // → weekend: 0.1371988681 // → bread: -0.0757554019 // → pudding: -0.0648203724 -// and so on... +// And so on... ``` -Most correlations seem to lie close to zero. Eating carrots, bread, or pudding apparently does not trigger squirrel-lycanthropy. The transformations _do_ seem to occur somewhat more often on weekends. Let's filter the results to show only correlations greater than 0.1 or less than -0.1: +Çoğu korelasyonun sıfıra yakın olduğu görünüyor. Havuç, ekmek veya puding yemek açıkça sincapa dönüşmeyi tetiklemiyor gibi görünüyor. Bununla birlikte, hafta sonlarında biraz daha sık meydana gelme eğiliminde olduğunu fark ediyoruz. Sonuçları, 0,1'den büyük veya -0,1'den küçük olan korelasyonları göstermek için filtreleyelim. ```{test: no, startCode: true} for (let event of journalEvents(JOURNAL)) { @@ -539,9 +539,9 @@ for (let event of journalEvents(JOURNAL)) { // → peanuts: 0.5902679812 ``` -Aha! There are two factors with a ((correlation)) clearly stronger than the others. Eating ((peanuts)) has a strong positive effect on the chance of turning into a squirrel, whereas brushing teeth has a significant negative effect. +Aha! Diğerlerinden açıkça daha güçlü bir ((korelasyon))a sahip olan iki faktör var. Fıstık yemek, bir sincap haline dönüşme şansı üzerinde güçlü bir pozitif etkiye sahipken, dişlerini fırçalamak ise önemli bir negatif etkiye sahiptir. -Interesting. Let's try something: +İlginç. Bir şey deneyelim. ``` for (let entry of JOURNAL) { @@ -554,23 +554,23 @@ console.log(phi(tableFor("peanut teeth", JOURNAL))); // → 1 ``` -That's a strong result. The phenomenon occurs precisely when Jacques eats ((peanuts)) and fails to brush his teeth. If only he weren't such a slob about dental hygiene, he'd never even have noticed his affliction. +Bu güçlü bir sonuç. Olay, Jacques fıstık yediği ve dişlerini fırçalamadığı zaman meydana geliyor. Keşke dental hijyen konusunda böylesine dikkatsiz olmasaydı, belki de bu hastalığını hiç fark etmeyecekti. -Knowing this, Jacques stops eating peanuts altogether and finds that his transformations stop. +Bunu öğrendikten sonra, Jacques fıstık yemeyi tamamen bırakır ve dönüşümlerinin durduğunu fark eder. {{index "weresquirrel example"}} -But it only takes a few months for him to notice that something is missing from this entirely human way of living. Without his feral adventures, Jacques hardly feels alive at all. He decides he'd rather be a full-time wild animal. After building a beautiful little tree house in the forest and equipping it with a peanut butter dispenser and a ten-year supply of peanut butter, he changes form one last time, and lives the short and energetic life of a squirrel. +Ancak, tamamen insanca yaşama şeklinde eksik bir şey olduğunu fark etmesi birkaç ayını alır. Vahşi maceraları olmadan Jacques kendini neredeyse hiç yaşamıyor gibi hisseder. Tam zamanlı bir vahşi hayvan olmayı tercih eder. Ormanda güzel bir ağaç ev inşa eder ve kurduğu bir fıstık ezmesi dağıtıcısına on yıllık fıstık ezmesi stoku sağladıktan sonra, son bir kez daha değişir ve bir sincap olarak kısa ve enerjik bir yaşam sürer. -## Further arrayology +## Diziler hakkında daha fazla bilgi {{index [array, methods], [method, array]}} -Before finishing the chapter, I want to introduce you to a few more object-related concepts. I'll start by introducing some generally useful array methods. +Bu bölümü bitirmeden önce, size birkaç daha objelerle ilgili kavramı tanıtmak istiyorum. Genel olarak kullanışlı birkaç dizi metodu tanıtarak başlayacağım. {{index "push method", "pop method", "shift method", "unshift method"}} -We saw `push` and `pop`, which add and remove elements at the end of an array, [earlier](data#array_methods) in this chapter. The corresponding methods for adding and removing things at the start of an array are called `unshift` and `shift`. +Bu bölümde [daha önce](data#array_methods) gördüğümüz `push` ve `pop` yöntemleri, bir dizinin sonuna eleman ekler ve kaldırır. Bir dizinin başına şeyler eklemek ve kaldırmak için karşılık gelen yöntemler `unshift` ve `shift` olarak adlandırılır. ``` let todoList = []; @@ -587,11 +587,11 @@ function rememberUrgently(task) { {{index "task management example"}} -This program manages a queue of tasks. You add tasks to the end of the queue by calling `remember("groceries")`, and when you're ready to do something, you call `getTask()` to get (and remove) the front item from the queue. The `rememberUrgently` function also adds a task but adds it to the front instead of the back of the queue. +Bu program, görevlerden oluşan bir kuyruğu yönetir. `remember("groceries")` çağrısıyla görevleri kuyruğun sonuna eklersiniz ve bir şey yapmaya hazır olduğunuzda, `getTask()` çağrısıyla kuyruğun önündeki öğeyi alırsınız (ve kaldırırsınız). `rememberUrgently` fonksiyonu da bir görev ekler ancak bunu kuyruğun sonuna değil önüne ekler. {{index [array, searching], "indexOf method", "lastIndexOf method"}} -To search for a specific value, arrays provide an `indexOf` method. The method searches through the array from the start to the end and returns the index at which the requested value was found—or -1 if it wasn't found. To search from the end instead of the start, there's a similar method called `lastIndexOf`: +Belirli bir değeri aramak için, diziler `indexOf` metodunu sağlar. Bu yöntem, istenen değerin bulunduğu dizinin indexini bulur ve döndürür - veya bulunamadıysa -1 değerini döndürür. Arama için dizinin sonundan başlamak isterseniz, benzer bir yöntem olan `lastIndexOf` vardır. ``` console.log([1, 2, 3, 2, 1].indexOf(2)); @@ -600,11 +600,11 @@ console.log([1, 2, 3, 2, 1].lastIndexOf(2)); // → 3 ``` -Both `indexOf` and `lastIndexOf` take an optional second argument that indicates where to start searching. +`indexOf` ve `lastIndexOf` her ikisi de başlamak için opsiyonel olan ikinci argüman alır ve nereden aramaya başlanacağını belirtir. {{index "slice method", [array, indexing]}} -Another fundamental array method is `slice`, which takes start and end indices and returns an array that has only the elements between them. The start index is inclusive, the end index exclusive. +Başka bir temel dizi metodu olan `slice`, başlangıç ve bitiş index değerlerini alır ve yalnızca bunlar arasındaki öğeleri içeren bir dizi döndürür. Başlangıç index değerinde bulunan değer döndürülen diziye dahilken bitiş index değerindeki değer hariçtir. ``` console.log([0, 1, 2, 3, 4].slice(2, 4)); @@ -615,13 +615,13 @@ console.log([0, 1, 2, 3, 4].slice(2)); {{index [string, indexing]}} -When the end index is not given, `slice` will take all of the elements after the start index. You can also omit the start index to copy the entire array. +Bitiş dizini verilmediğinde, `slice` başlangıç index değerinden sonraki tüm öğeleri alır. Ayrıca tüm diziyi kopyalamak adına başlangıç index değerini de vermeyebilirsiniz. {{index concatenation, "concat method"}} -The `concat` method can be used to append arrays together to create a new array, similar to what the `+` operator does for strings. +`concat` metodu dizileri bir araya getirerek yeni bir dizi oluşturmada da kullanılabilir, bu işlem `+` operatörünün dizinlere yaptığı işleme benzerdir. -The following example shows both `concat` and `slice` in action. It takes an array and an index and returns a new array that is a copy of the original array with the element at the given index removed: +Aşağıdaki örnek, hem `concat` hem de `slice` metodlarının kullanımını gösteriyor. Bir dizi ve bir index değeri alıp verilen index değerindeki öğe çıkarılmış olan orijinal dizinin bir kopyasını döndürür. ``` function remove(array, index) { @@ -632,13 +632,13 @@ console.log(remove(["a", "b", "c", "d", "e"], 2)); // → ["a", "b", "d", "e"] ``` -If you pass `concat` an argument that is not an array, that value will be added to the new array as if it were a one-element array. +`concat` metoduna bir dizi olmayan bir argüman verirseniz, bu değer yeni diziye tek bir öğe barındıran bir diziymiş gibi eklenecektir. -## Strings and their properties +## Dizeler ve özellikleri {{index [string, properties]}} -We can read properties like `length` and `toUpperCase` from string values. But if we try to add a new property, it doesn't stick. +Dizin değerlerinden `length` ve `toUpperCase` gibi özellikleri okuyabiliriz. Ancak yeni bir özellik eklemeye çalışırsanız, yapışmaz. ``` let kim = "Kim"; @@ -647,11 +647,11 @@ console.log(kim.age); // → undefined ``` -Values of type string, number, and Boolean are not objects, and though the language doesn't complain if you try to set new properties on them, it doesn't actually store those properties. As mentioned earlier, such values are immutable and cannot be changed. +Dize, sayı ve Boolean türlerinin değerleri nesneler değildir ve dil bunlara yeni özellikler eklemeye çalışırsanız şikayet etmese de aslında bu özellikleri saklamaz. Daha önce belirtildiği gibi, bu tür değerler değiştirilemezler. {{index [string, methods], "slice method", "indexOf method", [string, searching]}} -But these types do have built-in properties. Every string value has a number of methods. Some very useful ones are `slice` and `indexOf`, which resemble the array methods of the same name: +Ancak, bu türlerin yerleşik özellikleri vardır. Her dize değeri bir belirli özelliklere sahiptir. Bazı çok kullanışlı olanları `slice` ve `indexOf` metodlarıdır ve aynı isimde olan dizi metodlarına benzerler. ``` console.log("coconuts".slice(4, 7)); @@ -660,7 +660,7 @@ console.log("coconut".indexOf("u")); // → 5 ``` -One difference is that a string's `indexOf` can search for a string containing more than one character, whereas the corresponding array method looks only for a single element: +Bir fark, bir dizenin `indexOf` metodunun birden fazla karakter içeren bir dizeyi arayabilmesidir, oysa ilgili dizi metodu yalnızca tek bir öğe arar. ``` console.log("one two three".indexOf("ee")); @@ -669,7 +669,7 @@ console.log("one two three".indexOf("ee")); {{index [whitespace, trimming], "trim method"}} -The `trim` method removes whitespace (spaces, newlines, tabs, and similar characters) from the start and end of a string: +`trim` metodu, bir dizinin başından ve sonundan boşlukları (boşluklar, yeni satırlar, tab vb. karakterler) kaldırır. ``` console.log(" okay \n ".trim()); @@ -678,7 +678,7 @@ console.log(" okay \n ".trim()); {{id padStart}} -The `zeroPad` function from the [previous chapter](functions) also exists as a method. It is called `padStart` and takes the desired length and padding character as arguments: +[Önceki bölüm](functions)'deki `zeroPad` fonksiyonu aynı zamanda bir metod olarak da mevcuttur. `padStart` olarak adlandırılır ve istenen uzunluğu ve dolgu karakterini argüman olarak alır. ``` console.log(String(6).padStart(3, "0")); @@ -689,7 +689,7 @@ console.log(String(6).padStart(3, "0")); {{index "split method"}} -You can split a string on every occurrence of another string with `split` and join it again with `join`: +Bir dizeyi başka bir dizenin her görünümünde `split` aracılıyla bölebilir ve onu tekrar `join` ile birleştirebilirsiniz. ``` let sentence = "Secretarybirds specialize in stomping"; @@ -702,7 +702,7 @@ console.log(words.join(". ")); {{index "repeat method"}} -A string can be repeated with the `repeat` method, which creates a new string containing multiple copies of the original string, glued together: +Bir dizeyi `repeat` metodunu kullanarak tekrarlayabilirsiniz, böylelikle eski dizeyi birden fazla kez içerisinde barındıran başka yeni bir dize oluşturmuş olursunuz. ``` console.log("LA".repeat(3)); @@ -711,7 +711,7 @@ console.log("LA".repeat(3)); {{index ["length property", "for string"], [string, indexing]}} -We have already seen the string type's `length` property. Accessing the individual characters in a string looks like accessing array elements (with a complication that we'll discuss in [Chapter ?](higher_order#code_units)). +Dize türünün `length` özelliğini zaten gördük. Bir dizideki bireysel karakterlere erişmek, dizi öğelerine erişmek gibi görünür ([bölüm ?](higher_order#code_units)'da inceleyeceğimiz bir karmaşıklıkla). ``` let string = "abc"; @@ -723,11 +723,15 @@ console.log(string[1]); {{id rest_parameters}} -## Rest parameters +## Kalan parametreleri {{index "Math.max function", "period character", "max example", spread, [array, "of rest arguments"]}} -It can be useful for a function to accept any number of ((argument))s. For example, `Math.max` computes the maximum of _all_ the arguments it is given. To write such a function, you put three dots before the function's last ((parameter)), like this: +Bir fonksiyonunun belirli olmayan, herhangi bir sayıda argüman kabul etmesi yararlı olabilir. Örneğin, `Math.max`, verildiğinde tüm verilen argümanların maksimumunu hesaplar. + +{{index "period character", "max example", spread, [array, "of rest arguments"]}} + +Böyle bir fonksiyon yazmak için, fonksiyonun son ((parametresi))nın önüne üç nokta koyarsınız: ```{includeCode: strip_log} function max(...numbers) { @@ -741,11 +745,11 @@ console.log(max(4, 1, 9, -2)); // → 9 ``` -When such a function is called, the _((rest parameter))_ is bound to an array containing all further arguments. If there are other parameters before it, their values aren't part of that array. When, as in `max`, it is the only parameter, it will hold all arguments. +Böyle bir fonksiyon çağrıldığında, _((kalan parametre))_ tüm diğer argümanları içeren bir diziyle ilişkilendirilir. Eğer ondan önce başka parametreler varsa, bu değerler bu dizinin bir parçası olmayacaktır ancak eğer `max` fonksiyonda olduğu gibi tek başına bir kalan parametresi varsa o zaman tüm değişkenleri içerecektir. {{index [function, application]}} -You can use a similar three-dot notation to _call_ a function with an array of arguments: +Benzer bir üç nokta gösterimi kullanarak bir fonksiyonu bir dizi argümanla çağırmak da mümkündür. ``` let numbers = [5, 1, 7]; @@ -753,11 +757,11 @@ console.log(max(...numbers)); // → 7 ``` -This "((spread))s" out the array into the function call, passing its elements as separate arguments. It is possible to include an array like that along with other arguments, as in `max(9, ...numbers, 2)`. +Bu, diziyi fonksiyon çağrısına (("yayarak")) öğelerini ayrı argümanlar olarak geçirir. Bu şekilde, `max(9, ...numbers, 2)` şeklinde hem bir diziyi yayarak hem de yaymayarak farklı argümanlar vermek mümkündür. {{index "[] (array)"}} -Square bracket array notation similarly allows the triple-dot operator to spread another array into the new array: +Köşeli parantez dizisi gösterimi, üç nokta operatörünü başka bir diziyi yeni diziye yaymak için de kullanılabilir. ``` let words = ["never", "fully"]; @@ -767,7 +771,7 @@ console.log(["will", ...words, "understand"]); {{index "{} (object)"}} -This works even in curly brace objects, where it adds all properties from another object. If a property is added multiple times, the last value to be added wins: +Bu süslü parantez nesnelerinde de çalışmaktadır ve başka bir nesnedeki tüm özellikleri diğer nesneye ekler. Eğer aynı addaki bir özellik aynı objeye tekrar ve tekrar farklı değerlerle eklenirse, en son eklenmiş olan değer o isimdeki özelliğin değeri olacaktır. ``` let coordinates = {x: 10, y: 0}; @@ -775,29 +779,29 @@ console.log({...coordinates, y: 5, z: 1}); // → {x: 10, y: 5, z: 1} ``` -## The Math object +## Math nesnesi {{index "Math object", "Math.min function", "Math.max function", "Math.sqrt function", minimum, maximum, "square root"}} -As we've seen, `Math` is a grab bag of number-related utility functions such as `Math.max` (maximum), `Math.min` (minimum), and `Math.sqrt` (square root). +Gördüğümüz gibi, `Math`, `Math.max` (maksimum), `Math.min` (minimum) ve `Math.sqrt` (karekök) gibi sayılarla ilgili yardımcı fonksiyonları bir arada barındıran bir nesnedir. {{index namespace, [object, property]}} {{id namespace_pollution}} -The `Math` object is used as a container to group a bunch of related functionality. There is only one `Math` object, and it is almost never useful as a value. Rather, it provides a _namespace_ so that all these functions and values do not have to be global bindings. +`Math` nesnesi, bir dizi ilgili fonksiyonaliteyi gruplamak için bir konteyner olarak kullanılır. Yalnızca bir `Math` nesnesi vardır ve hemen hemen hiç bir zaman değer olarak yararlı değildir. Daha çok, tüm bu fonksiyonların ve değerlerin global bağlantıları olmasına gerek kalmaması için bir _ad alanı_ sağlar. {{index [binding, naming]}} -Having too many global bindings "pollutes" the namespace. The more names have been taken, the more likely you are to accidentally overwrite the value of some existing binding. For example, it's not unlikely you'll want to name something `max` in one of your programs. Since JavaScript's built-in `max` function is tucked safely inside the `Math` object, you don't have to worry about overwriting it. +Çok fazla global bağlantıların varlığı ad alanını "kirletir". Ne kadar çok isim alındıysa, bir varolan bağlantının değerini yanlışlıkla değiştirme olasılığınız o kadar artar. Örneğin, programlarınızdan birinde bir şeyi `max` olarak adlandırmak istemek olasıdır. JavaScript'in yerleşik `max` işlevi güvenli bir şekilde `Math` nesnesinin içine gizlenmiş olduğundan ötürü onun değerini istemeden değiştirmemiz olasılığı üzerine endişelenmemize gerek yoktur. {{index "let keyword", "const keyword"}} -Many languages will stop you, or at least warn you, when you are defining a binding with a name that is already taken. JavaScript does this for bindings you declared with `let` or `const` but—perversely—not for standard bindings nor for bindings declared with `var` or `function`. +Birçok dil, zaten alınmış bir isme sahip bir bağlantı tanımladığınızda sizi durdurur veya en azından uyarır. JavaScript bunu, `let` veya `const` ile tanımladığınız bağlanmalar için yapar ama tuhaf bir şekilde standart bağlantılar ya da `var` veya `function` ile tanımlanan bağlantılar için yapmaz. {{index "Math.cos function", "Math.sin function", "Math.tan function", "Math.acos function", "Math.asin function", "Math.atan function", "Math.PI constant", cosine, sine, tangent, "PI constant", pi}} -Back to the `Math` object. If you need to do ((trigonometry)), `Math` can help. It contains `cos` (cosine), `sin` (sine), and `tan` (tangent), as well as their inverse functions, `acos`, `asin`, and `atan`, respectively. The number π (pi)—or at least the closest approximation that fits in a JavaScript number—is available as `Math.PI`. There is an old programming tradition of writing the names of ((constant)) values in all caps: +`Math` nesnesine geri dönelim. Eğer ((trigonometri)) yapmanız gerekiyorsa, `Math` size yardımcı olabilir. `cos` (kosinüs), `sin` (sinüs) ve `tan` (tanjant) gibi trigonometrik fonksiyonları, ayrıca bunların ters fonksiyonlarını, sırasıyla `acos`, `asin` ve `atan` içerir. Pi sayısı—veya en azından bir JavaScript sayısına sığan en yakın yaklaşım—`Math.PI` olarak mevcuttur. Sabit değerlerin adlarını tamamı büyük harflerle yazma gibi eski bir programlama geleneği vardır. ```{test: no} function randomPointOnCircle(radius) { @@ -809,11 +813,11 @@ console.log(randomPointOnCircle(2)); // → {x: 0.3667, y: 1.966} ``` -If you're not familiar with sines and cosines, don't worry. I'll explain them when they are used in this book, in [Chapter ?](dom#sin_cos). +Eğer sinüs ve kosinüslerle aşina değilseniz, endişelenmeyin. Kitapta kullanıldıklarında, [bölümün ?](dom#sin_cos)'da açıklayacağım. {{index "Math.random function", "random number"}} -The previous example used `Math.random`. This is a function that returns a new pseudorandom number between zero (inclusive) and one (exclusive) every time you call it: +Önceki örnek, `Math.random` kullanıyordu. Bu, her çağrıldığında sıfır (dahil) ile bir (hariç) arasında bir yarı rastgele sayı döndüren bir fonksiyondur. ```{test: no} console.log(Math.random()); @@ -826,28 +830,28 @@ console.log(Math.random()); {{index "pseudorandom number", "random number"}} -Though computers are deterministic machines—they always react the same way if given the same input—it is possible to have them produce numbers that appear random. To do that, the machine keeps some hidden value, and whenever you ask for a new random number, it performs complicated computations on this hidden value to create a new value. It stores a new value and returns some number derived from it. That way, it can produce ever new, hard-to-predict numbers in a way that _seems_ random. +Bilgisayarlar deterministik makinelerdir—her zaman aynı giriş verildiğinde her zaman aynı şekilde tepki verirler—ancak onları rastgele görünen sayılar üretmeleri için yönlendirebilirsiniz. Bunun için, makine bazı gizli bir değeri saklar ve yeni bir rastgele sayı istediğinizde, bu gizli değer üzerinde karmaşık hesaplamalar yaparak yeni bir değer oluşturur. Yeni bir değer saklar ve ondan türetilmiş bir sayı döndürür. Bu şekilde her zaman rastgele gibi görünen yeni ve tahmin edilmesi zor sayılar üretebilir. {{index rounding, "Math.floor function"}} -If we want a whole random number instead of a fractional one, we can use `Math.floor` (which rounds down to the nearest whole number) on the result of `Math.random`: +Kesirli bir sayı yerine bütün rastgele bir sayı istiyorsak, `Math.random` fonksiyonunun sonucuna `Math.floor` (en yakın tam sayıya yuvarlar) kullanabiliriz. ```{test: no} console.log(Math.floor(Math.random() * 10)); // → 2 ``` -Multiplying the random number by 10 gives us a number greater than or equal to 0 and below 10. Since `Math.floor` rounds down, this expression will produce, with equal chance, any number from 0 through 9. +Rastgele sayıyı 10 ile çarptığımızda, 0 veya daha büyük bir sayı ve 10'un altında bir sayı elde ederiz. `Math.floor` yuvarladığı için, bu ifade, eşit bir şansla, 0 ile 9 arasındaki herhangi bir sayıyı üretecektir. {{index "Math.ceil function", "Math.round function", "Math.abs function", "absolute value"}} -There are also the functions `Math.ceil` (for "ceiling", which rounds up to a whole number), `Math.round` (to the nearest whole number), and `Math.abs`, which takes the absolute value of a number, meaning it negates negative values but leaves positive ones as they are. +`Math.ceil`(en yakın bir üst tam sayıya yuvarlar), `Math.round`(en yakın tam sayıya yuvarlar) ve `Math.abs` gibi bir sayının mutlak değerini alan, yani verilen sayıyı eksi ile çarpan ancak verilen sayı zaten pozitifse olduğu gibi bırakan fonksiyonlar da vardır. -## Destructuring +## Parçalara ayırma {{index "phi function"}} -Let's return to the `phi` function for a moment. +Bir an için `phi` fonksiyonuna geri dönelim. ```{test: wrap} function phi(table) { @@ -861,7 +865,7 @@ function phi(table) { {{index "destructuring binding", parameter}} -One reason this function is awkward to read is that we have a binding pointing at our array, but we'd much prefer to have bindings for the _elements_ of the array—that is, `let n00 = table[0]` and so on. Fortunately, there is a succinct way to do this in JavaScript: +Bu fonksiyonun okunması zor olmasının bir nedeni, dizimize işaret eden bir bağlantımızın olması, ancak dizinin elemanları için `let n00 = table[0]` benzeri bir bağlantımızın olmasını bize okunurlukta çok daha yardımcı olacaktır. Neyse ki, JavaScript'te bunu kısa ve öz bir şekilde yapmanın yolu bulunmakta. ``` function phi([n00, n01, n10, n11]) { @@ -873,11 +877,11 @@ function phi([n00, n01, n10, n11]) { {{index "let keyword", "var keyword", "const keyword", [binding, destructuring]}} -This also works for bindings created with `let`, `var`, or `const`. If you know that the value you are binding is an array, you can use ((square brackets)) to "look inside" of the value, binding its contents. +Bu, `let`, `var` veya `const` ile oluşturulan bağlantılar için çalışmaktadır. Bağlantı oluşturduğunuz değerin bir dizi olduğunu bildiğinizde, içeriğine "bakmak" için ((köşeli parantezleri)) kullanabilir ve içeriğindeki değerlere bağlantılar oluşturabilirsiniz. {{index [object, property], [braces, object]}} -A similar trick works for objects, using braces instead of square brackets: +Köşeli parantezler yerine süslü parantezler kullanılan ve nesneler için çalışan diğer bir yöntem. ``` let {name} = {name: "Faraji", age: 23}; @@ -887,13 +891,13 @@ console.log(name); {{index null, undefined}} -Note that if you try to destructure `null` or `undefined`, you get an error, much as you would if you directly try to access a property of those values. +Unutmayın ki, `null` veya `undefined`'i ayrıştırmaya çalışırsanız, bu değerlerin özelliklerine doğrudan erişmeye çalıştığınızdan ötürü bir hata alırsınız. -## Optional property access +## Opsiyonel özellik erişimi {{index "optional chaining", "period character"}} -When you aren't sure whether a given value produces an object but still want to read a property from it when it does, you can use a variant of the dot notation: `object?.property`. +Belirli bir nesnenin var olduğundan emin değilseniz, ancak var olduğunda ondan bir özelliği okumak istiyorsanız, nokta notasyonunun bir varyantını kullanabilirsiniz: `object?.property`. ``` function city(object) { @@ -905,9 +909,9 @@ console.log(city({name: "Vera"})); // → undefined ``` -The expression `a?.b` means the same as `a.b` when `a` isn't null or undefined. When it is, it evaluates to undefined. This can be convenient when, as in the example, you aren't sure that a given property exists or when a variable might hold an undefined value. +`a?.b` ifadesi, `a` değeri `null` veya `undefined` değilse `a.b` ifadesiyle aynı anlamına gelir ancak eğer `null` veya `undefined` ise o zaman, değeri `undefined` olur. Örnekte de olduğu gibi, belirli bir özelliğin varlığından emin olmadığınızda kullanışlı olabilir. -A similar notation can be used with square bracket access, and even with function calls, by putting `?.` in front of the parentheses or brackets: +Benzer bir notasyon `?.` koyularak köşeli parantez erişimi ile köşeli parantezlerden önce, hatta fonksiyon çağrılarında parantezlerden önce de kullanılabilir. ``` console.log("string".notAMethod?.()); @@ -920,21 +924,21 @@ console.log({}.arrayProp?.[0]); {{index [array, representation], [object, representation], "data format", [memory, organization]}} -Because properties grasp their value rather than contain it, objects and arrays are stored in the computer's memory as sequences of bits holding the _((address))es_—the place in memory—of their contents. An array with another array inside of it consists of (at least) one memory region for the inner array and another for the outer array, containing (among other things) a number that represents the address of the inner array. +Özellikler değerlerini içermek yerine kavradığındna ötürü, nesneler ve diziler bilgisayarın belleğinde, içeriklerinin _adresini_ bit dizileri halinde depolamaktadır. Dolayısıyla, içinde başka bir dizi bulunan bir dizi, iç dizi için en az bir bellek bölgesi ve iç dizenin adresini temsil eden bir numara içeren dış dizi için başka bir bellek bölgesinden oluşur. -If you want to save data in a file for later or send it to another computer over the network, you have to somehow convert these tangles of memory addresses to a description that can be stored or sent. You _could_ send over your entire computer memory along with the address of the value you're interested in, I suppose, but that doesn't seem like the best approach. +Veriyi daha sonra bir dosyada saklamak veya ağ üzerinden başka bir bilgisayara göndermek istiyorsanız, bu bellek adreslerinin karmakarışık dizilerini saklanabilir veya gönderilebilir bir açıklamaya dönüştürmek zorundasınız. Tahminimce, ilgilendiğiniz değerin adresiyle birlikte tüm bilgisayar belleğinizi gönderebilirsiniz, ancak bu en iyi yaklaşım gibi görünmüyor. {{indexsee "JavaScript Object Notation", JSON}} {{index serialization, "World Wide Web"}} -What we can do is _serialize_ the data. That means it is converted into a flat description. A popular serialization format is called _((JSON))_ (pronounced "Jason"), which stands for JavaScript Object Notation. It is widely used as a data storage and communication format on the Web, even in languages other than JavaScript. +Yapabileceğimiz şey, veriyi _serileştirmek_. Bu, verinin düz bir açıklamaya dönüştürülmesi anlamına gelir. Popüler bir seri hale getirme biçimi, _((JSON))_ olarak adlandırılan (ceysın olarak telaffuz edilen) bir biçimdir ve JavaScript Nesne Notasyonu anlamına gelir. Web'de JavaScript dışındaki dillerde bile veri depolama ve iletişim biçimi olarak geniş bir şekilde kullanılmaktadır. {{index [array, notation], [object, creation], [quoting, "in JSON"], comment}} -JSON looks similar to JavaScript's way of writing arrays and objects, with a few restrictions. All property names have to be surrounded by double quotes, and only simple data expressions are allowed—no function calls, bindings, or anything that involves actual computation. Comments are not allowed in JSON. +JSON, JavaScript'in dizileri ve nesneleri yazma şekline benzer, ancak bazı kısıtlamaları vardır. Tüm özellik adları çift tırnaklarla çevrelenmelidir ve yalnızca basit veri ifadelerine izin verilir - fonksiyon çağrıları, bağlantılar veya gerçek hesaplamayı içeren hiçbir şey yoktur. JSON'da yorum satırlarına da izin verilmemektedir. -A journal entry might look like this when represented as JSON data: +Bir günlük girişi, JSON verisi olarak temsil edildiğinde şöyle görünebilir: ```{lang: "json"} { @@ -945,7 +949,7 @@ A journal entry might look like this when represented as JSON data: {{index "JSON.stringify function", "JSON.parse function", serialization, deserialization, parsing}} -JavaScript gives us the functions `JSON.stringify` and `JSON.parse` to convert data to and from this format. The first takes a JavaScript value and returns a JSON-encoded string. The second takes such a string and converts it to the value it encodes: +JavaScript, veriyi bu formata dönüştürmek ve bu formattan dönüştürmek için `JSON.stringify` ve `JSON.parse` fonksiyonlarını sağlar. İlki bir JavaScript değerini alır ve bir JSON formatında kodlanmış bir dize döndürür. İkincisi, JSON formatında kodlanmış bir dizeyi alır ve onu kodlandığı değere dönüştürür. ``` let string = JSON.stringify({squirrel: false, @@ -956,23 +960,23 @@ console.log(JSON.parse(string).events); // → ["weekend"] ``` -## Summary +## Özet -Objects and arrays provide ways to group several values into a single value. This allows us to put a bunch of related things in a bag and run around with the bag instead of wrapping our arms around all of the individual things and trying to hold on to them separately. +Nesneler ve diziler(ki diziler de belirli bir tür nesnedir) birden fazla değeri tek bir değere gruplama yolları sağlar. Kavramsal olarak, bu bize tüm bireysel şeylerin etrafına kollarımızı sarmak ve bunları ayrı ayrı tutmaya çalışmak yerine bir grup ilgili şeyi bir çantaya koyup çantayla koşmamıza olanak tanır. -Most values in JavaScript have properties, with the exceptions being `null` and `undefined`. Properties are accessed using `value.prop` or `value["prop"]`. Objects tend to use names for their properties and store more or less a fixed set of them. Arrays, on the other hand, usually contain varying amounts of conceptually identical values and use numbers (starting from 0) as the names of their properties. +`null` ve `undefined` değerleri dışında JavaScript'teki değerlerler özelliklere sahiptir. Özelliklere `value.prop` veya `value["prop"]` kullanılarak erişilir. Nesneler özelliklerinin adlarını kullanır ve bunların sabit bir kümesini saklar. Diziler ise genellikle kavramsal olarak aynı değerlerin değişen miktarlarını içerebilir ve özelliklerinin adları olarak sayıları (0'dan başlayarak) kullanır. -There _are_ some named properties in arrays, such as `length` and a number of methods. Methods are functions that live in properties and (usually) act on the value of which they are a property. +Dizilerde bazı adlandırılmış özellikler _vardır_, bunlar `length` ve metod isimleridir. Yöntemler, özelliklerde yaşayan ve genellikle özelliği oldukları değer üzerinde hareket eden fonksiyonlardır. -You can iterate over arrays using a special kind of `for` loop: `for (let element of array)`. +Diziler üzerinde bir tür özel `for` döngüsü kullanarak yineleme yapabilirsiniz, `for (let element of array)`. -## Exercises +## Egzersizler -### The sum of a range +### Belirli bir sayı aralığının toplamı {{index "summing (exercise)"}} -The [introduction](intro) of this book alluded to the following as a nice way to compute the sum of a range of numbers: +Bu kitabın [giriş](intro) kısmı, aşağıdakini bir aralıktaki sayıların toplamını hesaplamanın güzel bir yol olduğunu size söyledi: ```{test: no} console.log(sum(range(1, 10))); @@ -980,18 +984,18 @@ console.log(sum(range(1, 10))); {{index "range function", "sum function"}} -Write a `range` function that takes two arguments, `start` and `end`, and returns an array containing all the numbers from `start` up to and including `end`. +`start` ve `end` adında iki argüman alan `range` adlı bir fonksiyon yazın ki `start` argümanında verilen değerden başlayarak `end` argümanında bitecek şekilde her ikisini ve aralarındaki sayıları da içinde barındıracak bir dizi döndürsün. -Next, write a `sum` function that takes an array of numbers and returns the sum of these numbers. Run the example program and see whether it does indeed return 55. +Sonra, `sum` adlı içinde numaralar barındıran bir diziyi alan ve bunların toplamını hesaplayan bir fonksiyon yazın. Bunları bir araya getirip örnek programı çalıştırdığınızda 55 değerinin döndürülüp döndürülmediğini kontrol edin. {{index "optional argument"}} -As a bonus assignment, modify your `range` function to take an optional third argument that indicates the "step" value used when building the array. If no step is given, the elements should go up by increments of one, corresponding to the old behavior. The function call `range(1, 10, 2)` should return `[1, 3, 5, 7, 9]`. Make sure this also works with negative step values so that `range(5, 2, -1)` produces `[5, 4, 3, 2]`. +Bonus bir görev olarak, `range` fonksiyonunuzu, diziyi oluşturulurken kullanılan "adım" değerini belirten isteğe bağlı üçüncü bir argümanı alacak şekilde değiştirin. Adım verilmediğinde, öğeler normal davranış olan bir bir artırılarak gider. Fonksiyon çağrısı `range(1, 10, 2)`, `[1, 3, 5, 7, 9]` değerini döndürmelidir. Negatif adım değerleriyle de çalıştığından emin olmak için `aralık(5, 2, -1)` fonksiyon çağrısı `[5, 4, 3, 2]` değerini üretmelidir. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(range(1, 10)); // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] @@ -1007,38 +1011,38 @@ if}} {{index "summing (exercise)", [array, creation], "square brackets"}} -Building up an array is most easily done by first initializing a binding to `[]` (a fresh, empty array) and repeatedly calling its `push` method to add a value. Don't forget to return the array at the end of the function. +Bir dizi oluşturmanın en kolay yolu, öncelikle [] (temiz, boş bir dizi) için bir bağlantıyla başlamak ve bir değer eklemek için tekrar tekrar `push` metodunu çağırmaktır. Fonksiyonun sonunda diziyi döndürmeyi unutmayın. {{index [array, indexing], comparison}} -Since the end boundary is inclusive, you'll need to use the `<=` operator rather than `<` to check for the end of your loop. +Son sınır için verilen numara da dahil olduğu için, döngünün bitip bitmediğini kontrol etmek için `<` yerine `<=` operatörünü kullanmanız gerekecek. {{index "arguments object"}} -The step parameter can be an optional parameter that defaults (using the `=` operator) to 1. +`step`, varsayılan olarak 1 olan bir parametre olabilir (`=` operatörünü kullanarak). {{index "range function", "for loop"}} -Having `range` understand negative step values is probably best done by writing two separate loops—one for counting up and one for counting down—because the comparison that checks whether the loop is finished needs to be `>=` rather than `<=` when counting downward. +Negatif adım değerlerini `range` fonksiyonun anlaması için iki biri yukarı biri aşağı doğru sayan iki ayrı döngü yazılabilir. Döngünün bitip bitmediğini kontrol eden karşılaştırmanın, aşağı doğru sayarken `<=` yerine `>=` olması gerektiğini unutmamak önemlidir. -It might also be worthwhile to use a different default step, namely, -1, when the end of the range is smaller than the start. That way, `range(5, 2)` returns something meaningful, rather than getting stuck in an ((infinite loop)). It is possible to refer to previous parameters in the default value of a parameter. +Bitiş noktası, başlangıçtan küçük olduğunda farklı bir varsayılan `step` parametresi değeri, yani, -1 kullanmak da faydalı olabilir. Bu şekilde, `range(5, 2)` anlamlı bir şey döndürür ve sonsuz bir döngüye sıkışmaz. Bir parametrenin varsayılan değerinde önceki parametre değerlerine başvurmak mümkündür. hint}} -### Reversing an array +### Bir diziyi tersine çevirmek {{index "reversing (exercise)", "reverse method", [array, methods]}} -Arrays have a `reverse` method that changes the array by inverting the order in which its elements appear. For this exercise, write two functions, `reverseArray` and `reverseArrayInPlace`. The first, `reverseArray`, should take an array as argument and produce a _new_ array that has the same elements in the inverse order. The second, `reverseArrayInPlace`, should do what the `reverse` method does: _modify_ the array given as argument by reversing its elements. Neither may use the standard `reverse` method. +Dizilerin, öğelerin sırasını tersine çeviren bir `reverse` yöntemi vardır. Bu alıştırma için, `reverseArray` ve `reverseArrayInPlace` olmak üzere iki fonksiyon yazın. İlk fonksiyon, `reverseArray`, bir dizi alır ve ters sıradaki aynı öğelere sahip _yeni_ bir dizi üretir. İkinci fonksiyon, `reverseArrayInPlace`, `reverse` yönteminin yaptığı şeyi yapar: argüman olarak verilen diziyi öğelerini tersine çevirerek değiştirir. Hiçbiri standart `reverse` yöntemini kullanamaz. {{index efficiency, "pure function", "side effect"}} -Thinking back to the notes about side effects and pure functions in the [previous chapter](functions#pure), which variant do you expect to be useful in more situations? Which one runs faster? +[Önceki bölümde](functions#pure) yan etkiler ve saf fonksiyonlar hakkındaki notlara geri dönüp düşünerek, hangi varyantın daha fazla durumda kullanışlı olacağını ve hangisinin daha hızlı çalışmasını beklersiniz? {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. let myArray = ["A", "B", "C"]; console.log(reverseArray(myArray)); @@ -1057,23 +1061,24 @@ if}} {{index "reversing (exercise)"}} -There are two obvious ways to implement `reverseArray`. The first is to simply go over the input array from front to back and use the `unshift` method on the new array to insert each element at its start. The second is to loop over the input array backwards and use the `push` method. Iterating over an array backwards requires a (somewhat awkward) `for` specification, like `(let i = array.length - 1; i >= 0; i--)`. +Iterating over an array backwards requires a (somewhat awkward) `for` specification, like `(let i = array.length - 1; i >= 0; i--)`. +`reverseArray`'yı uygulamanın iki belirgin yolu vardır. İlk yöntem, verilen diziyi baştan sona doğru geçmek ve her öğeyi başlangıcına yerleştirmek için yeni dizi üzerinde `unshift` metodunu kullanmaktır. İkincisi, giriş dizisini tersten geçmek ve `push` yöntemini kullanmaktır. Bir diziyi tersten yinelemek için biraz garip bir `for` döngüsü gerektirir, örneğin `(let i = array.length - 1; i >= 0; i--)`. {{index "slice method"}} -Reversing the array in place is harder. You have to be careful not to overwrite elements that you will later need. Using `reverseArray` or otherwise copying the whole array (`array.slice()` is a good way to copy an array) works but is cheating. +Diziyi yerinde ters çevirmek daha zordur. Daha sonra ihtiyacınız olacak öğelerin üzerine yanlışlıkla yazıp onları kaybetmemeye dikkat etmelisiniz. `reverseArray` kullanmak veya aksi takdirde tüm diziyi kopyalamak (`array.slice()` bir diziyi kopyalamanın iyi bir yoludur) çalışır ancak hile yapmaktır. -The trick is to _swap_ the first and last elements, then the second and second-to-last, and so on. You can do this by looping over half the length of the array (use `Math.floor` to round down—you don't need to touch the middle element in an array with an odd number of elements) and swapping the element at position `i` with the one at position `array.length - 1 - i`. You can use a local binding to briefly hold on to one of the elements, overwrite that one with its mirror image, and then put the value from the local binding in the place where the mirror image used to be. +Püf noktası, ilk ve son öğeleri, ikinci ve sondan bir önceki öğeleri ve böylece devam ederek _değiştirmektir_. Bunun için dizinin uzunluğunun yarısı kadar döngü yapmanız gerekir (`Math.floor` kullanarak aşağı yuvarlama yapın - tek sayıda öğeye sahip bir dizide ortadaki öğeye dokunmanıza gerek yoktur) ve pozisyon `i` bağlantısındaki öğeyi `array.length - 1 - i` pozisyonundaki ile değiştirmektir. Bir öğeyi geçici olarak tutmak için yerel bir bağlantı kullanabilir, bunu aynasıyla değiştirerek üzerine yazabilir ve daha sonra yerel bağlantının değerini aynanın yerine koyabilirsiniz. hint}} {{id list}} -### A list +### Bir liste {{index ["data structure", list], "list (exercise)", "linked list", array, collection}} -As generic blobs of values, objects can be used to build all sorts of data structures. A common data structure is the _list_ (not to be confused with arrays). A list is a nested set of objects, with the first object holding a reference to the second, the second to the third, and so on: +Nesneler, genel değer birikintileri olarak, çeşitli veri yapılarını oluşturmak için kullanılabilir. Yaygın bir veri yapısı, dizi ile karıştırılmaması gereken listedir. Bir liste, birbirini referans alan nesnelerin iç içe geçmiş bir kümesidir, ilk nesne ikinciyi, ikinci nesne üçüncüyü ve böyle devam eder. ```{includeCode: true} let list = { @@ -1088,24 +1093,25 @@ let list = { }; ``` -The resulting objects form a chain, as shown in the following diagram: +Oluşan nesneler şu şekilde bir zincir oluşturur: {{figure {url: "img/linked-list.svg", alt: "A diagram showing the memory structure of a linked list. There are 3 cells, each with a value field holding a number, and a 'rest' field with an arrow to the rest of the list. The first cell's arrow points at the second cell, the second cell's arrow at the last cell, and the last cell's 'rest' field holds null.",width: "8cm"}}} {{index "structure sharing", [memory, structure sharing]}} -A nice thing about lists is that they can share parts of their structure. For example, if I create two new values `{value: 0, rest: list}` and `{value: -1, rest: list}` (with `list` referring to the binding defined earlier), they are both independent lists, but they share the structure that makes up their last three elements. The original list is also still a valid three-element list. +Listelerin güzel bir özelliği, yapılarının bir kısmını paylaşabilmesidir. Örneğin, `{value: 0, rest: list}` ve `{value: -1, rest: list}` (önceki bağlantıya referansta bulunarak) gibi iki yeni değer oluşturursam, bunlar bağımsız listelerdir, ancak son üç öğeyi oluşturan yapıyı paylaşırlar. Orjinal liste hala geçerli bir üç öğeli listedir. -Write a function `arrayToList` that builds up a list structure like the one shown when given `[1, 2, 3]` as argument. Also write a `listToArray` function that produces an array from a list. Add the helper functions `prepend`, which takes an element and a list and creates a new list that adds the element to the front of the input list, and `nth`, which takes a list and a number and returns the element at the given position in the list (with zero referring to the first element) or `undefined` when there is no such element. +Then add the helper functions `prepend`, which takes an element and a list and creates a new list that adds the element to the front of the input list, and `nth`, which takes a list and a number and returns the element at the given position in the list (with zero referring to the first element) or `undefined` when there is no such element. +`[1, 2, 3]` olarak verildiğinde gösterilen gibi bir liste yapısı oluşturan `arrayToList` adlı fonksiyonu yazın. Ayrıca, bir listeden bir dizi üreten `listToArray` adlı fonksiyonu da yazın. Ardından, bir öğe ve bir liste alıp öğeyi giriş listesinin önüne ekleyen yeni bir liste oluşturan `prepend`, bir liste ve bir sayı alıp listenin verilen konumundaki öğeyi (sıfır ilk öğeyi belirtir) veya böyle bir öğe yoksa `undefined` değeri döndüren `nth` yardımcı fonksiyonlarını ekleyin. {{index recursion}} -If you haven't already, also write a recursive version of `nth`. +Henüz yapmadıysanız, `nth` fonksiyonunun özyineli bir sürümünü de yazın. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(arrayToList([10, 20])); // → {value: 10, rest: {value: 20, rest: null}} @@ -1123,46 +1129,46 @@ if}} {{index "list (exercise)", "linked list"}} -Building up a list is easier when done back to front. So `arrayToList` could iterate over the array backwards (see the previous exercise) and, for each element, add an object to the list. You can use a local binding to hold the part of the list that was built so far and use an assignment like `list = {value: X, rest: list}` to add an element. +Bir listeyi arkadan öne doğru oluşturmak daha kolaydır. Bu nedenle, `arrayToList`, her öğe için bir nesne ekleyerek diziyi tersten geçebilir (önceki alıştırmaya bakın), bunu yaparken her öğe için listeye bir nesne ekleyin. O ana kadar akümüle edilmiş listeyi tutabilmek adına lokal bir bağlantı kullanabilir ve bir element eklemek adına `list = {value: X, rest: list}` gibi bir atama işlemi yapabilirsiniz. {{index "for loop"}} -To run over a list (in `listToArray` and `nth`), a `for` loop specification like this can be used: +Bir listenin üzerinden geçebilmek için(`listToArray` ve `nth` fonksiyonlarını kullanarak) bir `for` döngüsü kullanılabilir: ``` for (let node = list; node; node = node.rest) {} ``` -Can you see how that works? Every iteration of the loop, `node` points to the current sublist, and the body can read its `value` property to get the current element. At the end of an iteration, `node` moves to the next sublist. When that is null, we have reached the end of the list, and the loop is finished. +Nasıl çalıştığını görebiliyor musunuz? Döngünün her bir iterasyonunda `node` adlı bağlantı güncel alt listeye sahip ve böylelikle döngü gövdesi `value` özelliğini okuyarak güncel elementi alabiliyor. Döngü sonunda, `node` diğer alt listeye geçmekte. O değer `null` olduğunda listenin sonuna gelmiş ve döngüyü bitirmiş oluyoruz. {{index recursion}} -The recursive version of `nth` will, similarly, look at an ever smaller part of the "tail" of the list and at the same time count down the index until it reaches zero, at which point it can return the `value` property of the node it is looking at. To get the zeroth element of a list, you simply take the `value` property of its head node. To get element _N_ + 1, you take the *N*th element of the list that's in this list's `rest` property. +`nth` fonksiyonunun özyinelemeli sürümü, benzer şekilde, listenin "kuyruğunun" giderek daha küçük bir kısmına bakacak ve aynı zamanda dizini sıfıra kadar azaltacak ve sıfır olduğunda, baktığı düğümün `value` özelliğini döndürebilecektir. Bir listenin sıfırıncı öğesini almak için, baş düğümünün `value` özelliğini alırsınız. _N_ + 1 öğeyi almak için, bu listenin `rest` özelliğindeki listenin N'inci öğesini alırsınız. hint}} {{id exercise_deep_compare}} -### Deep comparison +### Derin karşılaştırma {{index "deep comparison (exercise)", [comparison, deep], "deep comparison", "== operator"}} -The `==` operator compares objects by identity, but sometimes you'd prefer to compare the values of their actual properties. +`==` operatörü nesneleri kimliğine göre karşılaştırır. Ancak bazen, gerçek özelliklerinin değerlerini karşılaştırmayı tercih edebilirsiniz. -Write a function `deepEqual` that takes two values and returns true only if they are the same value or are objects with the same properties, where the values of the properties are equal when compared with a recursive call to `deepEqual`. +`deepEqual` adında iki değeri alıp yalnızca aynı değer olduklarında veya özellikleri aynı olan nesneler olduklarında ve özelliklerin değerleri, `deepEqual` fonksiyonuna özyinelemeli bir çağrı ile karşılaştırıldığında eşitse true döndüren bir fonksiyon yazın. {{index null, "=== operator", "typeof operator"}} -To find out whether values should be compared directly (using the `===` operator for that) or have their properties compared, you can use the `typeof` operator. If it produces `"object"` for both values, you should do a deep comparison. But you have to take one silly exception into account: because of a historical accident, `typeof null` also produces `"object"`. +Değerlerin doğrudan karşılaştırılıp karşılaştırılmaması gerektiğini (`===` operatörünü kullanarak) veya özelliklerinin karşılaştırılması gerektiğini belirlemek için `typeof` operatörünü kullanabilirsiniz. İki değer için de `"object"` üretirse, derin bir karşılaştırma yapmalısınız. Ancak, bir saçma istisnayı hesaba katmanız gerekir: bir tarih öncesi kazadan dolayı, `typeof null` da "object" üretir. {{index "Object.keys function"}} -The `Object.keys` function will be useful when you need to go over the properties of objects to compare them. +`Object.keys` fonksiyonu nesnelerin özelliklerini karşılaştırmak için özelliklerin üzerinden geçmeniz gerektiğinde faydalı olacaktır. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. let obj = {here: {is: "an"}, object: 2}; console.log(deepEqual(obj, obj)); @@ -1179,14 +1185,14 @@ if}} {{index "deep comparison (exercise)", [comparison, deep], "typeof operator", "=== operator"}} -Your test for whether you are dealing with a real object will look something like `typeof x == "object" && x != null`. Be careful to compare properties only when _both_ arguments are objects. In all other cases you can just immediately return the result of applying `===`. +Gerçek bir nesne ile ilgilendiğinizi belirlemek için testiniz, `typeof x == "object" && x != null` gibi görünecektir. Özellikleri yalnızca _her iki_ argümanın da nesneler olduğunda karşılaştırmaya dikkat edin. Diğer tüm durumlarda, sadece `===` uygulamanın sonucunu hemen döndürebilirsiniz. {{index "Object.keys function"}} -Use `Object.keys` to go over the properties. You need to test whether both objects have the same set of property names and whether those properties have identical values. One way to do that is to ensure that both objects have the same number of properties (the lengths of the property lists are the same). And then, when looping over one of the object's properties to compare them, always first make sure the other actually has a property by that name. If they have the same number of properties and all properties in one also exist in the other, they have the same set of property names. +Özelliklerin üzerinden geçmek için Object.keys kullanın. İki nesnenin aynı özellik isim kümesine sahip olup olmadığını ve bu özelliklerin aynı değerlere sahip olup olmadığını test etmeniz gerekir. Bunu yapmanın bir yolu, her iki nesnenin de aynı sayıda özellik ismine sahip olmasını sağlamaktır (özellik listelerinin uzunlukları aynıdır). Ve sonra, onları karşılaştırmak için bir nesnenin özelliklerini dolaşırken, diğerinin o adla bir özelliğe sahip olduğundan emin olun. Eğer iki nesnenin de aynı sayıda özelliği varsa ve birindeki tüm özellik adları diğerinde de varsa, aynı özellik kümesine sahiptirler. {{index "return value"}} -Returning the correct value from the function is best done by immediately returning false when a mismatch is found and returning true at the end of the function. +Fonksiyondan doğru değeri döndürmek, bir eşleşme bulunduğunda hemen `false` döndürerek ve fonksiyonun sonunda `true` döndürerek en iyi şekilde yapılır. hint}} diff --git a/05_higher_order.md b/05_higher_order.md index 1dc9d912..4b437442 100644 --- a/05_higher_order.md +++ b/05_higher_order.md @@ -1,12 +1,12 @@ {{meta {load_files: ["code/scripts.js", "code/chapter/05_higher_order.js", "code/intro.js"], zip: "node/html"}}} -# Higher-Order Functions +# Higher-Order Fonksiyonlar {{quote {author: "C.A.R. Hoare", title: "1980 ACM Turing Award Lecture", chapter: true} {{index "Hoare, C.A.R."}} -There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. +Yazılım tasarımını iki şekilde oluşturmak mümkündür: Bir yolu, o kadar basit yapmaktır ki herhangi bir eksiklik olmasın, diğer yolu ise o kadar karmaşık yapmaktır ki açıkça herhangi bir eksiklik olmasın. quote}} @@ -14,11 +14,11 @@ quote}} {{index "program size"}} -A large program is a costly program, and not just because of the time it takes to build. Size almost always involves ((complexity)), and complexity confuses programmers. Confused programmers, in turn, introduce mistakes (_((bug))s_) into programs. A large program then provides a lot of space for these bugs to hide, making them hard to find. +Büyük bir program maliyetli bir programdır ve bunun yalnızca inşa etme süresiyle ilgili olduğunu söylemek yanlış olur. Boyut neredeyse her zaman karmaşıklığı içerir ve karmaşıklık programcıları kafası karıştırır. Kafası karışık olan programcılar da hatalar (bug) eklerler. Büyük bir program, bu hataların gizlenmesi için çok fazla alan sağlar ve onları bulmayı zorlaştırır. {{index "summing example"}} -Let's briefly go back to the final two example programs in the introduction. The first is self-contained and six lines long. +Girişteki son iki örnek programı kısaca gözden geçirelim. İlki kendine özgüdür ve altı satırdır. ``` let total = 0, count = 1; @@ -29,67 +29,67 @@ while (count <= 10) { console.log(total); ``` -The second relies on two external functions and is one line long. +İkincisi iki harici fonksiyona dayanır ve bir satır uzunluğundadır. ``` console.log(sum(range(1, 10))); ``` -Which one is more likely to contain a bug? +Hangisinin hata içerme olasılığı daha yüksektir? {{index "program size"}} -If we count the size of the definitions of `sum` and `range`, the second program is also big—even bigger than the first. But still, I'd argue that it is more likely to be correct. +`sum` ve `range` tanımlarının boyutunu sayarsak, ikinci program da büyüktür - hatta birincisinden daha büyüktür. Ancak yine de, doğru olma olasılığının daha yüksek olduğunu iddia ederim. {{index [abstraction, "with higher-order functions"], "domain-specific language"}} -This is because the solution is expressed in a ((vocabulary)) that corresponds to the problem being solved. Summing a range of numbers isn't about loops and counters. It is about ranges and sums. +Doğru olma olasılığı daha yüksektir çünkü çözüm, çözülen problemle uyumlu bir ((kelime dağarcığıyla)) ifade edilmiştir. Bir sayı aralığının toplanması döngüler ve sayıcılar hakkında değildir. Aralıklar ve toplamlar hakkındadır. -The definitions of this vocabulary (the functions `sum` and `range`) will still involve loops, counters, and other incidental details. But because they are expressing simpler concepts than the program as a whole, they are easier to get right. +Bu kelime dağarcığının tanımları (`sum` ve `range` fonksiyonları) hala döngüler, sayıcılar ve diğer tesadüfi ayrıntılar içerecektir. Ancak, programın tamamından daha basit kavramları ifade ettikleri için anlaşılmaları daha kolaydır. -## Abstraction +## Soyutlama -In the context of programming, these kinds of vocabularies are usually called _((abstraction))s_. Abstractions give us the ability to talk about problems at a higher (or more abstract) level, without getting sidetracked by uninteresting details. +Programlama bağlamında, bu tür kavramlar genellikle ((soyutlama)) olarak adlandırılır. Soyutlamalar, bizi, ilginç olmayan ayrıntılarla uğraştırmadan daha yüksek (veya daha soyut) bir seviyede problemleri tartışma yeteneği verir. {{index "recipe analogy", "pea soup"}} -As an analogy, compare these two recipes for pea soup. The first goes like this: +Bir benzetme olarak, bezelye çorbası için bu iki tarifi karşılaştırın. İlk tarif şöyle: {{quote -Put 1 cup of dried peas per person into a container. Add water until the peas are well covered. Leave the peas in water for at least 12 hours. Take the peas out of the water and put them in a cooking pan. Add 4 cups of water per person. Cover the pan and keep the peas simmering for two hours. Take half an onion per person. Cut it into pieces with a knife. Add it to the peas. Take a stalk of celery per person. Cut it into pieces with a knife. Add it to the peas. Take a carrot per person. Cut it into pieces. With a knife! Add it to the peas. Cook for 10 more minutes. +Her kişi başına 1 su bardağı kuru bezelye bir kaba koyun. Bezelyeler suyla iyi bir şekilde kaplanana kadar su ekleyin. Bezelyeleri en az 12 saat suyun içinde bırakın. Bezelyeleri sudan çıkarın ve bir tencereye koyun. Her kişi başına 4 su bardağı su ekleyin. Tencereyi kapatın ve bezelyelerin kısık ateşte iki saat boyunca kaynamasını sağlayın. Her kişi başına yarım soğan alın. Bir bıçakla parçalara kesin. Bezelyelere ekleyin. Her kişi başına bir sap kereviz alın. Bir bıçakla parçalara kesin. Bezelyelere ekleyin. Her kişi başına bir havuç alın. Parçalara kesin. Bir bıçakla! Bezelyelere ekleyin. 10 dakika daha pişirin. quote}} -And this is the second recipe: +Ve bu da ikinci tarif: {{quote -Per person: 1 cup dried split peas, 4 cups of water, half a chopped onion, a stalk of celery, and a carrot. +Her kişi başına: 1 su bardağı kuru bezelye, 4 su bardağı su, yarım doğranmış soğan, bir sap kereviz ve bir havuç. -Soak peas for 12 hours. Simmer for 2 hours. Chop and add vegetables. Cook for 10 more minutes. +Bezelyeleri 12 saat bekletin. 2 saat kaynatın. Sebzeleri doğrayın ve ekleyin. 10 dakika daha pişirin. quote}} {{index vocabulary}} -The second is shorter and easier to interpret. But you do need to understand a few more cooking-related words such as _soak_, _simmer_, _chop_, and, I guess, _vegetable_. +İkincisi daha kısa ve yorumlaması daha kolaydır. Ancak, _bekletme_, _kaynatma_, _doğrama_ ve sanırım _sebze_ gibi birkaç daha fazla yemekle ilgili kelimeyi anlamanız gerekecek. -When programming, we can't rely on all the words we need to be waiting for us in the dictionary. Thus, we might fall into the pattern of the first recipe—work out the precise steps the computer has to perform, one by one, blind to the higher-level concepts they express. +Programlama yaparken, ihtiyacımız olan tüm kelimelerin sözlükte bizi beklediğine güvenemeyiz. Bu nedenle, birinci tarifin kalıbına düşebiliriz - bilgisayarın adım adım yapması gereken kesin adımları çıkarırken, bunların ifade ettiği daha yüksek düzeydeki kavramlara kör oluruz. {{index abstraction}} -It is a useful skill, in programming, to notice when you are working at too low a level of abstraction. +Programlama yaparken, ne zaman çok düşük veya çok yüksek bir soyutlama seviyesinde çalıştığınızı fark etmek faydalı bir beceridir. -## Abstracting repetition +## Tekrarı soyutlama {{index [array, iteration]}} -Plain functions, as we've seen them so far, are a good way to build abstractions. But sometimes they fall short. +Şimdiye kadar gördüğümüz gibi düz fonksiyonlar, soyutlamalar oluşturmanın iyi bir yoludur. Ancak bazen yetersiz kalabilirler. {{index "for loop"}} -It is common for a program to do something a given number of times. You can write a `for` ((loop)) for that, like this: +Programın belirli bir sayıda bir şey yapması yaygındır. Bunu şöyle bir `for` ((döngüsü)) ile yapabilirsiniz: ``` for (let i = 0; i < 10; i++) { @@ -97,7 +97,7 @@ for (let i = 0; i < 10; i++) { } ``` -Can we abstract "doing something _N_ times" as a function? Well, it's easy to write a function that calls `console.log` _N_ times: +İşlemi "_N_ kez bir şey yapmak" şeklinde soyutlayabilir miyiz? Evet, bir `console.log` ifadesini _N_ kez çağıran bir fonksiyon yazmak oldukça kolaydır. ``` function repeatLog(n) { @@ -111,7 +111,7 @@ function repeatLog(n) { {{indexsee "higher-order function", "function, higher-order"}} -But what if we want to do something other than logging the numbers? Since "doing something" can be represented as a function and functions are just values, we can pass our action as a function value: +Ancak, sayıları görüntülemek dışında başka bir şey yapmak istersek? "bir şey yapmak" bir fonksiyon olarak temsil edilebilir ve fonksiyonlar sadece değerler olduklarına göre, eylemimizi bir fonksiyon değeri olarak iletebiliriz. ```{includeCode: "top_lines: 5"} function repeat(n, action) { @@ -126,7 +126,7 @@ repeat(3, console.log); // → 2 ``` -We don't have to pass a predefined function to `repeat`. Often, it is easier to create a function value on the spot instead: +`repeat` fonksiyonuna önceden tanımlanmış bir fonksiyon geçmek zorunda değiliz. Genellikle, yerinde bir fonksiyon değeri oluşturmak daha kolaydır. ``` let labels = []; @@ -139,17 +139,17 @@ console.log(labels); {{index "loop body", [braces, body], [parentheses, arguments]}} -This is structured a little like a `for` loop—it first describes the kind of loop and then provides a body. However, the body is now written as a function value, which is wrapped in the parentheses of the call to `repeat`. This is why it has to be closed with the closing brace _and_ closing parenthesis. In cases like this example where the body is a single small expression, you could also omit the braces and write the loop on a single line. +Bu, `for` döngüsüne biraz benzeyen bir şekilde yapılandırılmıştır - önce döngü türünü tanımlar, ardından bir gövde sağlar. Ancak, gövde artık bir fonksiyon değeri olarak yazılmıştır ve çağrının parantezleri içine alınmıştır. Bu nedenle kapatılması gereken süslü parantez ve kapanan normal parantezle kapatılmalıdır. Bu örnekte olduğu gibi, gövde tek bir küçük ifade ise süslü parantezleri atlayabilir ve döngüyü tek bir satırda da yazabilirsiniz. -## Higher-order functions +## Higher-order fonksiyonlar {{index [function, "higher-order"], [function, "as value"]}} -Functions that operate on other functions, either by taking them as arguments or by returning them, are called _higher-order functions_. Since we have already seen that functions are regular values, there is nothing particularly remarkable about the fact that such functions exist. The term comes from ((mathematics)), where the distinction between functions and other values is taken more seriously. +Başka fonksiyonlar üzerinde, fonskiyonu argüman olarak alarak ya da fonksiyon döndürerek işlem yapan fonksiyonlara _higher-order fonksiyonlar_ denir. Fonksiyonların sıradan değerler olduğunu zaten gördüğümüze göre, bu tür fonksiyonların varlığıyla ilgili olarak özellikle dikkate değer bir şey fark etmişizdir. Terim ((matematik))ten gelir, burada fonksiyonlar ve diğer değerler arasındaki ayrım daha ciddiye alınır. {{index abstraction}} -Higher-order functions allow us to abstract over _actions_, not just values. They come in several forms. For example, we can have functions that create new functions: +Higher-order fonksiyonlar, sadece değerleri değil _eylemleri_ soyutlamamıza izin verir. Birkaç formda gelirler. Mesela, yeni fonksiyonlar oluşturan fonksiyonlar oluşturabiliriz. ``` function greaterThan(n) { @@ -160,7 +160,7 @@ console.log(greaterThan10(11)); // → true ``` -We can also have functions that change other functions: +Ve diğer fonksiyonları değiştiren fonksiyonlara sahip olabiliriz. ``` function noisy(f) { @@ -176,7 +176,7 @@ noisy(Math.min)(3, 2, 1); // → called with [3, 2, 1] , returned 1 ``` -We can even write functions that provide new types of ((control flow)): +Yeni türlerde ((kontrol akışı)) sağlayan fonksiyonlar bile yazabiliriz. ``` function unless(test, then) { @@ -194,7 +194,7 @@ repeat(3, n => { {{index [array, methods], [array, iteration], "forEach method"}} -There is a built-in array method, `forEach`, that provides something like a `for`/`of` loop as a higher-order function: +`for`/`of` döngüsü gibi bir yapıyı higher-order fonksiyon olarak tanımlayan `forEach` adında yerleşik bir array metodu vardır. ``` ["A", "B"].forEach(l => console.log(l)); @@ -204,20 +204,19 @@ There is a built-in array method, `forEach`, that provides something like a `for {{id scripts}} -## Script data set +## Script data seti -One area where higher-order functions shine is data processing. To process data, we'll need some actual example data. This chapter will use a ((data set)) about scripts—((writing system))s such as Latin, Cyrillic, or Arabic. +Higher-order fonksiyonların parladığı bir alan veri işlemektir. Verileri işlemek için gerçek verilere ihtiyacımız olacak. Bu bölüm, Latin, Kiril veya Arap gibi ((yazı sistemileri)) hakkında((veri seti)) kullanacağız. -Remember ((Unicode)) from [Chapter ?](values#unicode), the system that assigns a number to each character in written language? Most of these characters are associated with a specific script. The standard contains 140 different scripts, of which 81 are still in use today and 59 are historic. +[Bölüm ?'ten](values#unicode) ((Unicode)) sistemini hatırladığınız mı? Şu konuşulan dillerdeki her karaktere bir sayı atayan sistem hani? Bu karakterlerin çoğu bir alfabeyle ilişkilidir. Standart, 140 farklı alfabeyi barındırır - 81'i hala günümüzde kullanılırken 59'u tarihidir. -Though I can fluently read only Latin characters, I appreciate the fact that people are writing texts in at least 80 other writing systems, many of which I wouldn't even recognize. For example, here's a sample of ((Tamil)) handwriting: +Ben sadece Latin karakterlerini akıcı bir şekilde okuyabilirim, ancak insanların en az 80 farklı yazı sistemine ait metinler yazdıklarını takdir ediyorum, bunların çoğunu bile tanımam. Örneğin, işte ((Tamil)) el yazısı örneği: {{figure {url: "img/tamil.png", alt: "A line of verse in Tamil handwriting. The characters are relatively simple, and neatly separated, yet completely different from Latin."}}} -{{index "SCRIPTS data set"}} - -The example ((data set)) contains some pieces of information about the 140 scripts defined in Unicode. It is available in the [coding sandbox](https://eloquentjavascript.net/code#5) for this chapter[ ([_https://eloquentjavascript.net/code#5_](https://eloquentjavascript.net/code#5))]{if book} as the `SCRIPTS` binding. The binding contains an array of objects, each of which describes a script: +{{index "SCRIPTS dataset"}} +Örnek ((data seti)), Unicode'da tanımlanan 140 yazı hakkında bazı bilgiler içerir. Bu, bu bölümde[ ([_https://eloquentjavascript.net/code#5_](https://eloquentjavascript.net/code#5))]{if book} `SCRIPTS` bağlantısı olarak [kod kum havuzunda](https://eloquentjavascript.net/code#5) mevcuttur. Bağlantı, her biri bir alfabeyi tanımlayan nesnelerin bir dizisini içerir. ```{lang: "json"} { @@ -230,17 +229,17 @@ The example ((data set)) contains some pieces of information about the 140 scrip } ``` -Such an object tells us the name of the script, the Unicode ranges assigned to it, the direction in which it is written, the (approximate) origin time, whether it is still in use, and a link to more information. The direction may be `"ltr"` for left to right, `"rtl"` for right to left (the way Arabic and Hebrew text are written), or `"ttb"` for top to bottom (as with Mongolian writing). +Böyle bir nesne, alfabenin adını, ona atanmış Unicode aralıklarını, yazıldığı yönu, (yaklaşık) köken zamanını, hala kullanılıp kullanılmadığını ve daha fazla bilgiye yönlendiren bir bağlantının linkini bize bildirir. Yön, soldan sağa için `"ltr"`, sağdan sola için `"rtl"`(Arapça ve İbranice metinlerin yazıldığı yöntem), veya üstten alta için `"ttb"`(Moğolca yazı gibi) olabilir. {{index "slice method"}} -The `ranges` property contains an array of Unicode character ((range))s, each of which is a two-element array containing a lower bound and an upper bound. Any character codes within these ranges are assigned to the script. The lower ((bound)) is inclusive (code 994 is a Coptic character) and the upper bound is non-inclusive (code 1008 isn't). +`ranges` özelliği, her biri bir alt sınır ve bir üst sınır içeren iki öğeli bir dizi içeren Unicode karakter ((aralık))larının bir dizisini içerir. Bu aralıklar içindeki herhangi bir karakter kodu yazıya atanır. Alt ((sınır)) kapsayıcıdır (kod 994 bir Kıpti karakteridir), üst sınır kapsayıcı değildir (kod 1008 değildir). -## Filtering arrays +## Dizileri filtrelemek {{index [array, methods], [array, filtering], "filter method", [function, "higher-order"], "predicate function"}} -If we want to find the scripts in the data set that are still in use, the following function might be helpful. It filters out elements in an array that don't pass a test. +Veri kümesinde kullanımda olan yazı sistemlerini bulmak istiyorsak, aşağıdaki fonksiyon faydalı olabilir. Bu, bir dizide bir testi geçmeyen öğeleri filtreler. ``` function filter(array, test) { @@ -259,13 +258,13 @@ console.log(filter(SCRIPTS, script => script.living)); {{index [function, "as value"], [function, application]}} -The function uses the argument named `test`, a function value, to fill a "gap" in the computation—the process of deciding which elements to collect. +Fonksiyon, hesaplama içinde bir "boşluk" doldurmak için `test` adlı fonksiyon değerindeki verilen argümanı kullanır. Böylelikle hangi elementi tutmak istediğine karar verir. {{index "filter method", "pure function", "side effect"}} -Note how the `filter` function, rather than deleting elements from the existing array, builds up a new array with only the elements that pass the test. This function is _pure_. It does not modify the array it is given. +Varolan diziden öğeleri silmek yerine, `filter` fonksiyonu, yalnızca testi geçen öğelerle yeni bir dizi oluşturur. Bu işlev \_saf_tır. Verilen diziyi değiştirmez. -Like `forEach`, `filter` is a ((standard)) array method. The example defined the function only to show what it does internally. From now on, we'll use it like this instead: +`forEach` gibi, `filter` bir ((standart)) dizi yöntemidir. Örnek, fonskiyonun içerisinde ne yaptığını göstermek için tanımlanmıştır. Bundan sonra, bunu şu şekilde kullanacağız: ``` console.log(SCRIPTS.filter(s => s.direction == "ttb")); @@ -274,15 +273,15 @@ console.log(SCRIPTS.filter(s => s.direction == "ttb")); {{id map}} -## Transforming with map +## map ile dönüştürmek {{index [array, methods], "map method"}} -Say we have an array of objects representing scripts, produced by filtering the `SCRIPTS` array somehow. We want an array of names instead, which is easier to inspect. +Diyelim ki `SCRIPTS` dizisini filtreleme işlemiyle üretilmiş olan yazı sistemlerini temsil eden nesnelerden bir dizimiz var. Ancak obje dizisi yerine, incelemesi daha kolay olan bir isim dizisi istiyoruz. {{index [function, "higher-order"]}} -The `map` method transforms an array by applying a function to all of its elements and building a new array from the returned values. The new array will have the same length as the input array, but its content will have been _mapped_ to a new form by the function: +`map` yöntemi, tüm öğelerine bir fonksiyon uygulayarak bir diziyi dönüştürür ve döndürülen değerlerden yeni bir dizi oluşturur. Yeni dizi, giriş dizisiyle aynı uzunluğa sahip olacak, ancak içeriği verilen fonksiyon tarafından yeni bir forma _haritalanmış_ olacak. ``` function map(array, transform) { @@ -298,21 +297,21 @@ console.log(map(rtlScripts, s => s.name)); // → ["Adlam", "Arabic", "Imperial Aramaic", …] ``` -Like `forEach` and `filter`, `map` is a standard array method. +`forEach` ve `filter` gibi, `map` bir standart dizi yöntemidir. -## Summarizing with reduce +## reduce aracılığıyla özetleme {{index [array, methods], "summing example", "reduce method"}} -Another common thing to do with arrays is to compute a single value from them. Our recurring example, summing a collection of numbers, is an instance of this. Another example is finding the script with the most characters. +Dizilerle yapılacak başka yaygın bir işlem, onlardan tek bir değer hesaplamaktır. Tekrarlayan bir örnek olan sayılardan oluşan bir dizinin toplamını bulmak, bunun bir örneğidir. Diğer bir örnek ise en fazla karaktere sahip yazıyı bulmaktır. {{indexsee "fold", "reduce method"}} {{index [function, "higher-order"], "reduce method"}} -The higher-order operation that represents this pattern is called _reduce_ (sometimes also called _fold_). It builds a value by repeatedly taking a single element from the array and combining it with the current value. When summing numbers, you'd start with the number zero and, for each element, add that to the sum. +Bu kalıbı temsil eden higher-order işlem _reduce_ (bazen _fold_ olarak da adlandırılır) adını taşır. Bu, bir diziden bir öğeleri tane tane alarak ve mevcut değerle birleştirerek bir değer oluşturur. Sayıları toplarken, sıfır sayısıyla başlayacak ve her öğeyi toplama ekleyeceksiniz. -The parameters to `reduce` are, apart from the array, a combining function and a start value. This function is a little less straightforward than `filter` and `map`, so take a close look at it: +`reduce`'un parametreleri, üzerinden geçilecek dizi dışında birleştirme fonksiyonu ve bir başlangıç değeri gerektirmektedir. Bu fonksiyon `filter`ve `map` fonskiyonlarından daha karmaşıktır, lütfen bu örneği dikkatlice bakın: ``` function reduce(array, combine, start) { @@ -327,9 +326,9 @@ console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0)); // → 10 ``` -{{index "reduce method", "SCRIPTS data set"}} +{{index "reduce method", "SCRIPTS dataset"}} -The standard array method `reduce`, which of course corresponds to this function, has an added convenience. If your array contains at least one element, you are allowed to leave off the `start` argument. The method will take the first element of the array as its start value and start reducing at the second element. +Standart dizi metodu ve örnekteki fonksiyonalite ile eşleşen `reduce`, ek bir rahatlığa sahiptir. Eğer diziniz en az bir elementten oluşmaktaysa, `start` argümanını kullanmak zorunda değilsiniz. Metod dizideki ilk elementi başlangıç değeri oalrak alır ve değeri döngüye devam ederek indirgemeye ikinci değerden başlar. ``` console.log([1, 2, 3, 4].reduce((a, b) => a + b)); @@ -338,7 +337,7 @@ console.log([1, 2, 3, 4].reduce((a, b) => a + b)); {{index maximum, "characterCount function"}} -To use `reduce` (twice) to find the script with the most characters, we can write something like this: +En çok karakteri barındıran yazı sistemini bulmak adına `reduce` fonksiyonunu kullanarak (ikinci kere) şöyle bir şey yazabiliriz: ``` function characterCount(script) { @@ -353,15 +352,15 @@ console.log(SCRIPTS.reduce((a, b) => { // → {name: "Han", …} ``` -The `characterCount` function reduces the ranges assigned to a script by summing their sizes. Note the use of destructuring in the parameter list of the reducer function. The second call to `reduce` then uses this to find the largest script by repeatedly comparing two scripts and returning the larger one. +`characterCount` fonksiyonu aralıkları boyutları toplayarak indirgemektedir. Parametre listesinde gerçekteştirilen destructuring işlemine dikkat edin. `reduce` fonksiyonuna olan ikinci çağrı bunu kullanarak her iki yazı sistemini karşılaştırarak daha büyük olan yazı sistemini döndürmektedir. -The Han script has more than 89,000 characters assigned to it in the Unicode standard, making it by far the biggest writing system in the data set. Han is a script sometimes used for Chinese, Japanese, and Korean text. Those languages share a lot of characters, though they tend to write them differently. The (US-based) Unicode Consortium decided to treat them as a single writing system to save character codes. This is called _Han unification_ and still makes some people very angry. +Han yazısı, Unicode standardında ona atanan 89.000'den fazla karakterle, veri kümesindeki en büyük yazı sistemidir. Han, bazen Çince, Japonca ve Korece metinlerde kullanılır. Bu diller birçok karakteri paylaşır, ancak genellikle farklı yazılır. (ABD merkezli) Unicode Konsorsiyumu, karakter kodlarını kaydetmek için bunları tek bir yazı sistemi olarak ele almaya karar verdi. Buna _Han birleşimi_ denir ve hala bazı insanları çok kızdırıyor. -## Composability +## Şekillendirilebilirlik {{index loop, maximum}} -Consider how we would have written the previous example (finding the biggest script) without higher-order functions. The code is not that much worse: +Daha önceki örneği (en büyük betiği bulma) higher-order fonksiyonlar olmadan nasıl yazacağımızı düşünelim. Kod pek de kötü değil. ```{test: no} let biggest = null; @@ -375,13 +374,13 @@ console.log(biggest); // → {name: "Han", …} ``` -There are a few more bindings, and the program is four lines longer, but it is still very readable. +Birkaç daha fazla bağlantı var ve program dört satır daha uzun. Ama yine de okunaklı. {{index "average function", composability, [function, "higher-order"], "filter method", "map method", "reduce method"}} {{id average_function}} -The abstractions provided by these functions really shine when you need to _compose_ operations. As an example, let's write code that finds the average year of origin for living and dead scripts in the data set: +Bu fonksiyonlar tarafından sağlanan soyutlamalar, işlemleri _birleştirmeniz_ gerektiğinde gerçekten parlar. Örneğin, veri setindeki yaşayan ve ölü betiklerin ortalama köken yıllarını bulan bir kod yazalım. ``` function average(array) { @@ -396,9 +395,9 @@ console.log(Math.round(average( // → 204 ``` -As you can see, the dead scripts in Unicode are, on average, older than the living ones. This is not a terribly meaningful or surprising statistic. But I hope you'll agree that the code used to compute it isn't hard to read. You can see it as a pipeline: we start with all scripts, filter out the living (or dead) ones, take the years from those, average them, and round the result. +Böylelikle, Unicode'deki ölü betiklerin ortalama olarak yaşayanlardan daha eski olduğunu görüyoruz. Bu çok da anlamlı veya şaşırtıcı bir istatistik değil. Ancak umarım bunun hesaplanmasında kullanılan kodun okunmasının zor olmadığını görmüşüzdür. Onu bir boru hattı olarak görebilirsiniz: tüm betiklerle başlıyoruz, yaşayan (veya ölü) olanları filtreliyoruz, onlardan yılları alıyoruz, bunların ortalamasını alıyoruz ve sonucu yuvarlıyoruz. -You could definitely also write this computation as one big ((loop)): +Bu hesaplamayı kesinlikle tek bir büyük ((döngü)) olarak da yazabilirdiniz. ``` let total = 0, count = 0; @@ -412,19 +411,19 @@ console.log(Math.round(total / count)); // → 1165 ``` -However, it is harder to see what was being computed and how. And because intermediate results aren't represented as coherent values, it'd be a lot more work to extract something like `average` into a separate function. +Ancak hesaplanan şeyin ne olduğunu ve nasıl olduğunu görmek daha zordur. Ve ara sonuçlar tutarlı değerler olarak temsil edilmediğinden, `average` gibi bir şeyi ayrı bir fonksiyona çıkarmak daha zor bir iş olurdu. {{index efficiency, [array, creation]}} -In terms of what the computer is actually doing, these two approaches are also quite different. The first will build up new arrays when running `filter` and `map`, whereas the second computes only some numbers, doing less work. You can usually afford the readable approach, but if you're processing huge arrays and doing so many times, the less abstract style might be worth the extra speed. +Bilgisayarın gerçekte ne yaptığı açısından, bu iki yaklaşım da oldukça farklıdır. İlk yaklaşım, `filter` ve `map` çalıştığında yeni diziler oluştururken, ikincisi sadece bazı sayıları hesaplar, daha az iş yapar. Okunabilir yaklaşımı genellikle seçebilirsiniz ancak devasa dizileri işliyorsanız ve bunu birçok kez yapıyorsanız, daha az soyut tarz, ek hız için değer olabilir. -## Strings and character codes +## Dize ve karakter kodları -{{index "SCRIPTS data set"}} +{{index "SCRIPTS dataset"}} -One interesting use of this data set would be figuring out what script a piece of text is using. Let's go through a program that does this. +Bu veri setinin ilginç bir kullanımı, bir metnin hangi betiği kullandığını bulmak olurdu. Hadi bunu yapan bir programı inceleyelim. -Remember that each script has an array of character code ranges associated with it. Given a character code, we could use a function like this to find the corresponding script (if any): +Her betiğin ilişkilendirilmiş bir karakter kodu aralığı dizisi olduğunu unutmayın. Bunun sayesinde, bir karakter kodu verildiğinde, varsa ilgili betiği bulmak için böyle bir fonksiyon kullanabiliriz: {{index "some method", "predicate function", [array, methods]}} @@ -444,21 +443,21 @@ console.log(characterScript(121)); // → {name: "Latin", …} ``` -The `some` method is another higher-order function. It takes a test function and tells you whether that function returns true for any of the elements in the array. +`some` metodu başka bir higher-order fonksiyondur. Bir test fonksiyonunu alır ve bu fonksiyonun dizideki öğelerden herhangi biri için doğru olup olmadığını size söyler. {{id code_units}} -But how do we get the character codes in a string? +Ancak bir dize içindeki karakter kodlarını nasıl alırız? -In [Chapter ?](values) I mentioned that JavaScript ((string))s are encoded as a sequence of 16-bit numbers. These are called _((code unit))s_. A ((Unicode)) ((character)) code was initially supposed to fit within such a unit (which gives you a little over 65,000 characters). When it became clear that wasn't going to be enough, many people balked at the need to use more memory per character. To address these concerns, ((UTF-16)), the format also used by JavaScript strings, was invented. It describes most common characters using a single 16-bit code unit but uses a pair of two such units for others. +[Bölüm ? içinde](values) belirtildiği gibi JavaScript ((dize))leri, bir dizi 16-bit numarası olarak kodlanmıştır. Bunlar ((kod birimi)) olarak adlandırılır. Bir ((Unicode)) ((karakter)) kodunun başlangıçta böyle bir birime sığması bekleniyordu (bu size birazdan 65.000'in üzerinde karakter verir). Ancak bu yeterli olmayacağını anlaşılınca, birçok kişi karakter başına daha fazla bellek kullanma gereksinimine itiraz etti. Bu endişeleri ele almak için, JavaScript dizeleri tarafından da kullanılan format olan ((UTF-16)) icat edildi. Bu, yaygın olarak kullanılan çoğu karakteri tek bir 16-bit kod birimi kullanarak açıklar, ancak diğerleri için bu birimden iki adet kullanır. {{index error}} -UTF-16 is generally considered a bad idea today. It seems almost intentionally designed to invite mistakes. It's easy to write programs that pretend code units and characters are the same thing. And if your language doesn't use two-unit characters, that will appear to work just fine. But as soon as someone tries to use such a program with some less common ((Chinese characters)), it breaks. Fortunately, with the advent of ((emoji)), everybody has started using two-unit characters, and the burden of dealing with such problems is more fairly distributed. +UTF-16 genellikle bugün kötü bir fikir olarak kabul edilir. Hemen hemen kasıtlı olarak hatalara davet etmek için tasarlanmış gibi görünüyor. Kod birimlerini ve karakterleri aynı şey gibi düşündüren programlar yazmak kolaydır. Ve diliniz iki birimli karakterler kullanmıyorsa, bu çalışır gibi görünecektir. Ancak birisi böyle bir programı bazı daha az yaygın ((Çin karakterleri)) ile kullanmaya çalıştığında, bozulur. Neyse ki, ((emoji))'lerin ortaya çıkmasıyla, herkes iki birimli karakterleri kullanmaya başladı ve bu tür sorunlarla başa çıkmanın yükü daha adil bir şekilde dağıtılmıştır. {{index [string, length], [string, indexing], "charCodeAt method"}} -Unfortunately, obvious operations on JavaScript strings, such as getting their length through the `length` property and accessing their content using square brackets, deal only with code units. +Maalesef, JavaScript dizilerindeki `length` özelliği aracılığıyla uzunluklarını almak ve içeriğine kare parantez kullanarak erişmek gibi işlemler yalnızca kod birimleriyle ilgilenir. ```{test: no} // Two emoji characters, horse and shoe @@ -475,11 +474,11 @@ console.log(horseShoe.codePointAt(0)); {{index "codePointAt method"}} -JavaScript's `charCodeAt` method gives you a code unit, not a full character code. The `codePointAt` method, added later, does give a full Unicode character, so we could use that to get characters from a string. But the argument passed to `codePointAt` is still an index into the sequence of code units. To run over all characters in a string, we'd still need to deal with the question of whether a character takes up one or two code units. +JavaScript'in `charCodeAt` yöntemi size bir kod birimi verir, tam bir karakter kodu vermez. Daha sonra eklenen `codePointAt` metodu, tam bir Unicode karakteri verir. Bu nedenle, bir diziden karakterleri almak için bunu kullanabiliriz. Ancak `codePointAt`'e verilen argüman hala bir kod birimleri dizisine verilen bir indekstir. Bu nedenle, bir dizedeki tüm karakterlerin üzerinden geçmek için hala bir karakterin bir veya iki kod birimi kapladığı sorunuyla ilgilenmemiz gerekir. {{index "for/of loop", character}} -In the [previous chapter](data#for_of_loop), I mentioned that a `for`/`of` loop can also be used on strings. Like `codePointAt`, this type of loop was introduced at a time when people were acutely aware of the problems with UTF-16. When you use it to loop over a string, it gives you real characters, not code units: +[Önceki bölümde](data#for_of_loop), bir `for/of` döngüsünün aynı zamanda dizelerde de kullanılabileceğini belirtmiştim. `codePointAt` gibi, bu tür bir döngü, UTF-16 ile ilgili sorunların farkında olunan bir dönemde tanıtıldı. Bir dize üzerinde döngü yapmak için kullandığınızda, size kod birimleri değil gerçek karakterler verir. ``` let roseDragon = "🌹🐉"; @@ -490,13 +489,13 @@ for (let char of roseDragon) { // → 🐉 ``` -If you have a character (which will be a string of one or two code units), you can use `codePointAt(0)` to get its code. +Eğer bir karakteriniz varsa (ki bu bir veya iki kod birimi uzunluğunda bir dizedir), kodunu almak için `codePointAt(0)` fonksiyonunu kullanabilirsiniz. -## Recognizing text +## Metni tanıma -{{index "SCRIPTS data set", "countBy function", [array, counting]}} +{{index "SCRIPTS dataset", "countBy function", [array, counting]}} -We have a `characterScript` function and a way to correctly loop over characters. The next step is to count the characters that belong to each script. The following counting abstraction will be useful there: +Bir `characterScript` fonksiyonumuz ve karakterler üzerinde doğru bir şekilde döngü yapmanın bir yolu var. Sonraki adım, her betiğe ait karakterlerin sayısını saymaktır. Aşağıdaki sayma soyutlaması burada yararlı olacaktır: ```{includeCode: strip_log} function countBy(items, groupName) { @@ -517,15 +516,15 @@ console.log(countBy([1, 2, 3, 4, 5], n => n > 2)); // → [{name: false, count: 2}, {name: true, count: 3}] ``` -The `countBy` function expects a collection (anything that we can loop over with `for`/`of`) and a function that computes a group name for a given element. It returns an array of objects, each of which names a group and tells you the number of elements that were found in that group. +`countBy` fonksiyonu bir koleksiyon (herhangi bir `for/of` döngüsü ile döngü yapabileceğimiz bir şey) ve bir öğe için bir grup adı hesaplayan bir fonksiyon bekler. Bir grup adını belirten ve bu grupta bulunan öğelerin sayısını söyleyen nesnelerden oluşan bir dizi döndürür. {{index "find method"}} -It uses another array method, `find`, which goes over the elements in the array and returns the first one for which a function returns true. It returns `undefined` when no such element is found. +Başka bir dizi yöntemi olan `find` kullanır. Bu yöntem, dizideki öğeleri gezinir ve verilen fonksiyonun true döndürdüğü ilk öğeyi döndürür. Böyle bir öğe bulunamadığında `undefined` döndürür. {{index "textScripts function", "Chinese characters"}} -Using `countBy`, we can write the function that tells us which scripts are used in a piece of text: +`countBy` kullanarak, bir metinde hangi betiklerin kullanıldığını söyleyen fonksiyonu yazabiliriz. ```{includeCode: strip_log, startCode: true} function textScripts(text) { @@ -548,47 +547,48 @@ console.log(textScripts('英国的狗说"woof", 俄罗斯的狗说"тяв"')); {{index "characterScript function", "filter method"}} -The function first counts the characters by name, using `characterScript` to assign them a name and falling back to the string `"none"` for characters that aren't part of any script. The `filter` call drops the entry for `"none"` from the resulting array since we aren't interested in those characters. +Fonksiyon önce karakterleri adlarına göre sayar, onlara bir isim atamak için `characterScript`'i kullanır ve herhangi bir betiğin parçası olmayan karakterler için `"none"` dizesini kullanır. `filter` çağrısı, sonuç dizisinden `"none"` girişlerini bu karakterlerle ilgilenmediğimiz için ayıklar. {{index "reduce method", "map method", "join method", [array, methods]}} -To be able to compute ((percentage))s, we first need the total number of characters that belong to a script, which we can compute with `reduce`. If no such characters are found, the function returns a specific string. Otherwise it transforms the counting entries into readable strings with `map` and then combines them with `join`. +((Yüzde))lerin hesaplanabilmesi için öncelikle bir betiğe ait toplam karakter sayısına ihtiyacımız var, bunu `reduce` ile hesaplayabiliriz. Eğer böyle bir karakter bulunmazsa, fonksiyon belirli bir dize döndürür. Aksi takdirde, sayma girişlerini `map` kullanarak okunabilir dizelere dönüştürür ve ardından bunları `join` ile birleştirir. -## Summary +## Özet -Being able to pass function values to other functions is a deeply useful aspect of JavaScript. It allows us to write functions that model computations with "gaps" in them. The code that calls these functions can fill in the gaps by providing function values. +Başka fonksiyon değerlerini diğer fonksiyonlara argüman olarka verebilmek, JavaScript'in derinlemesine kullanışlı bir yönüdür. Bu, aralarında "boşluklar" olan hesaplamaları modelleyen fonksiyonlar yazmamıza olanak tanır. Bu fonksiyonları çağıran kod, fonksiyon değerlerini sağlayarak boşlukları doldurabilir. -Arrays provide a number of useful higher-order methods. You can use `forEach` to loop over the elements in an array. The `filter` method returns a new array containing only the elements that pass the ((predicate function)). Transforming an array by putting each element through a function is done with `map`. You can use `reduce` to combine all the elements in an array into a single value. The `some` method tests whether any element matches a given predicate function, while `find` finds the first element that matches a predicate. +Diziler bir dizi kullanışlı higher-order metodlar sağlar. Bir dizideki öğeler üzerinde döngü yapmak için `forEach` kullanabilirsiniz. `filter` yöntemi, yalnızca ((test fonksiyonundan)) true değeriyle geçen öğeleri içeren yeni bir dizi döndürür. Her bir öğeyi bir işlemden geçirerek bir diziyi dönüştürmek için `map` kullanılır. Bir dizi içindeki tüm öğeleri birleştirmek bir değer elde etmek için `reduce` kullanabilirsiniz. `some` yöntemi, belirli bir test fonksiyonundan true değerini alan herhangi bir öğe olup olmadığını test eder. Ve `find`, bir test fonksiyonunu karşılayan ilk öğeyi bulur. -## Exercises +## Egzersizler -### Flattening +### Düzleştirme {{index "flattening (exercise)", "reduce method", "concat method", [array, flattening]}} -Use the `reduce` method in combination with the `concat` method to "flatten" an array of arrays into a single array that has all the elements of the original arrays. +Dizi içinde olan dizilerin tüm öğelerini içeren bir diziyi düzleştirerek oluşturabilmek için `reduce` yöntemini `concat` yöntemiyle beraber kullanın. {{if interactive ```{test: no} let arrays = [[1, 2, 3], [4, 5], [6]]; -// Your code here. +// Kodunuz buraya. // → [1, 2, 3, 4, 5, 6] ``` + if}} -### Your own loop +### Kendi döngün {{index "your own loop (example)", "for loop"}} -Write a higher-order function `loop` that provides something like a `for` loop statement. It should take a value, a test function, an update function, and a body function. Each iteration, it should first run the test function on the current loop value and stop if that returns false. It should then call the body function, giving it the current value, then finally call the update function to create a new value and start over from the beginning. +Bir `loop` adlı bir higher-order fonksiyon yazın ki bu fonksiyon, bir `for` döngüsü ifadesine benzer bir işlev sağlasın. Bir değer, bir test fonksiyonu, bir güncelleme fonksiyonu ve bir gövde fonksiyonunu parametre olarak almasını sağlayın. Her döngüde, önce mevcut döngü değerinde test fonksiyonunu çalıştırır ve bu yanıtın false döndüğü durumda durur. Ardından, mevcut değeri vererek gövde fonksiyonunu çağırır. Son olarak, yeni bir değer oluşturmak için güncelleme fonksiyonunu çağırır ve baştan başlar. -When defining the function, you can use a regular loop to do the actual looping. +Fonksiyonu tanımlarken gerçek döngüyü yapmak için normal bir döngü kullanabilirsiniz. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. loop(3, n => n > 0, n => n - 1, console.log); // → 3 @@ -598,19 +598,19 @@ loop(3, n => n > 0, n => n - 1, console.log); if}} -### Everything +### Her şey {{index "predicate function", "everything (exercise)", "every method", "some method", [array, methods], "&& operator", "|| operator"}} -Arrays also have an `every` method analogous to the `some` method. This method returns true when the given function returns true for _every_ element in the array. In a way, `some` is a version of the `||` operator that acts on arrays, and `every` is like the `&&` operator. +`some` metoduna benzer şekilde, dizilerin bir de `every` yöntemi vardır. Bu, verilen fonksiyonun dizideki _her öğe_ için true döndüğünde true döndürür. Bir bakıma, `some`, diziler üzerinde çalışan `||` operatörünün bir versiyonu gibidir ve `every` ise `&&` operatörüne benzer. -Implement `every` as a function that takes an array and a predicate function as parameters. Write two versions, one using a loop and one using the `some` method. +`every` metodunu bir dizi ve bir test fonksiyonunu parametre olarak alan bir fonksiyon yazarak uygulayın. Bir döngü kullanan ve bir de `some` yöntemini kullanan iki versiyon yazın. {{if interactive ```{test: no} function every(array, test) { - // Your code here. + // Kodunuz buraya. } console.log(every([1, 3, 5], n => n < 10)); @@ -627,27 +627,27 @@ if}} {{index "everything (exercise)", "short-circuit evaluation", "return keyword"}} -Like the `&&` operator, the `every` method can stop evaluating further elements as soon as it has found one that doesn't match. So the loop-based version can jump out of the loop—with `break` or `return`—as soon as it runs into an element for which the predicate function returns false. If the loop runs to its end without finding such an element, we know that all elements matched and we should return true. +`&&` operatörü gibi, `every` metodu, eşleşmeyen bir öğe bulur bulmaz daha fazla öğeyi değerlendirmeyi durdurabilir. Bu nedenle, döngü tabanlı versiyon, test fonksiyonunun false döndürdüğü bir öğe ile karşılaştığında döngüden çıkabilir—`break` veya `return` kullanarak. Döngü, böyle bir öğe bulmadan sonuna kadar çalışırsa, tüm öğelerin eşleştiğini ve `true` döndürmemiz gerektiğini biliriz. -To build `every` on top of `some`, we can apply _((De Morgan's laws))_, which state that `a && b` equals `!(!a || !b)`. This can be generalized to arrays, where all elements in the array match if there is no element in the array that does not match. +`every` metodunu `some` üzerine inşa etmek için, _De Morgan kanunlarını_ uygulayabiliriz, bu, `a && b`'nin `!(!a || !b)` ifadesine eşit olduğunu belirtir. Bu, dizide hiç eşleşmeyen bir öğe yoksa dizideki tüm öğelerin eşleştiği diziler için genelleştirilebilir. hint}} -### Dominant writing direction +### Baskın yazma yönü -{{index "SCRIPTS data set", "direction (writing)", "groupBy function", "dominant direction (exercise)"}} +{{index "SCRIPTS dataset", "direction (writing)", "groupBy function", "dominant direction (exercise)"}} -Write a function that computes the dominant writing direction in a string of text. Remember that each script object has a `direction` property that can be `"ltr"` (left to right), `"rtl"` (right to left), or `"ttb"` (top to bottom). +Metin içindeki baskın yazma yönünü hesaplayan bir fonksiyon yazın. Unutmayın ki her betik nesnesinin bir `direction` özelliği vardır ve bu `"ltr"` (soldan sağa), `"rtl"` (sağdan sola) veya `"ttb"` (üstden alta) olabilir. {{index "characterScript function", "countBy function"}} -The dominant direction is the direction of a majority of the characters that have a script associated with them. The `characterScript` and `countBy` functions defined earlier in the chapter are probably useful here. +Baskın yön, betiği olan karakterlerin çoğunluğunun yönüdür. Bölümde önceden tanımlanan `characterScript` ve `countBy` fonksiyonları burada muhtemelen kullanışlı olacaktır. {{if interactive ```{test: no} function dominantDirection(text) { - // Your code here. + // Kodunuz buraya. } console.log(dominantDirection("Hello!")); @@ -655,16 +655,17 @@ console.log(dominantDirection("Hello!")); console.log(dominantDirection("Hey, مساء الخير")); // → rtl ``` + if}} {{hint {{index "dominant direction (exercise)", "textScripts function", "filter method", "characterScript function"}} -Your solution might look a lot like the first half of the `textScripts` example. You again have to count characters by a criterion based on `characterScript` and then filter out the part of the result that refers to uninteresting (script-less) characters. +Çözümünüz, `textScripts` örneğinin ilk yarısına çok benzeyebilir. Yine, `characterScript` fonksiyonuna dayalı bir kriterle karakterları saymanız ve ardından ilginç olmayan (betiksiz) karakterleri filtrelemeniz gerekecektir. {{index "reduce method"}} -Finding the direction with the highest character count can be done with `reduce`. If it's not clear how, refer to the example earlier in the chapter, where `reduce` was used to find the script with the most characters. +En fazla karakter sayısına sahip yönu bulmak için `reduce` kullanılabilir. Nasıl yapılacağı açık değilse, bölümde daha önce en fazla karaktere sahip betiği bulmak için kullanılan `reduce` örneğine başvurun. hint}} diff --git a/06_object.md b/06_object.md index f1d9e228..bd1b1944 100644 --- a/06_object.md +++ b/06_object.md @@ -1,49 +1,51 @@ {{meta {load_files: ["code/chapter/06_object.js"], zip: "node/html"}}} -# The Secret Life of Objects +# Nesnelerin Gizli Yaşamı {{quote {author: "Barbara Liskov", title: "Programming with Abstract Data Types", chapter: true} -An abstract data type is realized by writing a special kind of program […] which defines the type in terms of the operations which can be performed on it. +Bir soyut veri türü, üzerinde gerçekleştirilebilecek işlemler açısından türü tanımlayan bir programı […] yazarak gerçekleştirilir. quote}} {{index "Liskov, Barbara", "abstract data type"}} -{{figure {url: "img/chapter_picture_6.jpg", alt: "Illustration of a rabbit next to its prototype, a schematic representation of a rabbit", chapter: framed}}} +{{figure {url: "img/chapter_picture_6.jpg", alt: "Bir tavşanın prototipinin yanında bir tavşanın şematik temsili resmi", chapter: framed}}} -[Chapter ?](data) introduced JavaScript's objects as containers that hold other data. +[Chapter ?](data) introduced JavaScript's objects, as containers that hold other data. -In programming culture, _((object-oriented programming))_ is a set of techniques that use objects as the central principle of program organization. Though no one really agrees on its precise definition, object-oriented programming has shaped the design of many programming languages, including JavaScript. This chapter describes the way these ideas can be applied in JavaScript. +Programlama kültüründe, _((nesne yönelimli programlama))_ adında bir şey var, nesneleri program organizasyonunun merkezi prensibi olarak kullanan bir teknik seti. Kesin tanımı hakkında herkes gerçekten anlaşmıyor olsa da, nesne yönelimli programlama birçok programlama dilinin tasarımını şekillendirmiştir, bunlar arasında JavaScript de bulunur. Bu bölüm, bu fikirlerin JavaScript'te nasıl uygulanabileceğini açıklanmaktadır. -## Abstract Data Types +## Soyut Veri Türleri {{index "abstract data type", type, "mixer example"}} -The main idea in object-oriented programming is to use objects, or rather _types_ of objects, as the unit of program organization. Setting up a program as a number of strictly separated object types provides a way to think about its structure and thus to enforce some kind of discipline, preventing everything from becoming entangled. +Nesne yönelimli programlamadaki ana fikir, nesneleri veya daha doğrusu nesne türlerini, program organizasyonunun birimi olarak kullanmaktır. Programı birkaç sıkı şekilde ayrılmış nesne türü olarak ayarlamak, yapısını düşünmenin bir yolunu sağlar ve böylece her şeyin karışmasını önleyerek bir tür disiplin uygular. -The way to do this is to think of objects somewhat like you'd think of an electric mixer or other consumer ((appliance)). The people who design and assemble a mixer have to do specialized work requiring material science and understanding of electricity. They cover all that up in a smooth plastic shell so that the people who only want to mix pancake batter don't have to worry about all that—they only have to understand the few knobs that the mixer can be operated with. +Bunu yapmanın yolu, nesneleri bir elektrikli mikser veya diğer tüketici ((alet)) gibi düşünmektir. Bir mikser tasarlayan ve monte eden insanlar vardır ve bunlar malzeme bilimi ve elektrik anlayışı gerektiren özelleşmiş işleri yapmak zorundadır. Tüm bunları pürüzsüz bir plastik kabuk içine kapatırlar, böylece sadece pancake hamurunu karıştırmak isteyen insanların bunlarla ilgilenmesine gerek kalmaz—sadece mikserin çalıştırılabilmesi için birkaç düğmeyi anlamaları yeterlidir. {{index "class"}} -Similarly, an _abstract data type_, or _object class_, is a subprogram that may contain arbitrarily complicated code but exposes a limited set of methods and properties that people working with it are supposed to use. This allows large programs to be built up out of a number of appliance types, limiting the degree to which these different parts are entangled by requiring them to only interact with each other in specific ways. +Benzer şekilde, bir soyut veri türü veya nesne sınıfı, onunla çalışan kişilerin kullanması gereken sınırlı bir yöntem ve özellik setini açığa çıkarabilen, ancak karmaşık kod içerebilen bir alt programdır. Bu, büyük programların birçok alet türü üzerine kurulabilmesine olanak tanır ve bu farklı parçaların sadece belirli yollarla birbirleriyle etkileşime girmesini gerektirerek bu parçaların birbirleriyle karışmasını sınırlar. {{index encapsulation, isolation, modularity}} -If a problem is found in one such object class, it can often be repaired or even completely rewritten without impacting the rest of the program. Even better, it may be possible to use object classes in multiple different programs, avoiding the need to recreate their functionality from scratch. You can think of JavaScript's built-in data structures, such as arrays and strings, as such reusable abstract data types. +Eğer bir nesne sınıfında bir problem bulunursa, genellikle bu, programın geri kalanını etkilemeden onarılabilir veya tamamen yeniden yazılabilir. + +Daha da iyisi, farklı programlardaki birden çok nesne sınıflarını kullanmak mümkün olabilir, bu da bunların işlevselliğini baştan başlatmaya gerek kalmadan kullanılabilir hale getirir. JavaScript'in dahili veri yapılarını, diziler ve dizeler gibi, böyle yeniden kullanılabilir soyut veri türleri olarak düşünebilirsiniz. {{id interface}} {{index [interface, object]}} -Each abstract data type has an _interface_, the collection of operations that external code can perform on it. Even basic things like numbers can be thought of as an abstract data type whose interface allows us to add them, multiply them, compare them, and so on. In fact, the fixation on single _objects_ as the main unit of organization in classical object-oriented programming is somewhat unfortunate, since useful pieces of functionality often involve a group of different object classes working closely together. +Her soyut veri türünün bir _arayüzü_ vardır, bu dış kodun onun üzerinde gerçekleştirebileceği işlemlerin koleksiyonudur. Sayılar gibi temel şeyler bile, onları ekleyebilme, çarpabilme, karşılaştırabilme gibi işlemleri gerçekleştirebileceğimiz bir arayüz olarak düşünülebilir. Aslında, klasik nesne yönelimli programlamada ana organizasyon birimi olarak tek _nesnelerin_ odaklanılması biraz talihsizdir çünkü sıklıkla kullanışlı işlev parçaları bir grup farklı nesne sınıfının bir araya gelmesiyle gerçekleşmektedir. {{id obj_methods}} -## Methods +## Metodlar {{index "rabbit example", method, [property, access]}} -In JavaScript, methods are nothing more than properties that hold function values. This is a simple method: +JavaScript'te metodlar, yalnızca fonksiyon değerlerini tutan özelliklerdir. Bu, basit bir metottur: ```{includeCode: "top_lines:6"} function speak(line) { @@ -60,24 +62,24 @@ hungryRabbit.speak("Got any carrots?"); {{index "this binding", "method call"}} -Typically a method needs to do something with the object on which it was called. When a function is called as a method—looked up as a property and immediately called, as in `object.method()`—the binding called `this` in its body automatically points at the object on which it was called. +Tipik olarak, bir yöntem, üzerinde çağrıldığı nesneyle bir şeyler yapması gerekir. Bir işlev bir yöntem olarak çağrıldığında—`object.method()` ifadesinde de olduğu gibi bir özellik aranıp çağırılır— `this` adlı bağlantı çağırılan fonksiyonun vücudu içinde otomatik olarak çağrıldığı nesneye işaret eder. {{id call_method}} {{index "call method"}} -You can think of `this` as an extra ((parameter)) that is passed to the function in a different way than regular parameters. If you want to provide it explicitly, you can use a function's `call` method, which takes the `this` value as its first argument and treats further arguments as normal parameters. +`this` değerini, normal parametrelerden farklı bir şekilde bir fonskiyona verilen bir ek ((parametre)) olarak düşünebilirsiniz. Açıkça sağlamak isterseniz, bir fonksiyonun `call` metodunu kullanabilirsiniz, bu yöntem `this` değerini ilk argümanı olarak alır ve diğer argümanları normal parametreler olarak işler. ``` speak.call(whiteRabbit, "Hurry"); // → The white rabbit says 'Hurry' ``` -Since each function has its own `this` binding whose value depends on the way it is called, you cannot refer to the `this` of the wrapping scope in a regular function defined with the `function` keyword. +Her fonksiyonun, değeri nasıl çağrıldığına bağlı olan kendi `this` bağlantısı olduğundan, bir `function` anahtar sözcüğü ile tanımlanan sıradan bir fonksiyonda kapsamın dışındaki `this` değerine başvuramazsınız. {{index "this binding", "arrow function"}} -Arrow functions are different—they do not bind their own `this` but can see the `this` binding of the scope around them. Thus, you can do something like the following code, which references `this` from inside a local function: +Ok fonksiyonları farklıdır—kendi `this` değerlerini bağlamazlar, ancak etraflarındaki kapsamın `this` bağlamını görebilirler. Bu nedenle, yerel bir fonksiyonun içinden `this` değerine ulaşan aşağıdaki gibi bir kod yazabilirsiniz: ``` let finder = { @@ -90,21 +92,21 @@ console.log(finder.find([4, 5])); // → true ``` -A property like `find(array)` in an object expression is a shorthand way of defining a method. It creates a property called `find` and gives it a function as its value. +Nesne ifadesindeki `find(array)` gibi bir özellik, bir metod tanımlamanın kısa yoludur. `find` adında bir özellik oluşturur ve değeri olarak bir fonksiyon verir. -If I had written the argument to `some` using the `function` keyword, this code wouldn't work. +Eğer `some` metoduna geçirilen argümanı `function` anahtar kelimesini kullanarak yazmış olsaydım, bu kod çalışmazdı. {{id prototypes}} -## Prototypes +## Prototipler -One way to create a rabbit object type with a `speak` method would be to create a helper function that has a rabbit type as parameter and returns an object holding that as its `type` property and our speak function in its `speak` property. +Bir `speak` metoduna sahip soyut bir tavşan türü oluşturmanın bir yolu, tavşan türünü parametre olarak alan ve bu türün tip özelliği ve konuşma fonksiyonunu içeren bir nesneyi döndüren bir yardımcı fonksiyon oluşturmaktır. -All rabbits share that same method. Especially for types with many methods, it would be nice if there was a way to keep a type's methods in a single place, rather than adding them to each object individually. +Tüm tavşanlar aynı yöntemi paylaşırlar. Özellikle çok sayıda metoda sahip türler için, bir türün yöntemlerini her nesneye ayrı ayrı eklemek yerine tek bir yerde tutmanın bir yolu olsa iyi olurdu. {{index [property, inheritance], [object, property], "Object prototype"}} -In JavaScript, _((prototype))s_ are the way to do that. Objects can be linked to other objects, to magically get all the properties that other object has. Plain old objects created with `{}` notation are linked to an object called `Object.prototype`. +JavaScript'te, _((prototipler))_ bunu yapmanın yoludur. Nesneler, diğer nesnelere bağlanarak diğer nesnenin sahip olduğu tüm özellikleri sihirli bir şekilde alabilirler. `{}` gösterimiyle oluşturulan normal nesneler, `Object.prototype` olarak adlandırılan bir nesneye bağlıdır. {{index "toString method"}} @@ -116,9 +118,9 @@ console.log(empty.toString()); // → [object Object] ``` -It looks like we just pulled a property out of an empty object. But in fact, `toString` is a method stored in `Object.prototype`, meaning it is available in most objects. +Boş bir nesneden bir özellik çıkardık gibi görünüyor. Ancak aslında `toString`, `Object.prototype` içinde depolanan bir yöntemdir, bu da çoğu nesnede mevcut olduğu anlamına gelir. -When an object gets a request for a property that it doesn't have, its prototype will be searched for the property. If that doesn't have it, the _prototype's_ prototype is searched, and so on until an object without prototype is reached (`Object.prototype` is such an object). +Bir nesne sahip olmadığı bir özelliğe istek aldığında, prototipi içinde bu özellik aranır. Eğer o prototip de bu özelliğe sahip değilse, _onun da_ prototipi aranır ve `Object.prototype` gibi artık bir prototip barındırmayan objeye kadar bu arama devam eder. ``` console.log(Object.getPrototypeOf({}) == Object.prototype); @@ -129,11 +131,11 @@ console.log(Object.getPrototypeOf(Object.prototype)); {{index "getPrototypeOf function"}} -As you'd guess, `Object.getPrototypeOf` returns the prototype of an object. +Tahmin edebileceğiniz gibi, `Object.getPrototypeOf` bir nesnenin prototipini döndürür. {{index inheritance, "Function prototype", "Array prototype", "Object prototype"}} -Many objects don't directly have `Object.prototype` as their ((prototype)) but instead have another object that provides a different set of default properties. Functions derive from `Function.prototype` and arrays derive from `Array.prototype`. +Birçok nesnenin ((prototipi)) olarak doğrudan `Object.prototype`'a sahip olmadığı, ancak farklı bir varsayılan özellik kümesi sağlayan başka bir nesneye sahip olduğu durumlar vardır. Fonksiyonlar `Function.prototype`'tan, diziler ise `Array.prototype`'tan türemiştir. ``` console.log(Object.getPrototypeOf(Math.max) == @@ -145,11 +147,11 @@ console.log(Object.getPrototypeOf([]) == Array.prototype); {{index "Object prototype"}} -Such a prototype object will itself have a prototype, often `Object.prototype`, so that it still indirectly provides methods like `toString`. +Bu tür bir prototip nesnesinin kendisinin de genellikle `Object.prototype` gibi bir prototipi olacaktır ki böylece hala `toString` gibi yöntemlere erişim sağlayabilsin. {{index "rabbit example", "Object.create function"}} -You can use `Object.create` to create an object with a specific ((prototype)): +Belirli bir ((prototip)) ile bir nesne oluşturmak için `Object.create`'i kullanabilirsiniz. ```{includeCode: "top_lines: 7"} let protoRabbit = { @@ -165,23 +167,23 @@ blackRabbit.speak("I am fear and darkness"); {{index "shared property"}} -The "proto" rabbit acts as a container for the properties shared by all rabbits. An individual rabbit object, like the black rabbit, contains properties that apply only to itself—in this case its type—and derives shared properties from its prototype. +"proto" tavşanı, tüm tavşanlar tarafından paylaşılan özellikleri içeren bir konteyner olarak davranır. Bir bireysel tavşan nesnesi, kendisine sadece kendi üzerine uygulanan özellikleri içerir—bu durumda tipi—ve paylaşılan özellikleri prototipinden türetir. {{id classes}} -## Classes +## Class'lar {{index "object-oriented programming", "abstract data type"}} -JavaScript's ((prototype)) system can be interpreted as a somewhat free-form take on abstract data types or ((class))es. A _class_ defines the shape of a type of object—what methods and properties it has. Such an object is called an _((instance))_ of the class. +JavaScript'in ((prototip)) sistemi, soyut veri tipleri veya ((sınıf))larının biraz serbest bir şekilde ele alınmış hali olarak yorumlanabilir. Bir sınıf, bir nesne türünün şeklini tanımlar—hangi yöntemlere ve özelliklere sahip olduğunu belirtir. Bu tür bir nesne, sınıfın bir ((örneği)) olarak adlandırılır. {{index [property, inheritance]}} -Prototypes are useful for defining properties for which all instances of a class share the same value. Properties that differ per instance, such as our rabbits' `type` property, need to be stored directly in the objects themselves. +Prototipler, bir sınıfın tüm örneklerinin aynı değere sahip olmasını istediğiniz özelliklerin tanımlanması için kullanışlıdır. Örneğin tavşanlarımızın tip özelliği gibi örnek başına farklı olan özellikler, doğrudan nesnelerin kendilerinde saklanmalıdır. {{id constructors}} -To create an instance of a given class, you have to make an object that derives from the proper prototype, but you _also_ have to make sure it itself has the properties that instances of this class are supposed to have. This is what a _((constructor))_ function does. +Belirli bir sınıfın bir örneğini oluşturmak için, uygun prototipten türeyen bir nesne yapmak zorundasınız, ancak ayrıca, kendisinin de bu sınıfın örneklerinin sahip olması gereken özelliklere sahip olduğundan emin olmanız gerekir. Bu, bir ((constructor)) fonksiyonun ne yaptığını gösterir. ``` function makeRabbit(type) { @@ -191,7 +193,7 @@ function makeRabbit(type) { } ``` -JavaScript's ((class)) notation makes it easier to define this type of function, along with a ((prototype)) object. +JavaScript'in ((sınıf)) notasyonu, bu tür bir fonksiyonu tanımlamayı ((prototip)) nesnesiyle kolaylaştırır. {{index "rabbit example", constructor}} @@ -208,17 +210,17 @@ class Rabbit { {{index "prototype property", [braces, class]}} -The `class` keyword starts a ((class declaration)), which allows us to define a constructor and a set of methods together. Any number of methods may be written inside the declaration's braces. This code has the effect of defining a binding called `Rabbit`, which holds a function that runs the code in `constructor` and has a `prototype` property which holds the `speak` method. +`class` anahtar kelimesi, bir ((sınıf bildirimi)) başlatır ve bir constructor ve bir dizi yöntemi bir arada tanımlamamıza olanak tanır. Bildirimin parantezleri içinde herhangi bir sayıda yöntem yazılabilir. Bu kod, `constructor` içindeki kodu çalıştıran ve `speak` yöntemini içeren bir `prototype` özelliğini tutan Rabbit adında bir bağlantı tanımlar. {{index "new operator", "this binding", [object, creation]}} -This function cannot be called like a normal function. Constructors, in JavaScript, are called by putting the keyword `new` in front of them. Doing so creates a fresh instance object whose prototype is the object from the function's `prototype` property, then runs the function with `this` bound to the new object, and finally returns the object. +Bu fonksiyon normal bir şekilde çağrılamaz. JavaScript'te, constructor'ları çağırmak için önlerine `new` anahtar kelimesini koymak gerekir. Bunu yapınca, fonksiyonun `prototype` özelliğini prototip olarak barındıran yeni bir obje oluşturulur ve fonksiyonun `this` bağlamını bu yeni oluşturulan objeye bağlayarak fonksiyonu çağırır, son olarak objeyi döndürür. ```{includeCode: true} let killerRabbit = new Rabbit("killer"); ``` -In fact, `class` was only introduced in the 2015 edition of JavaScript. Any function can be used as a constructor, and before 2015, the way to define a class was to write a regular function and then manipulate its `prototype` property. +Aslında, `class` JavaScript'in 2015 versiyonunda tanıtıldı. Herhangi bir fonksiyon bir constructor olarak kullanılabilir, ki zaten 2015'ten önce class tanımlamanın yolu normal bir fonksiyon yazıp ardından onun prototype özelliğini manipüle etmekti. ``` function ArchaicRabbit(type) { @@ -230,15 +232,15 @@ ArchaicRabbit.prototype.speak = function(line) { let oldSchoolRabbit = new ArchaicRabbit("old school"); ``` -For this reason, all non-arrow functions start with a `prototype` property holding an empty object. +Ok notasyonunda yazılmayan tüm fonksiyonların boş bir obje barındıran `prototype` özelliğiyle başlamasının sebebi budur. {{index capitalization}} -By convention, the names of constructors are capitalized so that they can easily be distinguished from other functions. +Geleneksel olarak, constructor adları diğer fonksiyonlardan kolayca ayırt edilebilmeleri için büyük harfle yazılır. {{index "prototype property", "getPrototypeOf function"}} -It is important to understand the distinction between the way a prototype is associated with a constructor (through its `prototype` property) and the way objects _have_ a prototype (which can be found with `Object.getPrototypeOf`). The actual prototype of a constructor is `Function.prototype` since constructors are functions. The constructor function's `prototype` _property_ holds the prototype used for instances created through it. +Bir ((prototipin)) bir constructor ile ilişkilendirilme şekli (onun prototype _özelliği_ aracılığıyla) ve bir nesnenin zaten var olan prototipi(bu, `Object.getPrototypeOf` ile bulunabilir) arasındaki farkı anlamanız önemlidir. Bir constructor gerçek prototipi, constructor'lar fonksiyon olduklarından ötürü `Function.prototype`'dır. `prototype` _özelliği_, bunun aracılığıyla oluşturulan örnekler için kullanılan prototipi tutar. ``` console.log(Object.getPrototypeOf(Rabbit) == @@ -251,7 +253,7 @@ console.log(Object.getPrototypeOf(killerRabbit) == {{index constructor}} -Constructors will typically add some per-instance properties to `this`. It is also possible to declare properties directly in the ((class declaration)). Unlike methods, such properties are added to ((instance)) objects, not the prototype. +Constructor'lar, genellikle `this`'e örnek başı değer atanacak birkaç özellik ekler. Özellikleri ayrıca ((sınıf bildirimi)) içinde doğrudan bildirmek de mümkündür. Metodların aksine, böyle özellikler ((örnek)) nesnelere eklenir, prototipe değil. ``` class Particle { @@ -262,7 +264,7 @@ class Particle { } ``` -Like `function`, `class` can be used both in statements and in expressions. When used as an expression, it doesn't define a binding but just produces the constructor as a value. You are allowed to omit the class name in a class expression. +`function` gibi, `class` hem beyanlarda hem de ifadelerde kullanılabilir. Bir ifade olarak kullanıldığında, bir bağlantı tanımlamaz, ancak sadece constructor'ı bir değer olarak üretir. Bir sınıf ifadesinde sınıf adının atlanması mümkündür. ``` let object = new class { getWord() { return "hello"; } }; @@ -270,16 +272,15 @@ console.log(object.getWord()); // → hello ``` - -## Private Properties +## Özel Özellikler {{index [property, private], [property, public], "class declaration"}} -It is common for classes to define some properties and ((method))s for internal use that are not part of their ((interface)). These are called _private_ properties, as opposed to _public_ ones, which are part of the object's external interface. +Sınıfların iç kullanım için ((arayüzlerinin)) bir parçası olmayan bazı özellik ve ((metodlar)) oluşturması yaygındır. Bunlara arayüzün parçası olan _public_ özelliklerin aksine _private_ özellikler denir. {{index [method, private]}} -To declare a private method, put a `#` sign in front of its name. Such methods can only be called from inside the `class` declaration that defines them. +Private metod tanımlamak için isminin başına `#` işareti koy. Bu metodlar sadece onları tanımlayan sınıf içerisinden çağırılabilir. ``` class SecretiveObject { @@ -293,13 +294,11 @@ class SecretiveObject { } ``` -When a class does not declare a constructor, it will automatically get an empty one. +Eğer `#getSecret`'ı sınıf dışından çağımaya çalışırsan bir hata alırsın çünkü onun varlığı sıvıf içerisinde tamamen dış dünyadan saklıdır. -If you try to call `#getSecret` from outside the class, you get an error. Its existence is entirely hidden inside the class declaration. +Private örnek özelliklerini kullanabilmek için onları önce tanımlamalısın. Normal özellikler onlara sadece bir değer vererek tanımlanabilir ancak private özellikler sınıf içerisinde tanımlanmak zorundadırlar. -To use private instance properties, you must declare them. Regular properties can be created by just assigning to them, but private properties _must_ be declared in the class declaration to be available at all. - -This class implements an appliance for getting random whole number below a given maximum number. It only has one ((public)) property: `getNumber`. +Bu sınıf verilen bir maksimum sayının altında rastgele bir sayı gösterecek bir cihazı implemente etmektedir ve sadece bir ((public)) özelliği vardır: `getNumber`. ``` class RandomSource { @@ -313,11 +312,11 @@ class RandomSource { } ``` -## Overriding derived properties +## Türetilmiş özellikleri geçersiz kılma {{index "shared property", overriding, [property, inheritance]}} -When you add a property to an object, whether it is present in the prototype or not, the property is added to the object _itself_. If there was already a property with the same name in the prototype, this property will no longer affect the object, as it is now hidden behind the object's own property. +Bir nesneye bir özellik eklediğinde içerisinde o özellik zaten var olsa da olmasa da o özellik nesnenin _kendisine_ eklenir. Eğer prototipte zaten aynı adda bir özellik varsa bu özellik artık o nesneyi o özelliğin başka bir nesneye ait olmasından ötürü etkilemeyecektir. ``` Rabbit.prototype.teeth = "small"; @@ -334,17 +333,17 @@ console.log(Rabbit.prototype.teeth); {{index [prototype, diagram]}} -The following diagram sketches the situation after this code has run. The `Rabbit` and `Object` ((prototype))s lie behind `killerRabbit` as a kind of backdrop, where properties that are not found in the object itself can be looked up. +Aşağıdaki diyahram durumu kod çalıştıktan sonra açıklamakta. `Rabbit` ve `Object` ((prototip))leri `killerRabbit`'te aranan özelliklerin kendisinde bulunamayınca bakılacak yedek yerler olarak durmaktadırlar. {{figure {url: "img/rabbits.svg", alt: "A diagram showing the object structure of rabbits and their prototypes. There is a box for the 'killerRabbit' instance (holding instance properties like 'type'), with its two prototypes, 'Rabbit.prototype' (holding the 'speak' method) and 'Object.prototype' (holding methods like 'toString') stacked behind it.",width: "8cm"}}} {{index "shared property"}} -Overriding properties that exist in a prototype can be a useful thing to do. As the rabbit teeth example shows, overriding can be used to express exceptional properties in instances of a more generic class of objects while letting the nonexceptional objects take a standard value from their prototype. +Prototipte var olan özelliklere yeni değerler atamak faydalı olabilir. `rabbit.teeth` örneği bunu göstermektedir, yeni değerler atamak istisnai olmayan nesnelerin prototiplerinden standart bir değeri almasına izin verirken, daha genel nesne sınıfının örneklerinde istisnai özellikleri ifade etmek için kullanılabilir. {{index "toString method", "Array prototype", "Function prototype"}} -Overriding is also used to give the standard function and array prototypes a different `toString` method than the basic object prototype. +Var olan bir özelliğe yeni bir değer atamak, standart fonksiyon ve dizi prototiplerine temel nesne prototipinden farklı bir `toString` metodu vermek için de kullanılır. ``` console.log(Array.prototype.toString == @@ -356,22 +355,22 @@ console.log([1, 2].toString()); {{index "toString method", "join method", "call method"}} -Calling `toString` on an array gives a result similar to calling `.join(",")` on it—it puts commas between the values in the array. Directly calling `Object.prototype.toString` with an array produces a different string. That function doesn't know about arrays, so it simply puts the word _object_ and the name of the type between square brackets. +Bir dizide `toString` çağırmak, ona `.join(",")` çağırmakla benzer bir sonuç verir—dizideki değerler arasına virgül koyar. Bir diziye doğrudan `Object.prototype.toString` çağırmak farklı bir dize üretir. Bu fonksiyon diziler hakkında bilgi sahibi değildir, bu nedenle sadece _object_ kelimesini ve türün adını köşeli parantezler arasına koyar. ``` console.log(Object.prototype.toString.call([1, 2])); // → [object Array] ``` -## Maps +## Map'ler {{index "map method"}} -We saw the word _map_ used in the [previous chapter](higher_order#map) for an operation that transforms a data structure by applying a function to its elements. Confusing as it is, in programming the same word is used for a related but rather different thing. +Bir [önceki bölümde](higher_order#map) _map_ kelimesini, öğelerine bir fonksiyon uygulayarak bir veri yapısını dönüştüren bir işlem için kullanıldığını gördük. Kafa karıştırıcı olmasına rağmen, programlamada aynı kelime ilişkili ancak farklı bir şey için de kullanılır. {{index "map (data structure)", "ages example", ["data structure", map]}} -A _map_ (noun) is a data structure that associates values (the keys) with other values. For example, you might want to map names to ages. It is possible to use objects for this. +Bir _map_ (isim) değerleri (anahtarlar) diğer değerlerle ilişkilendiren bir veri yapısıdır. Örneğin, isimleri yaşlara eşlemek isteyebilirsiniz. Bunun için nesneleri kullanmak mümkündür. ``` let ages = { @@ -390,11 +389,11 @@ console.log("Is toString's age known?", "toString" in ages); {{index "Object.prototype", "toString method"}} -Here, the object's property names are the people's names and the property values are their ages. But we certainly didn't list anybody named toString in our map. Yet, because plain objects derive from `Object.prototype`, it looks like the property is there. +Burada, nesnenin özellik adları insanların isimleri, özellik değerleri ise yaşlarıdır. Ancak kesinlikle haritamızda `toString` adında birini listelemedik. Yine de basit nesneler `Object.prototype`'tan türedikleri için, özellik orada gibi görünüyor. {{index "Object.create function", prototype}} -As such, using plain objects as maps is dangerous. There are several possible ways to avoid this problem. First, you can create objects with _no_ prototype. If you pass `null` to `Object.create`, the resulting object will not derive from `Object.prototype` and can safely be used as a map. +Bu nedenle, basit nesneleri haritalar olarak kullanmak tehlikelidir. Bu sorunu önlemenin birkaç olası yolu vardır. İlk olarak, hiçbir prototipe sahip olmayan nesneler oluşturmak mümkündür. `Object.create`'e `null` verirseniz, sonuçta elde edilen nesne `Object.prototype`'tan türetilmez ve güvenli bir şekilde bir map olarak kullanılabilir. ``` console.log("toString" in Object.create(null)); @@ -403,11 +402,11 @@ console.log("toString" in Object.create(null)); {{index [property, naming]}} -Object property names must be strings. If you need a map whose keys can't easily be converted to strings—such as objects—you cannot use an object as your map. +Nesne özellik adları dize olmalıdır. Anahtarları kolayca dizilere dönüştürülemeyen bir map'e ihtiyacınız varsa—örneğin nesneler—bir nesneyi map'iniz olarak kullanamazsınız. {{index "Map class"}} -Fortunately, JavaScript comes with a class called `Map` that is written for this exact purpose. It stores a mapping and allows any type of keys. +Neyse ki, JavaScript, tam olarak bu amaca yönelik olan `Map` adında bir sınıf ile gelir. Bir eşleme saklar ve her türden anahtara izin verir. ``` let ages = new Map(); @@ -425,11 +424,11 @@ console.log(ages.has("toString")); {{index [interface, object], "set method", "get method", "has method", encapsulation}} -The methods `set`, `get`, and `has` are part of the interface of the `Map` object. Writing a data structure that can quickly update and search a large set of values isn't easy, but we don't have to worry about that. Someone else did it for us, and we can go through this simple interface to use their work. +`set`, `get` ve `has` yöntemleri, `Map` nesnesinin arayüzünün bir parçasıdır. Büyük bir değer kümesini hızlı bir şekilde güncelleme ve arama yapabilen bir veri yapısı yazmak kolay değildir, ancak bununla ilgilenmemiz gerekmez. Başkası bunu bizim için yaptı ve bu basit arayüzü kullanarak çalışmalarını kullanabiliriz. {{index "hasOwn function", "in operator"}} -If you do have a plain object that you need to treat as a map for some reason, it is useful to know that `Object.keys` returns only an object's _own_ keys, not those in the prototype. As an alternative to the `in` operator, you can use the `Object.hasOwn` function, which ignores the object's prototype. +Herhangi bir nedenden ötürü basit bir nesneye bir map gibi davranmanız gerekiyorsa, `Object.keys`'in yalnızca bir nesnenin kendi anahtarlarını döndürdüğünü, prototiptekilerini döndürmediğini bilmeniz faydalı olabilir. `in` operatörü yerine, nesnenin prototipini yok sayan `Object.hasOwn` fonksiyonunu kullanabilirsiniz. ``` console.log(Object.hasOwn({x: 1}, "x")); @@ -438,11 +437,11 @@ console.log(Object.hasOwn({x: 1}, "toString")); // → false ``` -## Polymorphism +## Polimorfizm {{index "toString method", "String function", polymorphism, overriding, "object-oriented programming"}} -When you call the `String` function (which converts a value to a string) on an object, it will call the `toString` method on that object to try to create a meaningful string from it. I mentioned that some of the standard prototypes define their own version of `toString` so they can create a string that contains more useful information than `"[object Object]"`. You can also do that yourself. +Bir değeri dizeye dönüştüren `String` fonksiyonunu bir nesne üzerinde çağırdığınızda, bu nesne üzerinde `toString` yöntemini çağırarak ondan anlamlı bir dize oluşturmaya çalışır. Bazı standart prototiplerin kendi `toString` versiyonlarını tanımladığını belirttim, böylece `"[object Object]"`'ten daha kullanışlı bilgiler içeren bir dize oluşturabilirler. Kendiniz de bunu yapabilirsiniz. ```{includeCode: "top_lines: 3"} Rabbit.prototype.toString = function() { @@ -455,13 +454,13 @@ console.log(String(killerRabbit)); {{index "object-oriented programming", [interface, object]}} -This is a simple instance of a powerful idea. When a piece of code is written to work with objects that have a certain interface—in this case, a `toString` method—any kind of object that happens to support this interface can be plugged into the code and will be able to work with it. +Bu, güçlü bir fikrin basit bir örneğidir. Bir kod parçası, belirli bir arayüzü olan nesnelerle çalışmak üzere yazıldığında—bu durumda bir `toString` yöntemi—bu arayüzü destekleyen herhangi bir nesne kodun içine eklenerek ve onunla çalışabilir. -This technique is called _polymorphism_. Polymorphic code can work with values of different shapes, as long as they support the interface it expects. +Bu teknik, _polimorfizm_ olarak adlandırılır. Polimorfik kod, beklediği arayüzü destekleyen farklı şekillerdeki değerlerle çalışabilir. {{index "forEach method"}} -An example of a widely used interface is that of ((array-like object))s which have a `length` property holding a number, and numbered properties for each of their elements. Both arrays and strings support this interface, as do various other objects, some of which we'll see later in the chapters about the browser. Our implementation of `forEach` from [Chapter ?](higher_order) works on anything that provides this interface. In fact, so does `Array.prototype.forEach`. +Yaygın olarak kullanılan örnek olarak verilebilecek bir arayüz örneği, `length` özelliği tutan ve her bir eleman için numaralandırılmış özelliklere sahip ((dizi benzeri nesneler))'in arayüzüdür. Diziler ve dizeler bu arayüzü destekler, aynı şekilde bazı diğer nesneler de destekler, bunlardan bazılarını daha sonra browser hakkındaki bölümlerde göreceğiz. [Bölüm ?](higher_order) içindeki `forEach` uygulamamız, bu arayüzü sağlayan her şeyde çalışır. Aslında, `Array.prototype.forEach` da aynı şekilde çalışır. ``` Array.prototype.forEach.call({ @@ -473,13 +472,13 @@ Array.prototype.forEach.call({ // → B ``` -## Getters, setters, and statics +## Getter'lar, setter'lar, and static'ler {{index [interface, object], [property, definition], "Map class"}} -Interfaces often contain plain properties, not just methods. For example, `Map` objects have a `size` property that tells you how many keys are stored in them. +Arayüzler sadece yöntemler değil, genellikle özellikler içerir. Örneğin, `Map` nesnelerinin bir `size` özelliği vardır ve içlerinde saklanan anahtarların sayısını belirtir. -It is not necessary for such an object to compute and store such a property directly in the instance. Even properties that are accessed directly may hide a method call. Such methods are called _((getter))s_ and are defined by writing `get` in front of the method name in an object expression or class declaration. +Böyle bir bir nesnenin bir özelliği doğrudan örnekte hesaplaması ve saklaması gerekli değildir. Doğrudan erişilen özellikler bile bir yöntem çağrısını gizleyebilir. Böyle yöntemlere ((getter)) denir ve bunlar bir nesne ifadesi veya sınıf bildirimi içinde yöntem adının önüne `get` yazarak tanımlanır. ```{test: no} let varyingSize = { @@ -496,7 +495,7 @@ console.log(varyingSize.size); {{index "temperature example"}} -Whenever someone reads from this object's `size` property, the associated method is called. You can do a similar thing when a property is written to, using a _((setter))_. +Bu nesnenin `size` özelliğinden okuma yapıldığında, ilişkili yöntem çağrılır. Bir özelliğe bir değer atandığında _((setter))_ kullanarak benzer bir şey yapabilirsiniz. ```{startCode: true, includeCode: "top_lines: 16"} class Temperature { @@ -523,33 +522,27 @@ console.log(temp.celsius); // → 30 ``` -The `Temperature` class allows you to read and write the temperature in either degrees ((Celsius)) or degrees ((Fahrenheit)), but internally it stores only Celsius and automatically converts to and from Celsius in the `fahrenheit` getter and setter. +`Temperature` sınıfı, sıcaklığı ((°C)) veya ((°F)) olarak okumaya ve yazmaya izin verir, ancak içsel olarak sadece °C'ı depolar ve °F değerini değiştirmek veya okumak istediğinde °C değerini getter ve setter'da formüller kullanarak °F'a çevirir. {{index "static method", "static property"}} -Sometimes you want to attach some properties directly to your constructor function, rather than to the prototype. Such methods won't have access to a class instance but can, for example, be used to provide additional ways to create instances. +Bazen, yöntemleri prototip yerine doğrudan constructor fonksiyona eklemek istersiniz. Bu tür yöntemlerin bir sınıf örneğine erişimi olmaz ancak örneğin başka yollarla oluşturulması için kullanılabilirler. -Inside a class declaration, methods or properties that have `static` written before their name are stored on the constructor. For example, the `Temperature` class allows you to write `Temperature.fromFahrenheit(100)` to create a temperature using degrees Fahrenheit: +Sınıf bildirimi içinde, adlarının önünde `static` yazılı olan yöntemler veya özellikler kurucuda saklanır. Bu nedenle, `Temperature` sınıfı, °F cinsinden bir sıcaklık oluşturmak için `Temperature.fromFahrenheit(100)` yazmanıza izin verir. -``` -let boil = Temperature.fromFahrenheit(212); -console.log(boil.celsius); -// → 100 -``` - -## Symbols +## Symbol'ler {{index "for/of loop", "iterator interface"}} -I mentioned in [Chapter ?](data#for_of_loop) that a `for`/`of` loop can loop over several kinds of data structures. This is another case of polymorphism—such loops expect the data structure to expose a specific interface, which arrays and strings do. And we can also add this interface to our own objects! But before we can do that, we need to briefly take a look at the symbol type. +[Bölüm ?](data#for_of_loop) içinde bir `for/of` döngüsünün çeşitli veri yapıları üzerinde döngü yapabileceğini belirttim. Bu, başka bir polimorfizm örneğidir—bu tür döngüler, beklenen arayüzü ortaya koyan veri yapısını bekler, diziler ve dizeler de buna uyum sağlar. Ve kendi nesnelerimize de bu arayüzü ekleyebiliriz! Ancak bunu yapmadan önce, sembol türüne kısaca bir göz atmak gerekir. -It is possible for multiple interfaces to use the same property name for different things. For example, on array-like objects, `length` refers to the number of elements in the collection. But an object interface describing a hiking route could use `length` to provide the length of the route in meters. It would not be possible for an object to conform to both these interfaces. +Birden çok arayüzün, farklı şeyler için aynı özellik adını kullanması mümkündür. Örneğin, dizi benzeri nesnelerde, `length` koleksiyondaki öğelerin miktarına atıfta bulunur. Ancak bir yürüyüş rotasını tanımlayan bir nesne arayüzü, `length`'i rotanın metre cinsinden uzunluğunu sağlamak için kullanabilir. Böyle bir objenin bu iki arayüze uyum sağlaması mümkün değildir. -An object trying to be a route and array-like (maybe to enumerate its waypoints) is somewhat far-fetched, and this kind of problem isn't that common in practice. For things like the iteration protocol, though, the language designers needed a type of property that _really_ doesn't conflict with any others. So in 2015, _((symbol))s_ were added to the language. +Bir nesnenin hem rota hem de dizilere benzer arayüze sahip olmaya çalışması (belki de noktalarını numaralandırmak için) biraz abartılıdır ve bu tür bir sorun pratikte o kadar yaygın değildir. Ancak iterasyon protokolü gibi şeyler için, dil tasarımcıları bu tür bir özellik türüne _gerçekten_ başka hiçbir şeyle çelişmeyen bir tür özellik türüne ihtiyaç duyuyordu. Bu nedenle, 2015 yılında _((semboller))_ dilin bir parçası olarak eklendi. {{index "Symbol function", [property, naming]}} -Most properties, including all those we have seen so far, are named with strings. But it is also possible to use symbols as property names. Symbols are values created with the `Symbol` function. Unlike strings, newly created symbols are unique—you cannot create the same symbol twice. +Şimdiye kadar gördüğümüz tüm özellikler de dahil olmak üzere, çoğu özellik dizelerle adlandırılır. Ancak sembollerin özellik adı olarak da kullanılması mümkündür. Semboller, `Symbol` fonksiyonuyla oluşturulan değerlerdir. Dizelerin aksine, yeni oluşturulan semboller benzersizdir—aynı sembolü iki kez oluşturamazsınız. ``` let sym = Symbol("name"); @@ -560,9 +553,9 @@ console.log(killerRabbit[sym]); // → 55 ``` -The string you pass to `Symbol` is included when you convert it to a string and can make it easier to recognize a symbol when, for example, showing it in the console. But it has no meaning beyond that—multiple symbols may have the same name. +`Symbol`'e verdiğiniz dize, onu bir dizeye dönüştürdüğünüzde dahil edilir ve bir sembolü, örneğin, konsolda gösterirken tanımayı daha kolay hale getirir. Ancak bundan başka bir anlamı yoktur—birden çok sembol aynı adı taşıyabilir. -Being both unique and usable as property names makes symbols suitable for defining interfaces that can peacefully live alongside other properties, no matter what their names are. +Hem benzersiz hem de özellik adları olarak kullanılabilir olmaları, sembollerin adları ne olursa olsun diğer özelliklerle bir arada barış içinde yaşayabilen arayüzleri tanımlamak için uygun olmalarını sağlar. ```{includeCode: "top_lines: 1"} const length = Symbol("length"); @@ -576,7 +569,7 @@ console.log([1, 2][length]); {{index [property, naming]}} -It is possible to include symbol properties in object expressions and classes by using ((square bracket))s around the property name. That causes the expression between the brackets to be evaluated to produce the property name, analogous to the square bracket property access notation. +Nesne ifadelerinde ve sınıflarda sembol özelliklerini kullanmak için ((köşeli parantez))lerle sararak özellik adını kullanmak mümkündür. Bu, köşeli parantez özelliği erişim notasyonuna benzer şekilde, parantezler arasındaki ifadenin değerlendirilerek özellik adının oluşturulmasını sağlar. ``` let myTrip = { @@ -589,19 +582,19 @@ console.log(myTrip[length], myTrip.length); // → 21500 2 ``` -## The iterator interface +## Yineleyici arayüzü {{index "iterable interface", "Symbol.iterator symbol", "for/of loop"}} -The object given to a `for`/`of` loop is expected to be _iterable_. This means it has a method named with the `Symbol.iterator` symbol (a symbol value defined by the language, stored as a property of the `Symbol` function). +`for/of` döngüsüne verilen nesnenin _yinelenilebilir_ olması beklenir. Bu, `Symbol.iterator` sembolü ile adlandırılmış bir metoda (dil tarafından tanımlanan bir sembol değeri, `Symbol` fonksiyonunun bir özelliği olarak saklanır) sahip olması anlamına gelir. {{index "iterator interface", "next method"}} -When called, that method should return an object that provides a second interface, _iterator_. This is the actual thing that iterates. It has a `next` method that returns the next result. That result should be an object with a `value` property that provides the next value, if there is one, and a `done` property, which should be true when there are no more results and false otherwise. +Çağrıldığında, bu yöntem, ikinci bir arayüz olan _yineleyiciyi_ sağlayan bir nesne döndürmelidir. Bu, gerçekten yineleyen şeydir. Bir sonraki sonucu döndüren `next` yöntemine sahiptir. Bu sonuç, bir sonraki değeri sağlayan bir `value` özelliği ve daha çok sonuçların olup olmadığını belirten `done` özelliğine sahip bir nesne olmalıdır. -Note that the `next`, `value`, and `done` property names are plain strings, not symbols. Only `Symbol.iterator`, which is likely to be added to a _lot_ of different objects, is an actual symbol. +`next`, `value`, ve `done` özellik adlarının düz dize olduğunu, semboller olmadığını unutmayın. Yalnızca _birçok_ farklı nesnelere eklenebilecek olan `Symbol.iterator` gerçek bir semboldür. -We can directly use this interface ourselves. +Bu arayüzü doğrudan kendimiz kullanabiliriz. ``` let okIterator = "OK"[Symbol.iterator](); @@ -615,7 +608,7 @@ console.log(okIterator.next()); {{index ["data structure", list], "linked list", collection}} -Let's implement an iterable data structure similar to the linked list from the exercise in [Chapter ?](data). We'll write the list as a class this time. +[Chapter ?](data) alıştırmasındaki linked list benzeri bir yinelenebilir veri yapısı uygulayalım. Bu sefer listeyi bir sınıf olarak yazacağız. ```{includeCode: true} class List { @@ -638,9 +631,9 @@ class List { } ``` -Note that `this`, in a static method, points at the constructor of the class, not an instance—there is no instance around when a static method is called. +Statik bir yöntemdeki `this`, bir örneğe değil, sınıfın constructor fonksiyonuna işaret eder—bir statik yöntem çağrıldığında bir örnek yoktur. -Iterating over a list should return all the list's elements from start to end. We'll write a separate class for the iterator. +Bir liste üzerinde yinelendiğinde, listenin tüm öğeleri baştan sona döndürülmelidir. Yineleyici için ayrı bir sınıf yazacağız. {{index "ListIterator class"}} @@ -661,9 +654,9 @@ class ListIterator { } ``` -The class tracks the progress of iterating through the list by updating its `list` property to move to the next list object whenever a value is returned and reports that it is done when that list is empty (null). +`ListIterator` sınıfı, bir değer döndürüldüğünde `list` özelliğini güncelleyerek listedeki öğelerin üzerinden yinelenebilme ilerlemesini takip eder ve bu liste boş olduğunda (null) işlemi tamamlandığını bildirir. -Let's set up the `List` class to be iterable. Throughout this book, I'll occasionally use after-the-fact prototype manipulation to add methods to classes so that the individual pieces of code remain small and self-contained. In a regular program, where there is no need to split the code into small pieces, you'd declare these methods directly in the class instead. +`List` sınıfını yinelemeli hale getirelim. Bu kitap boyunca, kod parçalarının küçük ve kendi kendine yeten kalmasını sağlamak için sınıflara yöntemler eklemek adına prototip manipülasyonunu zaman zaman kullanacağım. Normal bir programda, kodun küçük parçalara ayrılmasına gerek olmadığında, bu yöntemleri doğrudan sınıfta bildirirsiniz. ```{includeCode: true} List.prototype[Symbol.iterator] = function() { @@ -673,7 +666,7 @@ List.prototype[Symbol.iterator] = function() { {{index "for/of loop"}} -We can now loop over a list with `for`/`of`. +Artık bir liste üzerinde `for`/`of` ile döngü yapabiliriz. ``` let list = List.fromArray([1, 2, 3]); @@ -687,26 +680,26 @@ for (let element of list) { {{index spread}} -The `...` syntax in array notation and function calls similarly works with any iterable object. For example, you can use `[...value]` to create an array containing the elements in an arbitrary iterable object. +Array notasyonunda ve fonksiyon çağrılarında `...` herhangi bir yinelemeli nesneyle çalışır. Bu nedenle örneğin, `[...value]` kullanarak bir yinelenebilir nesnedeki öğeleri içeren bir dizi oluşturabilirsiniz. ``` console.log([..."PCI"]); // → ["P", "C", "I"] ``` -## Inheritance +## Kalıtım {{index inheritance, "linked list", "object-oriented programming", "LengthList class"}} -Imagine we need a list type much like the `List` class we saw before, but because we will be asking for its length all the time, we don't want it to have to scan through its `rest` every time. Instead, we want to store the length in every instance for efficient access. +`List` sınıfında gördüğümüz gibi, bir listeye benzer bir liste tipine ihtiyacımız olduğunu hayal edin, ancak sürekli olarak uzunluğunu isteyeceğimiz için, her seferinde `rest` özelliğini taramasını istemiyoruz ve bunun yerine her örnekte uzunluğu verimli bir erişim için saklamak istiyoruz. {{index overriding, prototype}} -JavaScript's prototype system makes it possible to create a _new_ class, much like the old class but with new definitions for some of its properties. The prototype for the new class derives from the old prototype but adds a new definition for, say, the `length` getter. +JavaScript'in prototip sistemi, bir sınıfa, eskiden olduğu gibi, ancak bazı özelliklerinin yeni tanımları ile bir _yeni_ sınıf oluşturmayı mümkün kılar. Yeni sınıfın prototipi, eski prototipten türetilir ancak, diyelim ki, `length` getter metodu için için yeni bir tanım ekler. -In object-oriented programming terms, this is called _((inheritance))_. The new class inherits properties and behavior from the old class. +Nesne tabanlı programlama terimleriyle, buna _((kalıtım))_ denir. Yeni sınıf, eski sınıftan özellikler ve davranış alır. -```{includeCode: "top_lines: 17"} +```{includeCode: "top_lines: 12"} class LengthList extends List { #length; @@ -724,23 +717,23 @@ console.log(LengthList.fromArray([1, 2, 3]).length); // → 3 ``` -The use of the word `extends` indicates that this class shouldn't be directly based on the default `Object` prototype but on some other class. This is called the _((superclass))_. The derived class is the _((subclass))_. +`extends` kelimesinin kullanımı, bu sınıfın doğrudan varsayılan `Object` prototipi yerine başka bir sınıfa dayandırılması gerektiğini gösterir. Buna _((üst sınıf))_ denir. Türetilmiş sınıf, _((alt sınıf))_ tır. -To initialize a `LengthList` instance, the constructor calls the constructor of its superclass through the `super` keyword. This is necessary because if this new object is to behave (roughly) like a `List`, it is going to need the instance properties that lists have. +Bir `LengthList` örneğini başlatmak için, constructor, `super` anahtar kelimesi aracılığıyla üst sınıfının constructor fonksiyonunu çağırır. Bu, bu yeni nesne bir `List` gibi davranacaksa, listelerin sahip olduğu örnek özelliklere ihtiyacı olacağı için gereklidir. -The constructor then stores the list's length in a private property. If we had written `this.length` there, the class's own getter would have been called, which doesn't work yet, since `#length` hasn't been filled in yet. We can use `super.something` to call methods and getters on the superclass's prototype, which is often useful. +Constructor fonksiyonu, ardından listenin uzunluğunu private bir özelliğe saklar. Orada `this.length` yazsaydık, sınıfın kendi getter metodu çağrılırdı, ki bu henüz çalışmaz, çünkü `#length` henüz doldurulmadı. `super.something` kullanarak üst sınıfın prototipi üzerinde metodlar ve getter metodları çağırmak sıkça kullanışlıdır. -Inheritance allows us to build slightly different data types from existing data types with relatively little work. It is a fundamental part of the object-oriented tradition, alongside encapsulation and polymorphism. But while the latter two are now generally regarded as wonderful ideas, inheritance is more controversial. +Kalıtım, var olan veri türlerinden kolayca biraz farklı veri türleri oluşturmamıza izin verir. Bu, kapsülleme ve polimorfizm ile birlikte nesne tabanlı geleneğin temel bir parçasıdır. Ancak, son ikisi şimdi genellikle harika fikirler olarak kabul edilirken, kalıtım daha tartışmalıdır. {{index complexity, reuse, "class hierarchy"}} -Whereas ((encapsulation)) and polymorphism can be used to _separate_ pieces of code from one another, reducing the tangledness of the overall program, ((inheritance)) fundamentally ties classes together, creating _more_ tangle. When inheriting from a class, you usually have to know more about how it works than when simply using it. Inheritance can be a useful tool to make some types of programs more succinct, but it shouldn't be the first tool you reach for, and you probably shouldn't actively go looking for opportunities to construct class hierarchies (family trees of classes). +((Kapsülleme)) ve polimorfizm kodları birbirinden _ayırmak_ için kullanılabilirken, ((kalıtım)) temel olarak sınıfları birbirine bağlar, ve birbirine daha bağlı kodlar yaratır. Bir sınıftan kalıtım alırken, sınıfı sadece kullanmak yerine genellikle nasıl çalıştığı hakkında daha fazla bilgi sahibi olmanız gerekir. Kalıtım, bazı türdeki programları daha kısa hale getirmek için kullanışlı bir araç olabilir, ancak bunu kullanmaya yeltendiğiniz ilk araç olmamalıdır ve daha çok sınıf hiyerarşileri (sınıf ağaçları) oluşturma fırsatlarını aktif olarak aramamalısınız. -## The instanceof operator +## instanceof operatörü {{index type, "instanceof operator", constructor, object}} -It is occasionally useful to know whether an object was derived from a specific class. For this, JavaScript provides a binary operator called `instanceof`. +Nesnenin belirli bir sınıftan türetildiğini bilmek zaman zaman faydalı olabilir. Bunun için JavaScript, `instanceof` adında bir ikili operatör sağlar. ``` console.log( @@ -756,44 +749,44 @@ console.log([1] instanceof Array); {{index inheritance}} -The operator will see through inherited types, so a `LengthList` is an instance of `List`. The operator can also be applied to standard constructors like `Array`. Almost every object is an instance of `Object`. +Operatör, kalıtılmış türleri görür, bu nedenle bir `LengthList`, `List` sınıfının bir örneğidir. Operatör ayrıca `Array` gibi standart constructor fonksiyonlarına da uygulanabilir. Hemen hemen her nesne `Object` sınıfının bir örneğidir. -## Summary +## Özet -Objects do more than just hold their own properties. They have prototypes, which are other objects. They'll act as if they have properties they don't have as long as their prototype has that property. Simple objects have `Object.prototype` as their prototype. +Nesneler, kendi özelliklerini tutmanın ötesinde daha fazlasını yaparlar. Başka nesneler olan prototipleri vardır. Prototiplerinde bulunduğu sürece, sahip olmadıkları bir özelliğe sahipmiş gibi davranırlar. Basit nesnelerin prototipi `Object.prototype`'dır. -Constructors, which are functions whose names usually start with a capital letter, can be used with the `new` operator to create new objects. The new object's prototype will be the object found in the `prototype` property of the constructor. You can make good use of this by putting the properties that all values of a given type share into their prototype. There's a `class` notation that provides a clear way to define a constructor and its prototype. +Genellikle büyük harfle başlayan adları olan constructor fonksiyonlar, `new` operatörünün kullanımıyla yeni nesneler oluşturmak için kullanılabilir. Yeni nesnenin prototipi, constructor fonksiyonunun `prototype` özelliğinde bulunan nesne olacaktır. Verilen bir veri türün paylaştığı tüm özellikleri prototip nesnesine koyarak bundan fayda sağlayabilirsiniz. Bir constructor fonksiyonu ve onun prototipini net bir şekilde tanımlamanın temiz bir yolunu sağlayan `class` notasyonunu kullanabilirsiniz. -You can define getters and setters to secretly call methods every time an object's property is accessed. Static methods are methods stored in a class's constructor rather than its prototype. +Herhangi bir nesnenin herhangi bir özelliği erişildiğinde gizlice çağırılacak getter ve setter metodları tanımlayabilirsiniz. Statik metodlar, bir sınıfın constructor fonksiyonunda saklanan metodlardır, prototipinde değil. -The `instanceof` operator can, given an object and a constructor, tell you whether that object is an instance of that constructor. +`instanceof` operatörüne bir nesne ve bir constructor fonksiyonu verildiğinde, nesnenin o constructor fonksiyonunun bir örneği olup olmadığını size söyler. -One useful thing to do with objects is to specify an interface for them and tell everybody that they are supposed to talk to your object only through that interface. The rest of the details that make up your object are now _encapsulated_, hidden behind the interface. You can use private properties to hide a part of your object from the outside world. +Nesnelerle yapılacak yararlı şeylerden biri, onlar için bir arayüz belirtmek ve herkesin nesnenizle sadece o arayüz aracılığıyla iletişim kurması gerektiğini söylemektir. Nesnenizi oluşturan diğer ayrıntılar artık _kapsülleme_ aracılığıyla gizlenmiş olur ve arayüzün arkasında saklanır. Nesnenizin bir kısmını dış dünyadan gizlemek için private özellikler kullanabilirsiniz. -More than one type may implement the same interface. Code written to use an interface automatically knows how to work with any number of different objects that provide the interface. This is called _polymorphism_. +Birden fazla tür aynı arayüzü implemente edebilir. Bir arayüzü kullanmak için yazılmış kod, arayüzü sağlayan herhangi bir sayıda farklı nesneyle nasıl çalışılacağını otomatik olarak bilir. Buna _polimorfizm_ denir. -When implementing multiple classes that differ in only some details, it can be helpful to write the new classes as _subclasses_ of an existing class, _inheriting_ part of its behavior. +Birbirinden yalnızca bazı ayrıntılarda farklılık gösteren birden çok sınıfı implemente ederken, yeni sınıfları var olan bir sınıfın alt sınıfları olarak yazmak, davranışlarının bir kısmını kalıtım yoluyla alarak kullanmanıza yardımcı olabilir. -## Exercises +## Egzersizler {{id exercise_vector}} -### A vector type +### Bir vektör türü {{index dimensions, "Vec class", coordinates, "vector (exercise)"}} -Write a ((class)) `Vec` that represents a vector in two-dimensional space. It takes `x` and `y` parameters (numbers), that it saves to properties of the same name. +İki boyutlu uzayda bir vektörü temsil eden bir `Vec` adında ((Sınıf)) yazın. Parametre olarak `x` ve `y` (sayılar) alır ve bunları aynı adla özelliklere kaydeder. {{index addition, subtraction}} -Give the `Vec` prototype two methods, `plus` and `minus`, that take another vector as a parameter and return a new vector that has the sum or difference of the two vectors' (`this` and the parameter) _x_ and _y_ values. +`Vec` prototipine `plus` ve `minus` adında başka bir vektörü parametre olarak alan ve iki vektörün (`this` ve parametre) _x_ ve _y_ değerlerinin toplamını veya farkını döndüren iki ((metod)) tanımlayın. -Add a ((getter)) property `length` to the prototype that computes the length of the vector—that is, the distance of the point (_x_, _y_) from the origin (0, 0). +Prototipe, vektörün uzunluğunu hesaplayan `length` adında ((getter)) özelliği ekleyin - yani, noktanın (x, y) başlangıç noktasından (0, 0) uzaklığını hesaplar. {{if interactive ```{test: no} -// Your code here. +// Kodunuz buraya. console.log(new Vec(1, 2).plus(new Vec(2, 3))); // → Vec{x: 3, y: 5} @@ -802,45 +795,46 @@ console.log(new Vec(1, 2).minus(new Vec(2, 3))); console.log(new Vec(3, 4).length); // → 5 ``` + if}} {{hint {{index "vector (exercise)"}} -Look back to the `Rabbit` class example if you're unsure how `class` declarations look. +Eğer `class` beyanlarının nasıl göründüğünden emin değilseniz `Rabbit` sınıfı örneğine geri dönün. {{index Pythagoras, "defineProperty function", "square root", "Math.sqrt function"}} -Adding a getter property to the constructor can be done by putting the word `get` before the method name. To compute the distance from (0, 0) to (x, y), you can use the Pythagorean theorem, which says that the square of the distance we are looking for is equal to the square of the x-coordinate plus the square of the y-coordinate. Thus, [√(x^2^ + y^2^)]{if html}[[$\sqrt{x^2 + y^2}$]{latex}]{if tex} is the number you want. `Math.sqrt` is the way you compute a square root in JavaScript and `x ** 2` can be used to square a number. +Constructor fonksiyonuna bir ((getter)) özelliği eklemek, metod adından önce `get` kelimesini koymak suretiyle yapılabilir. (0, 0) ile (x, y) arasındaki mesafeyi hesaplamak için, aradığımız mesafenin karesinin, x-koordinatının karesi artı y-koordinatının karesiyle eşit olduğunu söyleyen Pisagor teoremini kullanabilirsiniz. Böylece, [√(x^2^ + y^2^)]{if html}[[$\sqrt{x^2 + y^2}$]{latex}]{if tex} istediğiniz sayıdır. JavaScript'te karekökü hesaplamak için `Math.sqrt` kullanılır ve bir sayının karesini almak için `x ** 2` kullanılanılır. hint}} -### Groups +### Gruplar {{index "groups (exercise)", "Set class", "Group class", "set (data structure)"}} {{id groups}} -The standard JavaScript environment provides another data structure called `Set`. Like an instance of `Map`, a set holds a collection of values. Unlike `Map`, it does not associate other values with those—it just tracks which values are part of the set. A value can be part of a set only once—adding it again doesn't have any effect. +Standart JavaScript ortamı, `Set` adında başka bir veri yapısı sağlar. Bir `Map` örneği gibi, bir küme bir değerler koleksiyonunu tutar. `Map`'in aksine, bunlarla ilişkilendirilmiş başka değerlerle ilgilenmez - sadece hangi değerlerin kümenin bir parçası olduğunu izler. Bir değer sadece bir kez kümenin parçası olabilir - tekrar eklenmesinin herhangi bir etkisi olmaz. {{index "add method", "delete method", "has method"}} -Write a class called `Group` (since `Set` is already taken). Like `Set`, it has `add`, `delete`, and `has` methods. Its constructor creates an empty group, `add` adds a value to the group (but only if it isn't already a member), `delete` removes its argument from the group (if it was a member), and `has` returns a Boolean value indicating whether its argument is a member of the group. +`Set` ismi zaten alınmış olduğundan ötürü `Group` adında bir sınıf yazın. `Set` gibi, `add`, `delete` ve `has` metodlarına sahip olsun. Constructor fonksiyonu boş bir grup oluştursun, `add` bir değeri eğer zaten bir üye değilse gruba eklesin, `delete` argümanını eğer bir üyeyse grubun içinden kaldırsın ve `has` argümanının grubun bir üyesi olup olmadığını gösteren bir Boolean değeri döndürsün. {{index "=== operator", "indexOf method"}} -Use the `===` operator, or something equivalent such as `indexOf`, to determine whether two values are the same. +İki değerin aynı olup olmadığını belirlemek için `===` operatörünü veya `indexOf` gibi bir şeyi kullanın. {{index "static method"}} -Give the class a static `from` method that takes an iterable object as argument and creates a group that contains all the values produced by iterating over it. +Sınıfta, bir yinelenebilen bir nesneyi argüman olarak alan ve üzerinde yinelemeyi gerçekleştirerek üretilen tüm değerleri içeren bir grup oluşturan bir statik `from` ((metodu)) oluşturun. {{if interactive ```{test: no} class Group { - // Your code here. + // Kodunuz buraya. } let group = Group.from([10, 20]); @@ -860,38 +854,38 @@ if}} {{index "groups (exercise)", "Group class", "indexOf method", "includes method"}} -The easiest way to do this is to store an array of group members in an instance property. The `includes` or `indexOf` methods can be used to check whether a given value is in the array. +Bunu yapmanın en kolay yolu, bir örnek özelliğinde grup üyelerinin bir dizisini depolamaktır. `includes` veya `indexOf` metotları, verilen bir değerin dizide olup olmadığını kontrol etmek için kullanılabilir. {{index "push method"}} -Your class's ((constructor)) can set the member collection to an empty array. When `add` is called, it must check whether the given value is in the array or add it, for example with `push`, otherwise. +Sınıfınızın ((constructor)) fonksiyonu, üye koleksiyonunu boş bir diziye atayabilir. `add` çağrıldığında, verilen değerin dizide olup olmadığını kontrol etmeli ve `push` gibi bir fonksiyonla eklemelidir. {{index "filter method"}} -Deleting an element from an array, in `delete`, is less straightforward, but you can use `filter` to create a new array without the value. Don't forget to overwrite the property holding the members with the newly filtered version of the array. +Diziden bir öğe silmek, `delete` daha karmaşıktır, ancak o değerin içinde bulunmadığı yeni bir dizi oluşturmak için `filter` kullanabilirsiniz. Üyeleri tutan özelliği, dizinin bu yeniden filtrelenmiş versiyonuyla atamayı unutmayın. {{index "for/of loop", "iterable interface"}} -The `from` method can use a `for`/`of` loop to get the values out of the iterable object and call `add` to put them into a newly created group. +`from` metodu, yinelenebilir nesneden değerleri almak ve bunları yeni oluşturulan bir gruba `add` metodu aracılığıyla koymak için `for`/`of` döngüsünü kullanabilir. hint}} -### Iterable groups +### Yinelenebilir gruplar {{index "groups (exercise)", [interface, object], "iterator interface", "Group class"}} {{id group_iterator}} -Make the `Group` class from the previous exercise iterable. Refer to the section about the iterator interface earlier in the chapter if you aren't clear on the exact form of the interface anymore. +Önceki alıştırmadan `Group` sınıfını yinelenebilir yapın. Eğer arayüzün tam olarak nasıl olduğundan emin değilseniz, bölümdeki yineleme arayüzünün yapısı hakkındaki bölüme bakın. -If you used an array to represent the group's members, don't just return the iterator created by calling the `Symbol.iterator` method on the array. That would work, but it defeats the purpose of this exercise. +Grubun üyelerini temsil etmek için bir dizi kullandıysanız, dizideki direk `Symbol.iterator` metodunu çağırarak oluşturulan yineleyiciyi döndürmeyin. Bu çalışır, ancak bu alıştırmanın amacını boşa çıkarır. -It is okay if your iterator behaves strangely when the group is modified during iteration. +Grubun yinelenme sırasında grubun değiştirilmesi durumunda yineleyicinizin garip davranması sorun değil. {{if interactive ```{test: no} -// Your code here (and the code from the previous exercise) +// Kodunuz buraya.(önceki egzersizden olan kodunuz da dahil olmak üzere) for (let value of Group.from(["a", "b", "c"])) { console.log(value); @@ -907,8 +901,8 @@ if}} {{index "groups (exercise)", "Group class", "next method"}} -It is probably worthwhile to define a new class `GroupIterator`. Iterator instances should have a property that tracks the current position in the group. Every time `next` is called, it checks whether it is done and, if not, moves past the current value and returns it. +Muhtemelen yeni bir `GroupIterator` sınıfını tanımlamak faydalı olacaktır. `Iterator` örnekleri, grubun mevcut konumunu izleyen bir özelliğe sahip olmalıdır. `next` her çağırıldığında tamamlanıp tamamlanmadığını kontrol eder ve tamamlanmadıysa mevcut değerin ötesine geçip onu döndürür. -The `Group` class itself gets a method named by `Symbol.iterator` that, when called, returns a new instance of the iterator class for that group. +`Group` sınıfı `Symbol.iterator` tarafından adlandırılan bir ((metod)) alır ve çağrıldığında, o grup için yeni bir `Iterator` sınıfı örneğini döndürür. hint}} diff --git a/07_robot.md b/07_robot.md index 4ba48840..5d70a924 100644 --- a/07_robot.md +++ b/07_robot.md @@ -1,28 +1,28 @@ {{meta {load_files: ["code/chapter/07_robot.js", "code/animatevillage.js"], zip: html}}} -# Project: A Robot +# Proje: Robot -{{quote {author: "Edsger Dijkstra", title: "The Threats to Computing Science", chapter: true} +{{quote {author: "Edsger Dijkstra", title: "Bilgisayar Bilimine Yönelik Tehditler", chapter: true} -The question of whether Machines Can Think [...] is about as relevant as the question of whether Submarines Can Swim. +[...] Makinelerin Düşünüp Düşünemeyeceği sorusu [...] Denizaltıların Yüzüp Yüzemeyeceği sorusu kadar alakalıdır. quote}} {{index "artificial intelligence", "Dijkstra, Edsger"}} -{{figure {url: "img/chapter_picture_7.jpg", alt: "Illustration of a robot holding a stack of packages", chapter: framed}}} +{{figure {url: "img/chapter_picture_7.jpg", alt: "Bir paket yığınını tutan bir robotun illüstrasyonu", chapter: framed}}} {{index "project chapter", "reading code", "writing code"}} -In "project" chapters, I'll stop pummeling you with new theory for a brief moment, and instead we'll work through a program together. Theory is necessary to learn to program, but reading and understanding actual programs is just as important. +"Proje" bölümlerinde, sizi kısa bir an için yeni teorilerle sıkmayı bırakacağım ve bunun yerine birlikte bir program üzerinden çalışacağız. Programlama öğrenmek için teoriye ihtiyaç vardır, ancak gerçek programları okuyup anlamak da en az teori kadar önemlidir. -Our project in this chapter is to build an ((automaton)), a little program that performs a task in a ((virtual world)). Our automaton will be a mail-delivery ((robot)) picking up and dropping off parcels. +Bu bölümdeki projemiz, bir ((otomasyon)) inşa etmek olacak, bir ((sanal dünya))da görev gerçekleştiren küçük bir program. Otomasyon, paketleri teslim alıp bırakan bir posta teslim ((robotu)) olacak. ## Meadowfield {{index "roads array"}} -The village of ((Meadowfield)) isn't very big. It consists of 11 places with 14 roads between them. It can be described with this array of roads: +((Meadowfield)) köyü çok büyük değil. 11 yer ve aralarında 14 yoldan oluşur. Köyün yollarını tanımlayan bu yol dizisi ile tanımlanabilir: ```{includeCode: true} const roads = [ @@ -36,13 +36,13 @@ const roads = [ ]; ``` -{{figure {url: "img/village2x.png", alt: "Pixel art illustration of a small village with 11 locations, labeled with letters, and roads going being them"}}} +{{figure {url: "img/village2x.png", alt: "11 konumlu, harflerle etiketlenmiş ve yolların onlara ait olduğu küçük bir köyün piksel sanat illüstrasyonu"}}} -The network of roads in the village forms a _((graph))_. A graph is a collection of points (places in the village) with lines between them (roads). This graph will be the world that our robot moves through. +Köydeki yol ağı bir _((grafik))_ oluşturur. Bir grafik, noktaların (köydeki yerler) ve aralarındaki çizgilerin (yollar) olduğu bir koleksiyonudur. Bu grafik, robotumuzun hareket ettiği dünya olacak. {{index "roadGraph object"}} -The array of strings isn't very easy to work with. What we're interested in is the destinations that we can reach from a given place. Let's convert the list of roads to a data structure that, for each place, tells us what can be reached from there. +Dize dizisiyle çalışmak pek kolay değildir. İlgilendiğimiz şey, belirli bir yerden ulaşılabilen hedeflerdir. Hadi bu yol dizisini bize her yer için nereye gidilebileceğini söyleyen bir veri tipine çevirelim. ```{includeCode: true} function buildGraph(edges) { @@ -64,33 +64,35 @@ function buildGraph(edges) { const roadGraph = buildGraph(roads); ``` +Kenarlar dizisi verildiğinde, `buildGraph` her bir düğüm için bağlı düğümlerin bir dizisini depolayan bir map nesnesi oluşturur. + {{index "split method"}} -Given an array of edges, `buildGraph` creates a map object that, for each node, stores an array of connected nodes. It uses the `split` method to go from the road strings—which have the form `"Start-End"`)—to two-element arrays containing the start and end as separate strings. +`"Başlangıç-Bitiş"` şeklinde olan yol dizelerinden başlangıç ve bitişi ayrı dizeler olarak içeren iki öğeli dizilere gitmek için `split` metodunu kullanır. -## The task +## Görev -Our ((robot)) will be moving around the village. There are parcels in various places, each addressed to some other place. The robot picks up parcels when it comes across them and delivers them when it arrives at their destinations. +((Robotumuz)) köyde dolaşacak. Çeşitli yerlerde paketler var, her biri başka bir yere adreslenmiş. Robot, onlara geldiğinde paketleri alır ve varış noktalarına vardığında teslim eder. -The automaton must decide, at each point, where to go next. It has finished its task when all parcels have been delivered. +Her noktada, otomasyon bir sonraki hamlesinde nereye gideceğine karar vermelidir. Görevi, tüm paketler teslim edildiğinde tamamlanmış olur. {{index simulation, "virtual world"}} -To be able to simulate this process, we must define a virtual world that can describe it. This model tells us where the robot is and where the parcels are. When the robot has decided to move somewhere, we need to update the model to reflect the new situation. +Bu işlemi simüle edebilmek için, bunu açıklayabilen bir sanal dünya tanımlamamız gerekir. Bu model, robotun nerede olduğunu ve paketlerin nerede olduğunu bize söyler. Robot bir yere gitmeye karar verdiğinde, yeni durumu yansıtmak için modeli güncellememiz gerekir. {{index [state, in objects]}} -If you're thinking in terms of ((object-oriented programming)), your first impulse might be to start defining objects for the various elements in the world: a ((class)) for the robot, one for a parcel, maybe one for places. These could then hold properties that describe their current ((state)), such as the pile of parcels at a location, which we could change when updating the world. +Eğer ((nesne tabanlı programlama)) terimleriyle düşünüyorsanız, ilk düşünceniz dünyadaki çeşitli unsurlar için nesneleri tanımlamaya başlamak olabilir: bir robot için bir ((sınıf)), bir paket için bir tane, belki yerler için bir tane. Bunlar daha sonra dünyayı güncellerken değişen ((durumlarını)) açıklayan özellikler içerebilir. -This is wrong. At least, it usually is. The fact that something sounds like an object does not automatically mean that it should be an object in your program. Reflexively writing classes for every concept in your application tends to leave you with a collection of interconnected objects that each have their own internal, changing state. Such programs are often hard to understand and thus easy to break. +Bu yanlış. En azından genellikle öyledir. Bir şeyin bir nesne gibi görünmesi, otomatik olarak programınızdaki bir nesne olması gerektiği anlamına gelmez. Uygulamanızdaki her kavram için otomatik olarak sınıflar yazmak, genellikle birbirine bağlı ve kendi iç değişen durumlarına sahip nesneler koleksiyonuyla sonuçlanır. Bu tür programlar genellikle anlaşılması zor ve bu nedenle hata vermesi daha kolaydır. {{index [state, in objects]}} -Instead, let's condense the village's state down to the minimal set of values that define it. There's the robot's current location and the collection of undelivered parcels, each of which has a current location and a destination address. That's it. +Bunun yerine, köyün durumunu, onu tanımlayan minimum değerler kümesine indirgeyelim. Robotun şu anki konumu ve teslim edilmemiş paketlerin koleksiyonu var, her biri bir güncel konuma ve bir hedef adresine sahip. Bu kadar. {{index "VillageState class", "persistent data structure"}} -While we're at it, let's make it so that we don't _change_ this state when the robot moves but rather compute a _new_ state for the situation after the move. +Ayrıca köydeki durum değerini _değiştirmek_ yerine hareketten sonra durumu _yeni_ bir değer olarak tekrardan hesaplayalım. ```{includeCode: true} class VillageState { @@ -113,13 +115,13 @@ class VillageState { } ``` -The `move` method is where the action happens. It first checks whether there is a road going from the current place to the destination, and if not, it returns the old state since this is not a valid move. +`move` metodu aksiyonun olduğu yerdir. Öncelikle, mevcut yerden varış noktasına giden bir yol olup olmadığını kontrol eder ve yoksa, bu geçerli bir hamle değil olduğundan eski durumu döndürür. {{index "map method", "filter method"}} -Next, the method creates a new state with the destination as the robot's new place. It also needs to create a new set of parcels—parcels that the robot is carrying (that are at the robot's current place) need to be moved along to the new place. And parcels that are addressed to the new place need to be delivered—that is, they need to be removed from the set of undelivered parcels. The call to `map` takes care of the moving, and the call to `filter` does the delivering. +Sonra, robotun yeni yeri barındıracak şekilde yeni bir durum oluşturur. Ancak aynı zamanda yeni bir paket seti oluşturması gerekir — robotun taşıdığı paketler (robotun şu anki yerinde olanlar) yeni yere taşınmalıdır. Ve yeni yere adreslenen paketler teslim edilmelidir — yani, teslim edilmemiş paketler setinden kaldırılmalıdır. `map` çağrısı taşımayı, `filter` çağrısı ise teslimi yapar. -Parcel objects aren't changed when they are moved but re-created. The `move` method gives us a new village state but leaves the old one entirely intact. +Paket nesneleri taşındığında değiştirilmez, yeniden oluşturulur. `move` metodu bize yeni bir köy durumu verir ancak eski durumu tamamen bırakır. ``` let first = new VillageState( @@ -136,15 +138,15 @@ console.log(first.place); // → Post Office ``` -The move causes the parcel to be delivered, which is reflected in the next state. But the initial state still describes the situation where the robot is at the post office and the parcel is undelivered. +Hareket, paketin teslim edilmesine neden olur ve bu, sonraki durumda yansıtılır. Ancak, başlangıç durumu hala robotun postanede olduğu ve paketin teslim edilmediği durumu açıklar. -## Persistent data +## Kalıcı veriler {{index "persistent data structure", mutability, ["data structure", immutable]}} -Data structures that don't change are called _((immutable))_ or _persistent_. They behave a lot like strings and numbers in that they are who they are and stay that way, rather than containing different things at different times. +Veri yapıları, değişmeyen (_((değişmez))_ veya _kalıcı_) olarak adlandırılır. Onlar, oldukları gibi olan ve her zaman aynı kalan diziler ve sayılar gibi davranırlar, farklı zamanlarda farklı şeyler içermezler. -In JavaScript, just about everything _can_ be changed, so working with values that are supposed to be persistent requires some restraint. There is a function called `Object.freeze` that changes an object so that writing to its properties is ignored. You could use that to make sure your objects aren't changed, if you want to be careful. Freezing does require the computer to do some extra work, and having updates ignored is just about as likely to confuse someone as having them do the wrong thing. I usually prefer to just tell people that a given object shouldn't be messed with and hope they remember it. +JavaScript'te, neredeyse her şey değiştirilebilir olduğu için, kalıcı olması gereken değerlerle çalışmak bazı kısıtlamalar gerektirir. Nesnenin özelliklerine yazma özelliğini yok sayacak şekilde bir nesneyi değiştiren `Object.freeze` adında bir fonksiyon vardır. Dikkatli olmak isterseniz nesnelerinizin değişmediğinden emin olmak için bunu kullanabilirsiniz. Dondurma, bilgisayarın ekstra bir iş yapmasını gerektirir, ayrıca güncellemelerin yok sayılması yanlış bir şey yapmak kadar kafa karıştırabilir. Bu yüzden genellikle belirli bir nesnenin değiştirilmemesi gerektiğini söylemeyi tercih eder ve bunu hatırlamalarını umarım. ``` let object = Object.freeze({value: 5}); @@ -153,21 +155,23 @@ console.log(object.value); // → 5 ``` -Why am I going out of my way to not change objects when the language is obviously expecting me to? Because it helps me understand my programs. This is about complexity management again. When the objects in my system are fixed, stable things, I can consider operations on them in isolation—moving to Alice's house from a given start state always produces the same new state. When objects change over time, that adds a whole new dimension of complexity to this kind of reasoning. +Dil açıkça benden neden nesneleri değiştirmememi bekliyorken neden yolumdan sapıp değişmemeleri için ekstra efor sarf ediyorum ki? + +Çünkü bu, programlarımı anlamama yardımcı olur. Bu yine karmaşıklık yönetimi hakkında. Sistemimdeki nesneler sabit, istikrarlı şeyler olduğunda, bunlar üzerindeki işlemleri izole bir şekilde düşünebilirim - belirli bir başlangıç durumundan Alice'in evine gitmek her zaman aynı yeni durumu üretir. Nesnelerin zamanla değişmesi, bu tür bir akıl yürütme için tamamen yeni bir karmaşıklık boyutu ekler. -For a small system like the one we are building in this chapter, we could handle that bit of extra complexity. But the most important limit on what kind of systems we can build is how much we can understand. Anything that makes your code easier to understand makes it possible to build a more ambitious system. +Bu bölümde inşa ettiğimiz küçük bir sistem için, bu biraz ekstra karmaşıklığı idare edebiliriz. Ancak inşa edebileceğimiz sistemlerin ne tür olduğunu belirleyen en önemli sınırlama, ne kadar anlayabileceğimizdir. Kodunuzu anlamayı kolaylaştıran her şey, daha iddialı bir sistem inşa etmeyi mümkün kılar. -Unfortunately, although understanding a system built on persistent data structures is easier, _designing_ one, especially when your programming language isn't helping, can be a little harder. We'll look for opportunities to use persistent data structures in this book, but we'll also be using changeable ones. +Ne yazık ki, kalıcı veri yapıları üzerine inşa edilmiş bir sistemi anlamak daha kolay olsa da, özellikle programlama dili yardımcı olmadığında, bunu _tasarlamak_ biraz daha zor olabilir. Bu kitapta kalıcı veri yapılarını kullanma fırsatlarını arayacağız, ancak değiştirilebilir olanları da kullanacağız. -## Simulation +## Simülasyon {{index simulation, "virtual world"}} -A delivery ((robot)) looks at the world and decides in which direction it wants to move. As such, we could say that a robot is a function that takes a `VillageState` object and returns the name of a nearby place. +Bir teslimat ((robotu)), dünyaya bakar ve hangi yöne gitmek istediğine karar verir. Bu nedenle, bir robotun, bir `VillageState` nesnesini alıp yakınlardaki bir yerin adını döndüren bir fonksiyon olduğunu söyleyebiliriz. {{index "runRobot function"}} -Because we want robots to be able to remember things so they can make and execute plans, we also pass them their memory and allow them to return a new memory. Thus, the thing a robot returns is an object containing both the direction it wants to move in and a memory value that will be given back to it the next time it is called. +Robotların plan yapabilmeleri ve uygulayabilmeleri adına şeyleri hatırlayabilmelerini istiyor ve onlara belleklerini verip yeni bellek döndürmelerine izin veriyoruz. Dolayısıyla, robotun döndürdüğü şey, hem hareket etmek istediği yön hem de bir sonraki çağrıldığında geri verilecek bir bellek değeri içeren bir nesnedir. ```{includeCode: true} function runRobot(state, robot, memory) { @@ -184,13 +188,13 @@ function runRobot(state, robot, memory) { } ``` -Consider what a robot has to do to "solve" a given state. It must pick up all parcels by visiting every location that has a parcel and deliver them by visiting every location to which a parcel is addressed, but only after picking up the parcel. +Verilen bir durumu "çözmek" için bir robotun ne yapması gerektiğini düşünün. Tüm paketleri toplamalı, her bir paket alındıktan sonra paketin adreslendiği her yer ziyaret edilerek teslim edilmelidir. -What is the dumbest strategy that could possibly work? The robot could just walk in a random direction every turn. That means, with great likelihood, it will eventually run into all parcels and then also at some point reach the place where they should be delivered. +Çalışması mümkün olan en aptalca strateji nedir? Robot her turda rastgele bir yöne yürüyebilir. Bu, büyük olasılıkla, sonunda tüm paketlere rastlayacak ve sonra onları teslim etmeleri gereken yere ulaşacak demektir. {{index "randomPick function", "randomRobot function"}} -Here's what that could look like: +İşte o fikir bu şekilde görünebilir: ```{includeCode: true} function randomPick(array) { @@ -205,11 +209,11 @@ function randomRobot(state) { {{index "Math.random function", "Math.floor function", [array, "random element"]}} -Remember that `Math.random()` returns a number between zero and one—but always below one. Multiplying such a number by the length of an array and then applying `Math.floor` to it gives us a random index for the array. +`Math.random()`'ın her zaman sıfır ve bir arasında ancak birin altında bir sayı döndürdüğünü hatırlayın. Böyle bir bir sayıyı bir dizi uzunluğu ile çarpmak ve ardından `Math.floor` uygulamak bize dizi için rastgele bir index verir. -Since this robot does not need to remember anything, it ignores its second argument (remember that JavaScript functions can be called with extra arguments without ill effects) and omits the `memory` property in its returned object. +Bu robotun herhangi bir şeyi hatırlamasına gerek olmadığı için, ikinci argümanını görmezden gelir (JavaScript fonksiyonlarının ek argümanlarla çağrılması herhangi bir olumsuz etkiye neden olmadığını hatırlayın) ve döndürdüğü nesnesinde `memory` özelliğini dahil etmez. -To put this sophisticated robot to work, we'll first need a way to create a new state with some parcels. A static method (written here by directly adding a property to the constructor) is a good place to put that functionality. +Bu sofistike robota iş vermek için önce bazı paketlerle yeni bir durum oluşturmanın bir yoluna ihtiyacımız var. Bir statik metod (burada doğrudan bir özelliği constructor fonksiyonuna ekleyerek yazıldı) bu işlevselliği koymak için iyi bir yerdir. ```{includeCode: true} VillageState.random = function(parcelCount = 5) { @@ -228,9 +232,9 @@ VillageState.random = function(parcelCount = 5) { {{index "do loop"}} -We don't want any parcels to be sent from the same place that they are addressed to. For this reason, the `do` loop keeps picking new places when it gets one that's equal to the address. +Gönderildiği ve adreslendiği yerin aynı olduğu herhangi bir paket istemiyoruz. Bu nedenle, `do` döngüsü, adresle eşit olan bir yer aldığında yeni yerler almaya devam ediyor. -Let's start up a virtual world. +Hadi sanal bir dünya başlatalım. ```{test: no} runRobot(VillageState.random(), randomRobot); @@ -240,25 +244,25 @@ runRobot(VillageState.random(), randomRobot); // → Done in 63 turns ``` -It takes the robot a lot of turns to deliver the parcels because it isn't planning ahead very well. We'll address that soon. +Paketlerin teslim edilmesi için robota birçok tur gerekir çünkü ileriye dönük iyi plan yapmıyor. Bunun için yakında bir çözüm bulacağız. {{if interactive -For a more pleasant perspective on the simulation, you can use the `runRobotAnimation` function that's available in [this chapter's programming environment](https://eloquentjavascript.net/code/#7). This runs the simulation, but instead of outputting text, it shows you the robot moving around the village map. +Simülasyon üzerinde daha hoş bir bakış açısı için, [bu bölümün programlama ortamında](https://eloquentjavascript.net/code/#7) bulunan `runRobotAnimation` fonksiyonunu kullanabilirsiniz. Bu, simülasyonu çalıştırır, ancak metin çıktısı yerine robotun köy haritasında dolaştığını size gösterir. ```{test: no} runRobotAnimation(VillageState.random(), randomRobot); ``` -The way `runRobotAnimation` is implemented will remain a mystery for now, but after you've read the [later chapters](dom) of this book, which discuss JavaScript integration in web browsers, you'll be able to guess how it works. +`runRobotAnimation`'ın nasıl uygulandığı şimdilik bir sır olarak kalacak, ancak bu kitabın [daha sonraki bölümlerinde](dom), tarayıcılardaki JavaScript entegrasyonunu tartıştığı zaman, nasıl çalıştığını tahmin edebileceksiniz. if}} -## The mail truck's route +## Posta kamyonunun rotası {{index "mailRoute array"}} -We should be able to do a lot better than the random ((robot)). An easy improvement would be to take a hint from the way real-world mail delivery works. If we find a route that passes all places in the village, the robot could run that route twice, at which point it is guaranteed to be done. Here is one such route (starting from the post office): +Rastgele bir ((robot))tan çok daha iyi yapabilmeliyiz. Kolay bir iyileştirme, gerçek dünya posta teslimatının çalışma şeklinden bir ipucu almak olacaktır. Köydeki tüm yerlerden geçen bir rota bulursak, robot bu rotayı iki kez çalıştırabilir ve bu noktada işinin bitmiş olacağı garantilenir. İşte böyle bir rota (posta ofisinden başlayarak): ```{includeCode: true} const mailRoute = [ @@ -271,7 +275,7 @@ const mailRoute = [ {{index "routeRobot function"}} -To implement the route-following robot, we'll need to make use of robot memory. The robot keeps the rest of its route in its memory and drops the first element every turn. +Rota takip eden robotu uygulamak için, robot hafızasını kullanmamız gerekecek. Robot, her turda hafızasındaki geri kalan rotayı saklar ve her turda ilk öğeyi bırakır. ```{includeCode: true} function routeRobot(state, memory) { @@ -282,7 +286,7 @@ function routeRobot(state, memory) { } ``` -This robot is a lot faster already. It'll take a maximum of 26 turns (twice the 13-step route) but usually less. +Bu robot zaten şimdiden çok daha hızlı. En fazla 26 tur alacak (13 adımlık rotanın iki katı) ama genellikle daha az. {{if interactive @@ -292,25 +296,25 @@ runRobotAnimation(VillageState.random(), routeRobot, []); if}} -## Pathfinding +## Yol bulma -Still, I wouldn't really call blindly following a fixed route intelligent behavior. The ((robot)) could work more efficiently if it adjusted its behavior to the actual work that needs to be done. +Yine de, sabit bir rotayı körü körüne takip etmeyi gerçekten akıllı davranış olarak adlandırmayız. ((Robot)), gerçekten yapılması gereken işe göre davranışını ayarlayarak daha verimli çalışabilir. {{index pathfinding}} -To do that, it has to be able to deliberately move toward a given parcel or toward the location where a parcel has to be delivered. Doing that, even when the goal is more than one move away, will require some kind of route-finding function. +Bunu yapabilmek için, belirli bir parselin yanına veya bir parselin teslim edilmesi gereken yere bilerek hareket edebilmesi gerekir. Bunun yapılması, hedef bir hamleden fazla uzakta olsa bile, bir tür rota bulma fonksiyonu gerektirir. -The problem of finding a route through a ((graph)) is a typical _((search problem))_. We can tell whether a given solution (a route) is valid, but we can't directly compute the solution the way we could for 2 + 2. Instead, we have to keep creating potential solutions until we find one that works. +((Graf)) içinden bir rota bulma problemi tipik bir _((arama problemi))_'dir. Verilen bir çözümün (bir rota) geçerli bir çözüm olup olmadığını söyleyebiliriz, ancak 2 + 2 için olduğu gibi doğrudan çözümü hesaplayamayız. Bunun yerine, işe yarayan bir tane bulana kadar potansiyel çözümler oluşturmaya devam etmeliyiz. -The number of possible routes through a graph is infinite. But when searching for a route from _A_ to _B_, we are interested only in the ones that start at _A_. We also don't care about routes that visit the same place twice—those are definitely not the most efficient route anywhere. So that cuts down on the number of routes that the route finder has to consider. +Bir graf içinden mümkün olan rotaların sayısı sonsuzdur. Ancak _A_ noktasından _B_ noktasına bir rota ararken, sadece _A_ noktasından başlayanlarla ilgileniriz. Ayrıca aynı yeri iki kez ziyaret eden rotaları umursamıyoruz - bunlar kesinlikle herhangi bir yerdeki en verimli rota değil. Bu, rota bulucunun düşünmesi gereken rota sayısını azaltır. -In fact, since we are mostly interested in the _shortest_ route, we want to make sure we look at short routes before we look at longer ones. A good approach would be to "grow" routes from the starting point, exploring every reachable place that hasn't been visited yet until a route reaches the goal. That way, we'll only explore routes that are potentially interesting, and we know that the first route we find is the shortest route (or one of the shortest routes, if there are more than one). +Aslında, genellikle _en kısa_ rotaya ilgi duyarız. Bu nedenle, daha uzun olanlara bakmadan önce kısa rotalara bakmak istiyoruz. Bir rota hedefine ulaşana kadar rotaları başlangıç noktasından büyüterek her henüz ziyaret edilmemiş erişilebilir yeri keşfetmek bu durumda iyi bir yaklaşım olurdu. Bu şekilde, potansiyel olarak ilginç olan rotaları keşfetmiş oluruz ve ilk bulduğumuz rotanın en kısa veya birden fazlaysa en kısalarından biri olan rota olduğunu biliyoruz. {{index "findRoute function"}} {{id findRoute}} -Here is a function that does this: +İşte bunu yapan bir fonksiyon: ```{includeCode: true} function findRoute(graph, from, to) { @@ -327,17 +331,17 @@ function findRoute(graph, from, to) { } ``` -The exploring has to be done in the right order—the places that were reached first have to be explored first. We can't immediately explore a place as soon as we reach it because that would mean places reached _from there_ would also be explored immediately, and so on, even though there may be other, shorter paths that haven't yet been explored. +Keşfetme işlemi doğru sırayla yapılmalıdır - ilk önce ulaşılan yerlerin öncelikle keşfedilmesi gerekir. Bir yeri ona ulaştığımız anda hemen keşfetmemeliyiz çünkü bu, _oradan ulaşılan yerlerin_ de hemen keşfedilmesi anlamına gelir ve bu böyle devam eder ancak oysa ki daha önceden keşfedilmemiş diğer daha kısa yollar olabilir. -Therefore, the function keeps a _((work list))_. This is an array of places that should be explored next, along with the route that got us there. It starts with just the start position and an empty route. +Bu nedenle, fonksiyon bir _((çalışma listesi))_ tutar. Bu, keşfedilmesi gereken yerlerin ve bizi oraya götüren rotanın bir listesidir. Sadece başlangıç pozisyonu ve boş bir rota ile başlar. -The search then operates by taking the next item in the list and exploring that, which means it looks at all roads going from that place. If one of them is the goal, a finished route can be returned. Otherwise, if we haven't looked at this place before, a new item is added to the list. If we have looked at it before, since we are looking at short routes first, we've found either a longer route to that place or one precisely as long as the existing one, and we don't need to explore it. +Arama, daha sonraki öğeyi listeye alarak ve bunu keşfeterek çalışır, yani o yerden giden tüm yollar incelenir. Eğer bunlardan biri hedefse, tamamlanmış bir rota döndürülebilir. Aksi takdirde, bu yeri daha önce görmediysek, yeni bir öğe listeye eklenir. Daha önce gördüysek, kısa rotalara önce baktığımız için, o yere daha uzun bir rota veya mevcut rotanın tam olarak uzunluğunda bir rota bulduk ve bunu keşfetmemize gerek yoktur. -You can visualize this as a web of known routes crawling out from the start location, growing evenly on all sides (but never tangling back into itself). As soon as the first thread reaches the goal location, that thread is traced back to the start, giving us our route. +Bunu, bilinen rotaların başlangıç konumundan dışarıya doğru her tarafından eşit büyüyen ve kendisine geri dönmeyecek bir şekilde yayılan bir ağ gibi görsel olarak hayal edebilirsiniz. İlk ipliğin hedef konumunu bulduğu anda, bu iplik başlangıç noktasına geri izlenir, böylece rotamızı alırız. {{index "connected graph"}} -Our code doesn't handle the situation where there are no more work items on the work list because we know that our graph is _connected_, meaning that every location can be reached from all other locations. We'll always be able to find a route between two points, and the search can't fail. +Kodumuz, iş listesinde artık iş öğeleri olmadığında nasıl başa çıkacağını ele almaz çünkü grafımızın _bağlı_ olduğunu biliyoruz, yani her konuma diğer tüm konumlardan ulaşılabilir. İki nokta arasında bir rota bulabileceğiz ve arama başarısız olamaz. ```{includeCode: true} function goalOrientedRobot({place, parcels}, route) { @@ -355,11 +359,11 @@ function goalOrientedRobot({place, parcels}, route) { {{index "goalOrientedRobot function"}} -This robot uses its memory value as a list of directions to move in, just like the route-following robot. Whenever that list is empty, it has to figure out what to do next. It takes the first undelivered parcel in the set and, if that parcel hasn't been picked up yet, plots a route toward it. If the parcel _has_ been picked up, it still needs to be delivered, so the robot creates a route toward the delivery address instead. +Bu robot hafıza değerini gideceği rotayı takip etmek amacıyla kullanır, aynı rota takıp eden robot gibi. Liste boş olduğunda, ne yapacağını bulmak zorundadır. Kümesindeki ilk teslim edilmemiş parseli alır ve bu parsel henüz alınmadıysa, ona doğru bir rota çizer. Pakelet _alınmışsa_, hala teslim edilmesi gerektiğinden, robot teslim adresine doğru bir rota oluşturur. {{if interactive -Let's see how it does. +Hadi bunu nasıl yaptığını görelim. ```{test: no, startCode: true} runRobotAnimation(VillageState.random(), @@ -368,53 +372,54 @@ runRobotAnimation(VillageState.random(), if}} -This robot usually finishes the task of delivering 5 parcels in about 16 turns. That's slightly better than `routeRobot` but still definitely not optimal. We'll continue refining it in the exercises. +Bu robot, genellikle 5 paketi teslim etme görevini yaklaşık 16 turda tamamlar. Bu, `routeRobottan` biraz daha iyidir, ancak kesinlikle olabilecek en iyi durum değil. -## Exercises +## Egzersizler -### Measuring a robot +### Bir robotun ölçülmesi {{index "measuring a robot (exercise)", testing, automation, "compareRobots function"}} -It's hard to objectively compare ((robot))s by just letting them solve a few scenarios. Maybe one robot just happened to get easier tasks or the kind of tasks that it is good at, whereas the other didn't. +((Robot))ları sadece birkaç senaryoyu çözmelerine izin vererek nesnel bir şekilde karşılaştırmak zordur. Belki de bir robot tesadüfen daha kolay görevler aldı ve diğeri alamadı ya da belki de bir robot tesadüfen daha iyi olduğu türde görevler alırken diğeri alamadı. -Write a function `compareRobots` that takes two robots (and their starting memory). It generates 100 tasks and lets each of the robots solve each of these tasks. When done, it outputs the average number of steps each robot took per task. +`compareRobots` adında iki ((robot)) (ve başlangıç hafızaları) alan bir fonksiyon yazın. Bu, 100 görev oluşturmalı ve her bir robotun bu görevleri çözmesine izin vermelidir. Bittiğinde, her robotun görev başına ortalama adım sayısını çıkarmalıdır. -For the sake of fairness, make sure you give each task to both robots, rather than generating different tasks per robot. +Adil olmak için, her robotu farklı görevlere değil, aynı görevlere yönlendirdiğinizden emin olmalısınız. {{if interactive ```{test: no} function compareRobots(robot1, memory1, robot2, memory2) { - // Your code here + // Kodunuz buraya. } compareRobots(routeRobot, [], goalOrientedRobot, []); ``` + if}} {{hint {{index "measuring a robot (exercise)", "runRobot function"}} -You'll have to write a variant of the `runRobot` function that, instead of logging the events to the console, returns the number of steps the robot took to complete the task. +Her iki robot için de görev veren `runRobot` fonksiyonunun bir varyantını yazmalısınız. Bu fonksiyon, konsola olayları kaydetmek yerine, robotun görevi tamamlamak için attığı adım sayısını döndürmelidir. -Your measurement function can then, in a loop, generate new states and count the steps each of the robots takes. When it has generated enough measurements, it can use `console.log` to output the average for each robot, which is the total number of steps taken divided by the number of measurements. +Ölçüm fonksiyonunuz ardından, bir döngü içinde yeni durumlar oluşturmalı ve her bir robotun attığı adımları saymalıdır. Yeterince ölçüm yapıldığında, her robot için ortalama adım sayısı olan toplam adım sayısı bölü ölçümlerin sayısının sonucunu `console.log` kullanarak çıkarmalıdır. hint}} -### Robot efficiency +### Robot verimliliği {{index "robot efficiency (exercise)"}} -Can you write a robot that finishes the delivery task faster than `goalOrientedRobot`? If you observe that robot's behavior, what obviously stupid things does it do? How could those be improved? +`goalOrientedRobottan` daha hızlı teslimat görevini tamamlayan bir robot yazabilir misiniz? O robotun davranışını gözlemlediğinizde, açıkça aptalca şeyler nelerdir? Onları nasıl iyileştirebilirsiniz? -If you solved the previous exercise, you might want to use your `compareRobots` function to verify whether you improved the robot. +Önceki egzersizi çözdüyseniz, robotu iyileştirip iyileştirmediğinizi doğrulamak için `compareRobots` fonksiyonunuzu kullanmak isteyebilirsiniz. {{if interactive ```{test: no} -// Your code here +// Kodunuz buraya. runRobotAnimation(VillageState.random(), yourRobot, memory); ``` @@ -425,35 +430,37 @@ if}} {{index "robot efficiency (exercise)"}} -The main limitation of `goalOrientedRobot` is that it considers only one parcel at a time. It will often walk back and forth across the village because the parcel it happens to be looking at happens to be at the other side of the map, even if there are others much closer. +`goalOrientedRobot`'un ana kısıtlaması, aynı anda yalnızca bir parseli düşünmesidir. Çoğu zaman, üzerinde durduğu parselin teslim noktasının haritanın diğer tarafında olması nedeniyle köyde ileri geri yürür ancak oysa ki o bulunduğu anda teslim edebileceği daha yakın noktalarda bulunan noktalar vardır. -One possible solution would be to compute routes for all packages and then take the shortest one. Even better results can be obtained, if there are multiple shortest routes, by preferring the ones that go to pick up a package instead of delivering a package. +Bir çözüm, tüm paketler için rotaları hesaplamak ve ardından en kısa olanı almak olabilir. Birden fazla en kısa rota varsa, bir paket almak yerine bir paketi teslim etmeyi tercih edenleri tercih ederek daha iyi sonuçlar elde edilebilir. hint}} -### Persistent group +### Kalıcı grup {{index "persistent group (exercise)", "persistent data structure", "Set class", "set (data structure)", "Group class", "PGroup class"}} -Most data structures provided in a standard JavaScript environment aren't very well suited for persistent use. Arrays have `slice` and `concat` methods, which allow us to easily create new arrays without damaging the old one. But `Set`, for example, has no methods for creating a new set with an item added or removed. +Standart bir JavaScript ortamında sağlanan çoğu veri yapısı, kalıcı kullanım için çok uygun değildir. Diziler, eskiyi bozmadan yeni diziler oluşturmamızı sağlayan `slice` ve `concat` metodlarına sahiptir. Ancak, `Set` örneğin, bir öğe eklenmiş veya kaldırılmış yeni bir set oluşturmak için yöntemlere sahip değildir. + +[? Bölüm](object#groups) içinden alınan `Group` sınıfına benzer yeni bir sınıf olan ve bir set değerler depolayan `PGroup` adında bir sınıf yazın. `Group` gibi, `add`, `delete` ve `has` metodlarına sahiptir. -Write a new class `PGroup`, similar to the `Group` class from [Chapter ?](object#groups), which stores a set of values. Like `Group`, it has `add`, `delete`, and `has` methods. Its `add` method, however, returns a _new_ `PGroup` instance with the given member added and leaves the old one unchanged. Similarly, `delete` creates a new instance without a given member. +Ancak, `add` metodunun, verilen üye eklenmiş bir yeni `PGroup` örneği döndürmesi ve eskiyi değiştirmemesi gerekir. Benzer şekilde, `delete` belirli bir üye olmadan yeni bir örnek oluşturur. -The class should work for values of any type, not just strings. It does _not_ have to be efficient when used with large numbers of values. +Sınıf, sadece dizeler değil, herhangi bir türün değerleri için çalışmalıdır. Büyük miktarda değerle kullanıldığında etkin olmak zorunda _değildir_. {{index [interface, object]}} -The ((constructor)) shouldn't be part of the class's interface (though you'll definitely want to use it internally). Instead, there is an empty instance, `PGroup.empty`, that can be used as a starting value. +((Constructor)), sınıfın arabirimine dahil edilmemelidir (ancak içsel olarak kullanmak isteyeceksinizdir). Bunun yerine, kullanılabilecek bir başlangıç değeri olan `PGroup.empty` adında bir boş örnek vardır. {{index singleton}} -Why do you need only one `PGroup.empty` value, rather than having a function that creates a new, empty map every time? +Neden her seferinde yeni, boş bir harita oluşturan bir işlev yerine yalnızca bir `PGroup.empty` değerine ihtiyacınız var? {{if interactive ```{test: no} class PGroup { - // Your code here + // Kodunuz buraya. } let a = PGroup.empty.add("a"); @@ -474,18 +481,18 @@ if}} {{index "persistent map (exercise)", "Set class", [array, creation], "PGroup class"}} -The most convenient way to represent the set of member values is still as an array since arrays are easy to copy. +Üye değerlerinin kümesini temsil etmenin en uygun yolu kopyalaması kolay olduğundan ötürü hala dizilerdir. {{index "concat method", "filter method"}} -When a value is added to the group, you can create a new group with a copy of the original array that has the value added (for example, using `concat`). When a value is deleted, you filter it from the array. +Bir değer grubuna eklendiğinde, eklenen değere sahip orijinal dizinin bir kopyası ile yeni bir grup oluşturabilirsiniz (örneğin, `concat` kullanarak). Bir değer silindiğinde, onu diziden filtreleyerek çıkarabilirsiniz. -The class's ((constructor)) can take such an array as argument and store it as the instance's (only) property. This array is never updated. +Sınıfın ((constructor)) fonksiyonu böyle bir diziyi (tek) özelliği olarak alabilir ve bunu örneğin özelliği olarak depolayabilir. Bu dizi asla güncellenmez. {{index "static property"}} -To add the `empty` property to the constructor, you can declare it as a static property. +`empty` özelliğini constructor fonksiyonuna eklemek adına bunu bir statik özellik olarak bildirebilirsiniz. -You need only one `empty` instance because all empty groups are the same and instances of the class don't change. You can create many different groups from that single empty group without affecting it. +Sadece bir `empty` örneğine ihtiyacınız vardır çünkü tüm boş gruplar aynıdır ve sınıfın örnekleri değişmez. Bu tek boş grubu etkilemeden kullanarak birçok farklı grup oluşturabilirsiniz. hint}} diff --git a/08_error.md b/08_error.md index dfb889b1..924ab623 100644 --- a/08_error.md +++ b/08_error.md @@ -1,46 +1,46 @@ {{meta {load_files: ["code/chapter/08_error.js"]}}} -# Bugs and Errors +# Sorun ve hatalar -{{quote {author: "Brian Kernighan and P.J. Plauger", title: "The Elements of Programming Style", chapter: true} +{{quote {author: "Brian Kernighan and P.J. Plauger", title: "Programlama Stilinin Unsurları", chapter: true} -Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. +Hata ayıklama, kodu yazmaktan iki kat daha zordur. Bu nedenle, mümkün olduğunca zeki bir şekilde kod yazarsanız, onu ayıklamak için yeterince zeki olmayacaksınız. quote}} -{{figure {url: "img/chapter_picture_8.jpg", alt: "Illustration showing various insects and a centipede", chapter: framed}}} +{{figure {url: "img/chapter_picture_8.jpg", alt: "Çeşitli böcekleri ve bir kırkayağı gösteren illüstrasyon", chapter: framed}}} {{index "Kernighan, Brian", "Plauger, P.J.", debugging, "error handling"}} -Flaws in computer programs are usually called _((bug))s_. It makes programmers feel good to imagine them as little things that just happen to crawl into our work. In reality, of course, we put them there ourselves. +Bilgisayar programlarındaki hatalar genellikle _((hata))_ olarak adlandırılır. Onları işimizin içine sürünen küçük şeyler olarak hayal etmek programcıların kendilerini iyi hissetmelerini sağlar. Gerçekte ise, tabii ki, onları kendimiz koyarız. -If a program is crystallized thought, we can roughly categorize bugs into those caused by the thoughts being confused and those caused by mistakes introduced while converting a thought to code. The former type is generally harder to diagnose and fix than the latter. +Bir program kristalleşmiş düşüncelerse, hataları düşüncelerin karıştırılması nedeniyle veya bir düşüncenin kod haline getirilirken yapılan hatalar nedeniyle oluşan hatalar olarak kabaca sınıflandırabilirsiniz. İlk tür genellikle ikincisinden daha zor teşhis edilir ve düzeltilir. -## Language +## Dil {{index parsing, analysis}} -Many mistakes could be pointed out to us automatically by the computer, if it knew enough about what we're trying to do. But here JavaScript's looseness is a hindrance. Its concept of bindings and properties is vague enough that it will rarely catch ((typo))s before actually running the program. Even then, it allows you to do some clearly nonsensical things without complaint, such as computing `true * "monkey"`. +Bilgisayar, ne yapmaya çalıştığımız hakkında yeterince bilgiye sahip olsaydı, birçok hatayı otomatik olarak bize gösterebilirdi. Ancak burada JavaScript'in gevşekliği bir engeldir. Bağlantılarının ve özelliklerinin kavramlarının belirsizliği, programı çalıştırmadan önce nadiren ((yazım hatalarını)) yakalar. Ve hatta öyle olsa bile, size `true * "monkey"` gibi açıkça mantıksız şeyleri yapmanıza izin verir, şikayet etmez. {{index [syntax, error], [property, access]}} -There are some things that JavaScript does complain about. Writing a program that does not follow the language's ((grammar)) will immediately make the computer complain. Other things, such as calling something that's not a function or looking up a property on an ((undefined)) value, will cause an error to be reported when the program tries to perform the action. +JavaScript'in şikayet ettiği bazı şeyler vardır. Dilin ((sözdizimi))ni izlemeyen bir program yazmak bilgisayarın hemen şikayet etmesini sağlar. Başka şeylere olarak örneğin fonksiyon olmayan bir şeyi çağırmak veya bir ((undefined)) değerinde özellik aramak, program harekete geçtiğinde bir hataya neden olur. {{index NaN, error}} -Often, however, your nonsense computation will merely produce `NaN` (not a number) or an undefined value, while the program happily continues, convinced that it's doing something meaningful. The mistake will manifest itself only later, after the bogus value has traveled through several functions. It might not trigger an error at all but silently cause the program's output to be wrong. Finding the source of such problems can be difficult. +Ancak genellikle, bu saçma hesaplama sadece `NaN` (sayı değil) veya tanımsız bir değer üretirken, program yaptığı şeyin anlamlı olduğuna ikna olmuş ve mutlu bir halde devam eder. Hata, sadece sahte değer birkaç fonksiyondan geçtikten sonra kendini gösterir. Hata hiç tetiklenmeyebilir, ancak sessizce programın çıktısını yanlış yapabilir. Bu tür sorunların kaynağını bulmak zor olabilir. -The process of finding mistakes—bugs—in programs is called _((debugging))_. +Programlardaki hataları bulma sürecine ((hata ayıklama)) denir. -## Strict mode +## Katı mod {{index "strict mode", [syntax, error], function}} {{indexsee "use strict", "strict mode"}} -JavaScript can be made a _little_ stricter by enabling _strict mode_. This can done by putting the string `"use strict"` at the top of a file or a function body. Here's an example: +JavaScript, _katı modu_ etkinleştirilerek _biraz_ daha katı hale getirilebilir. Bunun için dosyanın veya fonksiyon gövdesinin üstüne `"use strict"` dizesini koymak yeterlidir. İşte bir örnek: -```{test: "error \"ReferenceError: counter is not defined\""} +```{test: "error "ReferenceError: counter is not defined""} function canYouSpotTheProblem() { "use strict"; for (counter = 0; counter < 10; counter++) { @@ -54,17 +54,17 @@ canYouSpotTheProblem(); {{index ECMAScript, compatibility}} -Code inside classes and modules (which we will discuss in [Chapter ?](modules)) is automatically strict. The old non-strict behavior still exists only because some old code might depend on it, and the language designers work hard to avoid breaking any existing programs. +Code inside classes and modules (which we will discuss in [Chapter ?](modules)) is automatically strict. The old nonstrict behavior still exists only because some old code might depend on it, and the language designers work hard to avoid breaking any existing programs. {{index "let keyword", [binding, global]}} -Normally, when you forget to put `let` in front of your binding, as with `counter` in the example, JavaScript quietly creates a global binding and uses that. In strict mode, an ((error)) is reported instead. This is very helpful. It should be noted, though, that this doesn't work when the binding in question already exists somewhere in scope. In that case, the loop will still quietly overwrite the value of the binding. +Normalde, örnekte olduğu gibi bağlantının önüne `let` koymayı unuttuğunuzda, JavaScript sessizce genel bir bağlantı oluşturur ve onu kullanır. Katı modda ise, bir ((hata)) bildirilir. Bu çok yardımcı olur. Bununla birlikte, söz konusu bağlantı zaten kapsamın başka bir yerinde varsa, bu durumda döngü hala sessizce bağlantının değerini üzerine yazar. {{index "this binding", "global object", undefined, "strict mode"}} -Another change in strict mode is that the `this` binding holds the value `undefined` in functions that are not called as ((method))s. When making such a call outside of strict mode, `this` refers to the global scope object, which is an object whose properties are the global bindings. So if you accidentally call a method or constructor incorrectly in strict mode, JavaScript will produce an error as soon as it tries to read something from `this`, rather than happily writing to the global scope. +Katı moddaki başka bir değişiklik, `this` bağlantısının, ((metod)) olarak çağrılmayan fonksiyonlarda `undefined` değerini taşımasıdır. Bu tür bir çağrıyı katı mod dışında yaparken, `this` küresel kapsam nesnesine atıfta bulunur, bu da özellikleri küresel bağlantılardan oluşan bir nesnedir. Dolayısıyla, katı modda bir yöntemi veya `constructor` fonksiyonunu yanlışlıkla yanlış bir şekilde çağırırsanız, JavaScript, küresel kapsama değerler yazmak yerine `this` bağlantısından bir şey okumaya çalışıldığında hemen bir hata üretir. -For example, consider the following code, which calls a ((constructor)) function without the `new` keyword so that its `this` will _not_ refer to a newly constructed object: +Örneğin aşağıdaki kodu düşünün, `new` anahtar kelimesi olmadan ((constructor)) fonksiyonunu çağırır, böylece `this` bağlantısı _yeni_ oluşturulan bir nesneye atanmaz: ``` function Person(name) { this.name = name; } @@ -75,34 +75,34 @@ console.log(name); {{index error}} -The bogus call to `Person` succeeded but returned an undefined value and created the global binding `name`. In strict mode, the result is different. +Bu nedenle, `Person` constructor fonksiyonuna yapılan yanlış çağrı başarılı oldu, ancak tanımsız bir değer döndü ve `name` adında bir küresel bir bağlantı oluşturdu. Katı modda, sonuç farklıdır. -```{test: "error \"TypeError: Cannot set properties of undefined (setting 'name')\""} +```{test: "error "TypeError: Cannot set properties of undefined (setting 'name')""} "use strict"; function Person(name) { this.name = name; } let ferdinand = Person("Ferdinand"); // forgot new // → TypeError: Cannot set property 'name' of undefined ``` -We are immediately told that something is wrong. This is helpful. +Hemen bir şeyin yanlış olduğu bize bildirilir. Bu yardımcı olur. -Fortunately, constructors created with the `class` notation will always complain if they are called without `new`, making this less of a problem even in non-strict mode. +Neyse ki, `class` notasyonuyla oluşturulan constructor fonksiyonları `new` olmadan çağrıldığında her zaman bir şikayet bildirir, bu da bu sorunun katı mod dışında olmamıza rağmen engellenmesini sağlar. {{index parameter, [binding, naming], "with statement"}} -Strict mode does a few more things. It disallows giving a function multiple parameters with the same name and removes certain problematic language features entirely (such as the `with` statement, which is so wrong it is not further discussed in this book). +Katı mod birkaç başka şey daha yapar. Bir fonksiyona aynı isimli birden fazla parametre vermenizi engeller ve bazı sorunlu dil özelliklerini tamamen kaldırır (örneğin, çok yanlış olan ve bu kitapta daha fazla tartışılmayacak olan `with` ifadesi gibi). {{index debugging}} -In short, putting `"use strict"` at the top of your program rarely hurts and might help you spot a problem. +Kısacası, programınızın başına `"use strict"` koymak nadiren zarar verir ve bir sorunu fark etmenize yardımcı olabilir. -## Types +## Tipler -Some languages want to know the types of all your bindings and expressions before even running a program. They will tell you right away when a type is used in an inconsistent way. JavaScript considers types only when actually running the program, and even there often tries to implicitly convert values to the type it expects, so it's not much help. +Bazı diller, bir programı çalıştırmadan önce tüm bağlantılarınızın ve ifadelerinizin türlerini bilmek ister. Bir türün tutarsız bir şekilde kullanıldığı durumlar hemen belirtilir. JavaScript, türleri sadece programı çalıştırırken dikkate alır ve hatta orada bile sıklıkla değerleri beklediği türe implicit bir şekilde dönüştürmeye çalışır, bu yüzden çok yardımcı olmaz. -Still, types provide a useful framework for talking about programs. A lot of mistakes come from being confused about the kind of value that goes into or comes out of a function. If you have that information written down, you're less likely to get confused. +Yine de türler programlar hakkında konuşmak adına kullanışlı bir çerçeve sağlar. Birçok hata, bir fonksiyona giren veya çıkan değer türü hakkında kafanız karıştığında gelir. Bu bilgiyi yazılı olarak belirtirseniz, kafanız karışma olasılığınız daha az olur. -You could add a comment like the following before the `findRoute` function from the previous chapter to describe its type: +Önceki bölümdeki `findRoute` fonksiyonunun türünü açıklamak için, aşağıdaki gibi bir yorum ekleyebilirsiniz: ``` // (graph: Object, from: string, to: string) => string[] @@ -111,31 +111,31 @@ function findRoute(graph, from, to) { } ``` -There are a number of different conventions for annotating JavaScript programs with types. +JavaScript programlarını türlerle işaretlemenin birkaç farklı üzerine anlaşılmış ve sıklıkla kullanılan yolları vardır. -One thing about types is that they need to introduce their own complexity to be able to describe enough code to be useful. What do you think would be the type of the `randomPick` function that returns a random element from an array? You'd need to introduce a _((type variable))_, _T_, which can stand in for any type, so that you can give `randomPick` a type like `(T[]) → T` (function from an array of *T*s to a *T*). +Türler hakkında bir şey, yararlı olacak kadar yeterli kodu açıklayabilmeleri için kendi karmaşıklıklarını tanıtmaları gerektiğidir. Bir diziden rastgele bir öğe döndüren `randomPick` fonksiyonunun türü sizce ne olmalıdır? Bunun için `randomPick` fonksiyonuna herhangi bir tür değeri alabilecek bir ((tür değişkeni)) `T` tanıtmalısınız ki `randomPick` fonksiyonuna `(T[]) → T` (_T_ türünde bir dizi alan ve bir _T_ türünde veri döndüren fonksiyon) gibi bir tür verebilin. {{index "type checking", TypeScript}} {{id typing}} -When the types of a program are known, it is possible for the computer to _check_ them for you, pointing out mistakes before the program is run. There are several JavaScript dialects that add types to the language and check them. The most popular one is called [TypeScript](https://www.typescriptlang.org/). If you are interested in adding more rigor to your programs, I recommend you give it a try. +Bir programın türleri bilindiğinde, bilgisayarın bunları kontrol edebilir ve program çalıştırılmadan önce hataları belirtebilir. Dilin türler ekleyen ve bunları kontrol eden birkaç JavaScript lehçeleri vardır. En popüler olanı [TypeScript](https://www.typescriptlang.org/) olarak adlandırılır. Programlarınıza daha fazla titizlik eklemek istiyorsanız, denemenizi öneririm. -In this book, we'll continue using raw, dangerous, untyped JavaScript code. +Bu kitapta, ham, tehlikeli, türsüz JavaScript kodunu kullanmaya devam edeceğiz. -## Testing +## Test yapma {{index "test suite", "run-time error", automation, testing}} -If the language is not going to do much to help us find mistakes, we'll have to find them the hard way: by running the program and seeing whether it does the right thing. +Dilin kendisi hataları bulmamıza çok yardımcı olmayacaksa, zor yoldan hataları bulmak için programı çalıştırıp doğru şeyi yapıp yapmadığına bakmak durumunda kalacağız. -Doing this by hand, again and again, is a really bad idea. Not only is it annoying, it also tends to be ineffective since it takes too much time to exhaustively test everything every time you make a change. +Bunu el ile tekrar tekrar yapmak gerçekten kötü bir fikirdir. Sadece can sıkıcı olmakla kalmaz, aynı zamanda her değişiklik yaptığınızda her şeyi kapsamlı bir şekilde test etmek çok zaman alacağından genellikle etkisiz olur. -Computers are good at repetitive tasks, and testing is the ideal repetitive task. Automated testing is the process of writing a program that tests another program. Writing tests is a bit more work than testing manually, but once you've done it, you gain a kind of superpower: it takes you only a few seconds to verify that your program still behaves properly in all the situations you wrote tests for. When you break something, you'll immediately notice, rather than randomly running into it at some later time. +Bilgisayarlar tekrarlayan görevlerde iyidir ve test etme ideal bir tekrarlayan görevdir. Otomatik test, başka bir programı test eden bir program yazma sürecidir. Testleri yazmak manuel olarak test etmekten biraz daha fazla çalışma gerektirir, ancak bir kez yaptıktan sonra, bir tür süper güç kazanırsınız: programınızın hala yazdığınız tüm durumlarda doğru şekilde davrandığını doğrulamak için sadece birkaç saniyenizi alır. Bir şeyi bozarsanız başka bir zamanda rastgele karşılaşmak yerine hemen fark edersiniz. {{index "toUpperCase method"}} -Tests usually take the form of little labeled programs that verify some aspect of your code. For example, a set of tests for the (standard, probably already tested by someone else) `toUpperCase` method might look like this: +Testler genellikle kodunuzun bazı yönlerini doğrulayan küçük etiketli programlar şeklinde olur. Örneğin, (standart olarak dilin içinde bulunan ve zaten muhtemelen başka biri tarafından zaten test edilmiş olan) `toUpperCase` metodunun bir dizi testi şöyle olabilir: ``` function test(label, body) { @@ -155,27 +155,28 @@ test("don't convert case-less characters", () => { {{index "domain-specific language"}} -Writing tests like this tends to produce rather repetitive, awkward code. Fortunately, there exist pieces of software that help you build and run collections of tests (_((test suites))_) by providing a language (in the form of functions and methods) suited to expressing tests and by outputting informative information when a test fails. These are usually called _((test runners))_. +Böyle testler yazmak genellikle oldukça tekrarlayan garip kodlar üretir. Neyse ki, test koleksiyonları oluşturmanıza ve çalıştırmanıza yardımcı olan yazılım parçaları vardır (_((test paketleri))_), testleri ifade etmek için fonksiyonlar ve metotlar şeklinde uygun bir dil sağlayar ve bir test başarısız olduğunda bilgilendirici bilgiler verir. Bunlar genellikle _((test çalıştırıcıları))_ olarak adlandırılır. {{index "persistent data structure"}} -Some code is easier to test than other code. Generally, the more external objects that the code interacts with, the harder it is to set up the context in which to test it. The style of programming shown in the [previous chapter](robot), which uses self-contained persistent values rather than changing objects, tends to be easy to test. +Bazı kodlar diğer kodlardan daha kolay test edilir. Genellikle, kodun etkileşimde bulunduğu daha fazla harici nesne varsa, test etmek için o çevreyi kurmak daha zordur. [Önceki bölümde](robot) gösterilen programlama tarzı, değişen nesneler yerine kendi başına kalıcı değerler kullandığı için test etmesi daha kolaydır. -## Debugging +## Hata ayıklama {{index debugging}} -Once you notice there is something wrong with your program because it misbehaves or produces errors, the next step is to figure out _what_ the problem is. +Programınızın yanlış davrandığını veya hatalar ürettiğini fark ettiğinizde, bir sonraki adım sorunun _ne_ olduğunu bulmaktır. -Sometimes it is obvious. The ((error)) message will point at a specific line of your program, and if you look at the error description and that line of code, you can often see the problem. +Bazen bu açıktır. ((Hata)) mesajı programınızın belirli bir satırına işaret eder ve hata açıklamasıyla o kod satırına baktığınızda, genellikle sorunu görebilirsiniz. {{index "run-time error"}} -But not always. Sometimes the line that triggered the problem is simply the first place where a flaky value produced elsewhere gets used in an invalid way. If you have been solving the ((exercises)) in earlier chapters, you will probably have already experienced such situations. +Ancak her zaman değil. Bazen sorunu tetikleyen satır, başka bir yerde üretilen bir tutarsız değerin geçersiz bir şekilde kullanıldığı ilk yerdir. Daha önceki bölümlerdeki ((alıştırmaları)) çözüyorsanız, muhtemelen böyle durumlarla zaten karşılaşmışsınızdır. {{index "decimal number", "binary number"}} -The following example program tries to convert a whole number to a string in a given base (decimal, binary, and so on) by repeatedly picking out the last ((digit)) and then dividing the number to get rid of this digit. But the strange output that it currently produces suggests that it has a ((bug)). +The following example program tries to convert a whole number to a stri ng in a given base (decimal, binary, and so on) by repeatedly picking out the last ((digit)) and then dividing the number to get rid of this digit. But the strange output that it currently produces suggests that it has a ((bug)). +Aşağıdaki örnek program, bir tam sayıyı son ((basamağı)) seçip bu basamağı atmak için numarayı bölerek verilen bir tabandaki (onluk, ikili, vb.) bir dizeye dönüştürmeyi deniyor. Ancak şu anda tuhaf çıktılar ürettiği için bir ((hata)) olduğunu gösterir. ``` function numberToString(n, base = 10) { @@ -196,15 +197,15 @@ console.log(numberToString(13, 10)); {{index analysis}} -Even if you see the problem already, pretend for a moment that you don't. We know that our program is malfunctioning, and we want to find out why. +Sorunu zaten görseniz bile, bir an için görmemiş gibi davranın. Programımızın yanlış çalıştığını biliyoruz ve neden olduğunu bulmak istiyoruz. {{index "trial and error"}} -This is where you must resist the urge to start making random changes to the code to see whether that makes it better. Instead, _think_. Analyze what is happening and come up with a ((theory)) of why it might be happening. Then make additional observations to test this theory—or, if you don't yet have a theory, make additional observations to help you come up with one. +Burada kodu rastgele değiştirerek durumu düzeltecek mi girişimlerine direnmelisiniz. Bunun yerine _düşünün_. Neler olduğunu analiz edin ve neden olduğuna dair bir ((teori)) ortaya koyun. Daha sonra, bu teoriyi test etmek için ek gözlemler yapın—veya henüz bir teoriniz yoksa, bir teori üretmenize yardımcı olacak ek gözlemler yapın. {{index "console.log", output, debugging, logging}} -Putting a few strategic `console.log` calls into the program is a good way to get additional information about what the program is doing. In this case, we want `n` to take the values `13`, `1`, and then `0`. Let's write out its value at the start of the loop. +Programa stratejik birkaç `console.log` çağrısı eklemek, programın ne yaptığı hakkında ek bilgi almanın iyi bir yoludur. Bu durumda, `n`'in `13`, `1` ve ardından `0` değerlerini almasını istiyoruz. Hadi döngünün başında değerini konsola yazdıralım. ```{lang: null} 13 @@ -217,31 +218,31 @@ Putting a few strategic `console.log` calls into the program is a good way to ge {{index rounding}} -_Right_. Dividing 13 by 10 does not produce a whole number. Instead of `n /= base`, what we actually want is `n = Math.floor(n / base)` so that the number is properly "shifted" to the right. +_Doğru_. 13'ü 10'a bölmek bir tam sayı üretmez. `n /= base` yerine, `n = Math.floor(n / taban)` istediğimiz şeydir, böylece sayı uygun şekilde sağa "kaydırılır". {{index "JavaScript console", "debugger statement"}} -An alternative to using `console.log` to peek into the program's behavior is to use the _debugger_ capabilities of your browser. Browsers come with the ability to set a _((breakpoint))_ on a specific line of your code. When the execution of the program reaches a line with a breakpoint, it is paused, and you can inspect the values of bindings at that point. I won't go into details, as debuggers differ from browser to browser, but look in your browser's ((developer tools)) or search the Web for instructions. +Programın davranışına bakmanın `console.log` kullanmaktan başka bir yolu da, tarayıcınızın _hata ayıklayıcı_ yeteneklerini kullanmaktır. Tarayıcılar, kodunuzun belirli bir satırında _((kesme noktası))_ ayarlama yeteneğine sahiptir. Programın yürütmesi, bir kesme noktası olan bir satıra ulaştığında durur ve bu noktadaki bağlantıların değerlerini inceleyebilirsiniz. Ayrıntılara girmeyeceğim çünkü hata ayıklayıcılar tarayıcıdan tarayıcıya değişir, ancak tarayıcınızın ((geliştirici araçları))nda arayın veya Web'de talimatları arayın. -Another way to set a breakpoint is to include a `debugger` statement (consisting simply of that keyword) in your program. If the ((developer tools)) of your browser are active, the program will pause whenever it reaches such a statement. +Başka bir kesme noktası ayarlamak için programınıza bir `debugger` ifadesi (yalnızca bu anahtar kelime) eklemektir. Tarayıcınızın ((geliştirici araçları)) etkinse, program böyle bir ifadeye ulaştığında duracaktır. -## Error propagation +## Hata yayılımı {{index input, output, "run-time error", error, validation}} -Not all problems can be prevented by the programmer, unfortunately. If your program communicates with the outside world in any way, it is possible to get malformed input, to become overloaded with work, or to have the network fail. +Üzülerek söylemeliyim ki, tüm sorunlar programcı tarafından önlenebilir değildir. Programınızın dış dünya ile iletişim kurması durumunda, hatalı giriş almak, iş yüküyle aşırı yüklenmek veya internet ağının başarısız olması mümkündür. {{index "error recovery"}} -If you're programming only for yourself, you can afford to just ignore such problems until they occur. But if you build something that is going to be used by anybody else, you usually want the program to do better than just crash. Sometimes the right thing to do is take the bad input in stride and continue running. In other cases, it is better to report to the user what went wrong and then give up. In either situation the program has to actively do something in response to the problem. +Sadece kendiniz için programlama yapıyorsanız, bu tür sorunları oluşuncaya kadar görmezden gelebilirsiniz. Ancak başkaları tarafından kullanılacak bir şey inşa ederseniz, genellikle programın sadece çökmekten daha iyi bir şey yapmasını istersiniz. Bazen doğru şey, verilen yanlış değeri kabul edip çalışmaya devam etmektir. Diğer durumlarda, kullanıcıya neyin yanlış gittiğini bildirmek ve ardından vazgeçmektir. Ancak her iki durumda da, program, soruna yanıt olarak aktif olarak bir şey yapmak zorundadır. {{index "promptNumber function", validation}} -Say you have a function `promptNumber` that asks the user for a number and returns it. What should it return if the user inputs "orange"? +Örneğin, kullanıcıdan bir sayı isteyen ve onu döndüren bir `promptNumber` fonksiyonunuz olsun. Kullanıcı "orange" yazarsa ne yapmalıdır? {{index null, undefined, "return value", "special return value"}} -One option is to make it return a special value. Common choices for such values are `null`, `undefined`, or `-1`. +Bir seçenek, ona özel bir değer döndürmektir. Bu tür değerler için yaygın seçimler `null`, `undefined` veya `-1`'dir. ```{test: no} function promptNumber(question) { @@ -253,11 +254,11 @@ function promptNumber(question) { console.log(promptNumber("How many trees do you see?")); ``` -Now any code that calls `promptNumber` must check whether an actual number was read and, failing that, must somehow recover—maybe by asking again or by filling in a default value. Or it could again return a special value to _its_ caller to indicate that it failed to do what it was asked. +Şimdi, `promptNumber` çağıran kodun, gerçekten bir sayı alınıp alınmadığını kontrol etmesi ve bunun başarısız olduğu durumda nasıl kurtarılacağını bir şekilde düzeltmesi gerekir—belki tekrar sorarak veya bir varsayılan bir değerle doldurarak. Ya da istenilenin yapılamadığını belirtmek için tekrar _kendisini çağrıran_ yere özel bir değer döndürebilir. {{index "error handling"}} -In many situations, mostly when ((error))s are common and the caller should be explicitly taking them into account, returning a special value is a good way to indicate an error. It does, however, have its downsides. First, what if the function can already return every possible kind of value? In such a function, you'll have to do something like wrap the result in an object to be able to distinguish success from failure, the way the `next` method on the iterator interface does. +Bir genellikle hata döndüren bir fonksiyonu çağıran ve bu hataları dikkate alan fonksiyonlar için, başarısız olan çağırılan fonksiyondan özel değerler döndürmek hatayı belirtmek için iyi bir yöntemdir. Ancak tabii ki, bunun da olumsuz yanları var. Birinci olarak, ya çağırılan bu fonksiyon her türlü herhangi bir değer döndürebiliyorsa? Böyle bir fonksiyonda başarıyı başarısızlıktan ayırt etmek için iterator arayüzündeki `next` metodunda da olduğu gibi sonucu bir nesnenin içine almak gibi bir şey yapmanız gerekir. ``` function lastElement(array) { @@ -271,25 +272,26 @@ function lastElement(array) { {{index "special return value", readability}} -The second issue with returning special values is that it can lead to awkward code. If a piece of code calls `promptNumber` 10 times, it has to check 10 times whether `null` was returned. If its response to finding `null` is to simply return `null` itself, callers of the function will in turn have to check for it, and so on. +Özel değerler döndürmenin ikinci sorunu, garip gözüken kodla sonuçlanabilir olmasıdır. Bir kod parçası `promptNumber`'ı 10 kez çağırırsa, 10 kez `null` değerinin döndürülüp döndürülmediğini kontrol etmesi gerekir. Ve eğer `null` bulursa verdiği yanıt sadece `null`'u döndürmekse, o fonksiyonu çağıran fonksiyonlar da onu kontrol etmek zorunda kalacak ve bu da böylece devam edecek. -## Exceptions +## İstisnalar {{index "error handling"}} -When a function cannot proceed normally, what we would often _like_ to do is just stop what we are doing and immediately jump to a place that knows how to handle the problem. This is what _((exception handling))_ does. +Bir fonksiyon normal olarak devam edemezse, genellikle yapmak _istediğimiz_ şey, yaptığımız işi durdurmak ve hemen sorunu nasıl ele alacağını bilen bir yere atlamaktır. Bu _((istisna işleme))_ dediğimiz şeydir. {{index ["control flow", exceptions], "raising (exception)", "throw keyword", "call stack"}} -Exceptions are a mechanism that makes it possible for code that runs into a problem to _raise_ (or _throw_) an exception. An exception can be any value. Raising one somewhat resembles a super-charged return from a function: it jumps out of not just the current function but also its callers, all the way down to the first call that started the current execution. This is called _((unwinding the stack))_. You may remember the stack of function calls mentioned in [Chapter ?](functions#stack). An exception zooms down this stack, throwing away all the call contexts it encounters. +İstisnalar, bir sorunla karşılaşan kodun bir istisna _oluşturmasını_ (veya _fırlatmasını_) mümkün kılan bir mekanizmadır. Bir istisna herhangi bir değer olabilir. Bir istisna oluşturmak, bir fonksiyondan geri dönüş yapmanın hızlandırılmış bir versiyonunu andırır: sadece mevcut fonksiyondan çıkmakla kalmaz, mevcut yürütmeyi başlatan ilk çağrıya kadar olan tüm çağıran fonksiyonlardan da çıkar. Buna _((yığını açma))_ denir. [Bölüm ?](functions#stack) içinde bahsedilen fonksiyon çağrılarının yığınını hatırlıyor olabilirsiniz. Bir istisna bu yığından hızla aşağı iner ve karşılaştığı tüm çağrı bağlamlarını atar. {{index "error handling", [syntax, statement], "catch keyword"}} -If exceptions always zoomed right down to the bottom of the stack, they would not be of much use. They'd just provide a novel way to blow up your program. Their power lies in the fact that you can set "obstacles" along the stack to _catch_ the exception as it is zooming down. Once you've caught an exception, you can do something with it to address the problem and then continue to run the program. +Eğer istisnalar her zaman yığının en altına doğru ilerleselerdi, pek faydalı olmazlardı. Sadece programınızı patlatmanın yeni bir yolunu sağlarlardı. Güçleri, istisnayı aşağı inerken yığında engeller ayarlayarak onları _yakalayabilmeniz_ gerçeğinde yatar. Bir istisnayı yakaladıktan sonra, onunla bir şeyler yapabilir ve ardından programı çalıştırmaya devam edebilirsiniz. -Here's an example: +Bir örnek: {{id look}} + ``` function promptDirection(question) { let result = prompt(question); @@ -315,29 +317,29 @@ try { {{index "exception handling", block, "throw keyword", "try keyword", "catch keyword"}} -The `throw` keyword is used to raise an exception. Catching one is done by wrapping a piece of code in a `try` block, followed by the keyword `catch`. When the code in the `try` block causes an exception to be raised, the `catch` block is evaluated, with the name in parentheses bound to the exception value. After the `catch` block finishes—or if the `try` block finishes without problems—the program proceeds beneath the entire `try/catch` statement. +`throw` anahtar kelimesi bir istisna oluşturmak için kullanılır. Bir istisna yakalamak, bir parçayı kodu `try` bloğu içine alarak yapılır, ardından `catch` anahtar kelimesi gelir. `try` bloğundaki kod bir istisna oluşturursa, `catch` bloğu, parantez içindeki ismi istisna değeri ile bağlar şekilde değerlendirilir. `catch` bloğu sorunsuz şekilde tamamlandıktan sonra—veya sorun olmadan `try` bloğu tamamlanırsa—program tüm `try/catch` ifadesinin altından devam eder. {{index debugging, "call stack", "Error type"}} -In this case, we used the `Error` ((constructor)) to create our exception value. This is a ((standard)) JavaScript constructor that creates an object with a `message` property. Instances of `Error` also gather information about the call stack that existed when the exception was created, a so-called _((stack trace))_. This information is stored in the `stack` property and can be helpful when trying to debug a problem: it tells us the function where the problem occurred and which functions made the failing call. +Bu durumda, istisna değerimizi oluşturmak için `Error` ((constructor)) fonksiyonunu kullandık. Bu, bir `message` özelliğine sahip bir nesne oluşturan ((standart)) bir JavaScript constructor fonksiyonudur. `Error` örnekleri, istisna oluşturulurken var olan çağrı yığını hakkında da ayrıca bilgi toplar ve buna ((yığın izi)) denir. Bu bilgi `stack` özelliğinde depolanır ve bir sorunu gidermeye çalışırken yardımcı olabilir: bize sorunun hangi fonksiyonda meydana geldiğini ve başarısız olan çağrıyı hangi fonksiyonların yaptığını söyler. {{index "exception handling"}} -Note that the `look` function completely ignores the possibility that `promptDirection` might go wrong. This is the big advantage of exceptions: error-handling code is necessary only at the point where the error occurs and at the point where it is handled. The functions in between can forget all about it. +`look` fonksiyonunun `promptDirection` fonksiyonunun yanlış gitme olasılığını tamamen göz ardı ettiğine dikkat edin. Bu, istisnaların büyük avantajı: hata işleme kodu, yalnızca hata meydana geldiği noktada ve onun ele alındığı noktada gereklidir. Aradaki işlevlerin hepsi bu sorunları unutabilir. -Well, almost... +Yani, neredeyse... -## Cleaning up after exceptions +## İstisnalardan sonra temizlik {{index "exception handling", "cleaning up", ["control flow", exceptions]}} -The effect of an exception is another kind of control flow. Every action that might cause an exception, which is pretty much every function call and property access, might cause control to suddenly leave your code. +Bir istisnanın etkisi başka bir tür kontrol akışıdır. Bir istisnaya neden olabilecek her eylem, yani neredeyse her fonksiyon çağrısı ve özellik erişimi, kontrolünüzü aniden kodunuzdan çıkabilir. -This means when code has several side effects, even if its "regular" control flow looks like they'll always all happen, an exception might prevent some of them from taking place. +Bu, kodun birden fazla yan etkiye sahip olduğu durumlarda, "düzenli" kontrol akışı her zaman gerçekleşecek gibi görünse bile, bir istisna bazılarını gerçekleştirmeyi engelleyebilir demektir. {{index "banking example"}} -Here is some really bad banking code: +İşte gerçekten kötü bir bankacılık kodu. ```{includeCode: true} const accounts = { @@ -361,17 +363,17 @@ function transfer(from, amount) { } ``` -The `transfer` function transfers a sum of money from a given account to another, asking for the name of the other account in the process. If given an invalid account name, `getAccount` throws an exception. +`transfer` fonksiyonu, verilen bir hesaptan başka bir hesaba bir miktar para transfer ederken, işlem sırasında diğer hesabın adını istemektedir. Geçersiz bir hesap adı verilirse, `getAccount` bir istisna fırlatmaktadır. -But `transfer` _first_ removes the money from the account and _then_ calls `getAccount` before it adds it to another account. If it is broken off by an exception at that point, it'll just make the money disappear. +Ancak, `transfer` önce parayı hesaptan çıkarır ve ardından başka bir hesaba eklermeden önce `getAccount` fonksiyonunu çağırır. Eğer bu noktada bir istisna tarafından kesilirse, sadece paranın gönderen kişiden kaybolmasına sebep olur. -That code could have been written a little more intelligently, for example by calling `getAccount` before it starts moving money around. But often problems like this occur in more subtle ways. Even functions that don't look like they will throw an exception might do so in exceptional circumstances or when they contain a programmer mistake. +Bu kod biraz daha akıllıca yazılabilirdi, örneğin para hareketi yapmaya başlamadan önce `getAccount` fonksiyonunu çağırarak. Ancak bu tür sorunlar genellikle daha ince yollarla ortaya çıkar. Bir fonksiyonun bir istisna fırlatmayacağını düşündüğünüzde bile, olağanüstü durumlarda veya bir programcı hatası içerdiğinde bunu yapabilir. -One way to address this is to use fewer side effects. Again, a programming style that computes new values instead of changing existing data helps. If a piece of code stops running in the middle of creating a new value, no existing data structures were damaged, making it easier to recover. +Bunu ele almanın bir yolu, daha az yan etki kullanmaktır. Yine, var olan verileri değiştirmek yerine yeni değerler hesaplayan bir programlama stili yardımcı olur. Bir kod parçası, yeni bir değer oluşturma sürecinin ortasında çalışmayı durdurursa, mevcut veri yapıları zarar görmediği için kurtarmak daha kolay olur. {{index block, "try keyword", "finally keyword"}} -Since that isn't always practical, `try` statements have another feature: they may be followed by a `finally` block either instead of or in addition to a `catch` block. A `finally` block says "no matter _what_ happens, run this code after trying to run the code in the `try` block." +Ancak bu her zaman pratik değildir. Bu yüzden `try` ifadelerinin başka bir özelliği vardır. Bunlar, bir `try` bloğuna, `catch` bloğu yerine veya ek olarak bir `finally` bloğu izleyebilirler. Bir `finally` bloğu, "ne olursa olsun, `try` bloğundaki kodu çalıştırmaya çalıştıktan sonra bu kodu çalıştır" der. ```{includeCode: true} function transfer(from, amount) { @@ -390,43 +392,44 @@ function transfer(from, amount) { } ``` -This version of the function tracks its progress, and if, when leaving, it notices that it was aborted at a point where it had created an inconsistent program state, it repairs the damage it did. +Bu fonksiyonun bu sürümü ilerleme durumunu takip eder ve ayrılırken, oluşturduğu tutarsız bir program durumu noktasında kesildiğini fark ederse, yaptığı zararı onarır. -Note that even though the `finally` code is run when an exception is thrown in the `try` block, it does not interfere with the exception. After the `finally` block runs, the stack continues unwinding. +Unutulmamalıdır ki, `try` bloğundaki bir istisna atıldığında bile `finally` kodunun çalıştırılmasına rağmen, istisna ile ilgilenmez. `finally` bloğu çalıştıktan sonra, yığın açılmaya devam eder. {{index "exception safety"}} -Writing programs that operate reliably even when exceptions pop up in unexpected places is hard. Many people simply don't bother, and because exceptions are typically reserved for exceptional circumstances, the problem may occur so rarely that it is never even noticed. Whether that is a good thing or a really bad thing depends on how much damage the software will do when it fails. +Beklenmedik yerlerde istisna oluştuğunda dahi güvenilir şekilde çalışan programlar yazmak zordur. Birçok insan bunu genellikle önemsemez ve istisnalar genellikle olağanüstü durumlarda oluştuğundan ötürü sorun nadiren fark edilir. Bunun iyi bir şey mi yoksa gerçekten kötü bir şey mi olduğunu yazılımın başarısız olduğunda ne kadar zarar vereceğine bağlıdır. -## Selective catching +## Seçici yakalama {{index "uncaught exception", "exception handling", "JavaScript console", "developer tools", "call stack", error}} -When an exception makes it all the way to the bottom of the stack without being caught, it gets handled by the environment. What this means differs between environments. In browsers, a description of the error typically gets written to the JavaScript console (reachable through the browser's Tools or Developer menu). Node.js, the browserless JavaScript environment we will discuss in [Chapter ?](node), is more careful about data corruption. It aborts the whole process when an unhandled exception occurs. +Bir istisna, yakalanmadan yığının en altına kadar ulaştığında, çevre tarafından ele alınır. Bunun ne anlama geldiği çevrelere göre değişir. Tarayıcılarda, hata genellikle JavaScript konsoluna yazılır (tarayıcının Araçlar veya Geliştirici menüsünden erişilebilir). [Bölüm ?](node) içinde tartışacağımız tarayıcısız JavaScript ortamı olan Node.js, veri bozulması konusunda daha dikkatlidir. Ele alınmayan bir istisna meydana geldiğinde, tüm işlemi sonlandırır. {{index crash, "error handling"}} -For programmer mistakes, just letting the error go through is often the best you can do. An unhandled exception is a reasonable way to signal a broken program, and the JavaScript console will, on modern browsers, provide you with some information about which function calls were on the stack when the problem occurred. +Programcı hataları için, hatanın gitmesine izin vermek çoğu zaman yapabileceğiniz en iyi şeydir. Ele alınmayan bir istisna, bozuk bir programı işaret etmenin makul bir yoludur ve JavaScript konsolu, modern tarayıcılarda, sorun meydana geldiğinde yığında hangi fonksiyon çağrılarının olduğuna dair bazı bilgiler sağlar. {{index "user interface"}} -For problems that are _expected_ to happen during routine use, crashing with an unhandled exception is a terrible strategy. +Rutin kullanım sırasında _meydana gelmesi beklenen_ sorunlar için, ele alınmayan bir istisna ile çökme korkunç bir stratejidir. {{index [function, application], "exception handling", "Error type", [binding, undefined]}} -Invalid uses of the language, such as referencing a nonexistent binding, looking up a property on `null`, or calling something that's not a function, will also result in exceptions being raised. Such exceptions can also be caught. +Dilin geçersiz kullanımları, var olmayan bir bağlantıya başvurmak, `null` üzerinde bir özellik aramak veya bir fonksiyon olmayan bir şeyi çağırmak gibi, aynı şekilde istisna yükseltilmesine neden olur. Böyle istisnalar da yakalanabilir. {{index "catch keyword"}} -When a `catch` body is entered, all we know is that _something_ in our `try` body caused an exception. But we don't know _what_ did or _which_ exception it caused. +Bir `catch` bloğuna girildiğinde, bildiğimiz tek şey, `try` bloğundaki bir şeyin bir istisna meydana getirdiğidir. Ancak _neyin_ istisnaya sebep oluduğu veya _hangi_ istisnaya sebep olunduğunu bilmiyoruz. {{index "exception handling"}} -JavaScript (in a rather glaring omission) doesn't provide direct support for selectively catching exceptions: either you catch them all or you don't catch any. This makes it tempting to _assume_ that the exception you get is the one you were thinking about when you wrote the `catch` block. +JavaScript (oldukça dikkate çeker bir ihmalde), istisnaları seçici olarak yakalamak için doğrudan destek sağlamaz: ya hepsini yakalarsınız ya da hiçbirini yakalamazsınız. Bu, `catch` bloğunun yazıldığı sırada düşündüğünüz istisna olduğunu _varsaymanızı_ cazip hale getirir. {{index "promptDirection function"}} But it might not be. Some other ((assumption)) might be violated, or you might have introduced a bug that is causing an exception. Here is an example that _attempts_ to keep on calling `promptDirection` until it gets a valid answer: +Ancak öyle olmayabilir. Başka bir ((varsayım)) ihlal edilmiş olabilir veya bir istisnaya neden olan bir hata eklemiş olabilirsiniz. İşte, geçerli bir yanıt alana kadar `promptDirection` fonksiyonunu çağırmaya devam etmeye _çalışan_ bir örnek: ```{test: no} for (;;) { @@ -442,19 +445,19 @@ for (;;) { {{index "infinite loop", "for loop", "catch keyword", debugging}} -The `for (;;)` construct is a way to intentionally create a loop that doesn't terminate on its own. We break out of the loop only when a valid direction is given. Unfortunately, we misspelled `promptDirection`, which will result in an "undefined variable" error. Because the `catch` block completely ignores its exception value (`e`), assuming it knows what the problem is, it wrongly treats the binding error as indicating bad input. Not only does this cause an infinite loop, it "buries" the useful error message about the misspelled binding. +`for (;;)` yapısı, kendi kendine sona ermeyen bir döngü oluşturmanın kasıtlı bir yoludur. Döngüden yalnızca geçerli bir yön verildiğinde çıkarız. _Ancak_ `promptDirection` fonksiyonunu yanlış yazdık, bu da "tanımsız değişken" hatasına neden olacaktır. `catch` bloğu, tamamen istisna değerini (`e`) görmezden geldiği için, sorunun ne olduğunu varsayarak bağlantı hatasını yanlışlıkla kötü giriş olarak işler. Bu sadece sonsuz bir döngüye neden olmakla kalmaz, aynı zamanda yanlış yazılmış bağlantıyla ilgili yararlı hata mesajını "gömülmüş" hale getirir. -As a general rule, don't blanket-catch exceptions unless it is for the purpose of "routing" them somewhere—for example, over the network to tell another system that our program crashed. And even then, think carefully about how you might be hiding information. +Genel bir kural olarak, birden fazla istisnayı genel bir şekilde yakalamayın, bunu sadece onları başka bir yere "yönlendirmek" amacıyla yapın - örneğin, programımızın çöktüğünü başka bir sisteme bildirmek için ağ üzerinden bir şey yapacaksınızdır, o zaman bu yapılabilir. Ancak o zaman bile nasıl bilgi gizleyebiliyor olduğunuzu dikkatlice düşünün. {{index "exception handling"}} -We want to catch a _specific_ kind of exception. We can do this by checking in the `catch` block whether the exception we got is the one we are interested in, and if not, rethrow it. But how do we recognize an exception? +Dolayısıyla, _belirli_ bir tür istisnayı yakalamak istiyoruz. Bunu `catch` bloğunda aldığımız istisnanın istediğimiz türde olup olmadığını kontrol ederek ve aksi takdirde yeniden fırlatarak yapabiliriz. Ancak bir istisnayı nasıl tanıyacağız? -We could compare its `message` property against the ((error)) message we happen to expect. But that's a shaky way to write code—we'd be using information that's intended for human consumption (the message) to make a programmatic decision. As soon as someone changes (or translates) the message, the code will stop working. +`message` özelliğini istisnanın ((hata)) mesajına karşı beklediğimiz mesajdan kontrol edebiliriz. Ancak bu, kod yazmanın pek iyi olmayan bir yoludur - programatik bir karar vermek için insan tüketimi adına tasarlanmış bilgileri (mesajı) kullanıyor oluruz. Birisi mesajı değiştirdiğinde (veya başka bir dile çevirdiğinde), kod çalışmayı durdurur. {{index "Error type", "instanceof operator", "promptDirection function"}} -Rather, let's define a new type of error and use `instanceof` to identify it. +Bunun yerine, yeni bir hata türü tanımlayalım ve bunu tanımlamak için `instanceof` kullanalım. ```{includeCode: true} class InputError extends Error {} @@ -469,11 +472,11 @@ function promptDirection(question) { {{index "throw keyword", inheritance}} -The new error class extends `Error`. It doesn't define its own constructor, which means that it inherits the `Error` constructor, which expects a string message as argument. In fact, it doesn't define anything at all—the class is empty. `InputError` objects behave like `Error` objects, except that they have a different class by which we can recognize them. +Yeni hata sınıfı `Error` sınıfından miras alır. Kendi `constructor` fonksiyonunu tanımlamaz, bu da `Error` constructor fonksiyonunu miras aldığı ve bir mesaj dizesi bekleyen `Error` constructor fonksiyonuna sahip olduğu anlamına gelir. Aslında hiçbir şeyi tanımlamaz - sınıf boştur. `InputError` nesneleri, onları tanıyabileceğimiz farklı bir sınıfa sahip olmaları dışında, `Error` nesneleri gibi davranır. {{index "exception handling"}} -Now the loop can catch these more carefully. +Şimdi döngü bunları daha dikkatli bir şekilde yakalayabilir. ```{test: no} for (;;) { @@ -493,15 +496,15 @@ for (;;) { {{index debugging}} -This will catch only instances of `InputError` and let unrelated exceptions through. If you reintroduce the typo, the undefined binding error will be properly reported. +Bu, yalnızca `InputError` örneklerini yakalar ve ilgili olmayan istisnaları geçirir. Yanlış yazım hatasını yeniden tanıttığınızda, tanımsız bağlantı hatası düzgün bir şekilde rapor edilir. -## Assertions +## İddialar {{index "assert function", assertion, debugging}} -_Assertions_ are checks inside a program that verify that something is the way it is supposed to be. They are used not to handle situations that can come up in normal operation but to find programmer mistakes. +_İddialar_ program içinde, bir şeyin olması gerektiği gibi olduğunu doğrulayan kontrollerdir. Bunlar normal işlem sırasında ortaya çıkabilecek durumlarla başa çıkmak için değil, programcı hatalarını bulmak için kullanılır. -If, for example, `firstElement` is described as a function that should never be called on empty arrays, we might write it like this: +Örneğin, `firstElement` fonksiyonu boş diziler üzerinde asla çağrılmaması gereken bir fonksiyon olarak tanımlanmışsa, şöyle yazabiliriz: ``` function firstElement(array) { @@ -514,29 +517,31 @@ function firstElement(array) { {{index validation, "run-time error", crash, assumption}} -Now, instead of silently returning undefined (which you get when reading an array property that does not exist), this will loudly blow up your program as soon as you misuse it. This makes it less likely for such mistakes to go unnoticed and easier to find their cause when they occur. +Artık sessizce tanımsız döndürmek yerine (bir dizide var olmayan bir özellik okunduğunda elde ettiğiniz), bunun kullanımını yanlış yaptığınızda programınızı yüksek sesle patlatacaktır. Bu tür hatalar gözden kaçırma olasılığını azaltır ve meydana geldiklerinde nedenlerini bulmayı kolaylaştırır. -I do not recommend trying to write assertions for every possible kind of bad input. That'd be a lot of work and would lead to very noisy code. You'll want to reserve them for mistakes that are easy to make (or that you find yourself making). +Her türlü kötü giriş için kontroller yazmayı önermem. Bu, çok fazla çalışma gerektirir ve çok gürültülü bir kod ile sonuçlanır. Onları yalnızca kolayca yapılan hatalar için (veya kendinizin yapmaya başladığını fark ettiğiniz hatalar için) saklamak istersiniz. -## Summary +## Özet -An important part of programming is finding, diagnosing, and fixing bugs. Problems can become easier to notice if you have an automated test suite or add assertions to your programs. +Programlamanın önemli bir parçası, hataları bulmak, teşhis etmek ve düzeltmektir. Otomatik bir test paketiniz varsa veya programlarınıza iddialar eklediyseniz, sorunları fark etmek daha kolay olabilir. -Problems caused by factors outside the program's control should usually be actively planned for. Sometimes, when the problem can be handled locally, special return values are a good way to track them. Otherwise, exceptions may be preferable. +Programın kontrolü dışındaki faktörlerden kaynaklanan sorunlar genellikle aktif olarak planlanmalıdır. Sorun yerel olarak ele alınabiliyorsa, özel dönüş değerleri onları izlemek için iyi bir yoldur. Aksi takdirde, istisnalar tercih edilebilir. -Throwing an exception causes the call stack to be unwound until the next enclosing `try/catch` block or until the bottom of the stack. The exception value will be given to the `catch` block that catches it, which should verify that it is actually the expected kind of exception and then do something with it. To help address the unpredictable control flow caused by exceptions, `finally` blocks can be used to ensure that a piece of code _always_ runs when a block finishes. +Bir istisna fırlatmak, yığının bir sonraki kapsayan `try/catch` bloğuna veya yığının dibine kadar açılmasına neden olur. İstisna değeri, bunu yakalayan `catch` bloğuna verilir, bu da gerçekten beklenen türde bir istisna olup olmadığını doğrulamalı ve ardından bununla bir şeyler yapmalıdır. İstisnaların neden olduğu öngörülemeyen kontrol akışıyla başa çıkmaya yardımcı olmak için, bir bloğun bitişinde bir parça kodun _her zaman_ çalışmasını sağlamak için `finally` blokları kullanılabilir. -## Exercises +## Egzersizler -### Retry +### Yeniden deneme {{index "primitiveMultiply (exercise)", "exception handling", "throw keyword"}} Say you have a function `primitiveMultiply` that in 20 percent of cases multiplies two numbers and in the other 80 percent of cases raises an exception of type `MultiplicatorUnitFailure`. Write a function that wraps this clunky function and just keeps trying until a call succeeds, after which it returns the result. +primitiveMultiply adında, %20'lik bir olasılıkla iki sayıyı çarpan ve diğer %80'lik bir olasılıkla MultiplicatorUnitFailure türünde bir istisna yükselten bir fonksiyonunuz olduğunu varsayalım. Bu sıkışık fonksiyonu saran ve bir çağrı başarılı olana kadar denemeye devam eden bir fonksiyon yazın. {{index "catch keyword"}} Make sure you handle only the exceptions you are trying to handle. +Yalnızca ele almaya çalıştığınız istisnaları ele aldığınızdan emin olun. {{if interactive @@ -552,12 +557,13 @@ function primitiveMultiply(a, b) { } function reliableMultiply(a, b) { - // Your code here. + // Kodunuz buraya. } console.log(reliableMultiply(8, 8)); // → 64 ``` + if}} {{hint @@ -565,16 +571,18 @@ if}} {{index "primitiveMultiply (exercise)", "try keyword", "catch keyword", "throw keyword"}} The call to `primitiveMultiply` should definitely happen in a `try` block. The corresponding `catch` block should rethrow the exception when it is not an instance of `MultiplicatorUnitFailure` and ensure the call is retried when it is. +primitiveMultiply çağrısı kesinlikle bir try bloğunda gerçekleşmelidir. Karşılık gelen catch bloğu, istisna MultiplicatorUnitFailure türünden değilse istisnayı yeniden fırlatmalı ve türünden bir istisna olduğunda çağrının yeniden denendiğinden emin olmalıdır. To do the retrying, you can either use a loop that stops only when a call succeeds—as in the [`look` example](error#look) earlier in this chapter—or use ((recursion)) and hope you don't get a string of failures so long that it overflows the stack (which is a pretty safe bet). +Yeniden deneme yapmak için, bir çağrının başarılı olana kadar durmayan bir döngü kullanabilirsiniz - bu bölümdeki look örneğinde olduğu gibi - veya ((rekürsiv)) kullanabilir ve yığını aşırı derecede dolduracak kadar uzun bir hata dizisi almayı umabilirsiniz (bu oldukça güvenli bir bahis). hint}} -### The locked box +### Kilitli kutu {{index "locked box (exercise)"}} -Consider the following (rather contrived) object: +Aşağıdaki (oldukça yapay) nesneyi düşünün: ``` const box = new class { @@ -592,11 +600,11 @@ const box = new class { {{index "private property", "access control"}} -It is a ((box)) with a lock. There is an array in the box, but you can get at it only when the box is unlocked. +Bu, bir kilitli kutu. Kutuda bir dizi var, ancak kutu kilidi açık olmadığı sürece ona erişemezsiniz. {{index "finally keyword", "exception handling"}} -Write a function called `withBoxUnlocked` that takes a function value as argument, unlocks the box, runs the function, and then ensures that the box is locked again before returning, regardless of whether the argument function returned normally or threw an exception. +`withBoxUnlocked` adında bir fonksiyon yazın; bu fonksiyon, bir fonksiyon değeri alsın, kutunun kilidini açsın, aldığı fonksiyonu çalıştırsın ve ardından, argüman olarak verilen fonksiyonun normal olarak çalışmasından veya bir istisna fırlatmasından bağımsız olarak döndürmeden önce kutunun kilidinin geri kilitli olduğundan emin olsun. {{if interactive @@ -614,7 +622,7 @@ const box = new class { }; function withBoxUnlocked(body) { - // Your code here. + // Kodunuz buraya. } withBoxUnlocked(() => { @@ -634,14 +642,14 @@ console.log(box.locked); if}} -For extra points, make sure that if you call `withBoxUnlocked` when the box is already unlocked, the box stays unlocked. +Ek puanlar için, kutu zaten açıkken `withBoxUnlocked` çağrılırsa, kutunun açık kalmasını sağlayın. {{hint {{index "locked box (exercise)", "finally keyword", "try keyword"}} -This exercise calls for a `finally` block. Your function should first unlock the box and then call the argument function from inside a `try` body. The `finally` block after it should lock the box again. +Bu alıştırma, bir `finally` bloğu gerektirir. Fonksiyonunuz öncelikle kutuyu kilidini açmalı ve ardından argüman olarak verilen fonksiyonu bir try gövdesi içinde çağırmalıdır. Sonrasında gelen `finally` bloğu aracılığıyla kutuyu tekrar kilitlemelidir. -To make sure we don't lock the box when it wasn't already locked, check its lock at the start of the function and unlock and lock it only when it started out locked. +Kutuyu kilitli olmadığında kilitlememek için, fonksiyonun başında kilidini kontrol edin ve kilidini sadece kilitli başlamışken açın veya kapatın. hint}} diff --git a/09_regexp.md b/09_regexp.md index 4610562c..c8398cb5 100644 --- a/09_regexp.md +++ b/09_regexp.md @@ -1,8 +1,8 @@ -# Regular Expressions +# Düzenli İfadeler {{quote {author: "Jamie Zawinski", chapter: true} -Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems. +Bazı insanlar, bir problemle karşılaştıklarında, 'Biliyorum, düzenli ifadeleri kullanacağım.' dediklerinden ötürü artık iki probleme sahip olurlar. quote}} @@ -10,58 +10,58 @@ quote}} {{if interactive -{{quote {author: "Master Yuan-Ma", title: "The Book of Programming", chapter: true} +{{quote {author: "Master Yuan-Ma", title: "Programlama Kitabı", chapter: true} -When you cut against the grain of the wood, much strength is needed. When you program against the grain of the problem, much code is needed. +Ahşabın damarına karşı keserseniz, çok güç gerekir. Problemin yapısına karşı programlama yaptığınızda, çok fazla kod gerekir. quote}} if}} -{{figure {url: "img/chapter_picture_9.jpg", alt: "Illustration of a railroad system representing the syntactic structure of regular expressions", chapter: "square-framed"}}} +{{figure {url: "img/chapter_picture_9.jpg", alt: "Düzenli ifadelerin sözdizimsel yapısını temsil eden bir demiryolu sisteminin illüstrasyonu.", chapter: "square-framed"}}} {{index evolution, adoption, integration}} -Programming ((tool))s and techniques survive and spread in a chaotic, evolutionary way. It's not always the best or brilliant ones that win but rather the ones that function well enough within the right niche or that happen to be integrated with another successful piece of technology. +Programlama ((araç))ları ve teknikleri, kaotik, evrimsel bir şekilde hayatta kalır ve yayılır. Her zaman en iyi veya parlak olanlar kazanmaz, ancak doğru nişte yeterince iyi işleyenler veya tesadüfen başka başarılı bir teknoloji parçası ile entegre olanlar kazanır. {{index "domain-specific language"}} -In this chapter, I will discuss one such tool, _((regular expression))s_. Regular expressions are a way to describe ((pattern))s in string data. They form a small, separate language that is part of JavaScript and many other languages and systems. +Bu bölümde, bu araçlardan bir tanesini tartışacağım: _((düzenli ifadeler))_. Düzenli ifadeler, dize verilerindeki ((kalıpları)) tanımlamanın bir yoludur. JavaScript'in ve birçok başka dilin ve sistemlerin bir parçası olan küçük, ayrı bir dil oluştururlar. {{index [interface, design]}} -Regular expressions are both terribly awkward and extremely useful. Their syntax is cryptic and the programming interface JavaScript provides for them is clumsy. But they are a powerful ((tool)) for inspecting and processing strings. Properly understanding regular expressions will make you a more effective programmer. +Düzenli ifadeler hem son derece sakar hem de son derece kullanışlıdır. Söz dizimi kriptiktir ve JavaScript'in onlar için sağladığı programlama arayüzü sakattır. Ancak, dizeleri incelemek ve işlemek için güçlü bir ((araç))tırlar. Düzenli ifadeleri doğru anlamak, sizi daha etkili bir programcı yapacaktır. -## Creating a regular expression +## Düzenli ifade oluşturma {{index ["regular expression", creation], "RegExp class", "literal expression", "slash character"}} -A regular expression is a type of object. It can be either constructed with the `RegExp` constructor or written as a literal value by enclosing a pattern in forward slash (`/`) characters. +Düzenli ifade bir tür nesnedir. `RegExp` ((constructor)) fonskiyonunu çağırarak oluşturulabilir veya bir kalıbı ileri eğik çizgi (`/`) karakterleri arasına alarak yazıp da oluşturulabilir. ``` let re1 = new RegExp("abc"); let re2 = /abc/; ``` -Both of those regular expression objects represent the same ((pattern)): an _a_ character followed by a _b_ followed by a _c_. +Bu iki düzenli ifade nesnesi aynı ((kalıbı)) temsil eder: bir _a_ karakteri ardından bir _b_ ardından bir _c_. {{index ["backslash character", "in regular expressions"], "RegExp class"}} -When using the `RegExp` constructor, the pattern is written as a normal string, so the usual rules apply for backslashes. +`RegExp` ((constructor)) fonskiyonunu kullanılırken, kalıp normal bir dize olarak yazılır, bu nedenle ters eğik çizgiler için normal kurallar geçerlidir. {{index ["regular expression", escaping], [escaping, "in regexps"], "slash character"}} -The second notation, where the pattern appears between slash characters, treats backslashes somewhat differently. First, since a forward slash ends the pattern, we need to put a backslash before any forward slash that we want to be _part_ of the pattern. In addition, backslashes that aren't part of special character codes (like `\n`) will be _preserved_, rather than ignored as they are in strings, and change the meaning of the pattern. Some characters, such as question marks and plus signs, have special meanings in regular expressions and must be preceded by a backslash if they are meant to represent the character itself. +Kalıbın eğik çizgi karakterleri arasında göründüğü ikinci notasyon durumunda, ters eğik çizgileri biraz farklı bir şekilde işler. İlk olarak, bir ileri eğik çizgi kalıbı sonlandıracağından ötürü kalıbın bir parçası olmasını istediğimiz herhangi bir ileri eğik çizgi önüne bir ters eğik çizgi koymamız gerekir. Ayrıca, özel karakter kodlarının (`\n` gibi) bir parçası olmayan ters eğik çizgiler, dize içinde olduğu gibi görmezden gelinmez ve kalıbın anlamını değiştirir. Soru işaretleri ve artı işaretleri gibi bazı karakterler, düzenli ifadelerde özel anlamlara sahiptir ve karakterin kendisini temsil etmek isteniyorsa öncesine bir ters eğik çizgi yazılmalıdır. ``` let aPlus = /A\+/; ``` -## Testing for matches +## Eşleşenler için test etmek {{index matching, "test method", ["regular expression", methods]}} -Regular expression objects have a number of methods. The simplest one is `test`. If you pass it a string, it will return a ((Boolean)) telling you whether the string contains a match of the pattern in the expression. +Düzenli ifade nesnelerinin bir dizi metodları vardır. En basiti `test` metodudur. Bir dize geçirirseniz, ifadenin kalıbına uyan dizeyi içerip içermediğini size söyleyen bir ((Boolean)) döndürür. ``` console.log(/abc/.test("abcde")); @@ -72,17 +72,17 @@ console.log(/abc/.test("abxde")); {{index pattern}} -A ((regular expression)) consisting of only nonspecial characters simply represents that sequence of characters. If _abc_ occurs anywhere in the string we are testing against (not just at the start), `test` will return `true`. +Yalnızca özel olmayan karakterlerden oluşan bir düzenli ifade basit olarak, o karakter dizisini temsil eder. _abc_ dizesi, test ettiğimiz dizide (başlangıç dışında yerlerde de olacak şekilde) herhangi bir yerde bulunursa, `test` metodu `true` döndürür. -## Sets of characters +## Karakter setleri {{index "regular expression", "indexOf method"}} -Finding out whether a string contains _abc_ could just as well be done with a call to `indexOf`. Regular expressions are useful because they allow us to describe more complicated ((pattern))s. +Bir dizinin _abc_ içerip içermediğini öğrenmek, `indexOf` ile de yapılabilir. Düzenli ifadeler, daha karmaşık ((kalıpları)) tanımlamamıza izin verdiği için kullanışlıdır. -Say we want to match any ((number)). In a regular expression, putting a ((set)) of characters between square brackets makes that part of the expression match any of the characters between the brackets. +Diyelim ki bir ((sayı)) eşleştirmek istiyoruz. Bir düzenli ifade içinde, karakterler arasına kare parantezler arasında bir ((küme)) karakterler yerleştirmek, ifadenin bu kısmının parantezler arasındaki karakterlerden herhangi birini eşleştirmesini sağlar. -Both of the following expressions match all strings that contain a ((digit)): +Her iki ifade de bir ((rakam)) içeren tüm dizeleri eşleştirir: ``` console.log(/[0123456789]/.test("in 1992")); @@ -93,25 +93,25 @@ console.log(/[0-9]/.test("in 1992")); {{index "hyphen character"}} -Within square brackets, a hyphen (`-`) between two characters can be used to indicate a ((range)) of characters, where the ordering is determined by the character's ((Unicode)) number. Characters 0 to 9 sit right next to each other in this ordering (codes 48 to 57), so `[0-9]` covers all of them and matches any ((digit)). +Kare parantezler arasında, iki karakter arasındaki bir tire (-), karakterin ((Unicode)) numarası tarafından belirlenen bir karakterler ((aralığı))nı göstermek için kullanılabilir. 0'dan 9'a olan bu karakterler bu sıralamada hemen yan yanadırlar (kodlar 48 ila 57), bu nedenle `[0-9]` tümünü kapsar ve herhangi bir ((rakamı)) eşleştirir. {{index [whitespace, matching], "alphanumeric character", "period character"}} -A number of common character groups have their own built-in shortcuts. Digits are one of them: `\d` means the same thing as `[0-9]`. +Birçok yaygın karakter grubunun kendi yerleşik kısayolları vardır. Rakamlar bunlardan biridir: `\d`, `[0-9]` ile aynı anlama gelir. {{index "newline character", [whitespace, matching]}} {{table {cols: [1, 5]}}} -| `\d` | Any ((digit)) character -| `\w` | An alphanumeric character ("((word character))") -| `\s` | Any whitespace character (space, tab, newline, and similar) -| `\D` | A character that is _not_ a digit -| `\W` | A nonalphanumeric character -| `\S` | A nonwhitespace character -| `.` | Any character except for newline +| `\d` | Herhangi bir ((rakam)) karakter +| `\w` | Herhangi bir alfasayısal ("((kelime karakteri))") +| `\s` | Herhangi bir boşluk karakteri (boşluk, tab, yeni satır, vb.) +| `\D` | Rakam _olmayan_ bir karakter +| `\W` | Alfasayısal olmayan bir karakter +| `\S` | Boşluk olmayan bir karakter +| `.` | Yeni satır dışında herhangi bir karakter -You could match a ((date)) and ((time)) format like 01-30-2003 15:20 with the following expression: +Bu nedenle, 01-30-2003 15:20 gibi bir ((tarih)) ve ((zaman)) biçimini şu şekilde eşleştirebilirsiniz: ``` let dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; @@ -123,15 +123,15 @@ console.log(dateTime.test("30-jan-2003 15:20")); {{index ["backslash character", "in regular expressions"]}} -That regular expression looks completely awful, doesn't it? Half of it is backslashes, producing a background noise that makes it hard to spot the actual ((pattern)) expressed. We'll see a slightly improved version of this expression [later](regexp#date_regexp_counted). +Bu tamamen berbat görünüyor, değil mi? Yarısından fazlası ters eğik çizgiler ve gerçekten ((kalıp)) ifade edilen kısmı bulmayı zorlaştıran bir arka plan gürültüsü oluşturuyor. Bu ifadenin [daha sonra](regexp#date_regexp_counted) biraz geliştirilmiş bir sürümünü göreceğiz. {{index [escaping, "in regexps"], "regular expression", set}} -These backslash codes can also be used inside ((square brackets)). For example, `[\d.]` means any digit or a period character. The period itself, between square brackets, loses its special meaning. The same goes for other special characters, such as the plus sign (`+`). +Bu ters eğik çizgi kodları aynı zamanda ((kare parantezler)) içinde de kullanılabilir. Örneğin, `[\d.]`, herhangi bir rakam veya bir nokta karakterini ifade eder. Ancak nokta kendisi, kare parantezler arasında, özel anlamını kaybeder. `+` işareti gibi diğer özel karakterler için de aynı şey geçerlidir. {{index "square brackets", inversion, "caret character"}} -To _invert_ a set of characters—that is, to express that you want to match any character _except_ the ones in the set—you can write a caret (`^`) character after the opening bracket. +Bir karakterler kümesini tersine çevirmek - yani, kümedeki karakterlerin dışındakileri eşleştirmek istediğinizi belirtmek - için bir üst simge (`^`) karakterini açılış parantezinin hemen ardından yazabilirsiniz. ``` let nonBinary = /[^01]/; @@ -141,29 +141,29 @@ console.log(nonBinary.test("0111010112101001")); // → true ``` -## International characters +## Uluslararası karakterler {{index internationalization, Unicode, ["regular expression", internationalization]}} -Because of JavaScript's initial simplistic implementation and the fact that this simplistic approach was later set in stone as ((standard)) behavior, JavaScript's regular expressions are rather dumb about characters that do not appear in the English language. For example, as far as JavaScript's regular expressions are concerned, a "((word character))" is only one of the 26 characters in the Latin alphabet (uppercase or lowercase), decimal digits, and, for some reason, the underscore character. Things like _é_ or _β_, which most definitely are word characters, will not match `\w` (and _will_ match uppercase `\W`, the nonword category). +JavaScript'in başlangıçtaki basit implementasyonu ve bu basit yaklaşımın daha sonra ((standart)) davranış olarak belirlenmesi nedeniyle, JavaScript'in düzenli ifadeleri, İngilizce dilinde bulunmayan karakterler hakkında oldukça gariptir. Örneğin, JavaScript'in düzenli ifadelerine göre, bir (("kelime karakteri")), yalnızca Latin alfabesinin 26 karakterinden biridir (büyük veya küçük harf), ondalık basamaklar ve, nedense alt çizgi karakteri. _é_ veya _β_ gibi kesinlikle kelime karakterleri olan şeyler, `\w` eşleşirken büyük harfli `\W` olmayan kelime kategorisine eşleşmeyecektir. {{index [whitespace, matching]}} -By a strange historical accident, `\s` (whitespace) does not have this problem and matches all characters that the Unicode standard considers whitespace, including things like the ((nonbreaking space)) and the ((Mongolian vowel separator)). +Tuhaf bir tarihsel kazadan dolayı, `\s` (boşluk) bu sorunu yaşamaz ve Unicode standardı tarafından boşluk olarak kabul edilen tüm karakterleri eşleştirir, bunlar arasında ((boşluk karakteri)) ve ((Moğol ünlü ayırıcı)) gibi şeyler de vardır. {{index "character category", [Unicode, property]}} -It is possible to use `\p` in a regular expression to match all characters to which the Unicode standard assigns a given property. This allows us to match things like letters in a more cosmopolitan way. However, again due to compatibility with the original language standards, those are only recognized when you put a `u` character (for ((Unicode))) after the regular expression. +Bir düzenli ifade içinde `\p` kullanarak Unicode standartında belirli bir özellik verilen tüm karakterlerle eşleştirebilmek mümkündür. Bu, harfleri daha kozmopolit bir şekilde eşleştirmemize olanak tanır. Ancak, yine de orijinal dil standartlarıyla uyumluluktan dolayı, bunlar yalnızca düzenli ifadenin sonuna ((Unicode)) için bir `u` karakteri eklediğinizde tanınır. {{table {cols: [1, 5]}}} -| `\p{L}` | Any letter -| `\p{N}` | Any numeric character -| `\p{P}` | Any punctuation character -| `\P{L}` | Any non-letter (uppercase P inverts) -| `\p{Script=Hangul}` | Any character from the given script (see [Chapter ?](higher_order#scripts)) +| `\p{L}` | Herhangi bir harf +| `\p{N}` | Herhangi bir sayısal karakter +| `\p{P}` | Herhangi bir noktalama işareti karakteri +| `\P{L}` | Harf olmayan herhangi bir şey (büyük harf P tersine çevrilir) +| `\p{Script=Hangul}` | Verilen alfabe dosyasındaki herhangi bir karakter ([Bölüm ?](higher_order#scripts)) -Using `\w` for text processing that may need to handle non-English text (or even English text with borrowed words like “cliché”) is a liability, since it won't treat characters like “é” as letters. Though they tend to be a bit more verbose, `\p` property groups are more robust. +Düzenli ifadeleri `\w` aracılığıyla metin işleme amaçları için kullanmak, İngilizce olmayan metinlerde (hatta İngilizce olan ancak “cliché” gibi ödünç alınmış kelimeleri kullanan metinlerde) “é” gibi karakterleri harfler olarak işlemeyeceğinden bir dezavantajdır. İçerikleri biraz daha uzun olsa da, `\p` özellik grupları daha sağlamdır. ```{test: never} console.log(/\p{L}/u.test("α")); @@ -178,17 +178,17 @@ console.log(/\p{Script=Arabic}/u.test("α")); {{index "Number function"}} -On the other hand, if you are matching numbers in order to do something with them, you often do want `\d` for digits, since converting arbitrary numeric characters into a JavaScript number is not something that a function like `Number` can do for you. +Öte yandan, bir şeyler yapmak için sayıları eşleştirecekse, genellikle onlara yapılacak şeyler için `\d`'yi kullanmak istersiniz çünkü `Number` gibi bir fonksiyonun sizin için sayı atanmış rastgele herhangi bir karakterleri JavaScript sayısına dönüştürmesi mümkün değildir. -## Repeating parts of a pattern +## Bir desenin tekrarlanan bölümleri {{index ["regular expression", repetition]}} -We now know how to match a single digit. What if we want to match a whole number—a ((sequence)) of one or more ((digit))s? +Şimdi tek bir basamağı eşleştirmeyi nasıl yapacağımızı biliyoruz. Bir tam sayıyı - bir veya daha fazla ((rakam))ın bir ((dizi))sini eşleştirmek istersek ne yapmalıyız? {{index "plus character", repetition, "+ operator"}} -When you put a plus sign (`+`) after something in a regular expression, it indicates that the element may be repeated more than once. Thus, `/\d+/` matches one or more digit characters. +Düzenli ifadede bir artı işareti (`+`) bir şeyin birden fazla kez tekrarlanabileceğini gösterir. Dolayısıyla, `/\d+/`, bir veya daha fazla rakam karakteri eşleştirir. ``` console.log(/'\d+'/.test("'123'")); @@ -203,11 +203,11 @@ console.log(/'\d*'/.test("''")); {{index "* operator", asterisk}} -The star (`*`) has a similar meaning but also allows the pattern to match zero times. Something with a star after it never prevents a pattern from matching—it'll just match zero instances if it can't find any suitable text to match. +Yıldız (`*`) benzer bir anlama sahiptir, ancak aynı zamanda kalıbın sıfır kez eşleşmesine izin verir. Bir şeyin sonunda yıldız olan bir şey asla bir kalıbın eşleşmesini engellemez - uygun metni bulamazsa sadece sıfır örnekler eşleştirir. {{index "British English", "American English", "question mark"}} -A question mark (`?`) makes a part of a pattern _((optional))_, meaning it may occur zero times or one time. In the following example, the _u_ character is allowed to occur, but the pattern also matches when it is missing: +Bir soru işareti, kalıbın bir parçasını _((isteğe bağlı))_ yapar, yani sıfır veya bir kez olabilir. Aşağıdaki örnekte, _u_ karakterinin olması izin verilir, ancak kalıp aynı zamanda eksik olduğunda da eşleşir. ``` let neighbor = /neighbou?r/; @@ -219,11 +219,11 @@ console.log(neighbor.test("neighbor")); {{index repetition, [braces, "in regular expression"]}} -To indicate that a pattern should occur a precise number of times, use braces. Putting `{4}` after an element, for example, requires it to occur exactly four times. It is also possible to specify a ((range)) this way: `{2,4}` means the element must occur at least twice and at most four times. +Bir kalıbın belirli bir sayı kadar gerçekleşmesi gerektiğini belirtmek için süslü parantezler kullanın. Örneğin, bir öğeden sonra `{4}` yazmak, onun tam olarak dört kez gerçekleşmesini gerektirir. Ayrıca bu şekilde bir ((aralık)) belirlemek de mümkündür: `{2,4}` öğenin en az iki kez ve en fazla dört kez gerçekleşmesini gerektirir. {{id date_regexp_counted}} -Here is another version of the ((date)) and ((time)) pattern that allows both single- and double-((digit)) days, months, and hours. It is also slightly easier to decipher. +İşte hem tek hem de çift ((rakam)) günleri, ayları ve saatleri olan ((tarih)) ve ((zaman)) kalıbının başka bir versiyonu. Ayrıca anlaması da biraz daha kolaydır. ``` let dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/; @@ -231,13 +231,13 @@ console.log(dateTime.test("1-30-2003 8:45")); // → true ``` -You can also specify open-ended ((range))s when using braces by omitting the number after the comma. For example, `{5,}` means five or more times. +Süslü parantezleri kullanırken, bir sayıdan sonraki virgülü atlayarak açık uçlu ((aralık))lar belirleyebilirsiniz. Bu nedenle, `{5,}` beş veya daha fazla kez anlamına gelir. -## Grouping subexpressions +## Alt ifadeleri gruplandırma {{index ["regular expression", grouping], grouping, [parentheses, "in regular expressions"]}} -To use an operator like `*` or `+` on more than one element at a time, you must use parentheses. A part of a regular expression that is enclosed in parentheses counts as a single element as far as the operators following it are concerned. +`*` veya `+` gibi bir operatörü aynı anda birden fazla öğe üzerinde kullanmak istiyorsanız, parantezleri kullanmanız gerekir. Parantezlerle çevrili bir düzenli ifade parçası, onu takip eden operatörler açısından tek bir öğe olarak sayılır. ``` let cartoonCrying = /boo+(hoo+)+/i; @@ -247,17 +247,17 @@ console.log(cartoonCrying.test("Boohoooohoohooo")); {{index crying}} -The first and second `+` characters apply only to the second `o` in `boo` and `hoo`, respectively. The third `+` applies to the whole group `(hoo+)`, matching one or more sequences like that. +İlk ve ikinci `+` karakteri, sırasıyla _boo_ ve _hoo_'daki ikinci _o_ için uygulanır. Üçüncü `+`, `(hoo+)` grubuna tamamen uygulanır, bir veya daha fazla benzer dizilerle eşleşir. {{index "case sensitivity", capitalization, ["regular expression", flags]}} -The `i` at the end of the expression in the example makes this regular expression case-insensitive, allowing it to match the uppercase _B_ in the input string, even though the pattern is itself all lowercase. +Örnekteki ifadenin sonundaki `i`, bu düzenli ifadeyi harf büyüklüğüne duyarsız hale getirir, böylece model kendisi tamamen küçük harfken giriş dizgisindeki büyük harf _B_ ile de eşleşir. -## Matches and groups +## Maçlar ve gruplar {{index ["regular expression", grouping], "exec method", [array, "RegExp match"]}} -The `test` method is the absolute simplest way to match a regular expression. It tells you only whether it matched and nothing else. Regular expressions also have an `exec` (execute) method that will return `null` if no match was found and return an object with information about the match otherwise. +`test` metodu, bir düzenli ifadeyi eşlemek için mutlak en basit yoldur. Sadece eşleşip eşleşmediğini söyler ve başka hiçbir şey söylemez. Düzenli ifadelerin ayrıca `exec` (çalıştır) adlı bir metodu vardır; bu metot, eşleşme bulunamazsa `null` döndürür ve aksi takdirde eşleşme hakkında bilgi içeren bir nesne döndürür. ``` let match = /\d+/.exec("one two 100"); @@ -269,11 +269,11 @@ console.log(match.index); {{index "index property", [string, indexing]}} -An object returned from `exec` has an `index` property that tells us _where_ in the string the successful match begins. Other than that, the object looks like (and in fact is) an array of strings, whose first element is the string that was matched. In the previous example, this is the sequence of ((digit))s that we were looking for. +`exec` tarafından döndürülen bir nesne, başarılı eşleşmenin dizede _nerede_ başladığını belirten bir `index` özelliğine sahiptir. Bunun dışında, nesne eşleşen dizgeyi içeren bir dize dizisi gibi görünür ki zaten öyledir de. Önceki örnekte, bu aradığımız ((rakam)) dizisidir. {{index [string, methods], "match method"}} -String values have a `match` method that behaves similarly. +Dize değerleri benzer şekilde davranan bir `match` metodu içerir. ``` console.log("one two 100".match(/\d+/)); @@ -282,7 +282,7 @@ console.log("one two 100".match(/\d+/)); {{index grouping, "capture group", "exec method"}} -When the regular expression contains subexpressions grouped with parentheses, the text that matched those groups will also show up in the array. The whole match is always the first element. The next element is the part matched by the first group (the one whose opening parenthesis comes first in the expression), then the second group, and so on. +Düzenli ifade, parantezlerle gruplandırılmış alt ifadeler içeriyorsa, bu gruplarla eşleşen metinlerin de dizi içinde görünür. Tüm eşleşme her zaman ilk öğedir. Bir sonraki öğe, ilk grup tarafından eşleştirilen kısım (ifadenin içindeki açılış parantezi önce gelen grup), ardından ikinci grup ve sonrasıdır. ``` let quotedText = /'([^']*)'/; @@ -292,7 +292,7 @@ console.log(quotedText.exec("she said 'hello'")); {{index "capture group"}} -When a group does not end up being matched at all (for example, when followed by a question mark), its position in the output array will hold `undefined`. When a group is matched multiple times (for example, when followed by a `+`), only the last match ends up in the array. +Bir grup hiç eşleşmediğinde (örneğin, bir soru işareti tarafından izlendiğinde), çıktı dizisindeki konumu `undefined` değerini tutar. Ve bir grup birden fazla kez eşleşirse (örneğin, bir `+` tarafından izlendiğinde), yalnızca son eşleşme diziye girer. ``` console.log(/bad(ly)?/.exec("bad")); @@ -301,7 +301,7 @@ console.log(/(\d)+/.exec("123")); // → ["123", "3"] ``` -If you want to use parentheses purely for grouping, without having them show up in the array of matches, you can put `?:` after the opening parenthesis. +Eşleşmelerin yalnızca gruplama amacıyla kullanılmasını istiyor ve döndürülen dizide gösterilmesini istemiyorsanız, açılış parantezinden sonra `?:` ekleyebilirsiniz. ``` console.log(/(?:na)+/.exec("banana")); @@ -310,15 +310,15 @@ console.log(/(?:na)+/.exec("banana")); {{index "exec method", ["regular expression", methods], extraction}} -Groups can be useful for extracting parts of a string. If we don't just want to verify whether a string contains a ((date)) but also extract it and construct an object that represents it, we can wrap parentheses around the digit patterns and directly pick the date out of the result of `exec`. +Gruplar, bir dizgenin parçalarını çıkarmak için yararlı olabilir. Bir dizgenin yalnızca bir ((tarih)) içerip içermediğini kontrol etmekle kalmayıp aynı zamanda bunu çıkarmak ve bunu temsil eden bir nesne oluşturmak istiyorsak, parantezleri sayı desenlerinin etrafına sarabilir ve `exec` fonksiyonunun sonucundan tarihi seçebiliriz. -But first we'll take a brief detour to discuss the built-in way to represent date and ((time)) values in JavaScript. +Ancak önce, JavaScript'te tarih ve ((zaman)) değerlerini temsil etmenin yerleşik yolunu tartışacağımız kısa bir yolculuğa çıkacağız. -## The Date class +## Date sınıfı {{index constructor, "Date class"}} -JavaScript has a standard `Date` class for representing ((date))s, or rather, points in ((time)). If you simply create a date object using `new`, you get the current date and time. +JavaScript'in ((tarih))leri - veya daha doğrusu, ((zaman)) noktalarını - temsil etmek için standart bir sınıfı vardır. Bu `Date` olarak adlandırılır. Sadece `new` kullanarak basitçe bir tarih nesnesi oluşturursanız, mevcut tarihi ve zamanı alırsınız. ```{test: no} console.log(new Date()); @@ -327,7 +327,7 @@ console.log(new Date()); {{index "Date class"}} -You can also create an object for a specific time. +Belirli bir zaman için bir nesne oluşturabilirsiniz. ``` console.log(new Date(2009, 11, 9)); @@ -338,13 +338,13 @@ console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); {{index "zero-based counting", [interface, design]}} -JavaScript uses a convention where month numbers start at zero (so December is 11), yet day numbers start at one. This is confusing and silly. Be careful. +JavaScript, ay numaralarının sıfırdan başladığı bir kural kullanır (bu nedenle Aralık 11'dir), ancak gün numaraları bir'den başlar. Bu kafa karıştırıcı ve saçma. Dikkatli olun. -The last four arguments (hours, minutes, seconds, and milliseconds) are optional and taken to be zero when not given. +Son dört argüman (saatler, dakikalar, saniyeler ve milisaniyeler) isteğe bağlıdır ve verilmediğinde sıfır kabul edilir. {{index "getTime method", timestamp}} -Timestamps are stored as the number of milliseconds since the start of 1970, in the UTC ((time zone)). This follows a convention set by "((Unix time))", which was invented around that time. You can use negative numbers for times before 1970. The `getTime` method on a date object returns this number. It is big, as you can imagine. +Zaman damgaları, UTC ((zaman dilimi)) başlangıcından itibaren geçen milisaniye sayısı olarak depolanır. Bu, o zaman civarında icat edilen "((Unix zamanı))" tarafından belirlenen bir kuralı izler. 1970'den önceki zamanlar için negatif sayılar kullanabilirsiniz. Bir tarih nesnesindeki `getTime` metodu bu sayıyı döndürür. Tahmin edebileceğiniz gibi, bu büyüktür. ``` console.log(new Date(2013, 11, 19).getTime()); @@ -355,15 +355,15 @@ console.log(new Date(1387407600000)); {{index "Date.now function", "Date class"}} -If you give the `Date` constructor a single argument, that argument is treated as such a millisecond count. You can get the current millisecond count by creating a new `Date` object and calling `getTime` on it or by calling the `Date.now` function. +`Date` constructor fonksiyonuna tek bir argüman verirseniz, bu argüman milisaniye olarak kabul edilir. Mevcut milisaniye sayısını elde etmek için yeni bir `Date` nesnesi oluşturabilir ve üzerinde `getTime` çağrısı yapabilir veya `Date.now` fonksiyonunu çağırabilirsiniz. {{index "getFullYear method", "getMonth method", "getDate method", "getHours method", "getMinutes method", "getSeconds method", "getYear method"}} -Date objects provide methods such as `getFullYear`, `getMonth`, `getDate`, `getHours`, `getMinutes`, and `getSeconds` to extract their components. Besides `getFullYear` there's also `getYear`, which gives you the year minus 1900 (`98` or `119`) and is mostly useless. +Tarih nesneleri, bileşenlerini çıkarmak için `getFullYear`, `getMonth`, `getDate`, `getHours`, `getMinutes`, ve `getSeconds` gibi metodlar sağlar. `getFullYear` dışında, size yılın 1900 çıkarılmış halini (`98` veya `119`) veren `getYear` da vardır ve çoğunlukla kullanışsızdır. {{index "capture group", "getDate method", [parentheses, "in regular expressions"]}} -Putting parentheses around the parts of the expression that we are interested in, we can now create a date object from a string. +İlgilendiğimiz ifade parçalarını parantez içine alarak, şimdi bir dizeyi bir tarih nesnesine dönüştürebiliriz. ``` function getDate(string) { @@ -377,27 +377,27 @@ console.log(getDate("1-30-2003")); {{index destructuring, "underscore character"}} -The underscore (`_`) binding is ignored and used only to skip the full match element in the array returned by `exec`. +`exec` tarafından döndürülen dizideki `_` (alt çizgi) bağlantısı dikkate alınmaz ve yalnızca tam eşleşme öğesini atlamak için kullanılır. -## Boundaries and look-ahead +## Sınırlar ve görünüm {{index matching, ["regular expression", boundary]}} -Unfortunately, `getDate` will also happily extract a date from the string `"100-1-30000"`. A match may happen anywhere in the string, so in this case, it'll just start at the second character and end at the second-to-last character. +Maalesef, `getDate` aynı zamanda dize `"100-1-30000"` içinden de bir tarih alır. Bir eşleşme dize içinde herhangi bir yerde olabilir, bu nedenle bu durumda, sadece ikinci karakterden başlayıp sondan ikinci karakterde sona erecektir. {{index boundary, "caret character", "dollar sign"}} -If we want to enforce that the match must span the whole string, we can add the markers `^` and `$`. The caret matches the start of the input string, whereas the dollar sign matches the end. Thus `/^\d+$/` matches a string consisting entirely of one or more digits, `/^!/` matches any string that starts with an exclamation mark, and `/x^/` does not match any string (there cannot be an `x` before the start of the string). +Eşleşmenin dizeyi tamamen kaplaması gerektiğini zorlamak istiyorsak, `^` ve `$` işaretlerini ekleyebiliriz. Caret giriş dizesinin başlangıcına uyar, dolar işareti ise sona uyar. Bu nedenle, `/^\d+$/`, yalnızca bir veya daha fazla rakamdan oluşan bir dizeyi eşleştirir, `/^!/` bir ünlem işareti ile başlayan herhangi bir diziyi eşleştirir ve `/x^/` hiçbir dizeyi eşleştirmez (dizenin başlangıcından önce bir _x_ olamaz). {{index "word boundary", "word character"}} -There is also a `\b` marker that matches _word boundaries_, positions that have a word character one side, and a non-word character on the other. Unfortunately, these use the same simplistic concept of word characters as `\w`, and are therefore not very reliable. +"kelime sınırlarıyla" eşleşen `\b` işareti vardır, bu pozisyonlar bir tarafta kelime kararkteri bir tarafta kelime olmayan bir karakteri barındırır. `\w` da "kelime karakterleri" kavramı gibi basit kavramlarını kullanır ve bu nedenle pek güvenilir değildir. -Note that these boundary markers don't match any actual characters. They just enforce that a given condition holds at the place where they appears in the pattern. +Bu işaretlerin herhangi bir gerçek karakterle eşleşmediğini unutmayın. Sadece desende göründükleri yerde belirli bir koşulun geçerli olmasını sağlarlar. {{index "look-ahead"}} -_Look-ahead_ tests do something similar. They provide a pattern and will make the match fail if the input doesn't match that pattern, but don't actually move the match position forward. They are written between `(?=` and `)`. +İleri görüşlü testler de buna benzer bir şey yapar. Bir desen sağlar ve girdinin bu desene uymadığı durumlarda eşleşmeyi başarısız kılar, ancak aslında eşleşme konumunu ileri taşımaz. Bunlar `(?=` ve `)` arasında yazılır. ``` console.log(/a(?=e)/.exec("braeburn")); @@ -406,15 +406,15 @@ console.log(/a(?! )/.exec("a b")); // → null ``` -The `e` in the first example is necessary to match, but is not part of the matched string. The `(?! )` notation expresses a _negative_ look-ahead. This only matches if the pattern in the parentheses _doesn't_ match, causing the second example to only match `a` characters that don't have a space after them. +İlk örnekteki `e`'nin eşleşen dize parçasının bir parçası olmamasına rağmen eşleşme için gerekli olduğuna dikkat edin. `(?! )` notasyonu _negatif_ bir ön görüş ifade eder. Bu, ikinci örnekte yalnızca kendisinden sonra boşluk olmayan "a" karakterlerinin eşleşmesini sağlar. -## Choice patterns +## Seçim desenleri {{index branching, ["regular expression", alternatives], "farm example"}} -Say we want to know whether a piece of text contains not only a number but a number followed by one of the words _pig_, _cow_, or _chicken_, or any of their plural forms. +Bir metin parçasının sadece bir sayıyı değil, bir sayıyı ve bununla birlikte _pig_, _cow_, veya _chicken_ gibi kelimelerden birini veya bunların çoğul biçimlerinden herhangi birini içerip içermediğini bilmek istediğimizi varsayalım. -We could write three regular expressions and test them in turn, but there is a nicer way. The ((pipe character)) (`|`) denotes a ((choice)) between the pattern to its left and the pattern to its right. We can use it in expressions like this: +Üç düzenli ifade yazıp sırayla test edebiliriz, ancak daha güzel bir yol var. ((boru karakteri)) (`|`), solundaki desen ile sağdaki desen arasında ((seçim)) olarak işlev görür. Dolayısıyla, bunu diyebilirim: ``` let animalCount = /\d+ (pig|cow|chicken)s?/; @@ -426,63 +426,64 @@ console.log(animalCount.test("15 pugs")); {{index [parentheses, "in regular expressions"]}} -Parentheses can be used to limit the part of the pattern to which the pipe operator applies, and you can put multiple such operators next to each other to express a choice between more than two alternatives. +Parantezler, boru operatörünün uygulandığı desenin kısmını sınırlamak için kullanılabilir ve birden çok bu tür operatörü yan yana koyarak ikiden fazla alternatif arasında bir seçimi ifade edebilirsiniz. -## The mechanics of matching +## Eşleştirme mekaniği {{index ["regular expression", matching], [matching, algorithm], "search problem"}} -Conceptually, when you use `exec` or `test`, the regular expression engine looks for a match in your string by trying to match the expression first from the start of the string, then from the second character, and so on until it finds a match or reaches the end of the string. It'll either return the first match that can be found or fail to find any match at all. +Kavramsal olarak, `exec` veya `test` kullandığınızda, düzenli ifade motoru, dize içinde eşleşme arar ve ifadeyi ilk olarak dize başlangıcından itibaren eşleştirmeye çalışır, ardından ikinci karakterden itibaren ve bunu bir eşleşme bulana veya dize sonuna ulaşana kadar sürdürür. Bulunabilecek ilk eşleşmeyi ya döndürür ya da hiçbir eşleşme bulamaz. {{index ["regular expression", matching], [matching, algorithm]}} -To do the actual matching, the engine treats a regular expression something like a ((flow diagram)). This is the diagram for the livestock expression in the previous example: +Gerçek eşleştirmeyi yapmak için, motor, düzenli ifadeyi bir ((akış diyagramı)) gibi işler. Bu, önceki örnekteki hayvan ifadesinin diyagramıdır: -{{figure {url: "img/re_pigchickens.svg", alt: "Railroad diagram that first passes through a box labeled 'digit', which has a loop going back from after it to before it, and then a box for a space character. After that, the railroad splits in three, going through boxes for 'pig', 'cow', and 'chicken'. After those it rejoins, and goes through a box labeled 's', which, being optional, also has a railroad that passes it by. Finally, the line reaches the accepting state."}}} +{{figure {url: "img/re_pigchickens.svg", alt: "İlk önce 'rakam' etiketli bir kutudan geçen, sonra geri dönen bir döngü ve daha sonra bir boşluk karakteri için bir kutudan geçen demiryolu diyagramı. Bundan sonra, demiryolu üçte ayrılır, 'domuz', 'inek' ve 'tavuk' için kutulardan geçer. Onlardan sonra tekrar birleşir ve isteğe bağlı olarak, onu geçen bir demiryoluna sahip olan 'S' etiketli bir kutudan geçer. Son olarak, çizgi kabul eden duruma ulaşır."}}} {{index traversal}} -If we can find a path from the left side of the diagram to the right side, our expression matches. We keep a current position in the string, and every time we move through a box, we verify that the part of the string after our current position matches that box. +Our expression matches if we can find a path from the left side of the diagram to the right side. We keep a current position in the string, and every time we move through a box, we verify that the part of the string after our current position matches that box. +İfademiz, diyagramın sol tarafından sağ tarafına bir yol bulabilirse eşleşir. Dizgede bir geçerli konum tutarız ve her bir kutudan geçerken, mevcut konumumuzdan sonrasının kutu ile eşleşip eşleşmediğini doğrularız. {{id backtracking}} -## Backtracking +## Geri izleme {{index ["regular expression", backtracking], "binary number", "decimal number", "hexadecimal number", "flow diagram", [matching, algorithm], backtracking}} -The regular expression `/^([01]+b|[\da-f]+h|\d+)$/` matches either a binary number followed by a `b`, a hexadecimal number (that is, base 16, with the letters `a` to `f` standing for the digits 10 to 15) followed by an `h`, or a regular decimal number with no suffix character. This is the corresponding diagram: +Düzenli ifade `/^([01]+b|[\da-f]+h|\d+)$/` ya bir ikili sayıyının sonrasında bir _b_ olan, ya bir onaltılı sayıyı (yani, harfler _a_ ile _f_ 10 ile 15 arasındaki rakamları temsil ettiği) sonrasında bir _h_ olan ya da hiçbir son ek karakteri olmayan bir düzenli ondalık sayıyı eşleştirir. Bu, karşılık gelen diyagramdır: -{{figure {url: "img/re_number.svg", alt: "Railroad diagram for the regular expression '^([01]+b|\\d+|[\\da-f]+h)$'"}}} +{{figure {url: "img/re_number.svg", alt: "'^([01]+b|\\d+|[\\da-f]+h)$' düzenli ifadesi için demiryolu diyagramı."}}} {{index branching}} -When matching this expression, the top (binary) branch will often be entered even though the input does not actually contain a binary number. When matching the string `"103"`, for example, it becomes clear only at the `3` that we are in the wrong branch. The string _does_ match the expression, just not the branch we are currently in. +Bu ifadeyi eşleştirirken, girişin gerçekte bir ikili sayı içermediği durumda bile genellikle üst (ikili) şubeye girilir. Örneğin, dize `"103"` ile eşleştirirken, 3 karakterini gördüğümüzde yanlış şubede olduğumuzu sonradan anlayabiliriz. Dize ifadeye _uyar_, ancak şu anda bulunduğumuz şubeye değil. {{index backtracking, "search problem"}} -So the matcher _backtracks_. When entering a branch, it remembers its current position (in this case, at the start of the string, just past the first boundary box in the diagram) so that it can go back and try another branch if the current one does not work out. For the string `"103"`, after encountering the `3` character, the matcher starts trying the branch for hexadecimal numbers, which fails again because there is no `h` after the number. It then tries the decimal number branch. This one fits, and a match is reported after all. +Bu nedenle eşleyici geri döner. Bir şubeye girerken, mevcut konumunu (bu durumda diyagramdaki ilk sınır kutusunun hemen ötesinde, dizenin başlangıcında) hatırlar, böylece mevcut şube işe yaramazsa başka bir şube denemek için geri dönebilir. `"103"` dizesi için 3 karakterini gördükten sonra, onaltılı sayılar şubesini denemeye başlar, ancak sayıdan sonra bir _h_ olmadığı için bu şube başarısız olur. Sonra ondalık sayı şubesini dener. Bu uygun olur ve sonunda bir eşleşme bildirilir. {{index [matching, algorithm]}} -The matcher stops as soon as it finds a full match. This means that if multiple branches could potentially match a string, only the first one (ordered by where the branches appear in the regular expression) is used. +Eşleyici, bir tam eşleşme bulduğunda durur. Bu, birden çok şubenin bir dizeyi potansiyel olarak eşleştirebileceği durumlarda, yalnızca ilk şubenin (düzenli ifade içinde şubelerin göründüğü yere göre sıralanır) kullanılacağı anlamına gelir. -Backtracking also happens for ((repetition)) operators like + and `*`. If you match `/^.*x/` against `"abcxe"`, the `.*` part will first try to consume the whole string. The engine will then realize that it needs an `x` to match the pattern. Since there is no `x` past the end of the string, the star operator tries to match one character less. But the matcher doesn't find an `x` after `abcx` either, so it backtracks again, matching the star operator to just `abc`. _Now_ it finds an `x` where it needs it and reports a successful match from positions 0 to 4. +Geri dönme, `+` ve `*` gibi ((tekrar)) operatörleri için de geçerlidir. `"abcxe"` ile `/^.*x/` eşleşirse, `.*` kısmı önce tüm diziyi tüketmeye çalışır. Daha sonra, deseni eşleştirmek için bir _x_ gerektiğini fark eder. Dizinin sonunda bir _x_ olmadığı için, yıldız operatörü bir karakter daha az eşleşmeye çalışır. Ancak eşleşme, `abcx`'ten sonra bir _x_ bulamaz, bu nedenle tekrar geri döner ve yıldız operatörünü sadece `abc`'ye eşleştirmeye çalışır. Şimdi ihtiyacı olan yere bir _x_ bulur ve 0 ile 4 arasında başarılı bir eşleşme bildirir. {{index performance, complexity}} -It is possible to write regular expressions that will do a _lot_ of backtracking. This problem occurs when a pattern can match a piece of input in many different ways. For example, if we get confused while writing a binary-number regular expression, we might accidentally write something like `/([01]+)+b/`. +_Çok fazla_ dönme yapacak düzenli ifadeler yazmak mümkündür. Bu problem, bir desenin bir girişi birçok farklı şekilde eşleştirebilmesi durumunda ortaya çıkar. Örneğin, bir ikili sayı düzenli ifadesi yazarken kafamız karışırsa, yanlışlıkla `/([01]+)+b/` gibi bir şey yazabiliriz. -{{figure {url: "img/re_slow.svg", alt: "Railroad diagram for the regular expression '([01]+)+b'",width: "6cm"}}} +{{figure {url: "img/re_slow.svg", alt: "'([01]+)+b' düzenli ifadesi için demiryolu diyagramı.", width: "6cm"}}} {{index "inner loop", [nesting, "in regexps"]}} -If that tries to match some long series of zeros and ones with no trailing _b_ character, the matcher first goes through the inner loop until it runs out of digits. Then it notices there is no _b_, so it backtracks one position, goes through the outer loop once, and gives up again, trying to backtrack out of the inner loop once more. It will continue to try every possible route through these two loops. This means the amount of work _doubles_ with each additional character. For even just a few dozen characters, the resulting match will take practically forever. +Eğer bu, sona gelen _b_ karakteri olmadan uzun bir sıfır ve birler serisiyle eşleşmeye çalışırsa, eşleyici önce iç döngüden geçer ve bunu rakamlar bitene kadar yapmaya devam eder. Sonra _b_ olmadığını fark eder, bu yüzden bir konum geri döner, dış döngüden bir kez geçer ve yine vazgeçip iç döngüden bir kez daha geri dönmeye çalışır. Bu iki döngü arasındaki herhangi bir olası rotayı denemeye devam eder. Bu, her ek karakterle çalışmanın işini ikiye katlanacağı anlamına gelir. Yalnızca birkaç düzine karakter için bile, elde edilen eşleşme neredeyse sonsuza kadar sürer. -## The replace method +## replace metodu {{index "replace method", "regular expression"}} -String values have a `replace` method that can be used to replace part of the string with another string. +Dize değerleri, bir dizeyi başka bir dizeyle değiştirmek için `replace` metoduna sahiptir. ``` console.log("papa".replace("p", "m")); @@ -491,7 +492,7 @@ console.log("papa".replace("p", "m")); {{index ["regular expression", flags], ["regular expression", global]}} -The first argument can also be a regular expression, in which case the first match of the regular expression is replaced. When a `g` option (for _global_) is added after the regular expression, _all_ matches in the string will be replaced, not just the first. +İlk argüman ayrıca bir düzenli ifade de olabilir, bu durumda düzenli ifadenin ilk eşleşmesi değiştirilir. Düzenli ifadenin ardından bir `g` seçeneği (_global_ için) eklenirse, dizedeki yalnızca ilk değil _tüm_ eşleşmeler değiştirilir. ``` console.log("Borobudur".replace(/[ou]/, "a")); @@ -502,7 +503,7 @@ console.log("Borobudur".replace(/[ou]/g, "a")); {{index grouping, "capture group", "dollar sign", "replace method", ["regular expression", grouping]}} -The real power of using regular expressions with `replace` comes from the fact that we can refer to matched groups in the replacement string. For example, say we have a big string containing the names of people, one name per line, in the format `Lastname, Firstname`. If we want to swap these names and remove the comma to get a `Firstname Lastname` format, we can use the following code: +`replace` ile düzenli ifadeleri kullanmanın gerçek gücü, eşleşen gruplara değiştirme dizesinde başvurabileceğimiz gerçeğinden gelir. Örneğin, her bir satırda `Lastname, Firstname` biçiminde bir ad bulunan büyük bir dizeye sahip olduğumuzu varsayalım. Bu isimleri değiştirmek ve virgülü kaldırarak `Firstname Lastname` biçimini elde etmek istiyorsak, aşağıdaki kodu kullanabiliriz: ``` console.log( @@ -513,13 +514,13 @@ console.log( // Robin Milner ``` -The `$1` and `$2` in the replacement string refer to the parenthesized groups in the pattern. `$1` is replaced by the text that matched against the first group, `$2` by the second, and so on, up to `$9`. The whole match can be referred to with `$&`. +Değiştirme dizesindeki `$1` ve `$2`, desendeki parantez içi gruplara başvurur. `$1`, ilk gruba karşı eşleşen metin ile değiştirilir, `$2` ikinci grup ile değiştirilir ve böyle devam eder, `$9`'a kadar. Tüm eşleşme `$&` ile başvurulabilir. {{index [function, "higher-order"], grouping, "capture group"}} -It is possible to pass a function—rather than a string—as the second argument to `replace`. For each replacement, the function will be called with the matched groups (as well as the whole match) as arguments, and its return value will be inserted into the new string. +`replace` metoduna ikinci argüman olarak bir dize yerine fonksiyon vermek mümkündür. Her değiştirme için, fonksiyon, eşleşen gruplarla (ayrıca tüm eşleşme ile) argüman olarak çağrılır ve dönüş değeri yeni dizeye eklenir. -Here's an example: +İşte bir örnek: ``` let stock = "1 lemon, 2 cabbages, and 101 eggs"; @@ -536,15 +537,15 @@ console.log(stock.replace(/(\d+) (\p{L}+)/gu, minusOne)); // → no lemon, 1 cabbage, and 100 eggs ``` -This code takes a string, finds all occurrences of a number followed by an alphanumeric word, and returns a string that has one less of every such quantity. +Bu bir dize alır, bir alfasayısal kelime tarafından izlenen tüm sayı geçişlerini bulur ve o türdeki her sayıdan bir eksik dize döndürür. -The `(\d+)` group ends up as the `amount` argument to the function, and the `(\p{L}+)` group gets bound to `unit`. The function converts `amount` to a number—which always works since it matched `\d+` earlier—and makes some adjustments in case there is only one or zero left. +`(\d+)` grubu, fonksiyona `amount` argümanı olarak gelir ve `(\p{L}+)` grubu `unit` olarak gelir. Fonksiyon, `amount`'u bir sayıya dönüştürür -her zaman `\d+` ile eşleştiğinden- ve yalnızca bir veya sıfır kaldığında bazı ayarlamalar yapar. -## Greed +## Açgözlülük {{index greed, "regular expression"}} -We can use `replace` to write a function that removes all ((comment))s from a piece of JavaScript ((code)). Here is a first attempt: +Tüm ((yorum))ları bir JavaScript ((kodu)) parçasından kaldıran bir fonksiyon yazmak için `replace` metodunu kullanmak mümkündür. İşte bir ilk deneme: ```{test: wrap} function stripComments(code) { @@ -560,17 +561,17 @@ console.log(stripComments("1 /* a */+/* b */ 1")); {{index "period character", "slash character", "newline character", "empty set", "block comment", "line comment"}} -The part before the `|` operator matches two slash characters followed by any number of non-newline characters. The part for multiline comments is more involved. We use `[^]` (any character that is not in the empty set of characters) as a way to match any character. We cannot just use a period here because block comments can continue on a new line, and the period character does not match newline characters. +_Veya_ operatöründen önceki kısım iki eğik çizgi karakterini ve ardından gelen herhangi yeni satır olmayan karakteri eşleştirir. Çok satırlı yorumlar için kısım daha karmaşıktır. Herhangi bir karakteri eşleştirmenin bir yolu olarak `[^]` (boş karakter kümesinde olmayan herhangi bir karakter) kullanırız. Burada sadece bir nokta kullanamayız çünkü blok yorumları yeni bir satırda devam edebilir ve nokta karakteri yeni satır karakterlerini eşleştirmez. -But the output for the last line appears to have gone wrong. Why? +Ancak, son satırın çıktısında bir sorun varmış gibi duruyor. Neden? {{index backtracking, greed, "regular expression"}} -The `[^]*` part of the expression, as I described in the section on backtracking, will first match as much as it can. If that causes the next part of the pattern to fail, the matcher moves back one character and tries again from there. In the example, the matcher first tries to match the whole rest of the string and then moves back from there. It will find an occurrence of `*/` after going back four characters and match that. This is not what we wanted—the intention was to match a single comment, not to go all the way to the end of the code and find the end of the last block comment. +Desendeki `[^]*` kısmı, geri dönme bölümünde açıkladığım gibi, önce bulabileceği kadar çok şeyi eşleştirir. Bu, desenin bir sonraki kısmının başarısız olmasına neden olursa, eşleyici bir karakter geri gider ve oradan tekrar denemeye çalışır. Örnekte, eşleyici önce dizinin geri kalanının tamamını eşleştirmeye çalışır ve oradan geri gider. `*/`'nın bir eşleşmesini dört karakter geri giderek bulacaktır. Bu istediğimiz şey değildi - niyetimiz bir tek yorumu eşleştirmekti, kodun en sonuna gidip en sonda bulunan yorum bloğu sonunu bulmak değil. -Because of this behavior, we say the repetition operators (`+`, `*`, `?`, and `{}`) are _((greed))y_, meaning they match as much as they can and backtrack from there. If you put a ((question mark)) after them (`+?`, `*?`, `??`, `{}?`), they become nongreedy and start by matching as little as possible, matching more only when the remaining pattern does not fit the smaller match. +Bu davranış nedeniyle, tekrar operatörleri (`+`, `*`, `?`, ve `{}`) _((açgöz))lü_ olarak adlandırılır, yani olabildiğince çok şey eşleştirirler ve oradan geri dönerler. Onlardan sonra ((soru işareti)) (`+?`, `*?`, `??`, `{}?`) koyarsanız, artık açgözlü olmazlar ve önce mümkün olduğunca az eşleşen bir diziyle başlarlar, daha küçük eşleşme uygun gelmediğinde daha fazla eşleştirirler. -And that is exactly what we want in this case. By having the star match the smallest stretch of characters that brings us to a `*/`, we consume one block comment and nothing more. +Ve bu durumda tam olarak istediğimiz budur. Yıldızın bizi `*/`'a getiren en küçük karakter dizisini eşleştirmesiyle, bir blok yorumu tüketiriz ve daha fazlasını değil. ```{test: wrap} function stripComments(code) { @@ -580,13 +581,13 @@ console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1 ``` -A lot of ((bug))s in ((regular expression)) programs can be traced to unintentionally using a greedy operator where a nongreedy one would work better. When using a ((repetition)) operator, prefer the nongreedy variant. +((Düzenli ifade)) programlarında birçok ((hata)), daha iyi çalışan bir açgözlü olmayan operatör yerine yanlışlıkla açgözlü bir operatör kullanmanın sonucudur. Bir ((tekrar)) operatörü kullanırken, açgözlü olmayan varyantı tercih edin. -## Dynamically creating RegExp objects +## Dinamik olarak RegExp nesleri yaratmak {{index ["regular expression", creation], "underscore character", "RegExp class"}} -In some cases you may not know the exact ((pattern)) you need to match against when you are writing your code. Say you want to test for the user's name in a piece of text. You can build up a string and use the `RegExp` ((constructor)) on that. +Kodunuzu yazarken eşleştirmeniz gereken tam ((kalıbı)) bilmediğiniz durumlar vardır. Bir metin parçasında kullanıcının adını test etmek istediğinizi varsayalım. Bir dize biriktirip `RegExp` ((constructor)) fonksiyonunu üzerinde kullanabilirsiniz. İşte bir örnek: ``` let name = "harry"; @@ -597,13 +598,13 @@ console.log(regexp.test("Harry is a dodgy character.")); {{index ["regular expression", flags], ["backslash character", "in regular expressions"]}} -When creating the `\s` part of the string, we have to use two backslashes because we are writing them in a normal string, not a slash-enclosed regular expression. The second argument to the `RegExp` constructor contains the options for the regular expression—in this case, `"gi"` for global and case-insensitive. +Dize kısmımda `\s` oluşturulurken, bunları bir bir düzenli ifade içinde değil de normal dize içinde yazdığımızdan ötürü iki ters eğik çizgi kullanmamız gerekiyor. `RegExp` constructor fonksiyonunun ikinci argümanı, düzenli ifade seçeneklerini içerir -bu durumda, global ve harf büyüklüğüne duyarsız olan `"gi"`. -But what if the name is `"dea+hl[]rd"` because our user is a ((nerd))y teenager? That would result in a nonsensical regular expression that won't actually match the user's name. +Peki ya kullanıcımız adı `"dea+hl[]rd"` olan bir ergen ((geek)) ise? Bu, kullanıcının adını gerçekten eşleştirmeyen anlamsız bir düzenli ifadeye yol açar. {{index ["backslash character", "in regular expressions"], [escaping, "in regexps"], ["regular expression", escaping]}} -To work around this, we can add backslashes before any character that has a special meaning. +Bunu çözmek için, özel bir anlamı olan her karakterin önüne ters eğik çizgi ekleyebiliriz. ``` let name = "dea+hl[]rd"; @@ -615,11 +616,11 @@ console.log(regexp.test(text)); // → true ``` -## The search method +## search metodu {{index ["regular expression", methods], "indexOf method", "search method"}} -While the `indexOf` method on strings cannot be called with a regular expression, there is another method, `search`, that does expect a regular expression. Like `indexOf`, it returns the first index on which the expression was found, or -1 when it wasn't found. +Dize üzerindeki `indexOf` metodu bir düzenli ifade ile çağrılamaz. Ancak, düzenli ifade bekleyen başka bir yöntem olan `search` adında bir yöntem vardır. `indexOf` gibi, ifadenin bulunduğu ilk index pozisyonunu döndürür veya bulunamadığında -1 döndürür. ``` console.log(" word".search(/\S/)); @@ -628,21 +629,21 @@ console.log(" ".search(/\S/)); // → -1 ``` -Unfortunately, there is no way to indicate that the match should start at a given offset (like we can with the second argument to `indexOf`), which would often be useful. +Ne yazık ki, eşleşmenin belirli bir konumdan başlaması gerektiğini belirtmenin bir yolu yoktur (`indexOf`'deki ikinci argümanla yaptığımız gibi), bu genellikle kullanışlı olurdu. -## The lastIndex property +## lastIndex özelliği {{index "exec method", "regular expression"}} -The `exec` method similarly does not provide a convenient way to start searching from a given position in the string. But it does provide an *in*convenient way. +`exec` metodu benzer şekilde, dizinde belirli bir konumdan aramaya başlamanın kolay bir yolunu sağlamaz. Ancak kolay _olmayan_, zor bir yolunu sağlar. {{index ["regular expression", matching], matching, "source property", "lastIndex property"}} -Regular expression objects have properties. One such property is `source`, which contains the string that expression was created from. Another property is `lastIndex`, which controls, in some limited circumstances, where the next match will start. +Düzenli ifade nesnelerinin özellikleri vardır. Bunlardan biri `source` özelliğidir ve değerinde bu ifadenin oluşturulduğu dizeyi barındırır. Başka bir özellik de `lastIndex`'tir, bazı sınırlı durumlarda bir sonraki eşleşmenin nereden başlayacağını kontrol eder. {{index [interface, design], "exec method", ["regular expression", global]}} -Those circumstances are that the regular expression must have the global (`g`) or sticky (`y`) option enabled, and the match must happen through the `exec` method. Again, a less confusing solution would have been to just allow an extra argument to be passed to `exec`, but confusion is an essential feature of JavaScript's regular expression interface. +Bu durumlar, düzenli ifadenin global (`g`) veya yapışkan (`y`) seçeneğinin etkinleştirilmiş olması ve eşleşmenin `exec` metodu aracılığıyla gerçekleşmiş olması gereklidir. Tabii, daha az kafa karışıklığına sebep olmak için `exec` metoduna ekstra bir argümanın verilmesine izin verilmesi daha iyi olurdu, ancak karışıklık JavaScript'in düzenli ifade arayüzünün temel bir özelliğidir. ``` let pattern = /y/g; @@ -656,9 +657,9 @@ console.log(pattern.lastIndex); {{index "side effect", "lastIndex property"}} -If the match was successful, the call to `exec` automatically updates the `lastIndex` property to point after the match. If no match was found, `lastIndex` is set back to zero, which is also the value it has in a newly constructed regular expression object. +Eşleşme başarılı olduysa, `exec` çağrısı otomatik olarak `lastIndex` özelliğini eşleşmenin sonrasına işaret edecek şekilde günceller. Eğer bir eşleşme bulunamadıysa, `lastIndex` sıfıra, aynı zamanda yeni oluşturulan bir düzenli ifade nesnesinin sahip olduğu değere geri döner. -The difference between the global and the sticky options is that when sticky is enabled, the match will succeed only if it starts directly at `lastIndex`, whereas with global, it will search ahead for a position where a match can start. +Global ve yapışkan seçenekler arasındaki fark, yapışkan etkinleştirildiğinde, eşleşme ancak `lastIndex`'te doğrudan başlaması durumunda başarılı olacağıdır, global kullanıldığındaysa, bir eşleşmenin başlayabileceği bir konumu arar. ``` let global = /abc/g; @@ -671,7 +672,7 @@ console.log(sticky.exec("xyz abc")); {{index bug}} -When using a shared regular expression value for multiple `exec` calls, these automatic updates to the `lastIndex` property can cause problems. Your regular expression might be accidentally starting at an index left over from a previous call. +Birden fazla `exec` çağrısı için paylaşılan bir düzenli ifade değeri kullanırken, bu otomatik güncellemeler `lastIndex` özelliğinin değerinde sorunlara neden olabilir. Düzenli ifadeniz yanlışlıkla önceki bir çağrıdan kalan index değerinden başlayabilir. ``` let digit = /\d/g; @@ -683,18 +684,20 @@ console.log(digit.exec("and now: 1")); {{index ["regular expression", global], "match method"}} -Another interesting effect of the global option is that it changes the way the `match` method on strings works. When called with a global expression, instead of returning an array similar to that returned by `exec`, `match` will find _all_ matches of the pattern in the string and return an array containing the matched strings. +Global seçeneğin başka bir ilginç etkisi de, dizeler üzerindeki `match` metodunun çalışma şeklini değiştirmesidir. Global bir ifade ile çağrıldığında, `exec` tarafından döndürülen diziye benzer bir dizi döndürmek yerine, `match`, dizedeki desenin _tüm_ eşleşmelerini bulur ve eşleşen dizeleri içeren bir dizi döndürür. ``` console.log("Banana".match(/an/g)); // → ["an", "an"] ``` -So be cautious with global regular expressions. The cases where they are necessary—calls to `replace` and places where you want to explicitly use `lastIndex`—are typically the situations where you want to use them. +Dolayısıyla, global düzenli ifadelerle dikkatli olun. Bunların gerekli olduğu durumlar - `replace` çağrıları ve açıkça `lastIndex`'i kullanmak istediğiniz yerler- genellikle bunları kullanmak istediğiniz tek yerlerdir. + +### Tüm eşleşmeleri alma {{index "lastIndex property", "exec method", loop}} -A common thing to do is to find all the matches of a regular expression in a string. We can do this by using the `matchAll` method. +Bir dizedeki bir düzenli ifadenin tüm eşleşmelerini bulmanın yaygın bir kullanımı vardır. Bunu `matchAll` metodunu kullanarak yapabiliriz. ``` let input = "A string with 3 numbers in it... 42 and 88."; @@ -709,14 +712,15 @@ for (let match of matches) { {{index ["regular expression", global]}} -This method returns an array of match arrays. The regular expression given to `matchAll` _must_ have `g` enabled. +Bu metod, bir dizi eşleşme dizisi döndürür. Verilen düzenli ifadenin _mutlaka_ `g` seçeneği etkinleştirilmiş olmalıdır. {{id ini}} -## Parsing an INI file + +## Bir INI dosyasını ayrıştırma(parse etme) {{index comment, "file format", "enemies example", "INI file"}} -To conclude the chapter, we'll look at a problem that calls for ((regular expression))s. Imagine we are writing a program to automatically collect information about our enemies from the ((Internet)). (We will not actually write that program here, just the part that reads the ((configuration)) file. Sorry.) The configuration file looks like this: +Bölümü sonlandırmak için, ((düzenli ifade))lere ihtiyaç duyulan bir soruna bakacağız. Düşmanlarımız hakkında ((internet))ten bilgi toplamak için bir program yazdığımızı hayal edin. (Burada aslında bu programı yazmayacağız, sadece ((konfigürasyon)) dosyasını okuyan kısmı yazacağız. Maalesef.) Konfigürasyon dosyası şöyle görünüyor: ```{lang: "null"} searchengine=https://duckduckgo.com/?q=$1 @@ -737,25 +741,25 @@ outputdir=/home/marijn/enemies/davaeorn {{index grammar}} -The exact rules for this format—which is a widely used file format, usually called an _INI_ file—are as follows: +Bu biçim için kesin kurallar (genellikle _INI_ dosyası olarak adlandırılan yaygın bir biçimdir) şunlardır: -- Blank lines and lines starting with semicolons are ignored. +- Boş satırlar ve noktalı virgül ile başlayan satırlar yoksayılır. -- Lines wrapped in `[` and `]` start a new ((section)). +- [ ve ] içinde sarmalanan satırlar yeni bir ((bölüm)) başlatır. -- Lines containing an alphanumeric identifier followed by an `=` character add a setting to the current section. +- Alfasayısal bir tanımlayıcıyı takiben bir `=` karakter içeren satırlar, mevcut bölüme bir ayar ekler. -- Anything else is invalid. +- Bunlardan başka her şey geçersizdir. -Our task is to convert a string like this into an object whose properties hold strings for settings written before the first section header and subobjects for sections, with those subobjects holding the section's settings. +Görevimiz, böyle bir dizeyi, ilk bölüm başlığından önce yazılan ayarları tutan özelliklere sahip nesneye ve bölümleri tutan alt nesnelerleri barındıran bir nesneye dönüştürmektir. {{index "carriage return", "line break", "newline character"}} -Since the format has to be processed ((line)) by line, splitting up the file into separate lines is a good start. We saw the `split` method in [Chapter ?](data#split). Some operating systems, however, use not just a newline character to separate lines but a carriage return character followed by a newline (`"\r\n"`). Given that the `split` method also allows a regular expression as its argument, we can use a regular expression like `/\r?\n/` to split in a way that allows both `"\n"` and `"\r\n"` between lines. +Biçimin ((satır)) satır işlenmesini gerektirdiğinden, dosyayı ayrı satırlara ayırmak iyi bir başlangıçtır. `split` metodunu [bölüm ?](data#split) içinde gördük. Ancak, bazı işletim sistemleri, sadece bir yeni satır karakterini değil, bir taşıma dönüş karakteri ve ardından bir yeni satır karakteri (`"\r\n"`) kullanır. `split` metodunun da bir düzenli ifadeyi argüman olarak almasına izin verildiğinden, `/\r?\n/` gibi bir düzenli ifade kullanarak, satırlar arasında hem `"\n"` hem de `"\r\n"` izin veren bir şekilde bölebiliriz. ```{startCode: true} function parseINI(string) { - // Start with an object to hold the top-level fields + // En üst seviye alanları tutabilmek için bir nesneyle başla let result = {}; let section = result; for (let line of string.split(/\r?\n/)) { @@ -780,25 +784,25 @@ city=Tessaloniki`)); {{index "parseINI function", parsing}} -The code goes over the file's lines and builds up an object. Properties at the top are stored directly into that object, whereas properties found in sections are stored in a separate section object. The `section` binding points at the object for the current section. +Kod, dosyanın satırlarını geçer ve bir nesne oluşturur. Üstteki özellikler doğrudan bu nesneye depolanırken, bölümlerde bulunan özellikler ayrı bir bölüm nesnesine depolanır. `section` bağlantısı, mevcut bölüm için olan nesneye işaret eder. -There are two kinds of significant lines—section headers or property lines. When a line is a regular property, it is stored in the current section. When it is a section header, a new section object is created, and `section` is set to point at it. +İki tür önemli satır vardır - bölüm başlıkları veya özellik satırları. Bir satır normal bir özellik olduğunda, mevcut bölüme depolanır. Bir bölüm başlığı olduğunda, yeni bir bölüm nesnesi oluşturulur ve `section` bunua işaret etmesi için ayarlanır. {{index "caret character", "dollar sign", boundary}} -Note the recurring use of `^` and `$` to make sure the expression matches the whole line, not just part of it. Leaving these out results in code that mostly works but behaves strangely for some input, which can be a difficult bug to track down. +`^` ve `$` işaretinin ifadenin sadece bir parçası değil, tüm satırı eşleştirmesini sağlamak için tekrar tekrar kullanılmasına dikkat edin. Bunları bırakmak, çoğunlukla işe yarayan ancak bazı girdiler için garip davranan bir kod sonucu ile sonuçlanır, bu da takip edilmesi zor bir hatadır. {{index "if keyword", assignment, ["= operator", "as expression"]}} -The pattern `if (match = string.match(...))` makes use of the fact that the value of an ((assignment)) expression (`=`) is the assigned value. You often aren't sure that your call to `match` will succeed, so you can access the resulting object only inside an `if` statement that tests for this. To not break the pleasant chain of `else if` forms, we assign the result of the match to a binding and immediately use that assignment as the test for the `if` statement. +`if (match = string.match(...))` kalıbı, bir ((atama)) ifadesinin (`=`) değerinin atanmış değer olduğu gerçeğinden yararlanır. `match` çağrınızın başarılı olacağından emin olamazsınız, bu yüzden sonucu yalnızca bunu test eden bir `if` ifadesi içinde erişebilirsiniz. `else if` zincirini bozmamak için, eşleşmenin sonucunu bir bağlantıya atar ve hemen bu atamayı `if` ifadesi için test olarak kullanırız. {{index [parentheses, "in regular expressions"]}} -If a line is not a section header or a property, the function checks whether it is a comment or an empty line using the expression `/^\s*(;|$)/` to match lines that either contain only space, or space followed by a semicolon (making the rest of the line a comment). When a line doesn't match any of the expected forms, the function throws an exception. +Bir satır eğer bir bölüm başlığı veya bir özellik değilse, fonksiyon, `/^\s*(;|$)/` ifadesini kullanarak satırın bir yorum veya boş bir satır olup olmadığını kontrol eder. Bir satırın beklenen biçimlerden hiçbirine uymadığı durumda, fonksiyon bir istisna fırlatır. -## Code units and characters +## Kod birimleri ve karakterler -Another design mistake that's been standardized in JavaScript regular expressions is that by default, operators like `.` or `?` work on code units, as discussed in [Chapter ?](higher_order#code_units), not actual characters. This means characters that are composed of two code units behave strangely. +JavaScript düzenli ifadelerinde standartlaştırılmış başka bir tasarım hatası da, [bölüm ?](higher_order#code_units) içinde tartışıldığı gibi varsayılan olarak `.` veya `?` gibi operatörlerin gerçek karakterler yerine kod birimleri üzerinde çalışmasıdır. Bu, iki kod biriminden oluşan karakterlerin garip davranmasına neden olur. ``` console.log(/🍎{3}/.test("🍎🍎🍎")); @@ -809,9 +813,9 @@ console.log(/<.>/u.test("<🌹>")); // → true ``` -The problem is that the 🍎 in the first line is treated as two code units, and `{3}` is applied only to the second unit. Similarly, the dot matches a single code unit, not the two that make up the rose ((emoji)). +Sorun, birinci satırdaki 🍎 karakterinin iki kod biriminden oluştuğu şekilde işlenmesidir ve `{3}` kısmının yalnızca ikincisi üzerinde uygulanmasıdır. Benzer şekilde, nokta tek bir kod birimini eşleştirir, gül ((emoji))'sini oluşturan ikiyi değil. -You must add the `u` (Unicode) option to your regular expression to make it treat such characters properly. +Bu tür karakterleri uygun bir şekilde işlemesi için düzenli ifadenize `u` (Unicode) seçeneğini eklemeniz gerekir. ``` console.log(/🍎{3}/u.test("🍎🍎🍎")); @@ -822,67 +826,68 @@ console.log(/🍎{3}/u.test("🍎🍎🍎")); ## Summary -Regular expressions are objects that represent patterns in strings. They use their own language to express these patterns. +Düzenli ifadeler, dizelerdeki kalıpları temsil eden nesnelerdir. Bu kalıpları ifade etmek için kendi dillerini kullanırlar. {{table {cols: [1, 5]}}} -| `/abc/` | A sequence of characters -| `/[abc]/` | Any character from a set of characters -| `/[^abc]/` | Any character _not_ in a set of characters -| `/[0-9]/` | Any character in a range of characters -| `/x+/` | One or more occurrences of the pattern `x` -| `/x+?/` | One or more occurrences, nongreedy -| `/x*/` | Zero or more occurrences -| `/x?/` | Zero or one occurrence -| `/x{2,4}/` | Two to four occurrences -| `/(abc)/` | A group -| `/a|b|c/` | Any one of several patterns -| `/\d/` | Any digit character -| `/\w/` | An alphanumeric character ("word character") -| `/\s/` | Any whitespace character -| `/./` | Any character except newlines -| `/\p{L}/u` | Any letter character -| `/^/` | Start of input -| `/$/` | End of input -| `/(?=a)/` | A look-ahead test +| `/abc/` | Bir dizi karakter +| `/[abc]/` | Bir dizi karakterden herhangi bir karakter +| `/[^abc]/` | Bir karakter kümesinde _olmayan_ herhangi bir karakter +| `/[0-9]/` | Belirli bir karakter aralığındaki herhangi bir karakter +| `/x+/` | `'x'` kalıbının bir veya daha fazla tekrarı +| `/x+?/` | `'x'`kalıbının açgözlü olmayan bir veya daha fazla belirişi +|`/x\*/` | Sıfır veya daha fazla beliriş +|`/x?/` | Sıfır veya bir beliriş +|`/x{2,4}/` | İkiden dörde kadar beliriş +|`/(abc)/` | Bir grup +|`/a|b|c/` | Kalıplardan bir tanesi +|`/\d/` | Herhangi bir rakam karakteri +|`/\w/` | Alfasayısal bir karakter ("kelime karakteri") +|`/\s/` | Herhangi bir boşluk karakteri +|`/./` | Yeni satır dışında herhangi bir karakter +|`/\p{L}/u` | Herhangi bir harf karakter +|`/^/` | Girdi başlangıcı +|`/$/` | Girdi sonu +|`/(?=a)/` | İleri görüşlü bir test -A regular expression has a method `test` to test whether a given string matches it. It also has a method `exec` that, when a match is found, returns an array containing all matched groups. Such an array has an `index` property that indicates where the match started. +Düzenli ifade, verilen bir dizenin onunla eşleşip eşleşmediğini test etmek için `test` metoduna sahiptir. Ayrıca, bir eşleşme bulunduğunda, tüm eşleşen grupları içeren bir dizi döndüren `exec` adında bir metod da vardır. Böyle bir dizi, eşleşmenin nerede başladığını gösteren bir `index` özelliğine sahiptir. -Strings have a `match` method to match them against a regular expression and a `search` method to search for one, returning only the starting position of the match. Their `replace` method can replace matches of a pattern with a replacement string or function. +Düzenli ifadeyle dizeleri eşleştirmek için dizelerin bir `match` metodu ve sadece eşleşmenin başlangıç pozisyonunu arayıp döndürmek için bir `search` metodu vardır. Onların `replace` metodu, bir desenin eşleşmelerini bir değiştirme dizesi veya fonksiyonu ile değiştirebilir. -Regular expressions can have options, which are written after the closing slash. The `i` option makes the match case insensitive. The `g` option makes the expression _global_, which, among other things, causes the `replace` method to replace all instances instead of just the first. The `y` option makes and expression sticky, which means that it will not search ahead and skip part of the string when looking for a match. The `u` option turns on Unicode mode, which enables `\p` syntax and fixes a number of problems around the handling of characters that take up two code units. +Düzenli ifadelerin seçenekleri olabilir, bunlar kapatma eğik çizgi sonrasına yazılır. `i` seçeneği, eşleşmenin harf büyüklüğüne duyarsız yapar. `g` seçeneği ifadeyi global yapar, bu da `replace` metodunun yalnızca ilk eşleşen dize yerine tüm eşleşen dize parçalarının değiştirmesine neden olur. `y` seçeneği yapışkandır, bu da bir eşleşme ararken bir dizenin bir kısmını önemsizce atlamayıp teker teker arayacağı anlamına gelir. `u` seçeneği Unicode modunu açar, bu da `\p` sözdizimini etkinleştirir ve iki kod birimini alan karakterlerin işlenmesindeki oluşan bir takım sorunları düzeltir. -Regular expressions are a sharp ((tool)) with an awkward handle. They simplify some tasks tremendously but can quickly become unmanageable when applied to complex problems. Part of knowing how to use them is resisting the urge to try to shoehorn things into them that they cannot cleanly express. +Düzenli ifadeler, garip bir sapı olan keskin bir ((araç))tır. Bazı görevleri büyük ölçüde basitleştirirler ancak karmaşık sorunlara uygulandığında hızla yönetilemez hale gelebilirler. Onları nasıl kullanacağınızın bir parçası, temiz bir şekilde ifade edemeyecekleri şeyleri zorla onlara sokuşturma dürtüsüne karşı koymaktır. -## Exercises +## Egzersizler {{index debugging, bug}} -It is almost unavoidable that, in the course of working on these exercises, you will get confused and frustrated by some regular expression's inexplicable ((behavior)). Sometimes it helps to enter your expression into an online tool like [_debuggex.com_](https://www.debuggex.com/) to see whether its visualization corresponds to what you intended and to ((experiment)) with the way it responds to various input strings. +Bu alıştırmalar üzerinde çalışırken, bazı düzenli ifadelerin açıklanamayan ((davranış))ları tarafından kafa karışıklığına uğrayacağınız ve bunlardan bazıları tarafından hızla sinirleneceğiniz neredeyse kaçınılmazdır. Bazen, ifadenizi [_debuggex.com_](https://www.debuggex.com/) gibi çevrimiçi bir araca girerek, oluşturduğu görselleştirmenin istediğiniz şeyle uyuşup uyuşmadığını görmek ve çeşitli giriş dizelerine nasıl yanıt verdiğini test etmek yardımcı olabilir. ### Regexp golf {{index "program size", "code golf", "regexp golf (exercise)"}} -_Code golf_ is a term used for the game of trying to express a particular program in as few characters as possible. Similarly, _regexp golf_ is the practice of writing as tiny a regular expression as possible to match a given pattern and _only_ that pattern. +_Kod golfü_, belirli bir programı mümkün olduğunca az karakterle ifade etme oyunu için kullanılan bir terimdir. Benzer şekilde, _düzenli ifade golfü_, _yalnızca_ verilen o deseni eşleştirmek için mümkün olduğunca küçük bir düzenli ifade yazma uygulamasıdır. {{index boundary, matching}} -For each of the following items, write a ((regular expression)) to test whether the given pattern occurs in a string. The regular expression should match only strings containing the pattern. When your expression works, see whether you can make it any smaller. +Aşağıdaki her öğe için, verilen desenin bir dizide olup olmadığını test etmek için bir ((düzenli ifade)) yazın. Düzenli ifade, yalnızca deseni içeren dizeleri eşleştirmelidir. İfadeniz çalıştığında, onu daha da küçültebilme ihtimaliniz üzerine düşünün. - 1. _car_ and _cat_ - 2. _pop_ and _prop_ - 3. _ferret_, _ferry_, and _ferrari_ - 4. Any word ending in _ious_ - 5. A whitespace character followed by a period, comma, colon, or semicolon - 6. A word longer than six letters - 7. A word without the letter _e_ (or _E_) +1. _car_ ve _cat_ +2. _pop_ ve _prop_ +3. _ferret_, _ferry_, ve _ferrari_ +4. _ious_ ile biten herhangi bir kelime +5. Bir boşluk karakteri ve ardından nokta, virgül, iki nokta üst üste veya noktalı virgül gelen bir dize +6. Altı harften uzun bir kelime +7. _e_ (veya _E_) harfi olmayan bir kelime -Refer to the table in the [chapter summary](regexp#summary_regexp) for help. Test each solution with a few test strings. +Yardım için [bölüm özeti](regexp#summary_regexp) içindeki tabloya bakın. Her çözümü birkaç test dizisiyle test edin. {{if interactive + ``` -// Fill in the regular expressions +// Düzenli ifadeleri doldurun. verify(/.../, ["my car", "bad cats"], @@ -927,46 +932,49 @@ function verify(regexp, yes, no) { if}} -### Quoting style +### Tırnak stili {{index "quoting style (exercise)", "single-quote character", "double-quote character"}} -Imagine you have written a story and used single ((quotation mark))s throughout to mark pieces of dialogue. Now you want to replace all the dialogue quotes with double quotes, while keeping the single quotes used in contractions like _aren't_. +Bir hikaye yazdınızı ve diyalog parçalarını işaretlemek için tümüyle tek ((tırnak işareti)) kullandığınızı hayal edin. Şimdi, _aren't_ gibi kısaltmalarda kullanılan tek tırnakları koruyarak tüm diyalog alıntılarını çift tırnaklarla değiştirmek istiyorsunuz. {{index "replace method"}} -Think of a pattern that distinguishes these two kinds of quote usage and craft a call to the `replace` method that does the proper replacement. +Bu iki tür tırnak kullanımını ayıran bir desen düşünün ve doğru değiştirmeyi yapacak `replace` metoduna bir çağrı oluşturun. {{if interactive + ```{test: no} let text = "'I'm the cook,' he said, 'it's my job.'"; -// Change this call. +// Bu çağrıyı değiştir. console.log(text.replace(/A/g, "B")); // → "I'm the cook," he said, "it's my job." ``` + if}} {{hint {{index "quoting style (exercise)", boundary}} -The most obvious solution is to replace only quotes with a nonletter character on at least one side—something like `/\P{L}'|'\P{L}/`. But you also have to take the start and end of the line into account. +En açık çözüm, en az bir tarafında harf olmayan tırnakları değiştirmektir - `/\P{L}'|'\P{L}/` gibi bir şey. Ancak, satırın başlangıcını ve sonunu da dikkate almalısınız. {{index grouping, "replace method", [parentheses, "in regular expressions"]}} -In addition, you must ensure that the replacement also includes the characters that were matched by the `\P{L}` pattern so that those are not dropped. This can be done by wrapping them in parentheses and including their groups in the replacement string (`$1`, `$2`). Groups that are not matched will be replaced by nothing. +Ek olarak, değiştirmenin, `\P{L}` deseniyle eşleşen karakterleri de içermesini sağlamalısınız ki bunlar düşürülmesin. Bunun yapılması, parantez içine alarak ve değiştirme dizesine gruplarını (`$1`, `$2`) dahil ederek yapılabilir. Eşleşmeyen gruplar hiçbir şey ile değiştirilecektir. hint}} -### Numbers again +### Tekrar sayılar {{index sign, "fractional number", [syntax, number], minus, "plus character", exponent, "scientific notation", "period character"}} -Write an expression that matches only JavaScript-style ((number))s. It must support an optional minus _or_ plus sign in front of the number, the decimal dot, and exponent notation—`5e-3` or `1E10`—again with an optional sign in front of the exponent. Also note that it is not necessary for there to be digits in front of or after the dot, but the number cannot be a dot alone. That is, `.5` and `5.` are valid JavaScript numbers, but a lone dot isn't. +Sadece JavaScript tarzı ((sayı))ları eşleştiren bir ifade yazın. Sayının önünde isteğe bağlı eksi _veya_ artı işareti, ondalık nokta ve üstel gösterim - `5e-3` veya `1E10` - yine üstel önünde isteğe bağlı bir işaret ile desteklenmelidir. Ayrıca, noktanın önünde veya sonra rakamlar olması gerekli değildir, ancak sayı yalnızca bir nokta olamaz. Yani, `.5` ve `5.` geçerli JavaScript sayılarıdır, ancak yalnızca nokta _değildir_. {{if interactive + ```{test: no} -// Fill in this regular expression. +// Bu düzenli ifadeyi doldurun. let number = /^...$/; // Tests: @@ -990,16 +998,16 @@ if}} {{index ["regular expression", escaping], ["backslash character", "in regular expressions"]}} -First, do not forget the backslash in front of the period. +Öncelikle noktanın önüne ters eğik çizgi koymayı unutmayın. -Matching the optional ((sign)) in front of the ((number)), as well as in front of the ((exponent)), can be done with `[+\-]?` or `(\+|-|)` (plus, minus, or nothing). +Sayının önündeki isteğe bağlı ((işaret)) ile, aynı zamanda önündeki üstel işareti eşleştirmek `[+\-]?` veya `(\+|-|)` (artı, eksi veya hiçbir şey) aracılığıyla yapılabilir. {{index "pipe character"}} -The more complicated part of the exercise is the problem of matching both `"5."` and `".5"` without also matching `"."`. For this, a good solution is to use the `|` operator to separate the two cases—either one or more digits optionally followed by a dot and zero or more digits _or_ a dot followed by one or more digits. +Bu alıştırmanın daha karmaşık kısmı, `"5."` ve `".5"` dizelerini eşleştirirken `"."` dizesini eşleştirmemektir. Bu iki durumu ayırmak için `|` operatörünü kullanmak iyi bir çözümdür - ya bir veya daha fazla rakamın, isteğe bağlı olarak bir noktayla devam etmesi ve sıfır veya daha fazla rakamın ardından gelmesi _veya_ bir noktanın bir veya daha fazla rakamdan sonra geldiği durum. {{index exponent, "case sensitivity", ["regular expression", flags]}} -Finally, to make the _e_ case insensitive, either add an `i` option to the regular expression or use `[eE]`. +Son olarak, _e_ karakterini büyük/küçük harfe duyarsız hale getirmek için düzenli ifadeye bir `i` seçeneği ekleyin veya `[eE]` kullanın. hint}} diff --git a/10_modules.md b/10_modules.md index db4e7c51..622084a0 100644 --- a/10_modules.md +++ b/10_modules.md @@ -1,64 +1,64 @@ {{meta {load_files: ["code/packages_chapter_10.js", "code/chapter/07_robot.js"]}}} -# Modules +# Modüller -{{quote {author: "Tef", title: "Programming is Terrible", chapter: true} +{{quote {author: "Tef", title: "Programlamak Korkunç", chapter: true} -Write code that is easy to delete, not easy to extend. +Silmesi kolay olan kod yazın, üzerine daha fazla şey eklenmesi kolay olan kod değil. quote}} -{{index "Yuan-Ma", "Book of Programming"}} +{{index "Yuan-Ma", "Programlamanın Kitabı"}} -{{figure {url: "img/chapter_picture_10.jpg", alt: "Illustration of a complicated building built from modular pieces", chapter: framed}}} +{{figure {url: "img/chapter_picture_10.jpg", alt: "Modüler parçalardan inşa edilmiş karmaşık bir binanın illüstrasyonu.", chapter: framed}}} {{index organization, [code, "structure of"]}} -Ideally, a program has a clear, straightforward structure. The way it works is easy to explain, and each part plays a well-defined role. +İdeal olarak, bir programın açık ve anlaşılır bir yapısı vardır. Çalışma şeklini açıklamak kolaydır ve her bir parça iyi tanımlanmış bir rolü oynar. {{index "organic growth"}} -In practice, programs grow organically. Pieces of functionality are added as the programmer identifies new needs. Keeping such a program well-structured requires constant attention and work. This is work that will pay off only in the future, the _next_ time someone works on the program, so it's tempting to neglect it and allow the various parts of the program to become deeply entangled. +Uygulamada, programlar organik olarak büyür. Yeni ihtiyaçlar belirlendikçe fonksiyonalite parçaları eklenir. Böyle bir programın iyi yapılandırılmış kalması sürekli dikkat ve çalışma gerektirir. Bu, sadece gelecekte, _bir sonraki_ kişi program üzerinde çalıştığında ödüllendirilecek bir çalışmadır. Bu nedenle, ihmal etmek ve programın çeşitli parçalarının derinlemesine birbirine karışmasına izin vermek caziptir. {{index readability, reuse, isolation}} -This causes two practical issues. First, understanding an entangled system is hard. If everything can touch everything else, it is difficult to look at any given piece in isolation. You are forced to build up a holistic understanding of the entire thing. Second, if you want to use any of the functionality from such a program in another situation, rewriting it may be easier than trying to disentangle it from its context. +Bu iki pratik soruna neden olur. İlk olarak, karışık bir sistem anlamak zordur. Her şey her şeye dokunabiliyorsa, herhangi bir parçayı izole olarak incelemek zor olur. Tüm şeyin bütünlüklü bir anlayışını oluşturmak zorundasınız. İkinci olarak, böyle bir programın işlevselliğini başka bir durumda kullanmak istiyorsanız, bunu içinde bulunduğu düğümü çözmektense programı tamamen yeniden yazmak daha kolay olabilir. -The phrase "((big ball of mud))" is often used for such large, structureless programs. Everything sticks together, and when you try to pick out a piece, the whole thing comes apart, and you only succeed in making a mess. +"((büyük çamur topu))" ifadesi genellikle böyle büyük, yapısal olmayan programlar için kullanılır. Her şey her şeye yapışır ve bir parça seçmeye çalıştığınızda, bütün şey parçalanır ve sadece bir karmaşa oluşturmayı başarırsınız. -## Modular programs +## Modüler programlar {{index dependency, [interface, module]}} -_Modules_ are an attempt to avoid these problems. A ((module)) is a piece of program that specifies which other pieces it relies on and which functionality it provides for other modules to use (its _interface_). +_Modüller_ bu sorunları önlemeye yönelik bir girişimdir. ((Modül)), başka hangi parçalara bağımlı olduğunu ve diğer modüllerin kullanması için hangi işlevsellikleri sağladığını(*arayüz*ünü) belirten bir program parçasıdır. {{index "big ball of mud"}} -Module interfaces have a lot in common with object interfaces, as we saw them in [Chapter ?](object#interface). They make part of the module available to the outside world and keep the rest private. +Modül arayüzleri, [bölüm ?](object#interface) içinde gördüğümüz nesne arayüzleriyle çok ortak noktaya sahiptir. Modülün bir kısmını dış dünyaya kullanılabilir hale getirir ve geri kalanını özel tutar. {{index dependency}} -But the interface that a module provides for others to use is only half the story. A good module system also requires modules to specify which code _they_ use from other modules. These relations are called _dependencies_. If module A uses functionality from module B, it is said to _depend_ on that module. When these are clearly specified in the module itself, they can be used to figure out which other modules need to be present to be able to use a given module and to automatically load dependencies. +Ancak, bir modülün diğerlerinin kullanması için sağladığı arayüz sadece hikayenin yarısıdır. İyi bir modül sistemi ayrıca modüllerin diğer modüllerden _hangi kodları kullandıklarını_ belirtmelerini gerektirir. Bu ilişkiler _bağımlılıklar_ olarak adlandırılır. Modül A, modül B'den işlevsellik kullanıyorsa, buna _bağımlı_ olduğu söylenir. Bunlar modülde açıkça belirtildiğinde, bir modülü kullanabilmek için hangi diğer modüllerin mevcut olması gerektiğini anlayıp o bağımlılıkları otomatik olarak yüklemek için kullanılabilirler. -When the ways in which modules interact with each other are explicit, a system becomes more like ((LEGO)), where pieces interact through well-defined connectors, and less like mud, where everything mixes with everything else. +Modüllerin birbirleriyle etkileşim şekilleri açık olduğunda, bir sistem her şeyin her şeyle karıştığı çamur gibi olmak yerine parçaların iyi tanımlanmış bağlayıcılar aracılığıyla etkileştiği ((LEGO)) parçaları gibi olur. {{id es}} -## ES modules +## ES modülleri {{index "global scope", [binding, global]}} -The original JavaScript language did not have any concept of a module. All scripts ran in the same scope, and accessing a function defined in another script was done by referencing the global bindings created by that script. This actively encouraged accidental, hard-to-see entanglement of code and invited problems like unrelated scripts trying to use the same binding name. +Orijinal JavaScript dili herhangi bir modül kavramına sahip değildi. Tüm betikler aynı kapsamda çalışır ve başka bir betikte tanımlanan bir fonksiyona erişmek için o betik tarafından oluşturulan global bağlantılara referansla yapılırdı. Bu, kazara, görülmesi zor kod karışıklığına ve ilişkisiz betiklerin aynı bağlantı adını kullanmaya çalışmasına neden olurdu. {{index "ES modules"}} -Since ECMAScript 2015, JavaScript supports two different types of programs. _Scripts_ behave in the old way: their bindings are defined in the global scope, and they have no way to directly reference other scripts. _Modules_ get their own separate scope and support the `import` and `export` keywords, which aren't available in scripts, to declare their dependencies and interface. This module system is usually called _ES modules_ (where _ES_ stands for ECMAScript). +ECMAScript 2015'ten beri, JavaScript iki farklı program türünü desteklemektedir. _Betikler_ eski şekilde davranır: bağlantılar global kapsamda tanımlanır ve doğrudan diğer betiklere başvurma yolu yoktur. _Modüller_ kendi ayrı kapsamına sahiptir ve bağımlılıklarını ve arayüzlerini bildirmek için betiklerde bulunmayan `import` ve `export` anahtar kelimelerini destekler. Bu modül sistemi genellikle _ES modülleri_ olarak adlandırılır ("ES", "ECMAScript" anlamına gelir). -A modular program is composed of a number of such modules, wired together via their imports and exports. +Modüler bir program, bu tür modüllerin, başka modüllerden kullandıkları fonksiyonaliteleri ve başka modüllere kullabilabilir hale getirdikleri fonksiyonaliteleri kullanarak birbirine bağlandığı bir dizi modülden oluşur. {{index "Date class", "weekDay module"}} -The following example module converts between day names and numbers (as returned by `Date`'s `getDay` method). It defines a constant which is not part of its interface, and two functions which are. It has no dependencies. +Bu örnek modül, gün adları ile sayılar arasında dönüşüm yapar (`Date`'in `getDay` metodu tarafından döndürülenler aracılığıyla). Arayüzünün bir parçası olmayan bir sabit değer ve iki fonksiyon tanımlar. Hiçbir bağımlılığı yoktur. ``` const names = ["Sunday", "Monday", "Tuesday", "Wednesday", @@ -72,7 +72,7 @@ export function dayNumber(name) { } ``` -The `export` keyword can be put in front of a function, class, or binding definition to indicate that that binding is part of the module's interface. This makes it possible for other modules to use that binding by importing it. +`export` anahtar kelimesi, bir işlevin, sınıfın veya bağlantı tanımının modül arayüzünün bir parçası olduğunu belirtmek için önüne konabilir. Bu, diğer modüllerin onu içe aktararak kullanabilmesini mümkün kılar. ```{test: no} import {dayName} from "./dayname.js"; @@ -83,15 +83,15 @@ console.log(`Today is ${dayName(now.getDay())}`); {{index "import keyword", dependency, "ES modules"}} -The `import` keyword, followed by a list of binding names in braces, makes bindings from another module available in the current module. Modules are identified by quoted strings. +`import` anahtar kelimesi, süslü parantez içinde bağlantı adlarından oluşan bir listenin yazılması ardından, başka bir modüldeki bağlantıları mevcut modülde kullanılabilir hale getirir. Modüller tırnak içinde belirtilir. {{index [module, resolution], resolution}} -How such a module name is resolved to an actual program differs by platform. The browser treats them as Web addresses, whereas Node.js resolves them to files. When you run a module, all the other modules it depends on—and the modules _those_ depend on—are loaded, and the exported bindings are made available to the modules that import them. +Bir modül adının bir gerçek programa nasıl çözümleneceği platforma göre farklılık gösterir. Tarayıcı, bunları Web adresleri olarak ele alırken, Node.js bunları dosyalara çözümler. Bir modülü çalıştırmak için, o modülün bağımlı olduğu tüm diğer modüller - ve _bu bağımlı olunan modüllerin de bağımlı olduğu modüller_ de - yüklenir ve export anahtar kelimesi kullanılan tanımalar dış kullanıma müsait hale getirilir. -Import and export declarations cannot appear inside of functions, loops, or other blocks. They are immediately resolved when the module is loaded, regardless of how the code in the module executes. To reflect this, they must appear only in the outer module body. +İçe aktarma ve dışa aktarma bildirimleri, fonksiyonlar, döngüler veya diğer blokların içinde görünemez. Modül yüklendiğinde modüldeki kodun nasıl yürütüldüğünden bağımsız olarak hemen çözümlenirler ve bunu yansıtmak için modülün sadece dış gövdesinde görünmelidirler. -A module's interface thus consists of a collection of named bindings, which other modules that depend on the module can access. Imported bindings can be renamed to give them a new local name using `as` after their name. +Bu nedenle, bir modülün arayüzü, onlara bağımlı olan diğer modüllerin erişebildiği adlandırılmış bağlantılardan oluşur. İçe aktarılan bağlantılar, adlarının ardından `as` kullanılarak yeni bir yerel isim verilerek yeniden adlandırılabilir. ``` import {dayName as nomDeJour} from "./dayname.js"; @@ -99,73 +99,67 @@ console.log(nomDeJour(3)); // → Wednesday ``` -M module may also have a special export named `default`, which is often used for modules that only export a single binding. To define a default export, you write `export default` before an expression, a function declaration, or a class declaration. +Ayrıca, bir modülün özel olarak adlandırılmış `default` adlı bir dışa aktarma bildirisi olması mümkündür, bu genellikle yalnızca tek bir bağlantıyı dışa aktaran modüller için kullanılır. Varsayılan bir dışa aktarım tanımlamak için, bir fonksiyon bildiriminin veya bir sınıf bildiriminin önüne `export default` yazılır. ``` export default ["Winter", "Spring", "Summer", "Autumn"]; ``` -Such a binding is imported by omitting the braces around the name of the import. +Bu tür bir bağlantı, içe aktarmada adın etrafındaki süslü parantezleri kullanmadan içeri aktarılır. ``` import seasonNames from "./seasonname.js"; ``` -To import all bindings from a module at the same time, you can use `import *`. You provide a name, and that name will be bound to an object holding all the module's exports. This can be useful when you are using a lot of different exports. - -``` -import * as dayName from "./dayname.js"; -console.log(dayName.dayName(3)); -// → Wednesday -``` - -## Packages +## Paketler {{index bug, dependency, structure, reuse}} -One of the advantages of building a program out of separate pieces and being able to run some of those pieces on their own is that you might be able to use the same piece in different programs. +Bir programı ayrı parçalardan oluşturmanın ve bazı parçaları kendi başlarına çalıştırabilmenin avantajlarından biri, aynı parçayı farklı programlarda kullanabilme olasılığınızdır. {{index "parseINI function"}} -But how do you set this up? Say I want to use the `parseINI` function from [Chapter ?](regexp#ini) in another program. If it is clear what the function depends on (in this case, nothing), I can just copy that module into my new project and use it. But then, if I find a mistake in the code, I'll probably fix it in whichever program I'm working with at the time and forget to also fix it in the other program. +Ancak, bunu nasıl kurarsınız? Diyelim ki başka bir programda [bölüm ?](regexp#ini) içindeki `parseINI` fonksiyonunu kullanmak istiyorum. Fonksiyonun neye bağlı olduğu (bu durumda, hiçbir şeye) açıksa, sadece o modülü yeni projeme kopyalayabilir ve kullanabilirim. Ancak sonra, kodda bir hata bulursam, muhtemelen o sırada çalıştığım programda düzelteceğim ve aynı hatayı diğer programda da düzeltmeyi unutacağım. {{index duplication, "copy-paste programming"}} -Once you start duplicating code, you'll quickly find yourself wasting time and energy moving copies around and keeping them up to date. That's where _((package))s_ come in. A package is a chunk of code that can be distributed (copied and installed). It may contain one or more modules and has information about which other packages it depends on. A package also usually comes with documentation explaining what it does so that people who didn't write it might still be able to use it. +Kod kopyalamaya başladığınızda, zamanınızı ve enerjinizi kopyaları taşımak ve güncel tutmak için harcadığınızı hızla fark edersiniz. + +İşte burada \_((paket))\_ler devreye giriyor. Bir paket, dağıtılabilen (kopyalanabilen ve yüklenen) bir kod parçasıdır. Bir veya daha fazla modül içerebilir ve ne tür paketlere bağımlı olduğu hakkında bilgi içerir. Bir paket genellikle ne yaptığını açıklayan belgelerle birlikte gelir, böylece o programı yazmamış sadece kullanmak isteyen insanlar bile onu kullanabilirler. -When a problem is found in a package or a new feature is added, the package is updated. Now the programs that depend on it (which may also be packages) can copy the new ((version)) to get the improvements that were made to the code. +Bir pakette bir sorun bulunduğunda veya yeni bir özellik eklediğinde, paket güncellenir. Artık ona bağımlı olan programlar (ki bunlar da paketler olabilir) iyileştirmeleri almak için yeni ((sürümü)) kopyalayabilirler. {{id modules_npm}} {{index installation, upgrading, "package manager", download, reuse}} -Working in this way requires ((infrastructure)). We need a place to store and find packages and a convenient way to install and upgrade them. In the JavaScript world, this infrastructure is provided by ((NPM)) ([_https://npmjs.org_](https://npmjs.org)). +Bu şekilde çalışmak ((altyapı)) gerektirir. Paketleri depolamak ve bulmak için bir yer ve bunları kurmak ve yükseltmek için uygun bir yer gereklidir. JavaScript dünyasında, bu altyapı ((NPM)) ([https://npmjs.org](https://npmjs.org)) tarafından sağlanır. -NPM is two things: an online service where you can download (and upload) packages, and a program (bundled with Node.js) that helps you install and manage them. +NPM iki şeydir: paketleri indirebileceğiniz (ve yükleyebileceğiniz) çevrimiçi bir hizmet ve onları kurmanıza ve yönetmenize yardımcı olan Node.js ile birlikte paketlenmiş bir program. {{index "ini package"}} -At the time of writing, there are more than three million different packages available on NPM. A large portion of those are rubbish, to be fair. But almost every useful, publicly available JavaScript package can be found on NPM. For example, an INI file parser, similar to the one we built in [Chapter ?](regexp), is available under the package name `ini`. +Yazım sırasında, NPM'de üç milyondan fazla farklı paket bulunmaktadır. Adil olmak gerekirse, bunların büyük bir kısmı gereksizdir. Ancak neredeyse her kullanışlı, genel olarak erişilebilir JavaScript paketi NPM'de bulunabilir. Örneğin, [bölüm ?](regexp) içinde oluşturduğumuz bir INI dosyası ayrıştırıcısı, `ini` paketi adı altında bulunabilir. {{index "command line"}} -[Chapter ?](node) will show how to install such packages locally using the `npm` command line program. +[Chapter ?](node), bu tür paketleri `npm` komut satırı programını kullanarak yerel olarak nasıl kuracağınızı gösterecektir. -Having quality packages available for download is extremely valuable. It means that we can often avoid reinventing a program that 100 people have written before and get a solid, well-tested implementation at the press of a few keys. +İndirilebilir kaliteli paketlere sahip olmak son derece değerlidir. 100 kişi tarafından yazılmış bir programı yeniden icat etmekten genellikle kaçınabilir ve birkaç tuşa basarak sağlam, iyi test edilmiş bir uygulama elde edebiliriz. {{index maintenance}} -Software is cheap to copy, so once someone has written it, distributing it to other people is an efficient process. Writing it in the first place _is_ work, though, and responding to people who have found problems in the code or who want to propose new features is even more work. +Yazılım kopyalamak ucuzdur, bu yüzden biri yazdığında, başkalarına dağıtmak verimli bir süreçtir. Ancak bunu baştan yazmak _iştir_, ayrıca kodunuzda sorun bulan veya yeni özellikler önermek isteyen kişilere cevap vermek daha fazla iştir. -By default, you own the ((copyright)) to the code you write, and other people may use it only with your permission. But because some people are just nice and because publishing good software can help make you a little bit famous among programmers, many packages are published under a ((license)) that explicitly allows other people to use it. +Varsayılan olarak, yazdığınız kodun ((telif hakkı)) size aittir ve diğer kişiler yalnızca izninizle kullanabilirler. Ancak bazı insanlar nazik olduklarından ve iyi yazılım yayınlamak, yazılımcılar arasında biraz ünlü olmanıza yardımcı olabildiğinden ötürü birçok paket açıkça diğer insanların onu kullanmasına izin veren bir ((lisans)) altında yayınlanır. -Most code on ((NPM)) is licensed this way. Some licenses require you to also publish code that you build on top of the package under the same license. Others are less demanding, requiring only that you keep the license with the code as you distribute it. The JavaScript community mostly uses the latter type of license. When using other people's packages, make sure you are aware of their licenses. +((NPM))'deki çoğu kod bu şekilde lisanslanmıştır. Bazı lisanslar, paketin üzerine inşa ettiğiniz kodu da aynı lisans altında yayınlamanızı gerektirir. Diğerleri ise daha az talepkârdır ve sadece lisansı kodla birlikte dağıtmanızı isterler. JavaScript topluluğu genellikle bu son açıkladığım türdeki lisansları kullanır. Başkalarının paketlerini kullanırken, lisanslarını bilincinde olduğunuzdan emin olun. {{id modules_ini}} {{index "ini package"}} -Now, instead of writing our own INI file parser, we can use one from ((NPM)). +Artık kendi INI dosyası ayrıştırıcımızı yazmak yerine, ((NPM)) üzerinden bir tane kullanabiliriz. ``` import {parse} from "ini"; @@ -176,17 +170,15 @@ console.log(parse("x = 10\ny = 20")); {{id commonjs}} -## CommonJS modules +## CommonJS modülleri -Before 2015, when the JavaScript language had no built-in module system, people were already building large systems in JavaScript. To make that workable, they _needed_ ((module))s. +2015'ten önce, JavaScript dilinde gerçek bir yerleşik modül sistemi olmadığı zamanlarda da insanlar JavaScript'te büyük sistemler inşa ediyorlardı. Bunu çalışabilir yapmak için ((modül))lere _ihtiyaçları vardı_. {{index [function, scope], [interface, module], [object, as module]}} -The community designed its own improvised ((module system))s on top of the language. These use functions to create a local scope for the modules and regular objects to represent module interfaces. +Topluluk, kendi düzenlediği ((modül sistem))lerini dilden bağımsız olarak tasarladı. Bu modülleri, yerel bir kapsam oluştururken fonksiyonları kullanarak ve modül arayüzlerini temsil etmek için sıradan nesneleri kullanarak oluşturdular. -Initially, people just manually wrapped their entire module in an “((immediately invoked function -expression))” to create the module's scope and assigned their interface objects to a single global -variable. +Başlangıçta, insanlar modüllerine ayrı bir bağlam oluşturmak için "((hemen çağrılan fonksiyon ifadesi))" içine manuel olarak sarıp arayüz nesnelerini tek bir global değişkene atarlardı. ``` const weekDay = function() { @@ -204,21 +196,21 @@ console.log(weekDay.name(weekDay.number("Sunday"))); {{index dependency, [interface, module]}} -This style of modules provides ((isolation)), to a certain degree, but it does not declare dependencies. Instead, it just puts its interface into the ((global scope)) and expects its dependencies, if any, to do the same. This is not ideal. +Bu tür modüllerin stili, belirli bir dereceye kadar ((izolasyon)) sağlar, ancak bağımlılıkları bildirmez. Bunun yerine, arayüzünü ((genel kapsam))a koyar ve varsa bağımlılıklarının, aynısını yapmasını bekler. Bu ideal değildir. {{index "CommonJS modules"}} -If we implement our own module loader, we can do better. The most widely used approach to bolted-on JavaScript modules is called _CommonJS modules_. ((Node.js)) used this module system from the start (though it now also knows how to load ES modules), and it is the module system used by many packages on ((NPM)). +Eğer kendi modül yükleyicimizi uygularsak, daha iyi yapabiliriz. JavaScript modüllerini eklemek için en yaygın kullanılan yaklaşım _CommonJS modülleri_ olarak adlandırılır. ((Node.js)), bu tür modülleri başlangıçtan itibaren kullandı (ancak şimdi ayrıca ES modüllerini de yükleyebilir durumdadır) ve bu, NPM'deki birçok paket tarafından kullanılan modül sistemidir. {{index "require function", [interface, module], "exports object"}} -A CommonJS module looks like a regular script, but it has access to two bindings that it uses to interact with other modules. The first is a function called `require`. When you call this with the module name of your dependency, it makes sure the module is loaded and returns its interface. The second is an object named `exports`, which is the interface object for the module. It starts out empty and you add properties to it to define exported values. +Bir CommonJS modülü, düzenli bir betik gibi görünür, ancak diğer modüllerle etkileşim kurmak için kullandığı iki bağlantıya erişim sağlar. İlk olarak, `require` olarak adlandırılan bir fonskiyon. Bağımlılığınızın modül adıyla bunu çağırdığınızda, modülün yüklenip arayüzünü döndürmesini sağlar. İkincisi, modül için arayüz nesnesi olan `exports` adlı bir nesnedir. Başlangıçta boştur ve dışa aktarılan değerleri tanımlamak için ona özellikler eklersiniz. {{index "formatDate module", "Date class", "ordinal package", "date-names package"}} -This CommonJS example module provides a date-formatting function. It uses two ((package))s from NPM—`ordinal` to convert numbers to strings like `"1st"` and `"2nd"`, and `date-names` to get the English names for weekdays and months. It exports a single function, `formatDate`, which takes a `Date` object and a ((template)) string. +Bu CommonJS örnek modülü, bir tarih biçimlendirme fonksiyonu sağlar. NPM'den iki ((paket)) kullanır: sayıları `"1st"` ve `"2nd"` gibi dizelere dönüştürmek için `ordinal` paketini ve haftanın günler ve aylar için İngiliz isimlerini almak adına `date-names` paketini kullanır. Bir `Date` nesnesi ve bir ((şablon)) dizesi alan `formatDate` adlı tek bir fonksiyonu dışa aktarır. -The template string may contain codes that direct the format, such as `YYYY` for the full year and `Do` for the ordinal day of the month. You could give it a string like `"MMMM Do YYYY"` to get output like `November 22nd 2017`. +Şablon dizesi, `YYYY` gibi biçimi yönlendiren kodları içerebilir ve ayın sıra günü için `Do` gibi dizeleri içerebilir. `"MMMM Do YYYY"` gibi bir dize verebilirsiniz ve çıktı olarak `"November 22nd 2017"` gibi bir çıktı alırsınız. ``` const ordinal = require("ordinal"); @@ -238,9 +230,9 @@ exports.formatDate = function(date, format) { {{index "destructuring binding"}} -The interface of `ordinal` is a single function, whereas `date-names` exports an object containing multiple things—`days` and `months` are arrays of names. Destructuring is very convenient when creating bindings for imported interfaces. +`ordinal` paketinin arayüzü tek bir fonksiyon iken, `date-names` birçok şey içeren bir nesne dışa aktarır—`days` ve `months` isim dizileridir. İçe aktarılan arayüzler için bağlantılar oluştururken, parçalama yöntemi çok yararlı ve kullanışlıdır. -The module adds its interface function to `exports` so that modules that depend on it get access to it. We could use the module like this: +Modül, arayüz fonksiyonunu `exports` bağlantısına ekler ki böylece buna bağımlı olan modüller buna erişebilsin. Modülü şu şekilde kullanabiliriz: ``` const {formatDate} = require("./format-date.js"); @@ -250,13 +242,13 @@ console.log(formatDate(new Date(2017, 9, 13), // → Friday the 13th ``` -CommonJS is implemented with a module loader that, when loading a module, wraps its code in a function (giving it its own local scope), and passes the `require` and `exports` bindings to that function as arguments. +CommonJS, bir modülü yüklerken, kodunu bir fonksiyon içine sarar (kendi yerel kapsamını verir) ve `require` ve `exports` bağlantılarını bu fonksiyonu çağırırken argüman olarak bu bağlantılara argüman geçirir. {{id require}} {{index "require function", "CommonJS modules", "readFile function"}} -If we assume we have access to a `readFile` function that reads a file by name and gives us its content, we can define a simplified form of `require` like this: +Bir dosyanın adını verip onun içeriğini bize döndüren `readFile` adlı bir fonksiyonuna erişiminiz olduğunu varsayarsak, bir `require` fonksiyonunu basitleştirilmiş bir şekilde şu şekilde tanımlayabiliriz: ```{test: wrap, sandbox: require} function require(name) { @@ -275,79 +267,81 @@ require.cache = Object.create(null); {{index "Function constructor", eval, security}} -`Function` is a built-in JavaScript function that takes a list of arguments (as a comma-separated string) and a string containing the function body and returns a function value with those arguments and that body. This is an interesting concept—it allows a program to create new pieces of program from string data—but also a dangerous one, since if someone can trick your program into putting a string they provide into `Function`, they can make the program do anything they want. +`Function`, virgüllerle ayrılmış bir dize halinde bir liste argüman ve fonksiyon gövdesini içerisinde barındıran bir dizeyi argüman olarak alan ve bir fonksiyon değeri döndüren standart bir JavaScript fonksiyonudur. Bu ilginç olmakla beraber tehlikeli bir kavramdır—bir programın dize datasından yeni bir program oluşturmasını sağlar- çünkü birisi programınıza sağladığı bir dizeyi `Function` içine koymaya kandırabilirse, programa istediklerini yaptırabilirler. {{index [file, access]}} -Standard JavaScript provides no such function as `readFile`, but different JavaScript environments, such as the browser and Node.js, provide their own ways of accessing files. The example just pretends that `readFile` exists. +Standart JavaScript, `readFile` gibi bir fonksiyon sağlamaz sağlamaz—ancak tarayıcı ve Node.js gibi farklı JavaScript ortamları, dosyalara erişim için kendi yöntemlerini sağlar. Örnek, `readFile` fonksiyonunun var olduğunu varsayar. -To avoid loading the same module multiple times, `require` keeps a store (cache) of already loaded modules. When called, it first checks if the requested module has been loaded and, if not, loads it. This involves reading the module's code, wrapping it in a function, and calling it. +Aynı modülü birden fazla kez yüklememek için, `require`, zaten yüklenmiş modüllerin bir deposunu (önbellek) tutar. Çağrıldığında, önce istenen modülün yüklenip yüklenmediğini kontrol eder ve yüklenmediyse, yükler. Bu, modülün kodunu okuyup bir fonksiyon içine sarıp onu çağırarak yapılır. {{index "ordinal package", "exports object", "module object", [interface, module]}} -By defining `require`, `exports` as ((parameter))s for the generated wrapper function (and passing the appropriate values when calling it), the loader makes sure that these bindings are available in the module's ((scope)). +Oluşturulan sarıcı fonksiyon için için `require` ve `exports` değerlerini ((parametre))ler olarak tanımlayarak (ve fonksiyonu çağırırken uygun değerleri geçirerek), yükleyici bu bağlantıların modülün ((kapsam))ında kullanılabilir olduğundan emin olur. -An important difference between this system and ES modules is that ES module imports happen before a module's script starts running, whereas `require` is a normal function, invoked when the module is already running. Unlike `import` declarations, `require` calls _can_ appear inside functions, and the name of the dependency can be any expression that evaluates to a string, whereas `import` only allows plain quoted strings. +Bu sistemle ES modülleri arasındaki önemli bir fark, ES modülü modül yüklemelerinin bir modülün betiği çalışmaya başlamadan önce gerçekleşmesidir, oysa `require` normal bir fonksiyondur ve modül çalışırken çağrılır. `import` beyanlarının aksine, `require` çağrıları fonksiyonların içinde _görünebilir_ ve bağımlılık adı, sadece düz tırnaklı dizelere izin veren `import`'a kıyasla herhangi bir ifade olabilir. -The transition of the JavaScript community from CommonJS style to ES modules has been a slow and somewhat rough one. Fortunately we are now at a point where most of the popular packages on NPM provide their code as ES modules, and Node.js allows ES modules to import from CommonJS modules. While CommonJS code is still something you will run across, there is no real reason to write new programs in this style anymore. +JavaScript topluluğunun CommonJS stilinden ES modülleri stiline geçişi yavaş ve biraz sancılı olmuştur. Ancak neyse ki, şu anda NPM'deki popüler paketlerin çoğu kodlarını ES modülleri olarak sağlıyor ve Node.js, ES modüllerinin içine CommonJS modüllerinden aktarılmasına kod aktarılmasına izin veriyor. Bu nedenle, Ortak JS kodu hala karşılaşacağınız bir şey olsa da, artık yeni programları bu tarzda yazmanın gerçek bir nedeni yoktur. -## Building and bundling +## İnşaa etme ve paketleme {{index compilation, "type checking"}} -Many JavaScript packages aren't technically written in JavaScript. Language extensions such as TypeScript, the type checking ((dialect)) mentioned in [Chapter ?](error#typing), are widely used. People also often start using planned new language features long before they have been added to the platforms that actually run JavaScript. To make this possible, they _compile_ their code, translating it from their chosen JavaScript dialect to plain old JavaScript—or even to a past version of JavaScript—so that ((browsers)) can run it. +Çoğu JavaScript paketi, teknik olarak, JavaScript'te yazılmamaktadır. [Bölüm ?](error#typing) içinde bahsedilen tip denetimi ((lehçe))si olan TypeScript gibi uzantılar yaygın olarak kullanılmaktadır. İnsanlar ayrıca, gerçekte JavaScript'i çalıştıran platformlara henüz eklenmeden önce uzun süre planlanan dil uzantılarını kullanmaya başlarlar. + +Bunu mümkün kılmak için, kodlarını seçtikleri JavaScript lehçesinden düz eski JavaScript'e—veya hatta JavaScript'in bir önceki sürümüne—_çevirerek_ ((tarayıcı))ların onu çalıştırabilmesini sağlarlar. {{index latency, performance, [file, access], [network, speed]}} -Including a modular program that consists of 200 different files in a ((web page)) produces its own problems. If fetching a single file over the network takes 50 milliseconds, loading the whole program takes 10 seconds, or maybe half that if you can load several files simultaneously. That's a lot of wasted time. Because fetching a single big file tends to be faster than fetching a lot of tiny ones, web programmers have started using tools that combine their programs (which they painstakingly split into modules) into a single big file before they publish it to the Web. Such tools are called _((bundler))s_. +200 farklı dosyadan oluşan modüler bir programın bir ((web sayfası))na dahil edilmesi kendi sorunlarını ortaya çıkarır. Ağ üzerinden tek bir dosya almak 50 milisaniye sürerse, tüm programı yüklemek 10 saniye alır veya aynı anda birkaç dosya yükleyebilirseniz belki yarısı kadar. Bu çok zaman kaybettir. Tek büyük bir dosya almanın, birçok küçük dosya almaktan daha hızlı olma eğiliminde olması nedeniyle, web programcıları, programlarını (ki bunları titizlikle modüllerde bölmüşlerdi) web'e yayınlamadan önce birleştiren araçlar kullanmaya başlamışlardır. Bu tür araçlara \_((paketleyici))\_ler denir. {{index "file size"}} -And we can go further. Apart from the number of files, the _size_ of the files also determines how fast they can be transferred over the network. Thus, the JavaScript community has invented _((minifier))s_. These are tools that take a JavaScript program and make it smaller by automatically removing comments and whitespace, renaming bindings, and replacing pieces of code with equivalent code that take up less space. +Ve daha da ileri gidebiliriz. Dosyaların sayısının yanı sıra, dosyaların _büyüklüğü_ de ağ üzerinden ne kadar hızlı aktarılabileceklerini belirler. Bu nedenle, JavaScript topluluğu \_((küçültücü))\_ler adını verdiği şeyi icat etmiştir. Bunlar, bir JavaScript programını alır ve yorumları ve boşlukları otomatik olarak kaldırır, bağlantıları yeniden adlandırır ve daha az yer kaplayan eşdeğer kod parçaları ile değiştirip onu küçültürler. {{index pipeline, tool}} -It is not uncommon for the code that you find in an NPM package or that runs on a web page to have gone through _multiple_ stages of transformation—converting from modern JavaScript to historic JavaScript, combining the modules into a single file, and minifying the code. We won't go into the details of these tools in this book since there are many of them, and which one is popular changes regularly. Just be aware that such things exist, and look them up when you need them. +Bu nedenle, bir NPM paketinde veya bir web sayfasında bulduğunuz kodun _çoklu_ dönüşüm aşamalarından geçmiş olması yüksek ihtimaldir—modern JavaScript'ten tarihi JavaScript'e dönüştürülmüş, sonra modülleri tek bir dosyaya birleştirilmiş ve kod küçültülmüştür. Bu kitapta bu araçların detaylarına girmeyeceğiz çünkü bunlardan birçok tane var ve hangisinin popüler olduğu sürekli değişiyor. Sadece böyle şeylerin var olduğunu unutmayın ve ihtiyacınız olduğunda araştırın. -## Module design +## Modül dizaynı {{index [module, design], [interface, module], [code, "structure of"]}} -Structuring programs is one of the subtler aspects of programming. Any nontrivial piece of functionality can be organized in various ways. +Programları yapılandırma, programlamanın daha ince yönlerinden biridir. Herhangi bir önemli parçanın fonksiyonalitesi çeşitli şekillerde düzenlenebilir. -Good program design is subjective—there are trade-offs involved, and matters of taste. The best way to learn the value of well-structured design is to read or work on a lot of programs and notice what works and what doesn't. Don't assume that a painful mess is “just the way it is”. You can improve the structure of almost everything by putting more thought into it. +İyi bir program tasarımı, özneldir—bununla ilgili artı ve eksiler vardır ve insanların seçimleri farklıdır. İyi yapılandırılmış tasarımın değerini öğrenmenin en iyi yolu, birçok programı okumak veya üzerinde çalışmak ve işe yarayıp yaramayanları fark etmektir. Acılı bir karmaşanın "sadece olduğu gibi olduğunu" varsaymayın. Hemen hemen her şeyin yapısını daha fazla düşünerek iyileştirebilirsiniz. {{index [interface, module]}} -One aspect of module design is ease of use. If you are designing something that is intended to be used by multiple people—or even by yourself, in three months when you no longer remember the specifics of what you did—it is helpful if your interface is simple and predictable. +Modül tasarımının bir yönü kullanım kolaylığıdır. Birden fazla kişi tarafından kullanılması amaçlanan bir şey tasarlıyorsanız—veya hatta kendiniz, üç ay sonra ne yaptığınızın ayrıntılarını hatırlamadığınızda—arayüzünüzün basit ve öngörülebilir olması yardımcı olur. {{index "ini package", JSON}} -That may mean following existing conventions. A good example is the `ini` package. This module imitates the standard `JSON` object by providing `parse` and `stringify` (to write an INI file) functions, and, like `JSON`, converts between strings and plain objects. The interface is small and familiar, and after you've worked with it once, you're likely to remember how to use it. +Bu, var olan gelenekleri takip etmek anlamına gelebilir. İyi bir örnek, `ini` paketidir. Bu modül, bir INI dosyası yazmak için `parse` ve `stringify` fonksiyonlarını sağlayarak standart `JSON` nesnesini taklit eder ve `JSON` gibi, dize ve düz nesneler arasında dönüşüm yapar. Bu nedenle, arayüz küçük ve tanıdıktır ve bir kez çalıştıktan sonra nasıl kullanılacağını hatırlamanız muhtemeldir. {{index "side effect", "hard disk", composability}} -Even if there's no standard function or widely used package to imitate, you can keep your modules predictable by using simple ((data structure))s and doing a single, focused thing. Many of the INI-file parsing modules on NPM provide a function that directly reads such a file from the hard disk and parses it, for example. This makes it impossible to use such modules in the browser, where we don't have direct file system access, and adds complexity that would have been better addressed by _composing_ the module with some file-reading function. +Standart bir fonksiyon veya yaygın olarak kullanılan bir paketi taklit edecek bir standart fonksiyon yoksa bile, modüllerinizi basit ((veri yapı))ları kullanarak ve tek bir, odaklanmış şey yaparak öngörülebilir tutabilirsiniz. Örneğin, NPM'deki birçok INI dosyası ayrıştırma modülü, bir dosyayı doğrudan sabit diskinizden okuyup ve ayrıştıran bir fonksiyon sağlar. Bu, doğrudan dosya sistemine erişimimiz olayan tarayıcı ortamında böyle bir modülü kullanmayı imkansız hale getirir, ve bu modülü bazı dosya okuma fonksiyonlarıyla _birleştirerek_ çözülebilecek bir karmaşıklık eklerdi. {{index "pure function"}} -This points to another helpful aspect of module design—the ease with which something can be composed with other code. Focused modules that compute values are applicable in a wider range of programs than bigger modules that perform complicated actions with side effects. An INI file reader that insists on reading the file from disk is useless in a scenario where the file's content comes from some other source. +Bu, modül tasarımının başka bir yararlı yönünü işaret eder—bir şeyin diğer kodlarla nasıl birleştirilebileceğinin kolaylığı. Değerler hesaplayan odaklı modüller, yan etkileri olan ve karmaşık eylemler gerçekleştiren daha büyük modüllerden daha geniş bir program yelpazesine uygulanabilir. Diskten dosya okumak zorunda olan bir INI dosya okuyucusu, dosyanın içeriğinin başka bir kaynaktan geldiği senaryoda işe yaramaz. {{index "object-oriented programming"}} -Relatedly, stateful objects are sometimes useful or even necessary, but if something can be done with a function, use a function. Several of the INI file readers on NPM provide an interface style that requires you to first create an object, then load the file into your object, and finally use specialized methods to get at the results. This type of thing is common in the object-oriented tradition, and it's terrible. Instead of making a single function call and moving on, you have to perform the ritual of moving your object through its various states. And because the data is now wrapped in a specialized object type, all code that interacts with it has to know about that type, creating unnecessary interdependencies. +İlgili olarak, değişen bir durum barındıran nesneler bazen yararlı, hatta gereklidir ancak bir fonksiyonla yapılabilecek bir şey varsa, bir fonksiyon kullanın. NPM'deki birkaç INI dosyası okuyucusu, öncelikle bir nesne oluşturmanızı, ardından dosyayı nesnenize yüklemenizi ve son olarak sonuçlara erişmek için özel metodları kullanmanızı gerektiren bir arayüz stili sağlar. Bu tür şeyler, nesne yönelimli geleneğin bir parçasıdır ve korkunçtur. Tek bir fonksiyon çağrısı yapmak ve geçmek yerine, nesnenizi çeşitli durumlar boyunca hareket ettirme ritüelini gerçekleştirmeniz gerekir. Ve çünkü veri şimdi özelleşmiş bir nesne türüne sarılmış durumda olduğundan ötürü bununla etkileşim kuran tüm kodların o tür hakkında bilgi sahibi olması gerekir ve bu da gereksiz bağımlılıklar oluşmasını sağlar. -Often, defining new data structures can't be avoided—only a few basic ones are provided by the language standard, and many types of data have to be more complex than an array or a map. But when an array suffices, use an array. +Yeni veri yapılarını tanımlamak bazen kaçınılmazdır—dil standardı sadece birkaç temel yapıyı sağlar ve birçok veri türü bir diziden veya map veri tipinden daha karmaşık olmak zorundadır. Ancak bir dizi yeterliyken, bir dizi kullanın. -An example of a slightly more complex data structure is the graph from [Chapter ?](robot). There is no single obvious way to represent a ((graph)) in JavaScript. In that chapter, we used an object whose properties hold arrays of strings—the other nodes reachable from that node. +Biraz daha karmaşık bir veri yapısının bir örneği, [bölüm ?](robot) içindeki grafiktir. JavaScript'te bir ((grafik)) nasıl temsil edileceğine dair tek bir açık bir yol yoktur. O bölümde, diğer düğümlere o düğümden erişilebilen yerleri barındıran dizelerin dizilerini tutan bir nesne kullandık. -There are several different pathfinding packages on ((NPM)), but none of them uses this graph format. They usually allow the graph's edges to have a weight, which is the cost or distance associated with it. That isn't possible in our representation. +((NPM))'de birkaç farklı yol bulma paketi vardır ancak bunların hiçbiri bu grafik formatını kullanmaz. Genellikle, kenarların bir ağırlığı olmasına izin verirler, bu da onunla ilişkilendirilmiş maliyet veya mesafe anlamına gelir. Bu, bizim temsilimizde mümkün değildir. {{index "Dijkstra, Edsger", pathfinding, "Dijkstra's algorithm", "dijkstrajs package"}} -For example, there's the `dijkstrajs` package. A well-known approach to pathfinding, quite similar to our `findRoute` function, is called _Dijkstra's algorithm_, after Edsger Dijkstra, who first wrote it down. The `js` suffix is often added to package names to indicate the fact that they are written in JavaScript. This `dijkstrajs` package uses a graph format similar to ours, but instead of arrays, it uses objects whose property values are numbers—the weights of the edges. +Örneğin, `dijkstrajs` paketi vardır. Bir yol bulma için iyi bilinen bir yaklaşım ve bizim `findRoute` fonksiyonumuza oldukça benzemektedir, Edsger Dijkstra tarafından ilk kez yazıldıktan sonra _Dijkstra'nın algoritması_ olarak adlandırılmıştır. `js` eki sıklıkla paket adlarına eklenir ve bunların JavaScript'te yazıldığını belirtmek içindir. Bu `dijkstrajs` paketi, bizimkinin benzer bir grafik formatını kullanır, ancak diziler yerine, kenarların ağırlıkları olan sayıların olduğu nesneler kullanır. -If we wanted to use that package, we'd have to make sure that our graph was stored in the format it expects. All edges get the same weight since our simplified model treats each road as having the same cost (one turn). +Bu paketi kullanmak istesek, grafik formatımızın beklediği formatta olduğundan emin olmalıyız. Tüm kenarlar, bizim basitleştirilmiş modelimizde her yolun aynı maliyeti (bir dönüş) varmışçasına varsayıldığından, aynı ağırlığa sahiptir. ``` const {find_path} = require("dijkstrajs"); @@ -364,29 +358,29 @@ console.log(find_path(graph, "Post Office", "Cabin")); // → ["Post Office", "Alice's House", "Cabin"] ``` -This can be a barrier to composition—when various packages are using different data structures to describe similar things, combining them is difficult. Therefore, if you want to design for composability, find out what ((data structure))s other people are using and, when possible, follow their example. +Bu, birleştirme için bir engel olabilir—farklı veri yapılarını benzer şeyleri tanımlamak için kullanan çeşitli paketler onları birleştirmeyi zorlaştırır. Bu nedenle, birleşebilirlik için tasarım yapmak istiyorsanız, diğer insanların ne tür ((veri yapıları)) kullandığını bulun ve mümkünse onların örneğini takip edin. {{index design}} -Designing a fitting module structure for a program can be difficult. In the phase where you are still exploring the problem, trying different things to see what works, you might want to not worry about it too much since keeping everything organized can be a big distraction. Once you have something that feels solid, that's a good time to take a step back and organize it. +Bir programa uygun bir modül yapısı tasarlamak zor olabilir. Sorunu hala keşfetmeye çalıştığınız ve neyiş işe yarayıp yaramadığını test ettiğiniz aşamada her şeyi düzenli tutmaya çalışmak büyük bir dikkat dağıtıcı olabilir. Sağlam hisseden bir şeyiniz olduğunda, geri çekilip onu düzenlemek için iyi bir zamandır. -## Summary +## Özet -Modules provide structure to bigger programs by separating the code into pieces with clear interfaces and dependencies. The interface is the part of the module that's visible to other modules, and the dependencies are the other modules it makes use of. +Modüller, kodu net arayüzler ve bağımlılıklarla parçalara ayırarak daha büyük programlara yapı sağlar. Arayüz, modülün diğer modüller tarafından görülebilen kısmıdır ve bağımlılıklar, kullanılan diğer modüllerdir. -Because JavaScript historically did not provide a module system, the CommonJS system was built on top of it. Then at some point it _did_ get a built-in system, which now coexists uneasily with the CommonJS system. +JavaScript, tarihsel olarak bir modül sistemi sağlamadığı için, CommonJS sistemi üzerine inşa edildi. Sonra bir noktada, gerçekten yerleşik bir sistem _inşaa edildi_ ve şu anda CommonJS sistemiyle pek de uyumlu olmayan bir şekilde yan yana var olmayı sürdürmekte. -A package is a chunk of code that can be distributed on its own. NPM is a repository of JavaScript packages. You can download all kinds of useful (and useless) packages from it. +Bir paket, kendi başına dağıtılabilen bir kod parçasıdır. NPM, JavaScript paketlerinin bir deposudur. Oradan her türlü yararlı (ve yararsız) paketi indirebilirsiniz. -## Exercises +## Egzersizler -### A modular robot +### Modüler bir robot {{index "modular robot (exercise)", module, robot, NPM}} {{id modular_robot}} -These are the bindings that the project from [Chapter ?](robot) creates: +[Bölüm ?](robot) içindeki proje tarafından oluşturulan bağlantılar şu şekildedir: ```{lang: "null"} roads @@ -402,48 +396,48 @@ findRoute goalOrientedRobot ``` -If you were to write that project as a modular program, what modules would you create? Which module would depend on which other module, and what would their interfaces look like? +Eğer bu projeyi modüler bir program olarak yazsaydınız, hangi modülleri oluştururdunuz? Hangi modüller hangi diğer modüllere bağlı olurdu ve arayüzleri nasıl görünürdü? -Which pieces are likely to be available prewritten on NPM? Would you prefer to use an NPM package or write them yourself? +Hangi parçaların muhtemelen NPM'de önceden yazılmış olarak bulunacağını düşünüyorsunuz? Bir NPM paketi kullanmayı mı yoksa kendiniz mi yazmayı mı tercih edersiniz? {{hint {{index "modular robot (exercise)"}} -Here's what I would have done (but again, there is no single _right_ way to design a given module): +İşte ben olsaydım yapacağım şeyler (ancak yine de, belirli bir modül tasarımı için _tek bir doğru yol_ yoktur): {{index "dijkstrajs package"}} -The code used to build the road graph lives in the `graph` module. Because I'd rather use `dijkstrajs` from NPM than our own pathfinding code, we'll make this build the kind of graph data that `dijkstrajs` expects. This module exports a single function, `buildGraph`. I'd have `buildGraph` accept an array of two-element arrays, rather than strings containing hyphens, to make the module less dependent on the input format. +Yol grafiğini oluşturmak için kullanılan kod `graph` modülünde bulunur. Kendi yol bulma kodumuz yerine NPM'den `dijkstrajs` paketini kullanmayı tercih ettiğim için, `dijkstrajs`'ın beklediği türde grafik verilerini oluşturacağız. Bu modül, `buildGraph` adlı tek bir fonksiyonu dışa aktarır. Modülün giriş formatına olan bağımlılığını azaltmak için `buildGraph` fonksiyonunun tirelerle içindekileri ayıran bir dize yerine bir dizi iki öğeli diziyi kabul etmesini sağlardım. -The `roads` module contains the raw road data (the `roads` array) and the `roadGraph` binding. This module depends on `./graph.js` and exports the road graph. +`roads` modülü, ham yol verilerini (`roads` dizisi) ve `roadGraph` bağlantısını içerir. Bu modül `./graph.js` dosyasına bağlıdır ve yol grafiğini dışa aktarır. {{index "random-item package"}} -The `VillageState` class lives in the `state` module. It depends on the `./roads` module because it needs to be able to verify that a given road exists. It also needs `randomPick`. Since that is a three-line function, we could just put it into the `state` module as an internal helper function. But `randomRobot` needs it too. So we'd have to either duplicate it or put it into its own module. Since this function happens to exist on NPM in the `random-item` package, a reasonable solution is to just make both modules depend on that. We can add the `runRobot` function to this module as well, since it's small and closely related to state management. The module exports both the `VillageState` class and the `runRobot` function. +`VillageState` sınıfı, `state` modülünde yaşar. `./roads` modülüne bağımlıdır çünkü belirli bir yolun var olup olmadığını bilmesi gerekmektedir. Ayrıca `randomPick`'e ihtiyaç duyar. Bu, üç satırlık bir fonksiyon olduğu için bunu `state` modülüne bir dahili yardımcı fonksiyon olarak koyabiliriz. Ancak `randomRobot` da buna ihtiyaç duyar. Bu yüzden ya bunu kopyalamamız ya da kendi modülümüze koymamız gerekir. Bu fonksiyon, `random-item` paketinde zaten mevcut olduğu için, her iki modülü de buna bağlı hale getirmek uygun bir çözümdür. Bu modüle ayrıca, küçük olduğu ve durum yönetimiyle yakından ilgili olduğu için `runRobot` fonksiyonunu da ekleyebiliriz. Modül, hem `VillageState` sınıfını hem de `runRobot` fonksiyonunu dışa aktarır. -Finally, the robots, along with the values they depend on such as `mailRoute`, could go into an `example-robots` module, which depends on `./roads` and exports the robot functions. To make it possible for `goalOrientedRobot` to do route-finding, this module also depends on `dijkstrajs`. +Son olarak robotlar, `mailRoute` gibi bağımlılıklarıyla beraber `./roads`'a bağımlı olan ve robot fonksiyonlarını dışa aktaran bir `example-robots` modülüne konabilir. `goalOrientedRobot` fonksiyonunun rotalama yapabilmesi için, bu modül ayrıca `dijkstrajs` paketine bağımlıdır. -By offloading some work to ((NPM)) modules, the code became a little smaller. Each individual module does something rather simple and can be read on its own. Dividing code into modules also often suggests further improvements to the program's design. In this case, it seems a little odd that the `VillageState` and the robots depend on a specific road graph. It might be a better idea to make the graph an argument to the state's constructor and make the robots read it from the state object—this reduces dependencies (which is always good) and makes it possible to run simulations on different maps (which is even better). +((NPM)) modüllerine bazı işleri yükleyerek, kod biraz daha küçüldü. Her bir modül, oldukça basit bir şey yapar ve kendi başına okunabilir. Kodu modüllere bölmek ayrıca genellikle programın tasarımında daha ileri gelişmeleri önerir. Bu durumda, `VillageState` ve robotların belirli bir yol grafiğine bağlı olması biraz garip görünmektedir. Grafik, `state`'in constructor fonksiyonuna bir argüman olarak vermek ve robotların durum nesnesinden okumasını sağlamak daha iyi bir fikir olabilir—bu, bağımlılıkları azaltır (ki bu her zaman iyidir) ve farklı map değerlerinde simülasyonları çalıştırabilmeyi mümkün kılar (ki bu daha da iyidir). -Is it a good idea to use NPM modules for things that we could have written ourselves? In principle, yes—for nontrivial things like the pathfinding function you are likely to make mistakes and waste time writing them yourself. For tiny functions like `random-item`, writing them yourself is easy enough. But adding them wherever you need them does tend to clutter your modules. +NPM modüllerini yazabileceğimiz şeyler için kullanmak iyi bir fikir midir? İlkeler bakımından, evet—yol bulma gibi önemli olmayan şeyleri kendiniz yazarken muhtemelen hatalar yapar ve zaman kaybedersiniz. `random-item` gibi küçük fonksiyonlar için kendiniz yazmak yeterince kolaydır. Ancak onları ihtiyacınız olan her yere eklemek, modüllerinizi kalabalıklaştırmanızı sağlar. -However, you should also not underestimate the work involved in _finding_ an appropriate NPM package. And even if you find one, it might not work well or may be missing some feature you need. On top of that, depending on NPM packages means you have to make sure they are installed, you have to distribute them with your program, and you might have to periodically upgrade them. +Ancak, uygun bir NPM paketi _bulmanın_ getirdiği işi de küçümsememelisiniz. Ve bir tane bulsanız bile, iyi çalışmayabilir veya ihtiyacınız olan bazı özellikleri eksik olabilir. Üstelik, NPM paketlerine bağımlı olmak, onların kurulduğundan emin olmanızı ve programınızla birlikte dağıtmanız gerektiği anlamına gelir ve onları düzenli olarak güncellemeniz gerekebilir. -So again, this is a trade-off, and you can decide either way depending on how much a given package actually helps you. +Bu yüzden, tekrar ediyorum, bu bir ödünleşmedir ve bir paketin ne kadar yardımcı olduğuna bağlı olarak her iki şekilde de karar verebilirsiniz. hint}} -### Roads module +### Yollar modülü {{index "roads module (exercise)"}} -Write an ES module based on the example from [Chapter ?](robot) that contains the array of roads and exports the graph data structure representing them as `roadGraph`. It depends on a module `./graph.js` that exports a function `buildGraph`, used to build the graph. This function expects an array of two-element arrays (the start and end points of the roads). +[Chapter ?](robot) içindeki örneğe dayanarak bir ES modülü yazın, yolların bir dizisini içersin ve onları `roadGraph` olarak temsil eden grafik veri yapısını dışa aktarsın. Bu, grafik oluşturmak için kullanılan `buildGraph` adlı bir fonksiyonu dışa aktaran `./graph.js` adlı bir modüle bağımlı olmalıdır. Bu fonksiyon, iki öğeli dizilerden (yolların başlangıç ve bitiş noktaları) oluşan bir dizi bekler. {{if interactive ```{test: no} -// Add dependencies and exports +// Arayüz ve bağımlılıkları ekleyin const roads = [ "Alice's House-Bob's House", "Alice's House-Cabin", @@ -462,26 +456,26 @@ if}} {{index "roads module (exercise)", "destructuring binding", "exports object"}} -Since this is an ES module, you have to use `import` to access the graph module. That was described as exporting a `buildGraph` function, which you can pick out of its interface object with a destructuring `const` declaration. +Bu bir ES modül olduğundan, grafiğe erişmek için `import` kullanmanız gerekir. Bu, `const` beyanı aracılığıyla yapılarına ayırarak arayüz nesnesinden `buildGraph` fonksiyonunu seçebileceğiniz şekilde açıklanmıştır. -To export `roadGraph`, you put the keyword `export` before its definition. Because `buildGraph` takes a data structure that doesn't precisely match `roads`, the splitting of the road strings must happen in your module. +`roadGraph` fonksiyonunu dışa aktarmak için, tanımının önüne `export` anahtar kelimesini koyarsınız. `buildGraph`, `roads` ile tam olarak eşleşmeyen bir veri yapısı aldığından ötürü yol dizilerinin bölünmesi kendi modülünüzde olmalıdır. hint}} -### Circular dependencies +### Döngüsel bağımlılıklar {{index dependency, "circular dependency", "require function"}} -A circular dependency is a situation where module A depends on B, and B also, directly or indirectly, depends on A. Many module systems simply forbid this because whichever order you choose for loading such modules, you cannot make sure that each module's dependencies have been loaded before it runs. +Dairesel bağımlılık, modül A'nın B'ye, ve B'nin de doğrudan veya dolaylı olarak A'ya bağlı olduğu bir durumdur. Birçok modül sistemi bunu yasaklar çünkü bu tür modüllerin yüklenmesi için hangi sırayı seçerseniz seçin, her modülün çalıştırılmadan önce bağımlılıklarının yüklenmiş olup olmadığından emin olamazsınız. -((CommonJS modules)) allow a limited form of cyclic dependencies. As long as the modules don't access each other's interface until after they finish loading, cyclic dependencies are okay. +((CommonJS modülleri)) sınırlı bir dairesel bağımlılık biçimine izin verir. Modüller birbirlerinin arayüzlerine yüklenme işlemleri tamamlanmadan önce erişmedikçe, dairesel bağımlılıklar sorun değildir. -The `require` function given [earlier in this chapter](modules#require) supports this type of dependency cycle. Can you see how it handles cycles? +[Bu bölümün başlarında](modules#require) verilen `require` fonksiyonu bu tür bir bağımlılık döngüsünü destekler. Bununla nasıl başa çıktığını görebiliyor musunuz? {{hint {{index overriding, "circular dependency", "exports object"}} -The trick is that `require` adds the interface object for a module to its cache _before_ it starts loading the module. That way, if any `require` call made while it is running try to load it, it is already known, and the current interface will be returned, rather than starting to load the module once more (which would eventually overflow the stack). +Püf noktası, `require` fonksiyonunun modülü yüklemeye _başlamadan önce_ arayüz nesnesini önbelleğine eklemesidir. Bu şekilde, çalışırken yapılan herhangi bir `require` çağrısı, yüklenmiş olup olmadığı bilindiğinden, tüm modülü tekrar yüklemek yerine (bunu yapmak sonunda yığını taşmaya neden olurdu) mevcut arayüz döndürülmesini sağlar. hint}} diff --git a/11_async.md b/11_async.md index cf18415c..fd2bdfed 100644 --- a/11_async.md +++ b/11_async.md @@ -4,76 +4,76 @@ {{quote {author: "Laozi", title: "Tao Te Ching", chapter: true} -Who can wait quietly while the mud settles?\ -Who can remain still until the moment of action? +Çamur çökene kadar kim sessizce bekleyebilir?\ +Kim eylem anına kadar hareketsiz kalabilir? quote}} {{index "Laozi"}} -{{figure {url: "img/chapter_picture_11.jpg", alt: "Illustration showing two crows on a tree branch", chapter: framed}}} +{{figure {url: "img/chapter_picture_11.jpg", alt: "Bir ağaç dalındaki iki kargayı gösteren illüstrasyon.", chapter: framed}}} -The central part of a computer, the part that carries out the individual steps that make up our programs, is called the _((processor))_. The programs we have seen so far will keep the processor busy until they have finished their work. The speed at which something like a loop that manipulates numbers can be executed depends pretty much entirely on the speed of the computer's processor and memory. +Bilgisayarın merkezi parçası, programlarımızı oluşturan bireysel adımları gerçekleştiren kısım _((işlemci))_ olarak adlandırılır. Şimdiye kadar gördüğümüz programlar işlerini bitirene kadar işlemciyi meşgul tutarlar. Sayıları manipüle eden bir döngü gibi bir şeyin çalıştırılma hızı, büyük ölçüde bilgisayarın işlemcisinin ve belleğinin hızına bağlıdır. {{index [memory, speed], [network, speed]}} -But many programs interact with things outside of the processor. For example, they may communicate over a computer network or request data from the ((hard disk))—which is a lot slower than getting it from memory. +Ancak birçok program, işlemcinin dışındaki şeylerle etkileşime geçer. Örneğin, bir bilgisayar ağı üzerinden iletişim kurabilir veya ((hard disk))ten veri isteyebilir - bu, bellekten veri almaktan çok daha yavaştır. -When such a thing is happening, it would be a shame to let the processor sit idle—there might be some other work it could do in the meantime. In part, this is handled by your operating system, which will switch the processor between multiple running programs. But that doesn't help when we want a _single_ program to be able to make progress while it is waiting for a network request. +Böyle bir şey olurken, işlemciyi boşta bekletmek pek efektik olmaz çünkü bu sırada yapabileceği başka bir iş olabilir. Bu işlemciyi birden çok çalışan programlar arasında geçirerek kısmen işletim sistemi tarafından ele alınır. Ancak bu, bir tek programın bir ağ isteği beklerken ilerleme kaydetmesini istediğimizde işe yaramaz. -## Asynchronicity +## Eşzamansızlık {{index "synchronous programming"}} -In a _synchronous_ programming model, things happen one at a time. When you call a function that performs a long-running action, it returns only when the action has finished and it can return the result. This stops your program for the time the action takes. +Bir _eşzamanlı_ program modelinde, olaylar teker teker gerçekleşir. Uzun süren bir eylemi gerçekleştiren bir fonksiyonu çağırdığınızda, yalnızca eylem tamamlandığında ve sonucu döndüğünde geri döner. Bu, eylemin zaman aldığı süre boyunca programınızın durmasına sebep olur. {{index "asynchronous programming"}} -An _asynchronous_ model allows multiple things to happen at the same time. When you start an action, your program continues to run. When the action finishes, the program is informed and gets access to the result (for example, the data read from disk). +Bir _eşzamansız_ model, aynı anda birden çok şeyin gerçekleşmesine izin verir. Bir eylemi başlattığınızda, programınız çalışmaya devam eder. Eylem tamamlandığında, program bilgilendirilir ve sonuca erişir (örneğin, diskten okunan veri). -We can compare synchronous and asynchronous programming using a small example: a program that makes two requests over the ((network)) and then combines the results. +Eşzamanlı ve eşzamansız programlamayı bir örnekle karşılaştırabiliriz: ((network)) üzerinden iki istek yapan ve ardından sonucu birleştiren bir program. {{index "synchronous programming"}} -In a synchronous environment, where the request function returns only after it has done its work, the easiest way to perform this task is to make the requests one after the other. This has the drawback that the second request will be started only when the first has finished. The total time taken will be at least the sum of the two response times. +Bir eşzamanlı ortamda, talep fonksiyonu yalnızca işini bitirdikten sonra döndüğünde, bu görevi gerçekleştirmenin en kolay yolu istekleri birbiri ardına yapmaktır. Bu, ikinci istek yalnızca ilk istek tamamlandığında başlatılacağından dezavantajlıdır. Toplam süre en az iki yanıt süresinin toplamı olacaktır. {{index parallelism}} -The solution to this problem, in a synchronous system, is to start additional ((thread))s of control. A _thread_ is another running program whose execution may be interleaved with other programs by the operating system—since most modern computers contain multiple processors, multiple threads may even run at the same time, on different processors. A second thread could start the second request, and then both threads wait for their results to come back, after which they resynchronize to combine their results. +Bu sorunun çözümü, eşzamanlı bir sistemde ek kontrol ((thread))leri başlatmaktır. Bir _thread_, bir başka çalışan programdır ve işletim sistemi tarafından diğer programlarla birlikte aralıklı bir şekilde çalıştırılabilir - çoğu modern bilgisayar birden çok işlemci içerdiğinden, birden çok thread aynı anda farklı işlemcilerde çalışabilir. İkinci bir thread, ikinci isteği başlatabilir ve ardından her iki thread de sonuçlarını bekler, sonrasında sonuçlarını birleştirmek için yeniden senkronize olurlar. {{index CPU, blocking, "asynchronous programming", timeline, "callback function"}} -In the following diagram, the thick lines represent time the program spends running normally, and the thin lines represent time spent waiting for the network. In the synchronous model, the time taken by the network is _part_ of the timeline for a given thread of control. In the asynchronous model, starting a network action allows the program to continue running while the network communication happens alongside it, notifying the program when it is finished. +Aşağıdaki diyagramda, kalın çizgiler programın normal çalıştığı zamanı temsil ederken, ince çizgiler ağda beklenen zamanı temsil eder. Senkron modelde, ağın alması gereken süre, belirli bir kontrol ((thread))inin zaman çizelgesinin bir \_parçası_dır. Asenkron modelde ağ eyleminin başlatılması, programın devam etmesine izin verir ve ağ iletişimi yanında gerçekleşir, işlem sona erdiğinde programı bilgilendirir. -{{figure {url: "img/control-io.svg", alt: "Diagram of showing control flow in synchronous and asynchronous programs. The first part shows a synchronous program, where the program's active and waiting phases all happen on a single, sequential line. The second part shows a multi-threaded synchronous program, with two parallel lines, on which the waiting parts happen alongside each other, causing the program to finish faster. The last part shows an asynchronous program, where the multiple asynchronous actions branch off from the main program, which at some point stops, and then resumes whenever the first thing it was waiting for finishes.",width: "8cm"}}} +{{figure {url: "img/control-io.svg", alt: "Senkron ve asenkron programlarda kontrol akışını gösteren diyagram. İlk bölüm, programın aktif ve bekleme aşamalarının tek bir sıralı satırda gerçekleştiği senkronize bir programı göstermektedir. İkinci bölümde, bekleme parçalarının yan yana yer aldığı, programın daha hızlı bitmesine neden olan, iki paralel çizgiye sahip, çok iş parçacıklı bir senkronize program gösterilmektedir. Son bölüm, birden fazla eşzamansız eylemin ana programdan ayrıldığı, bir noktada duran ve beklediği ilk şey bittiğinde devam ettiği eşzamansız bir programı gösterir.",width: "8cm"}}} {{index ["control flow", asynchronous], "asynchronous programming", verbosity, performance}} -Another way to describe the difference is that waiting for actions to finish is _implicit_ in the synchronous model, while it is _explicit_—under our control—in the asynchronous one. +Farkı açıklamanın başka bir yolu, eylemlerin bitmesini beklemenin eşzamanlı modelde _örtük_ ancak asenkron modelde ise bizim kontrolümüz altında _açıkça_ olduğudur. -Asynchronicity cuts both ways. It makes expressing programs that do not fit the straight-line model of control easier, but it can also make expressing programs that do follow a straight line more awkward. We'll see some ways to reduce this awkwardness later in the chapter. +Eşzamansızlık iki yönde de keser. Doğrudan çizgi kontrol modeline uymayan programları ifade etmeyi kolaylaştırır, ancak doğrudan bir çizgi izleyen programları ifade etmeyi daha zor hale getirebilir. Bu zorluğu azaltmanın bazı yollarını bölümün ilerleyen kısımlarında göreceğiz. -Both prominent JavaScript programming platforms—((browser))s and ((Node.js))—make operations that might take a while asynchronous, rather than relying on ((thread))s. Since programming with threads is notoriously hard (understanding what a program does is much more difficult when it's doing multiple things at once), this is generally considered a good thing. +Öne çıkan JavaScript programlama platformları - ((browser))lar ve ((Node.js)) - zaman alabilecek işlemleri ((thread))lerden ziyade asenkron olarak yaparlar. Çünkü thread'lerle programlamak ünlü bir şekilde zordur (bir programın ne yaptığını anlamak, aynı anda birden fazla iş yaptığında çok daha zordur), bu genellikle iyi bir şey olarak kabul edilir. -## Callbacks +## Geri aramalar {{indexsee [function, callback], "callback function"}} -One approach to ((asynchronous programming)) is to make functions that need to wait for something take an extra argument, a _((callback function))_. The asynchronous function starts a process, sets things up so that the callback function is called when the process finishes, and then returns. +((Asenkron programlama)) yaklaşımlarından biri, bir şeyi beklemesi gereken fonksiyonlara ek bir argüman olarak bir _((geri çağrı fonksiyonu))_ vermektedir. Bir fonksiyon, bir işlemi başlatır, işlem tamamlandığında geri çağrı fonksiyonunun çağrılması için düzenlemeler yapar ve ardından değerini döndürür. {{index "setTimeout function", waiting}} -As an example, the `setTimeout` function, available both in Node.js and in browsers, waits a given number of milliseconds, then calls a function. +Örneğin, Node.js ve tarayıcılarda bulunan `setTimeout` fonksiyonu, belirli bir milisaniye (bir saniye bin milisaniyedir) bekler ve ardından bir fonksiyonu çağırır. ```{test: no} setTimeout(() => console.log("Tick"), 500); ``` -Waiting is not generally important work, but it can be very useful when you need to arrange for something to happen at a certain time or check whether some action is taking longer than expected. +Bekleme genellikle çok önemli bir iş türü değildir, ancak belirli bir zamanda bir şeyin yapılmasını ayarlamak veya başka bir eylemin beklenenden daha uzun sürüp sürmediğini kontrol etmek gerektiğinde çok kullanışlı olabilir. {{index "readTextFile function"}} -Another example of a common asynchronous operation is reading a file from a device's storage. Imagine you have a function `readTextFile` that reads a file's content as a string and passes it to a callback function. +Diğer bir yaygın asenkron işlemlerse cihazın depolama biriminden bir dosya okumaktır. Diyelim ki bir `readTextFile` fonksiyonunuz var ve bu bir dosyanın içeriğini bir dize olarak okur ve bunu bir geri çağrı fonksiyonuna verir. ``` readTextFile("shopping_list.txt", content => { @@ -84,9 +84,9 @@ readTextFile("shopping_list.txt", content => { // → Bananas ``` -The `readTextFile` function is not part of standard JavaScript. We will see how to read files in the browser and in Node.js in later chapters. +`readTextFile` fonksiyonu standart JavaScript'in bir parçası değildir. Tarayıcıda ve Node.js'te dosya okumanın nasıl yapıldığını sonraki bölümlerde göreceğiz. -Performing multiple asynchronous actions in a row using callbacks means that you have to keep passing new functions to handle the ((continuation)) of the computation after the actions. An asynchronous function that compares two files and produces a boolean indicating whether their content is the same might look like this: +Geri aramalar kullanarak ardışık olarak birden fazla asenkron işlem gerçekleştirmek, işlemlerden sonra hesaplamanın devamını ele almak için sürekli yeni fonksiyonlar geçirmeniz gerektiği anlamına gelir. İki dosyayı karşılaştıran ve içeriklerinin aynı olup olmadığını belirten bir asenkron fonksiyon, şu şekilde yazılabilir. ``` function compareFiles(fileA, fileB, callback) { @@ -98,21 +98,21 @@ function compareFiles(fileA, fileB, callback) { } ``` -This style of programming is workable, but the indentation level increases with each asynchronous action because you end up in another function. Doing more complicated things, such as wrapping asynchronous actions in a loop, can get awkward. +Bu programlama tarzı çalışabilir, ancak her asenkron işlemle girinti seviyesi artar çünkü başka bir fonksiyona girersiniz. Daha karmaşık şeyler yapmak, örneğin asenkron işlemleri bir döngü içine almak, garip olabilir. -In a way, asynchronicity is _contagious_. Any function that calls a function that works asynchronously must itself be asynchronous, using a callback or similar mechanism to deliver its result. Calling a callback is somewhat more involved and error-prone than simply returning a value, so needing to structure large parts of your program that way is not great. +Bir bakıma, eşzamansızlık bulaşıcıdır. Asenkron olarak çalışan bir fonksiyonu çağıran herhangi bir fonksiyon, sonucunu iletmek için bir geri çağrı veya benzeri bir mekanizma kullanarak kendisi de asenkron olmalıdır. Bir geri çağrı çağırmak, sadece bir değeri döndürmekten biraz daha karmaşıktır ve hata yapma olasılığı daha yüksektir, bu nedenle programınızın büyük kısımlarını bu şekilde yapılandırmanız gerektiğinde pek de iyi bir seçenek değildir. -## Promises +## Promise'lar -A slightly different way to build an asynchronous program is to have asynchronous functions return an object that represents its (future) result instead of passing around callback functions. This way such functions actually return something meaningful, and the shape of the program more closely resembles that of synchronous programs. +Asenkron bir program oluşturmanın biraz farklı bir yolu, asenkron fonksiyonların geri arama fonksiyonlarını dolaştırmak yerine, gelecekteki sonucunu temsil eden bir nesne döndürmeleridir. Bu şekilde, böyle fonksiyonlar aslında anlamlı bir şey döndürür ve programın yapısı, eşzamanlı programlarınkine daha yakın olur. {{index "Promise class", "asynchronous programming", "resolving (a promise)", "then method", "callback function"}} -This is what the standard class `Promise` is for. A _promise_ is a receipt representing a value that may not be available yet. It provides a `then` method that allows you to register a function that should be called when the action for which it is waiting finishes. When the promise is _resolved_, meaning its value becomes available, such functions (there can be multiple) are called with the result value. It is possible to call `then` on a promise that has already resolved—your function will still be called. +Standart `Promise` sınıfı bunun için kullanılır. Bir _promise_, henüz mevcut olmayan bir değeri temsil eden bir makbuzdur. `then` metodunu sağlar, böylece beklenen eylem tamamlandığında çağrılması gereken bir fonksiyonu kaydedebilirsiniz. `Promise` çözüldüğünde, yani değeri mevcut olduğunda, böyle fonksiyonlar (çoklu olabilir) sonuç değeriyle çağrılır. Zaten çözülmüş bir promise üzerinde `then` çağrısı yapmak mümkündür—fonksiyonunuz hala çağrılacaktır. {{index "Promise.resolve function"}} -The easiest way to create a promise is by calling `Promise.resolve`. This function ensures that the value you give it is wrapped in a promise. If it's already a promise, it is simply returned. Otherwise, you get a new promise that immediately resolves with your value as its result. +Bir promise oluşturmanın en kolay yolu, `Promise.resolve` çağrısını kullanmaktır. Bu fonksiyon, verdiğiniz değerin bir promise içine sarıldığından emin olur. Zaten bir promise ise, sadece döndürülür—aksi halde, değerinizi sonucu olarak hemen çözülen yeni bir promise alırsınız. ``` let fifteen = Promise.resolve(15); @@ -122,9 +122,9 @@ fifteen.then(value => console.log(`Got ${value}`)); {{index "Promise class"}} -To create a promise that does not immediately resolve, you can use `Promise` as a constructor. It has a somewhat odd interface: the constructor expects a function as argument, which it immediately calls, passing it a function that it can use to resolve the promise. +Hemen çözülmeyen bir promise oluşturmak için, `Promise`'ı bir constructor olarak kullanabilirsiniz. Biraz garip bir arayüze sahiptir—constructor, hemen çağrılan ve promise'i çözmek için kullanabileceği bir fonksiyon geçmesini bekler. -For example, this is how you could create a promise-based interface for the `readTextFile` function: +`readTextFile` fonksiyonu için promise tabanlı bir arayüzü bu şekilde oluşturabilirsiniz: {{index "textFile function"}} @@ -138,13 +138,13 @@ function textFile(filename) { textFile("plans.txt").then(console.log); ``` -Note how, in contrast to callback-style functions, this asynchronous function returns a meaningful value—a promise to give you the contents of the file at some point in the future. +Bu eşzamansız fonksiyonun anlamlı bir değer döndürdüğüne dikkat edin—gelecekte bir noktada dosyanın içeriğini size verecek bir promise. {{index "then method"}} -A useful thing about the `then` method is that it itself returns another promise. This one resolves to the value returned by the callback function or, if that returned value is a promise, to the value that promise resolves to. Thus, you can “chain” multiple calls to `then` together to set up a sequence of asynchronous actions. +`then` metodunun yararlı bir yönü, kendisinin de callback fonksiyonunun döndürdüğü değere çözülen başka bir promise döndürmesidir veya eğer o fonksiyon bir promise döndürürse, o promise'in çözüldüğü değere çözülen bir promise döndürür. Böylece, eşzamansız eylemler dizisini oluşturmak için birden fazla `then` çağrısını “zincirleyebilirsiniz”. -This function, which reads a file full of filenames, and returns the content of a random file in that list, shows this kind of asynchronous promise pipeline: +Bir dosya dolusu dosya adını okuyan ve listedeki rastgele bir dosyanın içeriğini döndüren bu fonksiyon, bu tür bir eşzamansız promise boru hattını gösterir. ``` function randomFile(listFile) { @@ -155,11 +155,11 @@ function randomFile(listFile) { } ``` -The function returns the result of this chain of `then` calls. The initial promise fetches the list of files as a string. The first `then` call transforms that string into an array of lines, producing a new promise. The second `then` call picks a random line from that, producing a third promise that yields a single filename. The final `then` call reads this file, so that the result of the function as a whole is a promise that returns the content of a random file. +Fonksiyon, `then` çağrıları zincirinin sonucunu döndürür. İlk promise, dosya listesini bir dize olarak alır. İlk `then` çağrısı, bu dizeyi bir dizi satıra dönüştürerek yeni bir promise üretir. İkinci `then` çağrısı, rastgele bir satır seçer ve tek bir dosya adı veren üçüncü bir promise üretir. Son `then` çağrısı bu dosyayı okur, böylece fonksiyonun tamamının sonucu, rastgele bir dosyanın içeriğini döndüren bir promise olur. -In this code, the functions used in the first two `then` calls return a regular value that will immediately be passed into the promise returned by `then` when the function returns. The last `then` call returns a promise (`textFile(filename)`), making it an actual asynchronous step. +Bu kodda, ilk iki `then` çağrısında kullanılan fonksiyonlar normal bir değer döndürür, bu değer fonksiyon döndüğünde hemen `then` tarafından döndürülen promise'e geçer. Sonuncusu bir promise (textFile(filename)) döndürür ve bu onu gerçek bir eşzamansız adım yapar. -It would also have been possible to perform all these steps inside a single `then` callback, since only the last step is actually asynchronous. But the kind of `then` wrappers that only do some synchronous data transformation are often useful, such as when you want to return a promise that produces a processed version of some asynchronous result. +Bu adımların hepsini tek bir `then` callback içinde yapmak da mümkün olurdu, çünkü aslında sadece son adım eşzamansızdır. Ancak sadece bazı eşzamanlı veri dönüşümleri yapan `then` sarmalayıcıları, genellikle bir eşzamansız sonucun işlenmiş bir sürümünü üreten bir promise döndürmek istediğinizde olduğu gibi, kullanışlıdır. ``` function jsonFile(filename) { @@ -169,19 +169,19 @@ function jsonFile(filename) { jsonFile("package.json").then(console.log); ``` -Generally, it is useful to think of a promise as a device that lets code ignore the question of when a value is going to arrive. A normal value has to actually exist before we can reference it. A promised value is a value that _might_ already be there or might appear at some point in the future. Computations defined in terms of promises, by wiring them together with `then` calls, are executed asynchronously as their inputs become available. +Genel olarak, promise'leri, bir değerin ne zaman geleceği sorusunu kodun görmezden gelmesine izin veren bir cihaz olarak düşünmek faydalıdır. Normal bir değer, ona referans verebilmemiz için aslında var olmalıdır. Promise edilen bir değer, zaten orada olabilecek veya gelecekte bir noktada ortaya çıkabilecek bir değerdir. Promise'lerle tanımlanan hesaplamalar, `then` çağrılarıyla birbirine bağlanarak, girdileri kullanılabilir hale geldikçe eşzamansız olarak yürütülür. -## Failure +## Arıza {{index "exception handling"}} -Regular JavaScript computations can fail by throwing an exception. Asynchronous computations often need something like that. A network request may fail, a file may not exist, or some code that is part of the asynchronous computation may throw an exception. +Normal JavaScript hesaplamaları bir istisna fırlatarak başarısız olabilir. Eşzamansız hesaplamalar da genellikle buna benzer bir şeye ihtiyaç duyar. Bir ağ isteği başarısız olabilir, bir dosya mevcut olmayabilir veya eşzamansız hesaplamanın bir parçası olan bazı kodlar bir istisna fırlatabilir. {{index "callback function", error}} -One of the most pressing problems with the callback style of asynchronous programming is that it makes it extremely difficult to ensure failures are properly reported to the callbacks. +Eşzamansız programlamanın callback stilindeki en acil sorunlardan biri, hataların doğru şekilde callback'lere bildirilmesini sağlamanın son derece zor olmasıdır. -A common convention is to use the first argument to the callback to indicate that the action failed, and the second to pass the value produced by the action when it was successful. +Yaygın olarak kullanılan bir konvansiyon, callback'in ilk argümanının eylemin başarısız olduğunu belirtmek için kullanılması ve ikincisinin eylemin başarılı olduğunda ürettiği değeri içermesidir. ``` someAsyncFunction((error, value) => { @@ -190,29 +190,29 @@ someAsyncFunction((error, value) => { }); ``` -Such callback functions must always check whether they received an exception and make sure that any problems they cause, including exceptions thrown by functions they call, are caught and given to the right function. +Bu tür callback fonksiyonları her zaman bir istisna alıp almadıklarını kontrol etmeli ve neden oldukları herhangi bir sorunun, çağırdıkları fonksiyonlar tarafından fırlatılan istisnalar da dahil olmak üzere, yakalanıp doğru fonksiyona iletildiğinden emin olmalıdır. {{index "rejecting (a promise)", "resolving (a promise)", "then method"}} -Promises make this easier. They can be either resolved (the action finished successfully) or rejected (it failed). Resolve handlers (as registered with `then`) are called only when the action is successful, and rejections are propagated to the new promise returned by `then`. When a handler throws an exception, this automatically causes the promise produced by its `then` call to be rejected. If any element in a chain of asynchronous actions fails, the outcome of the whole chain is marked as rejected, and no success handlers are called beyond the point where it failed. +Promises bunu kolaylaştırır. Bir promise ya çözülebilir (eylem başarıyla tamamlandı) ya da reddedilebilir (başarısız oldu). `then` ile kayıtlı çözümleyici fonksiyonlar yalnızca eylem başarılı olduğunda çağrılır ve reddedilmeler, `then` tarafından döndürülen yeni promise'e aktarılır. Bir handler bir istisna fırlattığında, bu otomatik olarak `then` çağrısının ürettiği promise'in reddedilmesine neden olur. Dolayısıyla, eşzamansız eylemler zincirindeki herhangi bir öğe başarısız olursa, tüm zincirin sonucu reddedilmiş olarak işaretlenir ve başarısız olduğu noktadan sonra hiçbir başarı handler'ı çağrılmaz. {{index "Promise.reject function", "Promise class"}} -Much like resolving a promise provides a value, rejecting one also provides a value, usually called the _reason_ of the rejection. When an exception in a handler function causes the rejection, the exception value is used as the reason. Similarly, when a handler returns a promise that is rejected, that rejection flows into the next promise. There's a `Promise.reject` function that creates a new, immediately rejected promise. +Bir promise'i çözmek nasıl bir değer sağlıyorsa, bir promise'i reddetmek de bir değer sağlar, genellikle reddetmenin nedeni olarak adlandırılır. Bir handler fonksiyonundaki bir istisna reddetmeye neden olduğunda, istisna değeri neden olarak kullanılır. Benzer şekilde, bir handler reddedilen bir promise döndürdüğünde, bu reddetme bir sonraki promise'e akar. `Promise.reject` fonksiyonu, yeni, anında reddedilen bir promise oluşturur. {{index "catch method"}} -To explicitly handle such rejections, promises have a `catch` method that registers a handler to be called when the promise is rejected, similar to how `then` handlers handle normal resolution. It's also very much like `then` in that it returns a new promise, which resolves to the original promise's value when that resolves normally and to the result of the `catch` handler otherwise. If a `catch` handler throws an error, the new promise is also rejected. +Bu tür reddetmeleri açıkça ele almak için, promise'lerin, reddedildiğinde bir handler kaydeden `catch` metodu vardır, tıpkı `then` handler'larının normal çözümlemeyi ele alması gibi. Ayrıca, `then` gibi, orijinal promise'in değeri normal olarak çözüldüğünde ve `catch` handler'ının sonucuna göre çözüldüğünde yeni bir promise döndürür. Eğer bir `catch` handler bir hata fırlatırsa, yeni promise de reddedilir. {{index "then method"}} -As a shorthand, `then` also accepts a rejection handler as a second argument, so you can install both types of handlers in a single method call: `.then(acceptHandler, rejectHandler)`. +Kısa bir yol olarak, `then` ikinci argüman olarak bir reddetme handler'ını da kabul eder, böylece her iki tür handler'ı tek bir metod çağrısında kurabilirsiniz. -A function passed to the `Promise` constructor receives a second argument, alongside the resolve function, which it can use to reject the new promise. +`Promise` constructor'ına geçen bir fonksiyon, resolve fonksiyonunun yanında reddetmek için kullanabileceği ikinci bir argüman alır. {{index "textFile function"}} -When our `readTextFile` function encounters a problem, it passes the error to its callback function as a second argument. Our `textFile` wrapper should actually check that argument, so that a failure causes the promise it returns to be rejected. +`readTextFile` fonksiyonumuz bir sorunla karşılaştığında, hatayı callback fonksiyonuna ikinci bir argüman olarak iletir. textFile sarmalayıcımız aslında bu argümana bakmalı, böylece bir başarısızlık döndürdüğü promise'in reddedilmesine neden olur. ```{includeCode: true} function textFile(filename) { @@ -225,7 +225,7 @@ function textFile(filename) { } ``` -The chains of promise values created by calls to `then` and `catch` thus form a pipeline through which asynchronous values or failures move. Since such chains are created by registering handlers, each link has a success handler or a rejection handler (or both) associated with it. Handlers that don't match the type of outcome (success or failure) are ignored. Handlers that do match are called, and their outcome determines what kind of value comes next—success when they return a non-promise value, rejection when they throw an exception, and the outcome of the promise when they return a promise. +`then` ve `catch` çağrılarıyla oluşturulan promise değer zincirleri, bu şekilde eşzamansız değerlerin veya hataların geçtiği bir boru hattı oluşturur. Bu tür zincirler handler'ları kaydederek oluşturulduğundan, her bağlantıda bir başarı handler'ı veya bir reddetme handler'ı (veya her ikisi) bulunur. Sonucun türüne (başarı veya başarısızlık) uymayan handler'lar yok sayılır. Ancak uyum sağlayanlar çağrılır ve sonuçları, sıradaki değerin türünü belirler—bir promise döndürmeyen bir değer döndüğünde başarı, bir istisna fırlattığında reddedilme ve bir promise döndürdüğünde promise'in sonucu. ```{test: no} new Promise((_, reject) => reject(new Error("Fail"))) @@ -239,39 +239,39 @@ new Promise((_, reject) => reject(new Error("Fail"))) // → Handler 2: nothing ``` -The first `then` handler function isn't called, because at that point of the pipeline the promise holds a rejection. The `catch` handler handles that rejection and returns a value, which is given to the second `then` handler function. +lk normal handler fonksiyonu çağrılmaz, çünkü boru hattının o noktasında promise bir reddetme taşır. `catch` handler bu reddetmeyi ele alır ve ikinci handler fonksiyonuna verilen bir değer döndürür. {{index "uncaught exception", "exception handling"}} -Much like an uncaught exception is handled by the environment, JavaScript environments can detect when a promise rejection isn't handled and will report this as an error. +Yakalanmamış bir istisnanın ortam tarafından ele alınması gibi, JavaScript ortamları bir promise reddedilmesinin ele alınmadığını tespit edebilir ve bunu bir hata olarak bildirecektir. ## Carla {{index "Carla the crow"}} -It's a sunny day in Berlin. The runway of the old, decommissioned airport is teeming with cyclists and inline skaters. In the grass near a garbage container a flock of crows noisily mills about, trying to convince a group of tourists to part with their sandwiches. +Berlin'de güneşli bir gün. Eski, hizmet dışı bırakılmış havaalanının pisti bisikletçiler ve patencilerle dolu. Bir çöp konteynerinin yanında, çimenlerin üzerinde, bir grup turistin sandviçlerinden vazgeçirmeye çalışan bir sürü karga gürültülü bir şekilde dolaşıyor. -One of the crows stands out—a large scruffy female with a few white feathers in her right wing. She is baiting people with a skill and confidence that suggest she's been doing this for a long time. When an elderly man is distracted by the antics of another crow, she casually swoops in, snatches his half-eaten bun from his hand, and sails away. +Kargalardan biri öne çıkıyor—sağ kanadında birkaç beyaz tüy olan büyük, dağınık bir dişi. İnsanları uzun zamandır bu işi yaptığına işaret eden bir beceri ve güvenle kandırıyor. Yaşlı bir adam başka bir karganın maskaralıklarıyla dikkati dağılırken, bu dişi karga rahatça süzülüyor, adamın elindeki yarısı yenmiş çöreği kapıyor ve uzaklaşıyor. -Contrary to the rest of the group, who look like they are happy to spend the day goofing around here, the large crow looks purposeful. Carrying her loot, she flies straight towards the roof of the hangar building, disappearing into an air vent. +Grubun geri kalanının burada vakit geçirip eğlenmekten mutlu göründüğünün aksine, büyük karga amaçlı görünüyor. Ganimetini taşıyan karga, doğruca hangar binasının çatısına doğru uçuyor ve bir hava deliğinde kayboluyor. -Inside the building, you can hear an odd tapping sound—soft, but persistent. It comes from a narrow space under the roof of an unfinished stairwell. The crow is sitting there, surrounded by her stolen snacks, half a dozen smartphones (several of which are turned on), and a mess of cables. She rapidly taps the screen of one of the phones with her beak. Words are appearing on it. If you didn't know better, you'd think she was typing. +Binanın içinde, tuhaf bir tıklama sesi duyulabiliyor—yumuşak ama ısrarcı. Ses, bitmemiş bir merdivenin çatısının altındaki dar bir alandan geliyor. Karga orada, çalınmış atıştırmalıklarının, yarım düzine akıllı telefonun (bunların birkaç tanesi açık) ve kabloların karmaşası arasında oturuyor. Gagasıyla hızla telefonlardan birinin ekranına tıklıyor. Ekranda kelimeler beliriyor. Eğer daha iyi bilmeseydiniz, yazı yazdığını düşünebilirdiniz. -This crow is known to her peers as “cāāw-krö”. But since those sounds are poorly suited for human vocal chords, we'll refer to her as Carla. +Bu karga, akranları tarafından “cāāw-krö” olarak bilinir. Ancak bu sesler insan ses tellerine pek uygun olmadığından, ona Carla diyeceğiz. -Carla is a somewhat peculiar crow. In her youth, she was fascinated by human language, eavesdropping on people until she had a good grasp of what they were saying. Later in life, her interest shifted to human technology, and she started stealing phones to study them. Her current project is learning to program. The text she is typing in her hidden lab is, in fact, a piece of asynchronous JavaScript code. +Carla, biraz tuhaf bir karga. Gençliğinde, insan diline hayrandı ve insanların ne söylediklerini iyice anlayana kadar onları gizlice dinlerdi. Daha sonraki yaşamında, ilgisi insan teknolojisine kaydı ve telefonları çalmaya başladı. Şu anki projesi programlamayı öğrenmek. Gizli laboratuvarında yazdığı metin aslında bir JavaScript kod parçası. -## Breaking In +## Zorla Girmek {{index "Carla the crow"}} -Carla loves the Internet. Annoyingly, the phone she is working on is about to run out of prepaid data. The building has a wireless network, but it requires a code to access. +Carla internete bayılıyor. Ne yazık ki, üzerinde çalıştığı telefonun ön ödemeli veri kotası bitmek üzere. Binada bir kablosuz ağ var, ancak erişim için bir kod gerekiyor. -Fortunately, the wireless routers in the building are 20 years old and poorly secured. Doing some research, Carla finds out that the network authentication mechanism has a flaw she can use. When joining the network, a device must send along the correct six-digit passcode. The access point will reply with a success or failure message depending on whether the right code is provided. However, when sending a partial code (say, only 3 digits), the response is different based on whether those digits are the correct start of the code or not. Sending incorrect numbers immediately returns a failure message. When sending the correct ones, the access point waits for more digits. +Neyse ki, binadaki kablosuz yönlendiriciler 20 yıllık ve kötü bir şekilde güvenlik sağlanmış. Biraz araştırma yaptıktan sonra, Carla ağın kimlik doğrulama mekanizmasında kullanabileceği bir açık buluyor. Ağa katılırken, cihazın doğru 6 haneli şifreyi göndermesi gerekiyor. Erişim noktası, doğru kod sağlandığında bir başarı mesajı, yanlış kod sağlandığında ise bir hata mesajı ile yanıt veriyor. Ancak, yalnızca kısmi bir kod (örneğin, sadece 3 hane) gönderildiğinde, yanıt bu hanelerin kodun doğru başlangıcı olup olmadığına göre değişiyor—yanlış bir sayı gönderildiğinde hemen bir hata mesajı alıyorsunuz. Doğru sayıları gönderdiğinizde ise erişim noktası daha fazla sayı bekliyor. -This makes it possible to greatly speed up the guessing of the number. Carla can find the first digit by trying each number in turn, until she finds one that doesn't immediately return failure. Having one digit, she can find the second digit in the same way, and so on, until she knows the entire passcode. +Bu, sayıyı tahmin etme sürecini büyük ölçüde hızlandırmayı mümkün kılar. Carla, ilk haneyi bulmak için her sayıyı sırayla deneyebilir ve hemen hata mesajı almayan sayıyı bulabilir. Bir haneyi bulduktan sonra, aynı şekilde ikinci haneyi de bulabilir ve bu şekilde devam ederek tüm şifreyi öğrenebilir. -Assume Carla has a `joinWifi` function. Given the network name and the passcode (as a string), the function tries to join the network, returning a promise that resolves if successful and rejects if the authentication failed. The first thing she needs is a way to wrap a promise so that it automatically rejects after it takes too much time, to allow the program to quickly move on if the access point doesn't respond. +Bir `joinWifi` fonksiyonuna sahip olduğumuzu varsayalım. Ağ adını ve şifreyi (bir string olarak) verdiğinizde, ağa katılmayı dener ve başarılı olursa çözülür, kimlik doğrulama başarısız olursa reddedilen bir promise döner. İlk olarak, bir promise'yi belirli bir süre sonra otomatik olarak reddedecek şekilde sarmanın bir yoluna ihtiyacımız var, böylece erişim noktası yanıt vermezse hızla ilerleyebiliriz. ```{includeCode: true} function withTimeout(promise, time) { @@ -282,11 +282,11 @@ function withTimeout(promise, time) { } ``` -This makes use of the fact that a promise can only be resolved or rejected once. If the promise given as argument resolves or rejects first, that result will be the result of the promise returned by `withTimeout`. If, on the other hand, the `setTimeout` fires first, rejecting the promise, any further resolve or reject calls are ignored. +Bu, bir promise'in yalnızca bir kez çözülebileceği veya reddedilebileceği gerçeğinden yararlanır—argüman olarak verilen promise önce çözülür veya reddedilirse, bu sonuç `withTimeout` tarafından döndürülen promise'nin sonucu olacaktır. Öte yandan, `setTimeout` önce çalışırsa ve promise'yi reddederse, sonraki çözme veya reddetme çağrıları yok sayılır. -To find the whole passcode, the program needs to repeatedly look for the next digit by trying each digit. If authentication succeeds, we know we have found what we are looking for. If it immediately fails, we know that digit was wrong, and must try the next digit. If the request times out, we have found another correct digit, and must continue by adding another digit. +Tüm şifreyi bulmak için, her haneyi deneyerek sıradaki haneyi tekrar tekrar aramamız gerekiyor. Kimlik doğrulama başarılı olursa, aradığımız şeyi bulduğumuzu biliriz. Hemen başarısız olursa, o hanenin yanlış olduğunu biliriz ve bir sonraki haneyi denememiz gerekir. İstek zaman aşımına uğrarsa, başka bir doğru haneyi bulduğumuzu ve bir sonraki haneyi ekleyerek devam etmemiz gerektiğini anlarız. -Because you cannot wait for a promise inside a `for` loop, Carla uses a recursive function to drive this process. On each call, this function gets the code as we know it so far, as well as the next digit to try. Depending on what happens, it may return a finished code or call through to itself, to either start cracking the next position in the code or to try again with another digit. +Bir `for` döngüsü içinde bir promise'yi bekleyemediğiniz için, Carla bu süreci yönlendirmek için özyinelemeli bir fonksiyon kullanıyor. Her çağrıda, şimdiye kadar bildiğimiz kodu ve denenecek bir sonraki haneyi alıyor. Olanlara bağlı olarak, bitmiş bir kod döndürebilir veya kodun bir sonraki pozisyonunu kırmaya başlamak ya da başka bir haneyle tekrar denemek için kendini çağırabilir. ```{includeCode: true} function crackPasscode(networkID) { @@ -308,32 +308,32 @@ function crackPasscode(networkID) { } ``` -The access point tends to respond to bad authentication requests in about 20 milliseconds, so to be safe, this function waits for 50 milliseconds before timing out a request. +Erişim noktası, kötü kimlik doğrulama isteklerine genellikle yaklaşık 20 milisaniyede yanıt verir, bu yüzden güvenli olmak için bu fonksiyon bir isteğin zaman aşımına uğraması için 50 milisaniye bekler. ``` crackPasscode("HANGAR 2").then(console.log); // → 555555 ``` -Carla tilts her head and sighs. This would have been more satisfying if the code had been a bit harder to guess. +Carla başını yana eğip iç çeker. Kodun tahmin edilmesi biraz daha zor olsaydı daha tatmin edici olurdu. -## Async functions +## Eşzamansız Fonksiyonlar {{index "Promise class", recursion}} -Even with promises, this kind of asynchronous code is annoying to write. Promises often need to be tied together in verbose, arbitrary-looking ways. To create an asynchronous loop, Carla was forced to introduce a recursive function. +Hatta promise'lerle bile, bu tür asenkron kod yazmak can sıkıcıdır. Promise'ler genellikle uzun ve karmaşık görünümlü şekillerde birbirine bağlanmak zorunda kalır. Ve sadece bir döngü oluşturmak için özyinelemeli bir fonksiyon kullanmak zorunda kaldık. {{index "synchronous programming", "asynchronous programming"}} -The thing the cracking function actually does is completely linear—it always waits for the previous action to complete before starting the next one. In a synchronous programming model, it'd be more straightforward to express. +Kırma fonksiyonunun aslında yaptığı şey tamamen doğrusaldır—her zaman bir sonraki adıma başlamadan önce önceki adımın tamamlanmasını bekler. Senkron bir programlama modelinde, bunu ifade etmek daha basit olurdu. {{index "async function", "await keyword"}} -The good news is that JavaScript allows you to write pseudo-synchronous code to describe asynchronous computation. An `async` function implicitly returns a promise and can, in its body, `await` other promises in a way that _looks_ synchronous. +İyi haber şu ki, JavaScript asenkron hesaplamayı tanımlamak için sözde senkron kod yazmanıza izin verir. Bir `async` fonksiyon, bir promise döndüren ve gövdesinde başka promise'leri senkronmuş gibi `await` edebilen bir fonksiyondur. {{index "findInStorage function"}} -We can rewrite `crackPasscode` like this: +`crackPasscode` fonksiyonunu şöyle yeniden yazabiliriz: ``` async function crackPasscode(networkID) { @@ -356,29 +356,27 @@ async function crackPasscode(networkID) { } ``` -This version more clearly shows the double loop structure of the function (the inner loop tries digit 0 to 9, the outer loop adds digits to the passcode). +Bu sürüm, fonksiyonun çift döngü yapısını daha net bir şekilde gösterir (iç döngü 0'dan 9'a kadar olan rakamları dener, dış döngü ise şifreye rakamlar ekler). {{index "async function", "return keyword", "exception handling"}} -An `async` function is marked by the word `async` before the `function` keyword. Methods can also be made `async` by writing `async` before their name. When such a function or method is called, it returns a promise. As soon as the function returns something, that promise is resolved. If the body throws an exception, the promise is rejected. +Bir `async` fonksiyon, `function` anahtar kelimesinin önüne `async` kelimesi eklenerek işaretlenir. Metodlar da adlarının önüne `async` eklenerek `async` yapılabilir. Böyle bir fonksiyon veya metod çağrıldığında, bir promise döner. Fonksiyon bir şey döner dönmez, o promise çözülür. Eğer gövdesi bir istisna fırlatırsa, promise reddedilir. {{index "await keyword", ["control flow", asynchronous]}} -Inside an `async` function, the word `await` can be put in front of an expression to wait for a promise to resolve and only then continue the execution of the function. If the promise rejects, an exception is raised at the point of the `await`. +Bir `async` fonksiyonun içinde, `await` kelimesi bir ifadenin önüne konularak bir promise'in çözülmesini bekler ve ancak o zaman fonksiyonun yürütülmesine devam eder. Promise reddedilirse, `await` noktasında bir istisna ortaya çıkar. -Such a function no longer runs from start to completion in one go like a regular JavaScript function. Instead, it can be _frozen_ at any point that has an `await` and can be resumed at a later time. +Böyle bir fonksiyon artık, normal bir JavaScript fonksiyonu gibi, başlangıçtan sona kadar tek seferde çalışmaz. Bunun yerine, `await` bulunan herhangi bir noktada dondurulabilir ve daha sonra devam ettirilebilir. -For most asynchronous code, this notation is more convenient than directly using promises. You do still need an understanding of promises, since in many cases you'll still interact with them directly. But when wiring them together, `async` functions are generally more pleasant to write than chains of `then` calls. +Çoğu asenkron kod için, bu notasyon promise'leri doğrudan kullanmaktan daha kullanışlıdır. Yine de promise'leri anlamanız gerekir, çünkü birçok durumda onlarla doğrudan etkileşime girersiniz. Ancak, promise'leri birbirine bağlarken, `async` fonksiyonları genellikle `then` çağrı zincirlerinden daha hoş yazılır. -{{id generator}} - -## Generators +## Generator'lar {{index "async function"}} -This ability of functions to be paused and then resumed again is not exclusive to `async` functions. JavaScript also has a feature called _((generator))_ functions. These are similar, but without the promises. +Fonksiyonların duraklatılıp yeniden başlatılabilme yeteneği sadece `async` fonksiyonlara özgü değildir. JavaScript'in ayrıca _((generator))_ fonksiyonlar adlı bir özelliği de vardır. Bunlar benzer şekilde çalışır, ancak promise'sızdir. -When you define a function with `function*` (placing an asterisk after the word `function`), it becomes a generator. When you call a generator, it returns an ((iterator)), which we already saw in [Chapter ?](object). +`function*` ile bir fonksiyon tanımladığınızda (kelimenin yanına bir yıldız işareti koyarak), bu bir generator olur. Bir generator çağırdığınızda, bir ((iterator)) döner ki bu, [Bölüm ?](object) bölümünde gördüğümüz gibidir. ``` function* powers(n) { @@ -398,9 +396,9 @@ for (let power of powers(3)) { {{index "next method", "yield keyword"}} -Initially, when you call `powers`, the function is frozen at its start. Every time you call `next` on the iterator, the function runs until it hits a `yield` expression, which pauses it and causes the yielded value to become the next value produced by the iterator. When the function returns (the one in the example never does), the iterator is done. +Başlangıçta, `powers` fonksiyonunu çağırdığınızda, fonksiyon başlangıçta dondurulmuş olur. Iterator üzerinde her `next` çağrıldığında, fonksiyon bir `yield` ifadesine ulaşana kadar çalışır, bu noktada duraklatılır ve elde edilen değer, iterator tarafından üretilen bir sonraki değer olur. Fonksiyon döndüğünde (örnekteki fonksiyon hiç dönmez), iterator tamamlanmış olur. -Writing iterators is often much easier when you use generator functions. The iterator for the `Group` class (from the exercise in [Chapter ?](object#group_iterator)) can be written with this generator: +Iterator'ları generator fonksiyonlar kullanarak yazmak genellikle çok daha kolaydır. `Group` sınıfı için iterator (egzersizden [Bölüm ?](object#group_iterator)) bu generator ile yazılabilir: {{index "Group class"}} @@ -421,31 +419,31 @@ class Group { {{index [state, in iterator]}} -There's no longer a need to create an object to hold the iteration state—generators automatically save their local state every time they yield. +Artık iterasyon durumunu tutacak bir nesne oluşturmaya gerek yok—generator'lar her yield ettiklerinde yerel durumlarını otomatik olarak kaydederler. -Such `yield` expressions may occur only directly in the generator function itself and not in an inner function you define inside of it. The state a generator saves, when yielding, is only its _local_ environment and the position where it yielded. +Bu tür `yield` ifadeleri sadece doğrudan generator fonksiyonun kendisinde meydana gelebilir ve içinde tanımladığınız bir iç fonksiyonda olamaz. Bir generator yield ettiğinde kaydettiği durum yalnızca _yerel_ çevresi ve yield ettiği pozisyondur. {{index "await keyword"}} -An `async` function is a special type of generator. It produces a promise when called, which is resolved when it returns (finishes) and rejected when it throws an exception. Whenever it yields (awaits) a promise, the result of that promise (value or thrown exception) is the result of the `await` expression. +Bir `async` fonksiyon, özel bir tür generator'dır. Çağrıldığında bir promise üretir ve bu promise, fonksiyon döndüğünde (tamamlandığında) çözülür ve bir istisna fırlattığında reddedilir. Bir promise yield ettiğinde (await), o promise'in sonucu (değer veya fırlatılan istisna) `await` ifadesinin sonucu olur. -## A Corvid Art Project +## Corvid Sanat Projesi {{index "Carla the crow"}} -One morning, Carla wakes up to unfamiliar noise from the tarmac outside of her hangar. Hopping onto the edge of the roof, she sees the humans are setting up for something. There's a lot of electric cabling, a stage, and some kind of big black wall being built up. +Bu sabah, Carla hangarının dışındaki asfalt pistten gelen alışılmadık bir gürültüyle uyandı. Çatı kenarına atlayarak insanların bir şeyler kurduğunu görüyor. Çok sayıda elektrik kablosu, bir sahne ve büyük siyah bir duvar inşa ediliyor. -Being a curious crow, Carla takes a closer look at the wall. It appears to consist of a number of large glass-fronted devices wired up to cables. On the back, the devices say “LedTec SIG-5030”. +Meraklı bir karga olan Carla, duvarı daha yakından inceliyor. Görünüşe göre bu duvar, kablolarla bağlanmış büyük cam önlü cihazlardan oluşuyor. Cihazların arkasında “LedTec SIG-5030” yazıyor. -A quick Internet search turns up a user's manual for these devices. They appear to be traffic signs, with a programmable matrix of amber LED lights. The intent is of the humans is probably to display some kind of information on them during their event. Interestingly, the screens can be programmed over a wireless network. Could it be they are connected to the building's local network? +Hızlı bir internet araması, bu cihazlar için bir kullanıcı kılavuzu ortaya çıkarıyor. Bu cihazlar, amber LED ışıkların programlanabilir bir matrisi ile trafik işaretleri gibi görünüyor. İnsanların amacı, muhtemelen etkinlikleri sırasında bu ekranlarda bir tür bilgi görüntülemek. İlginç bir şekilde, ekranlar kablosuz bir ağ üzerinden programlanabiliyor. Acaba bunlar binanın yerel ağına mı bağlı? -Each device on a network gets an _IP address_, which other devices can use to send it messages. We talk more about that in [Chapter ?](browser). Carla notices that her own phones all get addresses like `10.0.0.20` or `10.0.0.33`. It might be worth trying to send messages to all such addresses and see if any one of them responds to the interface described in the manual for the signs. +Bir ağdaki her cihaz bir IP adresi alır, bu adres diğer cihazların ona mesaj göndermesini sağlar. [Bölüm ?](browser) bölümünde bundan daha fazla bahsediyoruz. Carla, kendi telefonlarının `10.0.0.20` veya `10.0.0.33` gibi adresler aldığını fark eder. Bu adreslere mesaj göndermeyi denemek ve herhangi birinin, kılavuzda tarif edilen arabirime yanıt verip vermediğini görmek ilginç olabilir. -[Chapter ?](http) shows how to make real requests on real networks. In this chapter, we'll use a simplified dummy function called `request` for network communication. This function takes two arguments—a network address and a message, which may be anything that can be sent as JSON—and returns a promise that either resolves to a response from the machine at the given address, or a rejects if there was a problem. +[Bölüm ?](<(http)>), gerçek ağlarda gerçek istekler yapmayı gösteriyor. Bu bölümde, ağ iletişimi için `request` adında basitleştirilmiş bir sahte fonksiyon kullanacağız. Bu fonksiyon iki argüman alır—bir ağ adresi ve JSON olarak gönderilebilecek herhangi bir mesaj—ve verilen adresteki makineden bir yanıtla çözülmüş veya bir sorun olduğunda reddedilmiş bir promise döner. -According to the manual, you can change what is displayed on a SIG-5030 sign by sending it a message with content like `{"command": "display", "data": [0, 0, 3, …]}`, where `data` holds one number per LED dot, providing its brightness—0 means off, 3 means maximum brightness. Each sign is 50 lights wide and 30 lights high, so an update command should send 1500 numbers. +Kılavuza göre, bir SIG-5030 tabelasında görüntülenen içeriği, `{"command": "display", "data": [0, 0, 3, …]}` gibi bir mesaj göndererek değiştirebilirsiniz, burada `data` her LED noktası için bir parlaklık değeri tutar—0 kapalı demektir, 3 maksimum parlaklık demektir. Her tabela 50 ışık genişliğinde ve 30 ışık yüksekliğindedir, bu yüzden bir güncelleme komutu 1500 sayı göndermelidir. -This code sends a display update message to all addresses on the local network, to see what sticks. Each of the numbers in an IP address can go from 0 to 255. In the data it sends, it activates a number of lights corresponding to the network address's last number. +Bu kod, yerel ağdaki tüm adreslere bir ekran güncelleme mesajı gönderir, neyin işe yaradığını görmek için. Bir IP adresindeki sayılar 0'dan 255'e kadar gidebilir. Gönderdiği verilerde, ağ adresinin son numarasına karşılık gelen sayıda ışığı etkinleştirir. ``` for (let addr = 1; addr < 256; addr++) { @@ -460,9 +458,9 @@ for (let addr = 1; addr < 256; addr++) { } ``` -Since most of these addresses won't exist or will not accept such messages, the `catch` call makes sure network errors don't crash the program. The requests are all sent out immediately, without waiting for other requests to finish, in order to not waste time when some of the machines don't answer. +Çoğu adres var olmayacağı veya bu tür mesajları kabul etmeyeceği için, `catch` çağrısı ağ hatalarının programı çökertmediğinden emin olur. İstekler, makinelerin bazıları yanıt vermediğinde zaman kaybetmemek için diğer isteklerin bitmesini beklemeden hemen gönderilir. -Having fired off her network scan, Carla heads back outside to see the result. To her delight, all of the screens are now showing a stripe of light in their top left corners. They _are_ on the local network, and they _do_ accept commands. She quickly notes the numbers shown on each screen. There are 9 screens, arranged three high and three wide. They have the following network addresses: +Ağ taramasını başlattıktan sonra, Carla sonucu görmek için tekrar dışarı çıkar. Neşe içinde, tüm ekranların sol üst köşelerinde bir ışık şeridi gösterdiğini fark eder. Evet, yerel ağda _olduklarını_ ve komutları _kabul ettiklerini_ anlar. Hızla her ekranda gösterilen numaraları not eder. 9 ekran vardır, üç yüksekte ve üç genişlikte düzenlenmişlerdir. Aşağıdaki ağ adreslerine sahiptirler: ```{includeCode: true} const screenAddresses = [ @@ -472,17 +470,17 @@ const screenAddresses = [ ]; ``` -Now this opens up possibilities for all kinds of shenanigans. She could show “crows rule, humans drool” on the wall in giant letters. But that feels a bit crude. Instead, she plans to show a video of a flying crow covering all of the screens at night. +Bu, her türlü yaramazlık için imkanlar açar. Duvara kocaman harflerle "crows rule, humans drool" (kargalar hükmeder, insanlar salya akar) yazabilir. Ama bu biraz kaba gelir. Bunun yerine, gece boyunca tüm ekranları kaplayan uçan bir karga videosu göstermeyi planlar. -Carla finds a fitting video clip, in which a second and a half of footage can be repeated to create a looping video showing a crow's wingbeat. To fit the nine screens (each of which can show 50×30 pixels), Carla cuts and resizes the videos to get a series of 150×90 images, ten per second. Those are then each cut into nine rectangles, and processed so that the dark spots on the video (where the crow is) show a bright light, and the light spots (no crow) are left dark, which should create the effect of an amber crow flying against a black background. +Carla, karga kanat çırpmasını gösteren tekrarlayan bir video oluşturmak için bir buçuk saniyelik uygun bir video klip bulur. Dokuz ekrana (her biri 50 x 30 piksel gösterebilen) sığdırmak için, videoları keser ve yeniden boyutlandırır, böylece 150 x 90 boyutunda, saniyede on görüntü elde eder. Bunlar daha sonra dokuz dikdörtgen kesilerek işlenir, ve videodaki karanlık noktalar (karganın olduğu yerler) parlak ışık olarak gösterilir, ve aydınlık noktalar (karganın olmadığı yerler) karanlık bırakılır, bu da siyah bir arka plana karşı amber renginde uçan bir karga efekti yaratır. -She has set up the `clipImages` variable to hold an array of frames, where each frame is represented with an array of nine sets of pixels—one for each screen—in the format that the signs expect. +`clipImages` değişkeni, her karenin dokuz set pikselden oluşan bir dizi çerçeveyi tutacak şekilde ayarlanmıştır—her ekran için bir tane—tabelaların beklediği formatta. -To display a single frame of the video, Carla needs to send a request to all the screens at once. But she also needs to wait for the result of these requests, both in order to not start sending the next frame before the current one has been properly sent, and in order to notice when requests are failing. +Videonun tek bir karesini göstermek için, Carla'nın tüm ekranlara aynı anda bir istek göndermesi gerekir. Ancak aynı zamanda bu isteklerin sonucunu beklemesi de gerekir, hem mevcut kare düzgün bir şekilde gönderilmeden önce bir sonraki kareyi göndermemek için, hem de isteklerin başarısız olup olmadığını fark etmek için. {{index "Promise.all function"}} -`Promise` has a static method `all` that can be used to convert an array of promises into a single promise that resolves to an array of results. This provides a convenient way to have some asynchronous actions happen alongside each other, wait for them all to finish, and then do something with their results (or at least wait for them to make sure they don't fail). +`Promise` statik `all` metoduna sahiptir, bu metot bir dizi promisi, sonuçların bir dizisine çözülmüş tek bir promise dönüştürmek için kullanılabilir. Bu, bazı asenkron işlemlerin aynı anda gerçekleşmesini sağlamak, hepsinin bitmesini beklemek ve sonra sonuçlarıyla bir şeyler yapmak (veya en azından başarısız olmadıklarından emin olmak için beklemek) için uygun bir yol sağlar. ```{includeCode: true} function displayFrame(frame) { @@ -495,10 +493,9 @@ function displayFrame(frame) { } ``` -This maps over the images in `frame` (which is an array of display data arrays) to create an array -of request promises. It then returns a promise that combines all of those. +Bu, `frame` içindeki görüntüler üzerinde (bir dizi görüntü verisi dizisi) gezinir ve bir dizi istek promisi oluşturur. Ardından, bunları birleştiren bir promise döner. -In order to be able to stop a playing video, the process is wrapped in a class. This class has an asynchronous `play` method that returns a promise that only resolves when the playback is stopped again via the `stop` method. +Bir videoyu oynatmayı durdurabilmek için, işlem bir sınıf içinde sarılır. Bu sınıf, yalnızca `stop` metodu ile oynatma tekrar durdurulduğunda çözülen bir promise dönen asenkron `play` metoduna sahiptir. ```{includeCode: true} function wait(time) { @@ -527,7 +524,7 @@ class VideoPlayer { } ``` -The `wait` function wraps `setTimeout` in a promise that resolves after the given amount of milliseconds. This is useful for controlling the speed of the playback. +`wait` fonksiyonu, verilen milisaniye miktarından sonra çözülen bir promise içinde `setTimeout` fonksiyonunu sarar. Bu, oynatma hızını kontrol etmek için yararlıdır. ```{startCode: true} let video = new VideoPlayer(clipImages, 100); @@ -537,21 +534,21 @@ video.play().catch(e => { setTimeout(() => video.stop(), 15000); ``` -For the entire week that the screen wall stands, every evening, when it is dark, a huge glowing orange bird mysteriously appears on it. +Ekran duvarının bir hafta boyunca durduğu her akşam, karanlık olduğunda, üzerinde gizemli bir şekilde devasa bir parlayan turuncu kuş belirir. -## The event loop +## Olay Döngüsü {{index "asynchronous programming", scheduling, "event loop", timeline}} -An asynchronous program starts by running its main script, which will often set up callbacks to be called later. That main script, as well as the callbacks, run to completion in one piece, uninterrupted. But between them, the program may sit idle, waiting for something to happen. +Asenkron bir program, genellikle daha sonra çağrılacak geri çağrıları ayarlayan ana betiği çalıştırarak başlar. Bu ana betik ve geri çağrılar, bir parça halinde, kesintisiz olarak tamamlanır. Ancak bunlar arasında program, bir şeyin olmasını bekleyerek boşta kalabilir. {{index "setTimeout function"}} -So callbacks are not directly called by the code that scheduled them. If I call `setTimeout` from within a function, that function will have returned by the time the callback function is called. And when the callback returns, control does not go back to the function that scheduled it. +Bu yüzden geri çağrılar doğrudan onları zamanlamış olan kod tarafından çağrılmaz. Bir fonksiyon içinden `setTimeout` çağırırsam, geri çağrı fonksiyonu çağrıldığında o fonksiyon zaten dönmüş olur. Ve geri çağrı döndüğünde, kontrolü onu zamanlamış olan fonksiyona geri götürmez. {{index "Promise class", "catch keyword", "exception handling"}} -Asynchronous behavior happens on its own empty function ((call stack)). This is one of the reasons that, without promises, managing exceptions across asynchronous code is so hard. Since each callback starts with a mostly empty stack, your `catch` handlers won't be on the stack when they throw an exception. +Asenkron davranış, kendi başına boş bir fonksiyon ((çağrı yığını)) üzerinde gerçekleşir. Bu promise'lar olamadan eşzamansız kodu yönetmenin zor olmasını sağlayan sebeplerden biridir. Her çağrı yığını genel olarak boş başladığından ötürü, `catch` fonksiyonu bir istisna fırlatıldığında yığında olmayacak. ``` try { @@ -566,9 +563,9 @@ try { {{index thread, queue}} -No matter how closely together events—such as timeouts or incoming requests—happen, a JavaScript environment will run only one program at a time. You can think of this as it running a big loop _around_ your program, called the _event loop_. When there's nothing to be done, that loop is paused. But as events come in, they are added to a queue, and their code is executed one after the other. Because no two things run at the same time, slow-running code can delay the handling of other events. +Zamanlayıcılar veya gelen istekler gibi olaylar ne kadar yakın bir zamanda gerçekleşirse gerçekleşsin, JavaScript ortamı yalnızca bir programı aynı anda çalıştırır. Bu, programınızın _etrafında_ büyük bir döngü olan _olay döngüsü_ olarak düşünebilirsiniz. Bir şey yapılacak bir şey olmadığında, bu döngü durur. Ancak olaylar geldikçe, bunlar bir kuyruğa eklenir ve kodları sırayla yürütülür. Aynı anda iki şey çalışmadığı için, yavaş çalışan kodlar diğer olayların işlenmesini geciktirebilir. -This example sets a timeout but then dallies until after the timeout's intended point of time, causing the timeout to be late. +Bu örnek bir zamanlayıcı ayarlar ancak zamanlayıcının amaçlanan zaman noktasından sonra beklerken, zamanlayıcının geç olmasına neden olur. ``` let start = Date.now(); @@ -583,7 +580,7 @@ console.log("Wasted time until", Date.now() - start); {{index "resolving (a promise)", "rejecting (a promise)", "Promise class"}} -Promises always resolve or reject as a new event. Even if a promise is already resolved, waiting for it will cause your callback to run after the current script finishes, rather than right away. +Promise'lar her zaman yeni bir olay olarak çözülür veya reddedilir. Bir promise zaten çözülmüş olsa bile, onu beklemek mevcut betiği bitirdikten sonra gerçekleştirir, hemen değil. ``` Promise.resolve("Done").then(console.log); @@ -592,15 +589,15 @@ console.log("Me first!"); // → Done ``` -In later chapters we'll see various other types of events that run on the event loop. +Sonraki bölümlerde olay döngüsünde çalışan çeşitli diğer olay türlerini göreceğiz. -## Asynchronous bugs +## Eşzamansız hatalar {{index "asynchronous programming", [state, transitions]}} -When your program runs synchronously, in a single go, there are no state changes happening except those that the program itself makes. For asynchronous programs this is different—they may have _gaps_ in their execution during which other code can run. +Programınız senkron olarak, tek seferde çalıştığında, programın kendisinin yaptığı değişiklikler dışında herhangi bir durum değişikliği olmaz. Asenkron programlar için bu farklıdır—diğer kodun çalışabileceği _boşluklar_ olabilir. -Let's look at an example. This is a function that tries to report the size of each file in an array of files, making sure to read them all at the same time rather than in sequence. +Bir örneğe bakalım. Bu, bir dosya dizisindeki her dosyanın boyutunu rapor etmeye çalışan ve hepsini aynı anda okumaya çalışan bir fonksiyondur. {{index "fileSizes function"}} @@ -617,13 +614,13 @@ async function fileSizes(files) { {{index "async function"}} -The `async fileName =>` part shows how ((arrow function))s can also be made `async` by putting the word `async` in front of them. +`async fileName =>` kısmı, ((ok fonksiyonu))ların önüne `async` koyarak `async` yapılabileceğini gösterir. {{index "Promise.all function"}} -The code doesn't immediately look suspicious... it maps the `async` arrow function over the array of names, creating an array of promises, and then uses `Promise.all` to wait for all of these before returning the list they build up. +Kod hemen şüpheli görünmüyor... `async` ok fonksiyonunu isimler dizisine uygular, bir dizi söz oluşturur ve ardından `Promise.all` kullanarak bunların hepsini bekler ve oluşturdukları listeyi döner. -But this program is entirely broken. It'll always return only a single line of output, listing the file that took the longest to read. +Ama tamamen hatalıdır. Her zaman yalnızca tek bir çıktı satırı dönecek, en uzun sürede okunan dosyayı listeleyecektir. {{if interactive @@ -634,19 +631,19 @@ fileSizes(["plans.txt", "shopping_list.txt"]) if}} -Can you work out why? +Neden böyle olduğunu bulabilir misin? {{index "+= operator"}} -The problem lies in the `+=` operator, which takes the _current_ value of `list` at the time where the statement starts executing and then, when the `await` finishes, sets the `list` binding to be that value plus the added string. +Sorun `+=` operatöründe yatıyor, bu operatör ifadenin yürütülmeye başladığı zamandaki _mevcut_ `list` değerini alır ve ardından `await` bittiğinde, `list` bağlamasını o değer artı eklenen string olarak ayarlar. {{index "await keyword"}} -But between the time where the statement starts executing and the time where it finishes there's an asynchronous gap. The `map` expression runs before anything has been added to the list, so each of the `+=` operators starts from an empty string and ends up, when its storage retrieval finishes, setting `list` to the result of adding its line to the empty string. +Ancak ifadenin yürütülmeye başladığı zaman ile bittiği zaman arasında asenkron bir boşluk vardır. `map` ifadesi listeye herhangi bir şey eklenmeden önce çalışır, bu nedenle her bir `+=` operatörü boş bir stringden başlar ve depolama işlemi bittiğinde, `list`i satırın boş stringe eklenmesi sonucu olarak ayarlar. {{index "side effect"}} -This could have easily been avoided by returning the lines from the mapped promises and calling `join` on the result of `Promise.all`, instead of building up the list by changing a binding. As usual, computing new values is less error-prone than changing existing values. +Bu, mapped sözlerden satırları döndürerek ve bir bağlamayı değiştirmek yerine `Promise.all` sonucunda `join` çağırarak kolayca önlenebilirdi. Her zamanki gibi, yeni değerler hesaplamak, mevcut değerleri değiştirmekten daha az hata yapma olasılığı taşır. {{index "fileSizes function"}} @@ -660,25 +657,25 @@ async function fileSizes(files) { } ``` -Mistakes like this are easy to make, especially when using `await`, and you should be aware of where the gaps in your code occur. An advantage of JavaScript's _explicit_ asynchronicity (whether through callbacks, promises, or `await`) is that spotting these gaps is relatively easy. +Bu tür hataları yapmak kolaydır, özellikle `await` kullanırken, ve kodunuzdaki boşlukların nerede olduğunu bilmelisiniz. JavaScript'in _açık_ asenkronitesinin (geri çağrılar, sözler veya `await` yoluyla) bir avantajı, bu boşlukları fark etmenin nispeten kolay olmasıdır. -## Summary +## Özet -Asynchronous programming makes it possible to express waiting for long-running actions without freezing the whole program. JavaScript environments typically implement this style of programming using callbacks, functions that are called when the actions complete. An event loop schedules such callbacks to be called when appropriate, one after the other, so that their execution does not overlap. +Asenkron programlama, tüm programı dondurmadan uzun süreli işlemler için beklemeyi ifade etme imkanı sağlar. JavaScript ortamları genellikle bu tür programlamayı, işlemler tamamlandığında çağrılan fonksiyonlar olan geri çağrılar kullanarak uygular. Bir olay döngüsü, bu geri çağrıların uygun olduğunda sırayla çağrılmasını planlar, böylece bunların yürütülmesi örtüşmez. -Programming asynchronously is made easier by promises, objects that represent actions that might complete in the future, and `async` functions, which allow you to write an asynchronous program as if it were synchronous. +Asenkron programlama, gelecekte tamamlanabilecek işlemleri temsil eden nesneler olan sözler ve asenkron bir programı senkronmuş gibi yazmanıza izin veren `async` fonksiyonlar sayesinde daha kolay hale gelir. -## Exercises +## Egzersizler -### Quiet Times +### Sessiz Zamanlar {{index "quiet times (exercise)", "security camera", "Carla the crow", "async function"}} -There's a security camera near Carla's lab that's activated by a motion sensor. It is connected to the network and starts sending out a video stream when it is active. Because she'd rather not be discovered, Carla has set up a system that notices this kind of wireless network traffic and turns on a light in her lair whenever there is activity outside, so she knows when to keep quiet. +Carla'nın laboratuvarının yakınında bir hareket sensörü tarafından etkinleştirilen bir güvenlik kamerası var. Bu kamera ağa bağlı ve aktif olduğunda bir video akışı göndermeye başlar. Keşfedilmek istemediği için Carla, bu tür kablosuz ağ trafiğini fark eden ve dışarıda hareket olduğunda inişindeki bir ışığı açan bir sistem kurdu, böylece ne zaman sessiz kalması gerektiğini biliyor. {{index "Date class", "Date.now function", timestamp}} -She's also been logging the times at which the camera is tripped for a while and wants to use this information to visualize which times, in an average week, tend to be quiet, and which tend to be busy. The log is stored in files holding one time stamp number (as returned by `Date.now()`) per line. +Ayrıca bir süredir kameranın ne zaman etkinleştirildiğini kaydediyor ve bu bilgiyi kullanarak, ortalama bir haftada hangi zamanların sessiz, hangi zamanların yoğun olduğunu görselleştirmek istiyor. Kayıt, her satırda bir zaman damgası numarası (`Date.now()` tarafından döndürülen) tutan dosyalarda saklanır. ```{lang: null} 1695709940692 @@ -686,15 +683,15 @@ She's also been logging the times at which the camera is tripped for a while and 1695701189163 ``` -The `"camera_logs.txt"` file holds a list of log files. Write an asynchronous function `activityTable(day)` that for a given day of the week returns an array of 24 numbers, one for each hour of the day, that hold the number of camera network traffic observations seen in that hour of the day. Days are identified by number using the system used by `Date.getDay`, where Sunday is 0 and Saturday is 6. +`"camera_logs.txt"` dosyası, günlük dosyalarının bir listesini tutar. Haftanın belirli bir günü için, o günün her saati için, o saatte görülen kamera ağ trafiği gözlemlerinin miktarını tutan 24 sayılık bir dizi döndüren asenkron bir fonksiyon `activityTable(day)` yazın. Günler, `Date.getDay` tarafından kullanılan sisteme göre numaralandırılır, Pazar 0 ve Cumartesi 6'dır. -The `activityGraph` function, provided by the sandbox, summarizes such a table into a string. +Kum havuzu tarafından sağlanan `activityGraph` fonksiyonu, bu tür bir tabloyu bir string olarak özetler. {{index "textFile function"}} -To read the files, use the `textFile` function defined earlier—given a filename, it returns a promise that resolves to the file's content. Remember that `new Date(timestamp)` creates a `Date` object for that time, which has `getDay` and `getHours` methods returning the day of the week and the hour of the day. +Daha önce tanımlanan `textFile` fonksiyonunu kullanın—bir dosya adı verildiğinde, dosyanın içeriğine çözülen bir söz döner. `new Date(timestamp)` bir `Date` nesnesi oluşturduğunu ve bu nesnenin haftanın günü ve günün saati döndüren `getDay` ve `getHours` metodlarına sahip olduğunu unutmayın. -Both types of files—the list of log files and the log files themselves—have each piece of data on its own line, separated by newline (`"\n"`) characters. +Hem günlük dosyaları listesi hem de günlük dosyalarının kendileri, her veri parçasını kendi satırında, yeni satır (`"\n"`) karakterleriyle ayrılmış olarak tutar. {{if interactive @@ -714,22 +711,21 @@ if}} {{index "quiet times (exercise)", "split method", "textFile function", "Date class"}} -You will need to convert the content of these files to an array. The easiest way to do that is to use the `split` method on the string produced by `textFile`. Note that for the log files, that will still give you an array of strings, which you have to convert to numbers before passing them to `new Date`. +Bu dosyaların içeriğini bir diziye dönüştürmeniz gerekecek. Bunu yapmanın en kolay yolu, `textFile` tarafından üretilen string üzerinde `split` metodunu kullanmaktır. Günlük dosyaları için, bu hala size bir dizi string verecektir, bunları `new Date`'e geçmeden önce sayılara dönüştürmeniz gerekecek. -Summarizing all the time points into a table of hours can be done by creating a table (array) that holds a number for each hour in the day. You can then loop over all the timestamps (over the log files and the numbers in every log file) and for each one, if it happened on the correct day, take the hour it occurred in, and add one to the corresponding number in the table. +Tüm zaman noktalarını saatlerin bir tablosuna özetlemek, günün her saati için bir sayı tutan bir tablo (dizi) oluşturarak yapılabilir. Ardından, tüm zaman damgalarını (günlük dosyaları ve her günlük dosyasındaki numaraları) üzerinde dönebilir ve her biri için, doğru günde olmuşsa, gerçekleştiği saati alıp, tablodaki ilgili sayıya bir ekleyebilirsiniz. {{index "async function", "await keyword", "Promise class"}} -Make sure you use `await` on the result of asynchronous functions before doing anything with it, or you'll end up with a `Promise` where you expected a string. +Asenkron fonksiyonların sonucunu kullanmadan önce `await` kullandığınızdan emin olun, aksi takdirde bir string beklerken bir `Promise` ile karşılaşırsınız. hint}} - -### Real Promises +### Gerçek Promise'lar {{index "real promises (exercise)", "Promise class"}} -Rewrite the function from the previous exercise without `async`/`await`, using plain `Promise` methods. +Önceki alıştırmadan gelen fonksiyonu `async`/`await` olmadan, düz `Promise` metodlarını kullanarak yeniden yazın. {{if interactive @@ -746,21 +742,21 @@ if}} {{index "async function", "await keyword", performance}} -In this style, using `Promise.all` will be more convenient than trying to model a loop over the log files. In the `async` function, just using `await` in a loop is simpler. If reading a file takes some time, which of these two approaches will take the least time to run? +Bu stilde, `Promise.all` kullanmak, günlük dosyalarının üzerinde bir döngü modellemeye çalışmaktan daha uygun olacaktır. `async` fonksiyonunda, bir döngüde `await` kullanmak daha basittir. Bir dosyanın okunması biraz zaman alırsa, bu iki yaklaşımdan hangisi çalışması en az zaman alır? {{index "rejecting (a promise)"}} -If one of the files listed in the file list has a typo, and reading it fails, how does that failure end up in the `Promise` object that your function returns? +Dosya listesindeki dosyalardan biri yazım hatası içeriyorsa ve okunması başarısız olursa, bu hata fonksiyonunuzun döndürdüğü `Promise` nesnesinde nasıl son bulur? {{hint {{index "real promises (exercise)", "then method", "textFile function", "Promise.all function"}} -The most straightforward approach to writing this function is to use a chain of `then` calls. The first promise is produced by reading the list of log files. The first callback can split this list and map `textFile` over it to get an array of promises to pass to `Promise.all`. It can return the object returned by `Promise.all`, so that whatever that returns becomes the result of the return value of this first `then`. +Bu fonksiyonu yazmanın en basit yaklaşımı, bir `then` çağrıları zinciri kullanmaktır. İlk söz, günlük dosyalarının listesini okuyarak üretilir. İlk geri çağrı bu listeyi bölebilir ve `textFile`'i üzerinde haritalayarak `Promise.all`'a geçilecek bir dizi söz elde edebilir. `Promise.all` tarafından döndürülen nesneyi dönebilir, böylece onun döndürdüğü şey, bu ilk `then`'in dönüş değerinin sonucu olur. {{index "asynchronous programming"}} -We now have a promise that returns an array of log files. We can call `then` again on that, and put the timestamp-counting logic in there. Something like this: +Artık günlük dosyalarının bir dizisini döndüren bir sözümüz var. Bunun üzerinde tekrar `then` çağırabilir ve zaman damgası sayma mantığını oraya koyabiliriz. Şöyle bir şey: ```{test: no} function activityTable(day) { @@ -772,7 +768,7 @@ function activityTable(day) { } ``` -Or you could, for even better work scheduling, put the analysis of each file inside of the `Promise.all`, so that that work can be started for the first file that comes back from disk, even before the other files come back. +Veya daha iyi iş planlaması için, her dosyanın analizini `Promise.all` içine koyabilir, böylece diskten gelen ilk dosya geri gelmeden diğer dosyalar gelmeden bile bu iş başlatılabilir. ```{test: no} function activityTable(day) { @@ -789,23 +785,23 @@ function activityTable(day) { {{index "await keyword", scheduling}} -Which shows that the way you structure your promises can have a real effect on the way the work is scheduled. A simple loop with `await` in it will make the process completely linear—it waits for each file to load before proceeding. `Promise.all` makes it possible for multiple tasks to conceptually be worked on at the same time, allowing them to make progress while files are still being loaded. This can be faster, but it also makes the order in which things will happen less predictable. In this case, where we're only going to be incrementing numbers in a table, that isn't hard to do in a safe way. For other kinds of problems, it may be a lot more difficult. +Bu, sözlerinizi nasıl yapılandırdığınızın, işin planlanma şeklini gerçekten etkileyebileceğini gösterir. İçinde `await` olan basit bir döngü süreci tamamen doğrusal hale getirir—ilerlemeden önce her dosyanın yüklenmesini bekler. `Promise.all`, kavramsal olarak birden fazla görevin aynı anda çalışmasına, dosyalar hala yüklenirken ilerleme kaydetmelerine izin verir. Bu daha hızlı olabilir, ancak işlerin hangi sırayla gerçekleşeceğini daha az tahmin edilebilir hale getirir. Bu durumda, bir tablodaki sayıları artıracağımız için, bunu güvenli bir şekilde yapmak zor değildir. Diğer tür sorunlar için, bu çok daha zor olabilir. {{index "rejecting (a promise)", "then method"}} -When a file in the list doesn't exist, the promise returned by `textFile` will be rejected. Because `Promise.all` rejects if any of the promises given to it fail, the return value of the callback given to the first `then` will also be a rejected promise. That makes the promise returned by `then` fail, so that the callback given to the second `then` isn't even called, and a rejected promise is returned from the function. +Listede bir dosya bulunmadığında, `textFile` tarafından döndürülen söz reddedilir. `Promise.all`, verilen sözlerden herhangi biri başarısız olursa reddedildiği için, ilk `then`'e verilen geri çağrının dönüş değeri de reddedilen bir söz olacaktır. Bu, `then` tarafından döndürülen sözün başarısız olmasına neden olur, böylece ikinci `then`'e verilen geri çağrı bile çağrılmaz ve fonksiyondan reddedilen bir söz döner. hint}} -### Building Promise.all +### Promise.all'ı İnşaa Etmek {{index "Promise class", "Promise.all function", "building Promise.all (exercise)"}} -As we saw, given an array of ((promise))s, `Promise.all` returns a promise that waits for all of the promises in the array to finish. It then succeeds, yielding an array of result values. If a promise in the array fails, the promise returned by `all` fails too, passing on the failure reason from the failing promise. +Gördüğümüz gibi, bir dizi ((söz)) verildiğinde, `Promise.all`, dizideki tüm sözlerin bitmesini bekleyen bir söz döner. Ardından başarılı olur, sonuç değerlerinin bir dizisini verir. Dizideki bir söz başarısız olursa, `all` tarafından döndürülen söz de, başarısız olan sözden gelen başarısızlık nedeni ile başarısız olur. -Implement something like this yourself as a regular function called `Promise_all`. +Kendi `Promise_all` adlı düzenli bir fonksiyon olarak bunun gibi bir şey uygulayın. -Remember that after a promise has succeeded or failed, it can't succeed or fail again, and further calls to the functions that resolve it are ignored. This can simplify the way you handle failure of your promise. +Bir söz başarılı veya başarısız olduktan sonra, tekrar başarılı veya başarısız olamayacağını ve onu çözen fonksiyonlara yapılan sonraki çağrıların yoksayılacağını unutmayın. Bu, sözünüzün başarısızlığını ele alma biçiminizi basitleştirebilir. {{if interactive @@ -845,12 +841,12 @@ if}} {{index "Promise.all function", "Promise class", "then method", "building Promise.all (exercise)"}} -The function passed to the `Promise` constructor will have to call `then` on each of the promises in the given array. When one of them succeeds, two things need to happen. The resulting value needs to be stored in the correct position of a result array, and we must check whether this was the last pending ((promise)) and finish our own promise if it was. +`Promise` yapıcısına geçirilen fonksiyon, verilen dizideki her söz üzerinde `then` çağırmak zorunda kalacaktır. Bir tanesi başarılı olduğunda, iki şeyin olması gerekir. Elde edilen değer, bir sonuç dizisinin doğru konumunda saklanmalı ve bu son bekleyen ((söz)) olup olmadığını kontrol etmeliyiz ve öyleyse kendi sözümüzü bitirmeliyiz. {{index "counter variable"}} -The latter can be done with a counter that is initialized to the length of the input array and from which we subtract 1 every time a promise succeeds. When it reaches 0, we are done. Make sure you take into account the situation where the input array is empty (and thus no promise will ever resolve). +Bu, giriş dizisinin uzunluğuna göre başlatılan ve her seferinde 1 çıkarılan bir sayaçla yapılabilir. 0'a ulaştığında, işimiz biter. Girdi dizisinin boş olduğu (ve dolayısıyla hiçbir sözün asla çözülmeyeceği) durumu dikkate aldığınızdan emin olun. -Handling failure requires some thought but turns out to be extremely simple. Just pass the `reject` function of the wrapping promise to each of the promises in the array as a `catch` handler or as a second argument to `then` so that a failure in one of them triggers the rejection of the whole wrapper promise. +Başarısızlığı ele almak biraz düşünmeyi gerektirir, ancak son derece basit olduğu ortaya çıkar. Sadece sarıcı sözün `reject` fonksiyonunu dizi içerisindeki her bir sarılan söze `catch` ya da `then` fonksiyonunun ikici argümanı olarak verin ki böylelikle bu sarılmış sözlerde ortaya çıkan bir hata sarıcı sözün hata fonksiyonunu başlatsın. hint}} diff --git a/12_language.md b/12_language.md index a4993539..81302c28 100644 --- a/12_language.md +++ b/12_language.md @@ -1,44 +1,44 @@ {{meta {load_files: ["code/chapter/12_language.js"], zip: "node/html"}}} -# Project: A Programming Language +# Proje: Bir Programlama Dili {{quote {author: "Hal Abelson and Gerald Sussman", title: "Structure and Interpretation of Computer Programs", chapter: true} -The evaluator, which determines the meaning of expressions in a programming language, is just another program. +Evaluator, bir programlama dilindeki ifadelerin anlamını belirleyen, sadece başka bir programdır. quote}} {{index "Abelson, Hal", "Sussman, Gerald", SICP, "project chapter"}} -{{figure {url: "img/chapter_picture_12.jpg", alt: "Illustration showing an egg with holes in it, showing smaller eggs inside, which in turn have even smaller eggs in them, and so on", chapter: "framed"}}} +{{figure {url: "img/chapter_picture_12.jpg", alt: "İçinde delikler olan bir yumurtayı gösteren, içinde daha küçük yumurtaların olduğu ve bunların içinde daha da küçük yumurtaların bulunduğu illüstrasyon.", chapter: "framed"}}} -Building your own ((programming language)) is surprisingly easy (as long as you do not aim too high) and very enlightening. +Kendi ((programming language))'inizi oluşturmak şaşırtıcı derecede kolaydır (çok yüksek hedefler koymadığınız sürece) ve oldukça aydınlatıcıdır. -The main thing I want to show in this chapter is that there's no ((magic)) involved in building a programming language. I've often felt that some human inventions were so immensely clever and complicated that I'd never be able to understand them. But with a little reading and experimenting, they often turn out to be quite mundane. +Bu bölümde göstermek istediğim ana şey, bir programlama dili oluşturmanın içinde ((büyü)) olmadığının anlaşılmasıdır. İnsan icatlarının bazıları o kadar inanılmaz derecede zeki ve karmaşık görünmüştür ki, onları asla anlayamayacağımı düşünmüşümdür. Ancak biraz okuma ve deneme ile genellikle oldukça sıradan oldukları ortaya çıkar. {{index "Egg language", [abstraction, "in Egg"]}} -We will build a programming language called Egg. It will be a tiny, simple language—but one that is powerful enough to express any computation you can think of. It will allow simple ((abstraction)) based on ((function))s. +Egg adında bir programlama dili oluşturacağız. Küçük ve basit bir dil olacak, ancak aklınıza gelebilecek herhangi bir hesaplamayı ifade edebilecek kadar güçlü olacak. Basit ((soyutlamalar)) sağlayacaktır ve ((fonksiyon))lara dayalı olacaktır. {{id parsing}} -## Parsing +## Ayrıştırma(Parsing) {{index parsing, validation, [syntax, "of Egg"]}} -The most immediately visible part of a programming language is its _syntax_, or notation. A _parser_ is a program that reads a piece of text and produces a data structure that reflects the structure of the program contained in that text. If the text does not form a valid program, the parser should point out the error. +Bir programlama dilinin en hemen görülebilir kısmı, onun _syntax_ veya gösterimidir. Bir _parser_, bir metin parçasını okuyup, o metinde bulunan programın yapısını yansıtan bir veri yapısı üreten bir programdır. Metin geçerli bir program oluşturmuyorsa, parser hatayı belirtmelidir. {{index "special form", [function, application]}} -Our language will have a simple and uniform syntax. Everything in Egg is an ((expression)). An expression can be the name of a binding, a number, a string, or an _application_. Applications are used for function calls but also for constructs such as `if` or `while`. +Dilimiz basit ve tekdüze bir sözdizimine sahip olacak. Egg'deki her şey bir ((ifade))dir. Bir ifade bir bağlama adı, bir sayı, bir string veya bir _aplikasyon_ olabilir. Aplikasyonlar fonksiyon çağrıları için kullanılır ancak `if` veya `while` gibi yapılar için de kullanılır. {{index "double-quote character", parsing, [escaping, "in strings"], [whitespace, syntax]}} -To keep the parser simple, strings in Egg do not support anything like backslash escapes. A string is simply a sequence of characters that are not double quotes, wrapped in double quotes. A number is a sequence of digits. Binding names can consist of any character that is not whitespace and that does not have a special meaning in the syntax. +Parser'ı basit tutmak için, Egg'deki stringler ters eğik çizgi kaçışlarını desteklemez. Bir string, çift tırnak içinde yer alan çift tırnak olmayan karakterlerden oluşan bir dizidir. Bir sayı, basamaklardan oluşan bir dizidir. Bağlama adları, boşluk olmayan ve sözdiziminde özel bir anlamı olmayan herhangi bir karakterden oluşabilir. {{index "comma character", [parentheses, arguments]}} -Applications are written the way they are in JavaScript, by putting parentheses after an expression and having any number of ((argument))s between those parentheses, separated by commas. +Aplikasyonlar JavaScript'te olduğu gibi yazılır, bir ifadenin ardından parantez koyarak ve bu parantezler arasında virgülle ayrılmış herhangi bir sayıda ((argümanlar)) koyarak. ```{lang: null} do(define(x, 10), @@ -49,17 +49,17 @@ do(define(x, 10), {{index block, [syntax, "of Egg"]}} -The ((uniformity)) of the ((Egg language)) means that things that are ((operator))s in JavaScript (such as `>`) are normal bindings in this language, applied just like other ((function))s. Since the syntax has no concept of a block, we need a `do` construct to represent doing multiple things in sequence. +((Egg language))'in ((tekdüzeliği)), JavaScript'teki `>` gibi ((operator))lerin bu dilde normal bağlamalar olduğu anlamına gelir ve diğer fonksiyonlar gibi uygulanırlar. Ve sözdiziminde blok kavramı olmadığından, birden fazla şeyi ardışık olarak yapmak için bir `do` yapısına ihtiyacımız var. {{index "type property", parsing, ["data structure", tree]}} -The data structure that the parser will use to describe a program consists of ((expression)) objects, each of which has a `type` property indicating the kind of expression it is and other properties to describe its content. +Parser'ın bir programı tanımlamak için kullanacağı veri yapısı, her biri hangi tür ifade olduğunu belirten bir `type` özelliğine ve içeriğini tanımlayan diğer özelliklere sahip ((expression)) nesnelerinden oluşur. {{index identifier}} -Expressions of type `"value"` represent literal strings or numbers. Their `value` property contains the string or number value that they represent. Expressions of type `"word"` are used for identifiers (names). Such objects have a `name` property that holds the identifier's name as a string. Finally, `"apply"` expressions represent applications. They have an `operator` property that refers to the expression that is being applied, as well as an `args` property that holds an array of argument expressions. +`"value"` türündeki ifadeler, literal string veya sayıları temsil eder. Bunların `value` özelliği, temsil ettikleri string veya sayı değerini içerir. `"word"` türündeki ifadeler, tanımlayıcılar (isimler) için kullanılır. Bu tür nesneler, tanımlayıcının adını string olarak tutan bir `name` özelliğine sahiptir. Son olarak, `"apply"` ifadeleri uygulamaları temsil eder. Bunların uygulanan ifadeye başvuran bir `operator` özelliği ve bir dizi argüman ifadesi tutan bir `args` özelliği vardır. -The `>(x, 5)` part of the previous program would be represented like this: +Önceki programın `>(x, 5)` kısmı şu şekilde temsil edilir: ```{lang: "json"} { @@ -74,27 +74,27 @@ The `>(x, 5)` part of the previous program would be represented like this: {{indexsee "abstract syntax tree", "syntax tree", ["data structure", tree]}} -Such a data structure is called a _((syntax tree))_. If you imagine the objects as dots and the links between them as lines between those dots, as shown in the following diagram, the structure has a ((tree))like shape. The fact that expressions contain other expressions, which in turn might contain more expressions, is similar to the way tree branches split and split again. +Bu tür bir veri yapısına _((syntax tree))_ denir. Nesneleri noktalar olarak ve bunlar arasındaki bağlantıları bu noktalar arasındaki çizgiler olarak hayal ederseniz, ((tree)) benzeri bir şekle sahiptir. İfadelerin diğer ifadeleri içermesi, onların da daha fazla ifade içermesi, ağaç dallarının bölünmesi ve tekrar bölünmesine benzer. -{{figure {url: "img/syntax_tree.svg", alt: "A diagram showing the structure of the syntax tree for the example program. The root is labeled 'do' and has two children, one labeled 'define' and one labeled 'if'. Those in turn have more children, describing their content.", width: "5cm"}}} +{{figure {url: "img/syntax_tree.svg", alt: "Örnek programın sözdizimi ağacının yapısını gösteren diyagram. Kök 'do' olarak etiketlenmiştir ve biri 'define' ve diğeri 'if' etiketli iki çocuğu vardır. Bunların da içeriklerini açıklayan daha fazla çocuğu var.", width: "5cm"}}} {{index parsing}} -Contrast this to the parser we wrote for the configuration file format in [Chapter ?](regexp#ini), which had a simple structure: it split the input into lines and handled those lines one at a time. There were only a few simple forms that a line was allowed to have. +Bunu, [Chapter ?](<(regexp#ini)>)'deki yapılandırma dosyası biçimi için yazdığımız parser ile karşılaştırın; bu parser, basit bir yapıya sahipti: girdiyi satırlara böldü ve bu satırları tek tek ele aldı. Bir satırın sahip olabileceği sadece birkaç basit form vardı. {{index recursion, [nesting, "of expressions"]}} -Here we must find a different approach. Expressions are not separated into lines, and they have a recursive structure. Application expressions _contain_ other expressions. +Burada farklı bir yaklaşım bulmalıyız. İfadeler satırlara ayrılmamış ve yinelemeli bir yapıya sahiptir. Application ifadeleri diğer ifadeleri _içerir_. {{index elegance}} -Fortunately, this problem can be solved very well by writing a parser function that is recursive in a way that reflects the recursive nature of the language. +Neyse ki, bu sorun, dilin yinelemeli doğasını yansıtan yinelemeli bir parser fonksiyonu yazarak çok iyi çözülebilir. {{index "parseExpression function", "syntax tree"}} -We define a function `parseExpression` that takes a string as input. It returns an object containing the data structure for the expression at the start of the string, along with the part of the string left after parsing this expression. When parsing subexpressions (the argument to an application, for example), this function can be called again, yielding the argument expression as well as the text that remains. This text may in turn contain more arguments or may be the closing parenthesis that ends the list of arguments. +Bir string'i girdi olarak alan ve string'in başlangıcındaki ifade için veri yapısını içeren bir nesne ve bu ifadeyi ayrıştırdıktan sonra kalan string'i döndüren bir `parseExpression` fonksiyonu tanımlarız. Alt ifadeleri ayrıştırırken (örneğin bir application'ın argümanı), bu fonksiyon tekrar çağrılabilir, böylece argüman ifadesi ve kalan metin elde edilir. Bu metin sırayla daha fazla argüman içerebilir veya argüman listesini sonlandıran kapanış parantezi olabilir. -This is the first part of the parser: +Bu parser'ın ilk kısmıdır: ```{includeCode: true} function parseExpression(program) { @@ -122,15 +122,15 @@ function skipSpace(string) { {{index "skipSpace function", [whitespace, syntax]}} -Because Egg, like JavaScript, allows any amount of whitespace between its elements, we have to repeatedly cut the whitespace off the start of the program string. The `skipSpace` function helps with this. +Egg, JavaScript gibi, elemanları arasında herhangi bir miktarda boşluk bulunmasına izin verdiğinden, program string'inin başlangıcındaki boşlukları tekrar tekrar kesmemiz gerekir. `skipSpace` fonksiyonu bu konuda yardımcı olur. {{index "literal expression", "SyntaxError type"}} -After skipping any leading space, `parseExpression` uses three ((regular expression))s to spot the three atomic elements that Egg supports: strings, numbers, and words. The parser constructs a different kind of data structure depending on which expression matches. If the input does not match one of these three forms, it is not a valid expression, and the parser throws an error. We use the `SyntaxError` constructor here. This is an exception class defined by the standard, like `Error`, but more specific. +Herhangi bir önde gelen boşluğu geçtikten sonra, `parseExpression` Egg'in desteklediği üç atomik elemanı tespit etmek için üç ((regular expression)) kullanır: stringler, sayılar ve kelimeler. Parser, hangisi eşleşirse ona bağlı olarak farklı bir veri yapısı oluşturur. Girdi bu üç formdan birine uymuyorsa, geçerli bir ifade değildir ve parser bir hata oluşturur. `Error` yerine `SyntaxError`'ı kullanırız çünkü bu biraz daha spesifiktir—aynı zamanda geçersiz bir JavaScript programı çalıştırılmaya çalışıldığında oluşturulan hata türüdür. {{index "parseApply function"}} -We then cut off the part that was matched from the program string and pass that, along with the object for the expression, to `parseApply`, which checks whether the expression is an application. If so, it parses a parenthesized list of arguments. +Sonra eşleşen kısmı program string'inden kesip, bunu ifade için nesne ile birlikte `parseApply`'a geçiririz, bu ifade bir application olup olmadığını kontrol eder. Eğer öyleyse, parantezli bir argüman listesi ayrıştırır. ```{includeCode: true} function parseApply(expr, program) { @@ -157,13 +157,17 @@ function parseApply(expr, program) { {{index parsing, recursion}} -If the next character in the program is not an opening parenthesis, this is not an application, and `parseApply` returns the expression it was given. Otherwise, it skips the opening parenthesis and creates the ((syntax tree)) object for this application expression. It then recursively calls `parseExpression` to parse each argument until a closing parenthesis is found. The recursion is indirect, through `parseApply` and `parseExpression` calling each other. +Programdaki bir sonraki karakter açılış parantezi değilse, bu bir application değildir ve `parseApply` verilen ifadeyi döner. -Because an application expression can itself be applied (such as in `multiplier(2)(1)`), `parseApply` must, after it has parsed an application, call itself again to check whether another pair of parentheses follows. +{{index recursion}} + +Aksi takdirde, açılış parantezini atlar ve bu application ifadesi için ((syntax tree)) nesnesini oluşturur. Daha sonra, kapanış parantezi bulunana kadar her argümanı ayrıştırmak için `parseExpression`'ı yinelemeli olarak çağırır. Yineleme dolaylıdır, `parseApply` ve `parseExpression` birbirlerini çağırır. + +Bir application ifadesi kendisi uygulanabilir (örneğin `multiplier(2)(1)`), bu yüzden `parseApply` bir application ayrıştırdıktan sonra, başka bir parantez çifti olup olmadığını kontrol etmek için kendisini tekrar çağırmalıdır. {{index "syntax tree", "Egg language", "parse function"}} -This is all we need to parse Egg. We wrap it in a convenient `parse` function that verifies that it has reached the end of the input string after parsing the expression (an Egg program is a single expression), and that gives us the program's data structure. +Egg'i ayrıştırmak için ihtiyacımız olan her şey bu kadar. Bunu, bir ifadeyi ayrıştırdıktan sonra girdi string'inin sonuna ulaşıldığını doğrulayan ve bize programın veri yapısını veren uygun bir `parse` fonksiyonuna sararız (bir Egg programı tek bir ifadedir). ```{includeCode: strip_log, test: join} function parse(program) { @@ -183,13 +187,13 @@ console.log(parse("+(a, 10)")); {{index "error message"}} -It works! It doesn't give us very helpful information when it fails and doesn't store the line and column on which each expression starts, which might be helpful when reporting errors later, but it's good enough for our purposes. +İşe yarıyor! Başarısız olduğunda çok yardımcı bilgi vermiyor ve her ifadenin başladığı satır ve sütunu saklamıyor, bu da daha sonra hataları bildirirken faydalı olabilir, ancak bizim amaçlarımız için yeterince iyi. -## The evaluator +## Değerlendirici(Evaluator) {{index "evaluate function", evaluation, interpretation, "syntax tree", "Egg language"}} -What can we do with the syntax tree for a program? Run it, of course! And that is what the evaluator does. You give it a syntax tree and a scope object that associates names with values, and it will evaluate the expression that the tree represents and return the value that this produces. +Bir program için ((syntax tree)) ile ne yapabiliriz? Elbette çalıştırabiliriz! Ve değerlendirici tam olarak bunu yapar. Ona bir ((syntax tree)) ve isimleri değerlerle ilişkilendiren bir kapsam nesnesi verirsiniz ve bu, ağacın temsil ettiği ifadeyi değerlendirir ve ürettiği değeri döndürür. ```{includeCode: true} const specialForms = Object.create(null); @@ -223,27 +227,27 @@ function evaluate(expr, scope) { {{index "literal expression", scope}} -The evaluator has code for each of the ((expression)) types. A literal value expression produces its value. (For example, the expression `100` evaluates to the number 100.) For a binding, we must check whether it is actually defined in the scope and, if it is, fetch the binding's value. +Değerlendirici, her ((expression)) türü için koda sahiptir. Bir literal değer ifadesi kendi değerini üretir. (Örneğin, `100` ifadesi sadece 100 sayısını değerlendirir.) Bir bağlama için, bunun kapsamda gerçekten tanımlanıp tanımlanmadığını kontrol etmemiz ve eğer öyleyse, bağlamanın değerini almamız gerekir. {{index [function, application]}} -Applications are more involved. If they are a ((special form)), like `if`, we do not evaluate anything—we just and pass the argument expressions, along with the scope, to the function that handles this form. If it is a normal call, we evaluate the operator, verify that it is a function, and call it with the evaluated arguments. +Application'lar daha karmaşıktır. Eğer `if` gibi bir ((special form)) iseler, hiçbir şeyi değerlendirmeyiz ve argüman ifadelerini, kapsamla birlikte, bu formu yöneten fonksiyona geçiririz. Eğer normal bir çağrıysa, operatörü değerlendiririz, bunun bir fonksiyon olduğunu doğrularız ve değerlendirilmiş argümanlarla çağırırız. -We use plain JavaScript function values to represent Egg's function values. We will come back to this [later](language#egg_fun), when the special form `fun` is defined. +Egg'in fonksiyon değerlerini temsil etmek için sade JavaScript fonksiyon değerlerini kullanırız. Bu konuya daha [sonra](<(language#egg_fun)>), `fun` adı verilen ((special form)) tanımlandığında döneceğiz. {{index readability, "evaluate function", recursion, parsing}} -The recursive structure of `evaluate` resembles the structure of the parser, and both mirror the structure of the language itself. It would also be possible to combine the parser and the evaluator into one function and evaluate during parsing, but splitting them up this way makes the program clearer and more flexible. +`evaluate`'in yinelemeli yapısı, parser'ın benzer yapısına benzer ve her ikisi de dilin yapısını yansıtır. Parser ve değerlendiriciyi tek bir fonksiyona birleştirmek ve ayrıştırma sırasında değerlendirmek de mümkündür. Ancak bu şekilde ayırmak programı daha net ve esnek kılar. {{index "Egg language", interpretation}} -This is really all that's needed to interpret Egg. It's that simple. But without defining a few special forms and adding some useful values to the ((environment)), you can't do much with this language yet. +Egg'i yorumlamak için gereken her şey gerçekten bu kadar basittir. Ama birkaç özel form tanımlamadan ve ((environment))'a bazı kullanışlı değerler eklemeden, bu dil ile pek bir şey yapamazsınız. -## Special forms +## Özel formlar {{index "special form", "specialForms object"}} -The `specialForms` object is used to define special syntax in Egg. It associates words with functions that evaluate such forms. It is currently empty. Let's add `if`. +`specialForms` nesnesi, Egg'de özel sözdizimini tanımlamak için kullanılır. Bu, sözcükleri bu formaları değerlendiren fonksiyonlarla ilişkilendirir. Şu anda boş. `if` ekleyelim. ```{includeCode: true} specialForms.if = (args, scope) => { @@ -259,17 +263,17 @@ specialForms.if = (args, scope) => { {{index "conditional execution", "ternary operator", "?: operator", "conditional operator"}} -Egg's `if` construct expects exactly three arguments. It will evaluate the first, and if the result isn't the value `false`, it will evaluate the second. Otherwise, the third gets evaluated. This `if` form is more similar to JavaScript's ternary `?:` operator than to JavaScript's `if`. It is an expression, not a statement, and it produces a value, namely, the result of the second or third argument. +Egg'in `if` yapısı tam olarak üç argüman bekler. İlkini değerlendirecek ve eğer sonuç `false` değilse, ikincisini değerlendirecektir. Aksi takdirde, üçüncü değerlendirilir. Bu `if` formu, JavaScript'in `if`'inden çok JavaScript'in üçlü `?:` operatörüne benzer. Bir bildiri değil, ifadedir ve bir değer üretir, yani ikinci veya üçüncü argümanın sonucunu üretir. {{index Boolean}} -Egg also differs from JavaScript in how it handles the condition value to `if`. It will treat only the value `false` as false, not things like zero or the empty string. +Egg ayrıca `if` koşul değerini nasıl ele aldığında JavaScript'ten farklıdır. Sıfır veya boş string gibi şeyleri `false` olarak değerlendirmeyecek, sadece kesin değer `false` olarak değerlendirecektir. {{index "short-circuit evaluation"}} -The reason we need to represent `if` as a special form rather than a regular function is that all arguments to functions are evaluated before the function is called, whereas `if` should evaluate only _either_ its second or its third argument, depending on the value of the first. +`if`'i düzenli bir fonksiyon yerine özel bir form olarak temsil etmemizin nedeni, fonksiyonlara tüm argümanlar fonksiyon çağrılmadan önce değerlendirilir, oysa `if` yalnızca ya ikinci _ya da_ üçüncü argümanını değerlendirmelidir, ilk argümanın değerine bağlı olarak. -The `while` form is similar. +`while` formu benzerdir. ```{includeCode: true} specialForms.while = (args, scope) => { @@ -281,12 +285,12 @@ specialForms.while = (args, scope) => { } // Since undefined does not exist in Egg, we return false, - // for lack of a meaningful result. + // for lack of a meaningful result return false; }; ``` -Another basic building block is `do`, which executes all its arguments from top to bottom. Its value is the value produced by the last argument. +Diğer bir temel yapı taşı `do`'dur, tüm argümanlarını yukarıdan aşağıya doğru yürütür. Onun değeri, son argümanın ürettiği değerdir. ```{includeCode: true} specialForms.do = (args, scope) => { @@ -300,7 +304,7 @@ specialForms.do = (args, scope) => { {{index ["= operator", "in Egg"], [binding, "in Egg"]}} -To be able to create bindings and give them new values, we also create a form called `define`. It expects a word as its first argument and an expression producing the value to assign to that word as its second argument. Since `define`, like everything, is an expression, it must return a value. We'll make it return the value that was assigned (just like JavaScript's `=` operator). +Bağlamalar oluşturup onlara yeni değerler atayabilmek için, `define` adında bir form da oluştururuz. İlk argüman olarak bir kelime ve bu kelimeye atanacak değeri üreten bir ifade bekler. `define`, her şey gibi, bir ifade olduğundan, bir değer döndürmelidir. Bu değeri atanmış olan değeri döndürecek şekilde yapacağız (tıpkı JavaScript'in `=` operatörü gibi). ```{includeCode: true} specialForms.define = (args, scope) => { @@ -313,13 +317,13 @@ specialForms.define = (args, scope) => { }; ``` -## The environment +## Ortam {{index "Egg language", "evaluate function", [binding, "in Egg"]}} -The ((scope)) accepted by `evaluate` is an object with properties whose names correspond to binding names and whose values correspond to the values those bindings are bound to. Let's define an object to represent the ((global scope)). +`evaluate` tarafından kabul edilen ((scope)), isimleri bağlama isimlerine ve değerleri bu bağlamalara karşılık gelen değerlere karşılık gelen özellikleri olan bir nesnedir. ((global scope))'u temsil etmek için bir nesne tanımlayalım. -To be able to use the `if` construct we just defined, we must have access to ((Boolean)) values. Since there are only two Boolean values, we do not need special syntax for them. We simply bind two names to the values `true` and `false` and use them. +Yeni tanımladığımız `if` yapısını kullanabilmek için, ((Boolean)) değerlere erişimimiz olmalıdır. Yalnızca iki Boolean değeri olduğundan, bunlar için özel bir sözdizimine ihtiyacımız yoktur. İki ismi `true` ve `false` değerlerine bağlar ve kullanırız. ```{includeCode: true} const topScope = Object.create(null); @@ -328,7 +332,7 @@ topScope.true = true; topScope.false = false; ``` -We can now evaluate a simple expression that negates a Boolean value. +Artık bir Boolean değerini tersine çeviren basit bir ifadeyi değerlendirebiliriz. ``` let prog = parse(`if(true, false, true)`); @@ -338,7 +342,7 @@ console.log(evaluate(prog, topScope)); {{index arithmetic, "Function constructor"}} -To supply basic ((arithmetic)) and ((comparison)) ((operator))s, we will also add some function values to the ((scope)). In the interest of keeping the code short, we'll use `Function` to synthesize a bunch of operator functions in a loop instead of defining them individually. +Temel ((arithmetic)) ve ((comparison)) ((operator))ları sağlamak için, ((scope))'a bazı fonksiyon değerleri de ekleyeceğiz. Kodu kısa tutmak adına, her birini ayrı ayrı tanımlamak yerine, bir döngüde bir grup operatör fonksiyonu üretmek için `Function` kullanacağız. ```{includeCode: true} for (let op of ["+", "-", "*", "/", "==", "<", ">"]) { @@ -346,7 +350,7 @@ for (let op of ["+", "-", "*", "/", "==", "<", ">"]) { } ``` -It is also useful to have a way to ((output)) values, so we'll wrap `console.log` in a function and call it `print`. +Değerleri ((output)) etmek için bir yol da faydalıdır, bu yüzden `console.log`'u bir fonksiyon içine sarıp `print` olarak adlandıracağız. ```{includeCode: true} topScope.print = value => { @@ -357,7 +361,7 @@ topScope.print = value => { {{index parsing, "run function"}} -That gives us enough elementary tools to write simple programs. The following function provides a convenient way to parse a program and run it in a fresh scope: +Bu, basit programlar yazmak için yeterli temel araçları sağlar. Aşağıdaki fonksiyon, bir programı ayrıştırmak ve bunu yeni bir kapsamda çalıştırmak için kullanışlı bir yol sağlar: ```{includeCode: true} function run(program) { @@ -367,7 +371,7 @@ function run(program) { {{index "Object.create function", prototype}} -We'll use object prototype chains to represent nested scopes so that the program can add bindings to its local scope without changing the top-level scope. +Yerleşik kapsamları temsil etmek için nesne prototip zincirlerini kullanacağız, böylece program, üst düzey kapsamı değiştirmeden yerel kapsamına bağlamalar ekleyebilir. ``` run(` @@ -383,15 +387,17 @@ do(define(total, 0), {{index "summing example", "Egg language"}} -This is the program we've seen several times before that computes the sum of the numbers 1 to 10, expressed in Egg. It is clearly uglier than the equivalent JavaScript program—but not bad for a language implemented in less than 150 ((lines of code)). +Bu, 1'den 10'a kadar olan sayıların toplamını hesaplayan ve Egg'de ifade edilen programdır. Açıkça JavaScript eşdeğerinden daha çirkindir—ancak 150'den az ((lines of code)) ile uygulanmış bir dil için fena değil. {{id egg_fun}} -## Functions +## Fonksiyonlar {{index function, "Egg language"}} -A programming language without functions is a poor programming language indeed. Fortunately, it isn't hard to add a `fun` construct, which treats its last argument as the function's body and uses all arguments before that as the names of the function's parameters. +Fonksiyonsuz bir programlama dili gerçekten zayıf bir programlama dilidir. + +Neyse ki, son argümanını fonksiyonun gövdesi olarak ele alan ve ondan önceki tüm argümanları fonksiyonun parametre isimleri olarak kullanan bir `fun` yapısını eklemek zor değildir. ```{includeCode: true} specialForms.fun = (args, scope) => { @@ -421,7 +427,7 @@ specialForms.fun = (args, scope) => { {{index "local scope"}} -Functions in Egg get their own local scope. The function produced by the `fun` form creates this local scope and adds the argument bindings to it. It then evaluates the function body in this scope and returns the result. +Egg'deki fonksiyonlar kendi yerel kapsamlarını alır. `fun` formu tarafından üretilen fonksiyon bu yerel kapsamı oluşturur ve argüman bağlamalarını ona ekler. Daha sonra fonksiyon gövdesini bu kapsamda değerlendirir ve sonucu döndürür. ```{startCode: true} run(` @@ -440,37 +446,39 @@ do(define(pow, fun(base, exp, // → 1024 ``` -## Compilation +## Derleme(Compilation) {{index interpretation, compilation}} -What we have built is an interpreter. During evaluation, it acts directly on the representation of the program produced by the parser. +İnşaa etmiş olduğumuz şey bir yorumlayıcıdır. Değerlendirme sırasında, parser tarafından üretilen programın temsilinde doğrudan çalışır. {{index efficiency, performance, [binding, definition], [memory, speed]}} -_Compilation_ is the process of adding another step between the parsing and the running of a program, which transforms the program into something that can be evaluated more efficiently by doing as much work as possible in advance. For example, in well-designed languages it is obvious, for each use of a binding, which binding is being referred to, without actually running the program. This can be used to avoid looking up the binding by name every time it is accessed, instead directly fetching it from some predetermined memory location. +_Compilation_, bir programın çalıştırılmasından önceki adımlardan birini ekleyerek programı daha verimli bir şekilde değerlendirilebilecek bir şeye dönüştürme sürecidir. Örneğin, iyi tasarlanmış dillerde, bir bağlamanın her kullanımının hangi bağlamaya atıfta bulunduğu, programı gerçekten çalıştırmadan açıktır. Bu, bağlamayı her erişildiğinde adla aramak yerine, doğrudan önceden belirlenmiş bir bellek konumundan almayı sağlayabilir. -Traditionally, ((compilation)) involves converting the program to ((machine code)), the raw format that a computer's processor can execute. But any process that converts a program to a different representation can be thought of as compilation. +Geleneksel olarak, ((compilation)), programı, bir bilgisayarın işlemcisinin çalıştırabileceği ham format olan ((machine code))'a dönüştürmeyi içerir. Ancak, programı farklı bir temsile dönüştüren herhangi bir süreç derleme olarak düşünülebilir. {{index simplicity, "Function constructor", transpilation}} -It would be possible to write an alternative ((evaluation)) strategy for Egg, one that first converts the program to a JavaScript program, uses `Function` to invoke the JavaScript compiler on it, and runs the result. When done right, this would make Egg run very fast while still being quite simple to implement. +Egg için alternatif bir ((değerlendirme(evaluation))) stratejisi yazmak mümkündür; programı önce bir JavaScript programına dönüştüren, `Function` kullanarak JavaScript derleyicisini çağıran ve ardından sonucu çalıştıran bir strateji. Doğru yapıldığında, bu Egg'i çok hızlı çalıştırır ve hala oldukça basit bir şekilde uygulanabilir. -If you are interested in this topic and willing to spend some time on it, I encourage you to try to implement such a compiler as an exercise. +Eğer bu konuyla ilgileniyorsanız ve biraz zaman ayırmaya istekliyseniz, böyle bir derleyiciyi bir egzersiz olarak uygulamayı denemenizi öneririm. -## Cheating +## Hile yapmak {{index "Egg language"}} -When we defined `if` and `while`, you probably noticed that they were more or less trivial wrappers around JavaScript's own `if` and `while`. Similarly, the values in Egg are just regular old JavaScript values. Bridging the gap to a more primitive system, such as the machine code the processor understands, takes more effort—but the way it works resembles what we are doing here. +`if` ve `while` tanımladığımızda, bunların JavaScript'in kendi `if` ve `while` yapılarının etrafında daha az veya daha çok basit sarmalayıcılar olduğunu fark etmiş olabilirsiniz. Benzer şekilde, Egg'deki değerler sadece eski normal JavaScript değerleridir. -Though the toy language in this chapter doesn't do anything that couldn't be done better in JavaScript, there _are_ situations where writing small languages helps get real work done. +Egg'in JavaScript üzerine inşa edilmiş uygulaması ile bir programlama dilini doğrudan bir makinenin sağladığı ham fonksiyonellik üzerine inşa etmek için gereken iş ve karmaşıklığı karşılaştırırsanız, fark çok büyüktür. Her şeye rağmen, bu örnek size ((programlama dillerinin)) nasıl çalıştığı konusunda bir izlenim vermeyi amaçladı. -Such a language does not have to resemble a typical programming language. If JavaScript didn't come equipped with regular expressions, for example, you could write your own parser and evaluator for regular expressions. +Ve bir şeyler yapmaya gelince, hile yapmak her şeyi kendiniz yapmaktan daha etkilidir. Bu bölümdeki oyuncak dil JavaScript'te daha iyi yapılamayacak bir şey yapmıyor olsa da, küçük diller yazmanın gerçek işleri halletmeye yardımcı olduğu durumlar _vardır_. + +Böyle bir dil tipik bir programlama diline benzemek zorunda değildir. Örneğin, JavaScript düzenli ifadelerle donatılmış olarak gelmeseydi, kendi düzenli ifadelerinizi ayrıştırıcı ve değerlendirici olarak yazabilirdiniz. {{index "parser generator"}} -Or imagine you are building a program that makes it possible to quickly create parsers by providing a logical description of the language they need to parse. You could define a specific notation for that, and a compiler that compiles it to a parser program. +Ya da dev bir robotik ((dinazor)) inşa ettiğinizi ve onun ((davranışını)) programlamanız gerektiğini hayal edin. JavaScript bunu yapmanın en etkili yolu olmayabilir. Bunun yerine şöyle görünen bir dil seçebilirsiniz: ```{lang: null} expr = number | string | name | application @@ -486,15 +494,15 @@ application = expr '(' (expr (',' expr)*)? ')' {{index expressivity}} -This is what is usually called a _((domain-specific language))_, a language tailored to express a narrow domain of knowledge. Such a language can be more expressive than a general-purpose language because it is designed to describe exactly the things that need to be described in its domain and nothing else. +Bu genellikle ((domain-özel dil)) olarak adlandırılır, belirli bir bilgi alanını ifade etmek için tasarlanmış bir dil. Böyle bir dil, genel amaçlı bir dilden daha ifadeli olabilir çünkü tam olarak ifade edilmesi gereken şeyleri ifade etmek için tasarlanmıştır ve başka hiçbir şeyi. -## Exercises +## Egzersizler -### Arrays +### Diziler {{index "Egg language", "arrays in egg (exercise)", [array, "in Egg"]}} -Add support for arrays to Egg by adding the following three functions to the top scope: `array(...values)` to construct an array containing the argument values, `length(array)` to get an array's length, and `element(array, n)` to fetch the *n*th element from an array. +Egg'e diziler için destek ekleyin, en üst kapsama aşağıdaki üç fonksiyonu ekleyerek: `array(...values)` argüman değerlerini içeren bir dizi oluşturmak için, `length(array)` bir dizinin uzunluğunu almak için ve `element(array, n)` bir diziden n^inci^ öğeyi almak için. {{if interactive @@ -526,21 +534,21 @@ if}} {{index "arrays in egg (exercise)"}} -The easiest way to do this is to represent Egg arrays with JavaScript arrays. +Bunu yapmanın en kolay yolu, Egg dizilerini JavaScript dizileri ile temsil etmektir. {{index "slice method"}} -The values added to the top scope must be functions. By using a rest argument (with triple-dot notation), the definition of `array` can be _very_ simple. +En üst kapsama eklenen değerler fonksiyon olmalıdır. Bir rest argümanı (üç nokta notasyonu ile) kullanarak, `array` tanımını _çok_ basit hale getirebiliriz. hint}} -### Closure +### Kapanış(Closure) {{index closure, [function, scope], "closure in egg (exercise)"}} -The way we have defined `fun` allows functions in Egg to reference the surrounding scope, allowing the function's body to use local values that were visible at the time the function was defined, just like JavaScript functions do. +`fun`'ı tanımlama şeklimiz, Egg'deki fonksiyonların çevreleyen kapsamı referans almasına izin verir, bu da fonksiyonun gövdesinin fonksiyonun tanımlandığı anda görünen yerel değerleri kullanmasına izin verir, tıpkı JavaScript fonksiyonları gibi. -The following program illustrates this: function `f` returns a function that adds its argument to `f`'s argument, meaning that it needs access to the local ((scope)) inside `f` to be able to use binding `a`. +Aşağıdaki program bunu göstermektedir: `f` fonksiyonu, argümanını `f`'nin argümanına ekleyen bir fonksiyon döndürür, bu da `a` bağlamına ulaşabilmesi için `f` içindeki lokal kapsama(scope) erişimi olmasını gerektirir.. ``` run(` @@ -550,29 +558,29 @@ do(define(f, fun(a, fun(b, +(a, b)))), // → 9 ``` -Go back to the definition of the `fun` form and explain which mechanism causes this to work. +`fun` formunun tanımına geri dönün ve bunun çalışmasını sağlayan mekanizmayı açıklayın. {{hint {{index closure, "closure in egg (exercise)"}} -Again, we are riding along on a JavaScript mechanism to get the equivalent feature in Egg. Special forms are passed the local scope in which they are evaluated so that they can evaluate their subforms in that scope. The function returned by `fun` has access to the `scope` argument given to its enclosing function and uses that to create the function's local ((scope)) when it is called. +Yine, JavaScript mekanizmasını kullanarak Egg'de eşdeğer özelliği elde ediyoruz. Özel formlar, kendi alt formlarını bu kapsamda değerlendirebilmeleri için değerlendirildikleri yerel kapsamı alırlar. `fun` tarafından döndürülen fonksiyon, kapsayıcı fonksiyonuna verilen `scope` argümanına erişir ve çağrıldığında fonksiyonun yerel ((kapsamını)) oluşturmak için bunu kullanır. {{index compilation}} -This means that the ((prototype)) of the local scope will be the scope in which the function was created, which makes it possible to access bindings in that scope from the function. This is all there is to implementing closure (though to compile it in a way that is actually efficient, you'd need to do some more work). +Bu, yerel kapsamın ((prototipinin)) fonksiyonun oluşturulduğu kapsam olacağı anlamına gelir, bu da bu kapsamda bağlamalara fonksiyondan erişmeyi mümkün kılar. Bu, kapanışı(closure) uygulamak için gereken her şeydir (ancak bunu gerçekten verimli bir şekilde derlemek için biraz daha fazla iş yapmanız gerekir). hint}} -### Comments +### Yorumlar {{index "hash character", "Egg language", "comments in egg (exercise)"}} -It would be nice if we could write ((comment))s in Egg. For example, whenever we find a hash sign (`#`), we could treat the rest of the line as a comment and ignore it, similar to `//` in JavaScript. +Egg'de ((yorum)) yazabilmek güzel olurdu. Örneğin, bir hash işareti (`#`) bulduğumuzda, satırın geri kalanını bir yorum olarak ele alabilir ve JavaScript'teki `//` gibi görmezden gelebiliriz. {{index "skipSpace function"}} -We do not have to make any big changes to the parser to support this. We can simply change `skipSpace` to skip comments as if they are ((whitespace)) so that all the points where `skipSpace` is called will now also skip comments. Make this change. +Bunu desteklemek için ayrıştırıcıda büyük değişiklikler yapmamıza gerek yok. `skipSpace`'i, yorumları ((whitespace)) gibi atlayacak şekilde değiştirebiliriz, böylece `skipSpace`'in çağrıldığı tüm noktalar artık yorumları da atlayacaktır. Bu değişikliği yapın. {{if interactive @@ -592,35 +600,36 @@ console.log(parse("a # one\n # two\n()")); // operator: {type: "word", name: "a"}, // args: []} ``` + if}} {{hint {{index "comments in egg (exercise)", [whitespace, syntax]}} -Make sure your solution handles multiple comments in a row, with potentially whitespace between or after them. +Çözümünüzün, arka arkaya birden fazla yorumu, aralarında veya sonrasında potansiyel olarak boşluklarla birlikte ele aldığından emin olun. -A ((regular expression)) is probably the easiest way to solve this. Write something that matches "whitespace or a comment, zero or more times". Use the `exec` or `match` method and look at the length of the first element in the returned array (the whole match) to find out how many characters to slice off. +Bir ((düzenli ifade)) muhtemelen bunu çözmenin en kolay yoludur. "Boşluk veya yorum, sıfır veya daha fazla kez" eşleşen bir şey yazın. `exec` veya `match` metodunu kullanın ve döndürülen dizinin ilk öğesinin (tüm eşleşme) uzunluğuna bakarak ne kadar karakter dilimleneceğini bulun. hint}} -### Fixing scope +### Kapsamı düzeltme {{index [binding, definition], assignment, "fixing scope (exercise)"}} -Currently, the only way to assign a binding a value is `define`. This construct acts as a way both to define new bindings and to give existing ones a new value. +Şu anda bir bağlamaya değer atamanın tek yolu `define`. Bu yapı, yeni bağlamalar tanımlamanın ve mevcut olanlara yeni bir değer vermenin bir yolu olarak işlev görür. {{index "local binding"}} -This ((ambiguity)) causes a problem. When you try to give a nonlocal binding a new value, you will end up defining a local one with the same name instead. Some languages work like this by design, but I've always found it an awkward way to handle ((scope)). +Bu ((belirsizlik)) bir soruna yol açar. Yerel olmayan bir bağlamaya yeni bir değer vermeye çalıştığınızda, bunun yerine aynı ada sahip yerel bir bağlama tanımlarsınız. Bazı diller bu şekilde tasarlanmıştır, ancak ((kapsamı)) bu şekilde ele almanın her zaman garip bir yol olduğunu düşündüm. {{index "ReferenceError type"}} -Add a special form `set`, similar to `define`, which gives a binding a new value, updating the binding in an outer scope if it doesn't already exist in the inner scope. If the binding is not defined at all, throw a `ReferenceError` (another standard error type). +Yerel kapsamda zaten yoksa, dış kapsamda bir bağlamayı güncelleyerek yeni bir değer veren `define`'a benzer bir özel form `set` ekleyin. Bağlama hiç tanımlanmamışsa, bir `ReferenceError` (başka bir standart hata türü) atın. {{index "hasOwn function", prototype, "getPrototypeOf function"}} -The technique of representing scopes as simple objects, which has made things convenient so far, will get in your way a little at this point. You might want to use the `Object.getPrototypeOf` function, which returns the prototype of an object. Also remember that you can use `Object.hasOwn` to find out if a given object has a property. +Kapsamları basit nesneler olarak temsil etme tekniği, şu ana kadar işleri kolaylaştırmış olsa da, bu noktada sizi biraz engelleyecektir. Bir nesnenin prototipini döndüren `Object.getPrototypeOf` fonksiyonunu kullanmak isteyebilirsiniz. Ayrıca, belirli bir nesnenin bir özelliğe sahip olup olmadığını öğrenmek için `Object.hasOwn` kullanabileceğinizi unutmayın. {{if interactive @@ -639,16 +648,17 @@ do(define(x, 4), run(`set(quux, true)`); // → Some kind of ReferenceError ``` + if}} {{hint {{index [binding, "compilation of"], assignment, "getPrototypeOf function", "hasOwn function", "fixing scope (exercise)"}} -You will have to loop through one ((scope)) at a time, using `Object.getPrototypeOf` to go to the next outer scope. For each scope, use `Object.hasOwn` to find out whether the binding, indicated by the `name` property of the first argument to `set`, exists in that scope. If it does, set it to the result of evaluating the second argument to `set` and then return that value. +Bir sonraki dış kapsama geçmek için `Object.getPrototypeOf` kullanarak her seferinde bir ((kapsamı))ı döngüye almak zorunda kalacaksınız. Her kapsam için, `set`'in ilk argümanının `name` özelliği ile belirtilen bağlamanın o kapsamda olup olmadığını öğrenmek için `Object.hasOwn` kullanın. Eğer varsa, onu `set`'in ikinci argümanının değerlendirme sonucuna ayarlayın ve ardından bu değeri döndürün. {{index "global scope", "run-time error"}} -If the outermost scope is reached (`Object.getPrototypeOf` returns null) and we haven't found the binding yet, it doesn't exist, and an error should be thrown. +En dış kapsama ulaşıldığında (`Object.getPrototypeOf` null döndürür) ve hala bağlamayı bulamadıysanız, o bağlama mevcut değildir ve bir hata atılmalıdır. hint}} diff --git a/13_browser.md b/13_browser.md index 7700d0bd..6d0502af 100644 --- a/13_browser.md +++ b/13_browser.md @@ -1,78 +1,78 @@ -# JavaScript and the Browser +# JavaScript ve Tarayıcı(Browser) -{{quote {author: "Tim Berners-Lee", title: "The World Wide Web: A very short personal history", chapter: true} +{{quote {author: "Tim Berners-Lee", title: "World Wide Web: Kısa kişisel bir tarih", chapter: true} -The dream behind the Web is of a common information space in which we communicate by sharing information. Its universality is essential: the fact that a hypertext link can point to anything, be it personal, local or global, be it draft or highly polished. +Web’in ardındaki hayal, bilgi paylaşarak iletişim kurduğumuz ortak bir bilgi alanıdır. Evrenselliği esastır: Bir hiper metin bağlantısının, kişisel, yerel veya küresel, taslak veya çok iyi hazırlanmış olmasına bakılmaksızın herhangi bir şeye işaret edebilmesidir. quote}} {{index "Berners-Lee, Tim", "World Wide Web", HTTP, [JavaScript, "history of"], "World Wide Web"}} -{{figure {url: "img/chapter_picture_13.jpg", alt: "Illustration showing a telephone switchboard", chapter: "framed"}}} +{{figure {url: "img/chapter_picture_13.jpg", alt: "Bir telefon santralini gösteren illüstrasyon", chapter: "framed"}}} -The next chapters of this book will discuss web browsers. Without ((browser))s, there would be no JavaScript—or if there were, no one would ever have paid any attention to it. +Bu kitabın sonraki bölümleri web tarayıcılarından bahsedecek. Web ((tarayıcı))ları olmadan, JavaScript de olmazdı. Olsa bile, kimse ona asla dikkat etmezdi. {{index decentralization, compatibility}} -Web technology has been decentralized from the start, not just technically but also in terms of the way it evolved. Various browser vendors have added new functionality in ad hoc and sometimes poorly thought-out ways, which were then—sometimes—adopted by others—and finally set down as in ((standards)). +Web teknolojisi başlangıçtan itibaren sadece teknik olarak değil, aynı zamanda evrim şekli bakımından da merkezi olmayan bir yapıya sahip olmuştur. Çeşitli tarayıcı satıcıları, bazen düzensiz ve bazen de kötü düşünülmüş yollarla yeni fonksiyonellikler eklemiş, bu da bazen diğerleri tarafından benimsenmiş ve sonunda ((standartlar)) olarak belirlenmiştir. -This is both a blessing and a curse. On the one hand, it is empowering to not have a central party control a system but have it be improved by various parties working in loose ((collaboration)) (or occasionally, open hostility). On the other hand, the haphazard way in which the Web was developed means that the resulting system is not exactly a shining example of internal ((consistency)). Some parts of it are downright confusing and badly designed. +Bu hem bir nimet hem de bir lanettir. Bir yandan, merkezi bir otoritenin bir sistemi kontrol etmemesi ve bunun yerine çeşitli taraflarca gevşek ((işbirliği)) içinde (ya da bazen açık düşmanlıkla) geliştirilmesi güçlendirici bir durumdur. Diğer yandan, Web’in gelişigüzel bir şekilde geliştirilmiş olması, ortaya çıkan sistemin içsel ((tutarlılık)) açısından parlak bir örnek olmamasına neden olur. Bazı kısımları oldukça kafa karıştırıcı ve kötü tasarlanmış durumdadır. -## Networks and the Internet +## Ağlar ve İnternet -Computer ((network))s have been around since the 1950s. If you put cables between two or more computers and allow them to send data back and forth through these cables, you can do all kinds of wonderful things. +Bilgisayar ((ağ))ları 1950’lerden beri var. İki veya daha fazla bilgisayar arasında kablolar döşeyip bu kablolar aracılığıyla veri alışverişi yapmalarına izin verirseniz, her türlü harika şeyi yapabilirsiniz. -If connecting two machines in the same building allows us to do wonderful things, connecting machines all over the planet should be even better. The technology to start implementing this vision was developed in the 1980s, and the resulting network is called the _((Internet))_. It has lived up to its promise. +Ve aynı binadaki iki makineyi bağlamak harika şeyler yapmamızı sağlıyorsa, tüm gezegen üzerindeki makineleri bağlamak daha da iyi olmalıdır. Bu vizyonu hayata geçirecek teknoloji 1980’lerde geliştirildi ve ortaya çıkan ağa _((İnternet))_ adı verildi. Bu sözünü yerine getirdi. -A computer can use this network to shoot bits at another computer. For any effective ((communication)) to arise out of this bit-shooting, the computers on both ends must know what the bits are supposed to represent. The meaning of any given sequence of bits depends entirely on the kind of thing that it is trying to express and on the ((encoding)) mechanism used. +Bir bilgisayar bu ağı kullanarak başka bir bilgisayara bit gönderebilir. Bu bit gönderiminden etkili bir ((iletişim)) sağlamak için, her iki uçtaki bilgisayarlar bitlerin neyi temsil etmesi gerektiğini bilmelidir. Herhangi bir bit dizisinin anlamı, tamamen ifade etmeye çalıştığı şeye ve kullanılan ((kodlama)) mekanizmasına bağlıdır. {{index [network, protocol]}} -A _network ((protocol))_ describes a style of communication over a ((network)). There are protocols for sending email, for fetching email, for sharing files, and even for controlling computers that happen to be infected by malicious software. +Bir ağ ((protokolü)), bir ağ üzerindeki iletişim tarzını tanımlar. E-posta göndermek, e-posta almak, dosya paylaşmak ve hatta kötü niyetli yazılımlarla enfekte olmuş bilgisayarları kontrol etmek için protokoller vardır. -{{indexsee "Hypertext Transfer Protocol", HTTP}} +{{indexsee "HyperText Transfer Protocol", HTTP}} -The _Hypertext Transfer Protocol_ (((HTTP))) is a protocol for retrieving named ((resource))s (chunks of information, such as web pages or pictures). It specifies that the side making the request should start with a line like this, naming the resource and the version of the protocol that it is trying to use: +_Hypertext Transfer Protocol_ (((HTTP))), adlandırılmış ((kaynak))ların (web sayfaları veya resimler gibi bilgi parçalarının) alınması için bir protokoldür. İstek yapan tarafın, kaynağı ve kullanmak istediği protokolün sürümünü adlandıran şöyle bir satırla başlamasını belirtir: ```{lang: http} GET /index.html HTTP/1.1 ``` -There are many more rules about the way the requester can include more information in the ((request)) and the way the other side, which returns the resource, packages up its content. We'll look at HTTP in a little more detail in [Chapter ?](http). +İstek yapan tarafın daha fazla bilgi ekleyebilmesi ve diğer tarafın kaynağı nasıl paketlediği hakkında daha fazla kural vardır. HTTP’yi [bölüm ?](http) içinde biraz daha detaylı inceleyeceğiz. {{index layering, stream, ordering}} -Most protocols are built on top of other protocols. HTTP treats the network as a streamlike device into which you can put bits and have them arrive at the correct destination in the correct order. Providing those guarantees on top of the primitive data-sending that the network gives you is already a rather tricky problem. +Çoğu protokol, diğer protokoller üzerine kuruludur. HTTP, ağın içine bitler koyabileceğiniz ve bunların doğru sırayla doğru yere varmasını sağlayan bir cihaz gibi davranır. Ağın sağladığı bu ilkel veri gönderimi üzerinde bu işi sağlamak oldukça zor bir problemdir. {{index TCP}} {{indexsee "Transmission Control Protocol", TCP}} -The _Transmission Control Protocol_ (TCP) is a ((protocol)) that addresses this problem. All Internet-connected devices "speak" it, and most communication on the ((Internet)) is built on top of it. +_Transmission Control Protocol_ (TCP), bu problemi ele alan bir ((protokol))dür. Tüm internet bağlantılı cihazlar bunu “konuşur” ve İnternet’teki çoğu iletişim bunun üzerine kuruludur. {{index "listening (TCP)"}} -A TCP ((connection)) works as follows: one computer must be waiting, or _listening_, for other computers to start talking to it. To be able to listen for different kinds of communication at the same time on a single machine, each listener has a number (called a _((port))_) associated with it. Most ((protocol))s specify which port should be used by default. For example, when we want to send an email using the ((SMTP)) protocol, the machine through which we send it is expected to be listening on port 25. +Bir TCP ((bağlantısı)) şu şekilde çalışır: Bir bilgisayar, diğer bilgisayarların kendisiyle konuşmaya başlamasını bekler ya da _dinler_. Aynı makinede aynı anda farklı türlerde iletişimleri dinleyebilmek için, her dinleyicinin kendisiyle ilişkilendirilen bir numarası (bir _((port))_) vardır. Çoğu ((protokol)), varsayılan olarak hangi portun kullanılacağını belirtir. Örneğin, ((SMTP)) protokolünü kullanarak bir e-posta göndermek istediğimizde, gönderdiğimiz makinenin port 25’te dinlemesi beklenir. -Another computer can then establish a ((connection)) by connecting to the target machine using the correct port number. If the target machine can be reached and is listening on that port, the connection is successfully created. The listening computer is called the _((server))_, and the connecting computer is called the _((client))_. +Daha sonra başka bir bilgisayar, doğru port numarasını kullanarak hedef makineye bağlanarak bir ((bağlantı)) kurabilir. Hedef makineye erişilebilir ve o portta dinliyorsa, bağlantı başarılı bir şekilde kurulur. Dinleyen bilgisayara _((server))_, bağlanan bilgisayara ise _((client))_ denir. {{index [abstraction, "of the network"]}} -Such a connection acts as a two-way ((pipe)) through which bits can flow—the machines on both ends can put data into it. Once the bits are successfully transmitted, they can be read out again by the machine on the other side. This is a convenient model. You could say that ((TCP)) provides an abstraction of the network. +Böyle bir bağlantı, iki yönlü bir ((boru)) gibi davranır - her iki uçtaki makineler de içine veri koyabilir. Bitler başarıyla iletildikten sonra, karşı taraftaki makine tarafından yeniden okunabilir. Bu, uygun bir modeldir. ((TCP))’nin ağa bir soyutlama sağladığı söylenebilir. {{id web}} -## The Web +## Web -The _((World Wide Web))_ (not to be confused with the ((Internet)) as a whole) is a set of ((protocol))s and formats that allow us to visit web pages in a browser. "Web" refers to the fact that such pages can easily link to each other, thus connecting into a huge ((mesh)) that users can move through. +_((World Wide Web))_ (tüm ((Internet)) ile karıştırılmamalıdır), bir tarayıcıda web sayfalarını ziyaret etmemizi sağlayan bir dizi ((protokol)) ve formattır. İsmin “Web” kısmı, bu sayfaların kolayca birbirine bağlanabilmesine ve böylece kullanıcıların içinde hareket edebileceği büyük bir ((ağ)) oluşturmasına atıfta bulunur. -To become part of the Web, all you need to do is connect a machine to the ((Internet)) and have it listen on port 80 with the ((HTTP)) protocol so that other computers can ask it for documents. +Web’in bir parçası olmak için yapmanız gereken tek şey, bir makineyi ((Internet))e bağlamak ve ((HTTP)) protokolü ile port 80’de dinlemesini sağlamaktır, böylece diğer bilgisayarlar belgeleri isteyebilir. {{index URL}} -{{indexsee "Uniform Resource Locator", URL}} +{{indexsee "uniform resource locator", URL}} -Each ((document)) on the Web is named by a _Uniform Resource Locator_ (URL), which looks something like this: +Web’deki her ((belge))ye Uniform Resource Locator (URL) adı verilir ve şu şekilde görünür: ```{lang: null} http://eloquentjavascript.net/13_browser.html @@ -82,23 +82,23 @@ Each ((document)) on the Web is named by a _Uniform Resource Locator_ (URL), whi {{index HTTPS}} -The first part tells us that this URL uses the HTTP ((protocol)) (as opposed to, for example, encrypted HTTP, which would be _https://_). Then comes the part that identifies which ((server)) we are requesting the document from. Last is a path string that identifies the document (or _((resource))_) we are interested in. +İlk kısım, bu URL’nin HTTP ((protokolü))nü kullandığını belirtir (örneğin, şifrelenmiş HTTP, _https://_ olacaktır). Ardından, belgenin hangi ((server))dan isteneceğini belirleyen kısım gelir. Son olarak, ilgilendiğimiz belirli belgeyi (veya _((kaynak))_) tanımlayan bir yol dizesi gelir. -Machines connected to the Internet get an _((IP address))_, a number that can be used to send messages to that machine, and looks something like `149.210.142.219` or `2001:4860:4860::8888`. Since lists of more or less random numbers are hard to remember and awkward to type, you can instead register a _((domain)) name_ for an address or set of addresses. I registered _eloquentjavascript.net_ to point at the IP address of a machine I control and can thus use that domain name to serve web pages. +İnternete bağlanan makineler bir _((IP adresi))_ alır, bu, o makineye mesaj göndermek için kullanılabilen bir numaradır ve `149.210.142.219` veya `2001:4860:4860::8888` gibi görünür. Ancak rastgele sayıların listeleri hatırlaması zor ve yazması zahmetlidir, bu yüzden belirli bir adres veya adres seti için bir _((domain))_ adı kaydedebilirsiniz. Kontrol ettiğim bir makineye işaret etmek için eloquentjavascript.net kaydettim ve bu domain adını kullanarak web sayfaları sunabilirim. {{index browser}} -If you type this URL into your browser's ((address bar)), the browser will try to retrieve and display the ((document)) at that URL. First, your browser has to find out what address _eloquentjavascript.net_ refers to. Then, using the ((HTTP)) protocol, it will make a connection to the server at that address and ask for the resource _/13_browser.html_. If all goes well, the server sends back a document, which your browser then displays on your screen. +Bu URL’yi tarayıcınızın ((adres çubuğu))na yazarsanız, tarayıcı bu URL’deki ((belge))yi almaya ve görüntülemeye çalışacaktır. Önce tarayıcınız _eloquentjavascript.net_‘in hangi adrese karşılık geldiğini bulmalıdır. Ardından, ((HTTP)) protokolünü kullanarak, o adresteki server’a bir bağlantı kuracak ve _/13_browser.html_ kaynağını isteyecektir. Her şey yolunda giderse, server bir belge gönderir ve tarayıcınız bu belgeyi ekranınızda görüntüler. ## HTML {{index HTML}} -{{indexsee "Hypertext Markup Language", HTML}} +{{indexsee "HyperText Markup Language", HTML}} -_HTML_, which stands for _Hypertext Markup Language_, is the document format used for web pages. An HTML document contains ((text)), as well as _((tag))s_ that give structure to the text, describing things such as links, paragraphs, and headings. +HTML, _Hypertext Markup Language_’ın kısaltması olup, web sayfaları için kullanılan belge formatıdır. Bir HTML belgesi, metin ile birlikte, metne yapı kazandıran, bağlantılar, paragraflar ve başlıklar gibi şeyleri tanımlayan _((etiketler))_ içerir. -A short HTML document might look like this: +Kısa bir HTML belgesi şu şekilde görünebilir: ```{lang: "html"} @@ -118,45 +118,45 @@ A short HTML document might look like this: {{if book -This is what such a document would look like in the browser: +Böyle bir belgenin tarayıcıda görünümü şöyle olacaktır: -{{figure {url: "img/home-page.png", alt: "A rendered version of the home page example HTML",width: "6.3cm"}}} +{{figure {url: "img/home-page.png", alt: "Ana sayfa örnek HTML'sinin işlenmiş bir sürümü",width: "6.3cm"}}} if}} {{index [HTML, notation]}} -The tags, wrapped in ((angle brackets)) (`<` and `>`, the symbols for _less than_ and _greater than_), provide information about the ((structure)) of the document. The other ((text)) is just plain text. +Açı ((parantez))ler (`<` ve` >`, _küçüktür_ ve _büyüktür_ sembolleri), belgenin ((yapısı)) hakkında bilgi sağlar. Diğer ((metin)) ise sade metindir. {{index doctype, version}} -The document starts with ``, which tells the browser to interpret the page as _modern_ HTML, as opposed to obsolete styles used in the past. +Belge `` ile başlar, bu da tarayıcıya sayfayı _modern_ HTML olarak yorumlamasını, geçmişte kullanılan eski stillerden farklı olarak belirtir. {{index "head (HTML tag)", "body (HTML tag)", "title (HTML tag)", "h1 (HTML tag)", "p (HTML tag)"}} -HTML documents have a head and a body. The head contains information _about_ the document, and the body contains the document itself. In this case, the head declares that the title of this document is "My home page" and that it uses the UTF-8 encoding, which is a way to encode Unicode text as binary data. The document's body contains a heading (`
`). +HTML belgeleri bir baş ve bir gövdeye sahiptir. Baş, belge _hakkında_ bilgileri içerirken, gövde belgenin kendisini içerir. Bu durumda, baş, belgenin başlığının “Ana sayfam” olduğunu ve UTF-8 kodlamasını kullandığını belirtir; bu, Unicode metnini ikili veri olarak kodlama yöntemidir. Belgenin gövdesi bir başlık (`
`) içerir. {{index "href attribute", "a (HTML tag)"}} -Tags come in several forms. An ((element)), such as the body, a paragraph, or a link, is started by an _((opening tag))_ like `
` and ended by a _((closing tag))_ like `
`. Some opening tags, such as the one for the ((link)) (``), contain extra information in the form of `name="value"` pairs. These are called _((attribute))s_. In this case, the destination of the link is indicated with `href="http://eloquentjavascript.net"`, where `href` stands for "hypertext reference". +Etiketler birkaç formda gelir. Gövde, bir paragraf veya bağlantı gibi bir ((öğe)), bir _((açılış etiketi))_ `` ile başlatılır ve bir _((kapanış etiketi))_ `
` ile sonlandırılır. Bağlantı için kullanılan etiket (``) gibi bazı açılış etiketleri, `name="value"` çiftleri şeklinde ek bilgi içerir. Bunlara _((özellikler))_ denir. Bu durumda, bağlantının hedefi `href="http://eloquentjavascript.net"` ile belirtilir, burada `href` “hiper metin referansı” anlamına gelir. {{index "src attribute", "self-closing tag", "img (HTML tag)"}} -Some kinds of ((tag))s do not enclose anything and thus do not need to be closed. The metadata tag `` is an example of this. +Bazı ((etiket)) türleri herhangi bir şeyi kapsamaz ve bu nedenle kapatılmaları gerekmez. `` etiketi bunun bir örneğidir. {{index [escaping, "in HTML"]}} -To be able to include ((angle brackets)) in the text of a document even though they have a special meaning in HTML, yet another form of special notation has to be introduced. A plain opening angle bracket is written as `<` ("less than"), and a closing bracket is written as `>` ("greater than"). In HTML, an ampersand (`&`) character followed by a name or character code and a semicolon (`;`) is called an _((entity))_ and will be replaced by the character it encodes. +Bir belgenin metninde açı ((parantez))ler kullanabilmek için, HTML’de özel bir anlamı olan bu semboller için özel bir gösterim biçimi tanıtılmalıdır. Düz bir açılış açı parantezi `<` (“küçüktür”) ve kapanış parantezi `>` (“büyüktür”) olarak yazılır. HTML’de, bir isim veya karakter kodu ve noktalı virgül (`;`) ile takip edilen bir ampersand (`&`) karakterine _((varlık))_ denir ve kodladığı karakterle değiştirilir. {{index ["backslash character", "in strings"], "ampersand character", "double-quote character"}} -This is analogous to the way backslashes are used in JavaScript strings. Since this mechanism gives ampersand characters a special meaning too, they need to be escaped as `&`. Inside attribute values, which are wrapped in double quotes, `"` can be used to insert a literal quote character. +Bu, JavaScript dizelerinde ters eğik çizgilerin kullanılma şekline benzer. Bu mekanizma ampersand karakterlerine de özel bir anlam verdiğinden, `&` olarak kaçırılmaları gerekir. Çift tırnak içine alınmış özellik değerleri içinde, gerçek bir tırnak karakteri eklemek için `"` kullanılabilir. {{index "error tolerance", parsing}} -HTML is parsed in a remarkably error-tolerant way. When tags that should be there are missing, the browser automatically adds them. The way this is done has been standardized, and you can rely on all modern browsers to do it in the same way. +HTML, oldukça hata tolere eden bir şekilde ayrıştırılır. Eksik olması gereken etiketler olduğunda, tarayıcı bunları otomatik olarak ekler. Bunun yapılma şekli standartlaştırılmıştır ve tüm modern tarayıcıların aynı şekilde yapmasını bekleyebilirsiniz. -The following document will be treated just like the one shown previously: +Aşağıdaki belge daha önce gösterilen belge ile aynı şekilde ele alınacaktır: ```{lang: "html"} @@ -172,21 +172,21 @@ The following document will be treated just like the one shown previously: {{index "title (HTML tag)", "head (HTML tag)", "body (HTML tag)", "html (HTML tag)"}} -The ``, ``, and `` tags are completely gone. The browser knows that `` and `