diff --git a/.gitattributes b/.gitattributes index 6313b56c5..d3877a538 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ * text=auto eol=lf +*.svg binary diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..490051876 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: iliakan diff --git a/.gitignore b/.gitignore index 6f90fd190..1a71fb7c8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ sftp-config.json Thumbs.db +/svgs \ No newline at end of file diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index 209913080..11950ca16 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -1,10 +1,18 @@ # JavaScript'e Giriş +<<<<<<< HEAD Bakalım JavaScript nedir, ne yapılır ve hangi teknolojilerle birlikte çalışır. +======= +Let's see what's so special about JavaScript, what we can achieve with it, and what other technologies play well with it. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## JavaScript Nedir? +<<<<<<< HEAD *JavaScript*, ilk başta *"web belgelerine canlılık"* getirmek için oluşturulmuştur. +======= +*JavaScript* was initially created to "make web pages alive". +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu dilde yazılan kod kümelerine betik denir. Doğrudan HTML kodu içerisine yazılıp sayfa yüklendiğinde doğrudan çalışabilir. @@ -12,8 +20,13 @@ Komutlar herhangi bir derleme ve hazırlığa gereksinim duymadan doğrudan çal Bu yönden bakınca JavaScript diğer dillere kıyasla oldukça farklıdır. Bkz: [Java](https://en.wikipedia.org/wiki/Java_(programming_language)). +<<<<<<< HEAD ```smart header="Neden JavaScript?" JavaScript ilk yazıldığında, başka bir adı vardı: "LiveScript". Ancak Java dili o dönemlerde çok ünlü olduğundan dolayı yeni bir dil ve "küçük kardeş" gibi görünmesi açısından JavaScript olarak değiştirildi. +======= +```smart header="Why is it called JavaScript?" +When JavaScript was created, it initially had another name: "LiveScript". But Java was very popular at that time, so it was decided that positioning a new language as a "younger brother" of Java would help. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Ancak JavaScript gelişerek kendince yönergeleri [ECMAScript](http://en.wikipedia.org/wiki/ECMAScript) olan bağımsız bir dil haline geldi. Şu anda Java ile hiçbir ilgisi bulunmamaktadır. ``` @@ -25,26 +38,46 @@ Tarayıcılar bu JavaScript motoru gömülü bir biçimde gelirler. Bu ayrıca " Bu JavaScript motorlarından bazıları şunlardır; +<<<<<<< HEAD - [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- Chrome ve Opera. - [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- Firefox. - Internet Explorer'ın "Trident", "Chakra" takma adlı motorlarının yanında Microsoft Edge için "ChakraCore" adında ayrı bir motoru bulunmaktadır. Safari ise "Nitro", "SquirrelFish" ve "SquirrelFish Extreme" gibi takma adlarla adlandırılan JavaScript motorunu kullanmaktadır. Yukarıdaki terimleri aklınızda tutarsanız iyi olur, çünkü ileride şu tür tümcelerle karşılaşabilirsiniz: "V8'de A özelliğinin altyapısı", "Bu özelliğin altyapısının Chrome ve Opera'da bulunduğunu anlamanız gerekir." +======= +- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome, Opera and Edge. +- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox. +- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "Nitro" and "SquirrelFish" for Safari, etc. + +The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome, Opera and Edge. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```smart header="JavaScript Motoru Nasıl Çalışır?" Motorlar çok karmaşık yapılardır. Ancak kolay ögelere dayanırlar. +<<<<<<< HEAD 1. Eğer bu motor tarayıcıya gömülmüş ise yazılan JavaScript kodlarını ayrıştırır. 2. Sonra bu kodları makine diline çevirir. 3. Makine bu kodları çok hızlı bir biçimde çalıştırır. Motor bu sürecin her bir adımında iyileştirme yapar. Hatta derlenmiş ve çalışır durumda bulunan kodlardaki veri yapılarını inceler ve bunları iyileştirerek daha hızlı duruma getirir. Sonuç olarak yazılan bu kodlar çok hızlı bir biçimde çalışır. +======= +1. The engine (embedded if it's a browser) reads ("parses") the script. +2. Then it converts ("compiles") the script to machine code. +3. And then the machine code runs, pretty fast. + +The engine applies optimizations at each step of the process. It even watches the compiled script as it runs, analyzes the data that flows through it, and further optimizes the machine code based on that knowledge. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ## Tarayıcı içerisindeki JavaScript neler yapabilir? +<<<<<<< HEAD Günümüz JavaScript'i "güvenli" bir programlama dilidir. Düşük düzeydeki diller gibi bellek veya işlemciye doğrudan erişim sağlamaz. Tarayıcı için olduğundan dolayı böyle bir şeye gereksinim duymaz. +======= +Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or the CPU, because it was initially created for browsers which do not require it. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 JavaScript'in yapabilecekleri büyük bir oranda ortama dayanır. Örneğin [Node.JS](https://wikipedia.org/wiki/Node.js), JavaScript işlevleri ile dosyaları okuma, yazma veya ağ üzerinden isteme işlemlerini yapabilir. @@ -60,14 +93,23 @@ Tarayıcı içerisindeki JavaScript ise web sayfasında görsel değişikliklere ## Tarayıcı içerisinde bulunan JavaScript ne yapamaz? +<<<<<<< HEAD Tarayıcı içerisinde bulunan JavaScript kullanıcı güvenliği amacıyla sınırlandırılmıştır. Amaç zararlı web sitelerinin özel bilgilere erişip kullanıcıya zarar vermesini engellemektir. +======= +JavaScript's abilities in the browser are limited to protect the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu engellemeleri şu biçimde sıralayabiliriz : +<<<<<<< HEAD - Web sayfasında çalışan JavaScript dosyalara erişim sağlayamaz, saklama alanınızda bulunan programları kopyalayamaz veya çalıştıramaz. İşletim sisteminizin fonksiyonlarına doğrudan erişimi yoktur. +======= +- JavaScript on a webpage may not read/write arbitrary files on the hard disk, copy them or execute programs. It has no direct access to OS functions. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Günümüz tarayıcıları dosyalarla çalışmanıza izin verebilir. Ancak bu izin oldukça sınırlıdır. Örneğin, yalnızca dosyayı tarayıcıya taşıyıp bırakabilirsiniz veya `` kullanarak dosyayı seçebilirsiniz. +<<<<<<< HEAD Her zaman kullanıcıyla kamera veya mikrofon vasıtasıyla veya diğer aygıtlar aracılığıyla etkileşime geçebilirsiniz. Ancak kullanıcının kesin iznini almanız gerekir. Dolayısıyla bir web sayfası JavaScript ile gizliden sizin web kameranızı izleyemez veya çevrenizde bulunanlar hakkında bilgi alamaz. [NSA](https://en.wikipedia.org/wiki/National_Security_Agency) - Farklı sekmeler birbiri ile iletişime geçemez ve bilgi alışverişi yapamazlar. Bazı sitelerde aynı sekmeler iletişimde bulunabilir, örneğin bir sekmeden JavaScript ile diğer sekmeyi açabilirsiniz. Bu durumda bile, bir sayfa diğerinden farklı alan adı, kural veya kapılarda ise erişemez. @@ -78,22 +120,45 @@ Bu engellemeleri şu biçimde sıralayabiliriz : ![Sınırlamalar](limitations.svg) Bu sınırlar, tarayıcı dışında kullanıldığında ortadan kalkar. Örneğin, sunucular daha geniş yetkilere sahiptir. +======= + There are ways to interact with the camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency). +- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other page if they come from different sites (from a different domain, protocol or port). + + This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and must contain special JavaScript code that handles it. We'll cover that in the tutorial. + + This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com`, for example, and steal information from there. +- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation. + +![](limitations.svg) + +Such limitations do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugins/extensions which may ask for extended permissions. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## JavaScript'i eşsiz yapan nedir ? JavaScript'i eşsiz yapan en az 3 neden vardır: ```compare +<<<<<<< HEAD + HTML/CSS ile tamamen bütünleşik çalışması. + Basit şeyler basitçe yapılır. + Tüm önemli tarayıcılarda çalışır ve ön tanımlı olarak etkindir. +======= ++ Full integration with HTML/CSS. ++ Simple things are done simply. ++ Supported by all major browsers and enabled by default. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` JavaScript'ten başka bu üç özelliği taşıyan hiçbir tarayıcı teknolojisi yoktur. +<<<<<<< HEAD JavaScript'in eşsiz olma nedeni budur ve bu yüzden web sayfaları geliştirmekte kullanılan en yaygın araçtır. Yeni bir teknolojiyi öğrenmeye başlarken, sunacağı avantajlar için öngörü önemlidir. Bu sebeptendir ki, yeni diller ve tarayıcı yetkinlikleri içeren bu yönelimlere ayak uydurmalıyız. +======= +That said, JavaScript can be used to create servers, mobile applications, etc. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## JavaScript'e üstün diller @@ -101,20 +166,43 @@ JavaScript'in söz dizimi ve yazımı herkese uymayabilir. Her yiğidin yoğurt Bu olağan bir durum, çünkü tasarımlar ve gereksinimler kişiden kişiye göre değişir. +<<<<<<< HEAD Bundan dolayı yakın zamanda bir sürü yeni *transpiled* yani çevirilmiş diller türemiştir. Bu diller, çalıştırılmadan önce JavaScript'e çevriliyor. Günümüz araçları bu çeviri işini çok hızlı bir biçimde yapmaktadır. Gerçekte, doğrudan —siz yazarken bile— çevirme işini yapıp bu yeni dosyayı kullanılabilir duruma getirirler. +======= +So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu dillere örnek vermek gerekirse: +<<<<<<< HEAD - [CofeeScript](http://coffeescript.org) JavaScript için "şeker yazım" denebilecek bir dildir. Yazılımı daha kısadır ve daha temiz kod yazmaya yardımcı olur. Genellikle [Ruby](https://www.ruby-lang.org/tr/) geliştiriciler bunu sever. - [Typescript](http://www.typescriptlang.org/) durağan veri yapıları ile JavaScript yazılmasını sağlar. Karmaşık programlar geliştirmeyi kolaylaştırır. Microsoft tarafından geliştirilmiştir. - [Dart](https://www.dartlang.org/) kendi başına ayrı bir dildir. Tarayıcı üzerinde veya telefon uygulamalarında kendi motoru üzerinden çalıştırılır. Google'ın tarayıcılarda JavaScript yerine Dart'ı önermiş olmasına karşın, bugünlerde JavaScript'e çeviri yapılarak kullanılmaktadır. +======= +Examples of such languages: + +- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it. +- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft. +- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook. +- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google. +- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript. +- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node. + +There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bunlara daha fazla örnek eklenebilir. Yukarıdakileri bilseniz bile ne yaptığınızı tam olarak anlamak için JavaScript bilmelisiniz. +<<<<<<< HEAD ## Özet - JavaScript başlangıçta yalnızca ağ tarayıcılarında kullanılmak üzere geliştirilmiş bir dildi. Ancak günümüzde, birçok çevrede çalışabilir durumda. - JavaScript şu anda HTML/CSS ile bütünleşik olmasından ve geniş uyumluluğundan dolayı benzersizdir. - Birçok JavaScript'e çevirici dil bulunmaktadır. JavaScript'i iyi bir biçimde öğrendikten sonra bu dillere de bir bakmanızı öneririz. +======= +- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well. +- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS. +- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md index 779b2009b..f2cca37a6 100644 --- a/1-js/01-getting-started/2-manuals-specifications/article.md +++ b/1-js/01-getting-started/2-manuals-specifications/article.md @@ -1,12 +1,17 @@ # Kılavuz ve Şartnameler +<<<<<<< HEAD Bu kitap aslında bir *eğitim süreci*'dir. Amacı sizin kademeli olarak JavaScript öğrenmenizi sağlamaktır. Önce temellere alıştıktan sonra diğer kaynaklar üzerinde durulacaktır. ## Şartname +======= +This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 **ECMA-262 Şartnamesi** JavaScript için olabilecek en derin bilgilerin bulunduğu kaynaktır. Dili tanımlar. +<<<<<<< HEAD Fakat resmi bir dil kullanıldığından dolayı ilk seferde anlaması zordur. Eğer en güvenilir kaynak neredir diye soracak olursanız bunun cevabı **ECMA-262 Şartnamesi**'dir. Fakat her an gidip kolayca bilgi alabileceğiniz bir kaynak değildir. Son taslağına adresinden erişebilirsiniz. @@ -16,9 +21,21 @@ Daha geniş kitleler tarafından kullanılmayan yeni özelliklere ve önerilere Ayrıca, tarayıcı için geliştirme yapıyorsanız, [ikinci bölümden](info:browser-environment) farklı eğitimlere bakabilirsiniz. ## Kılavuz +======= +[The ECMA-262 specification](https://www.ecma-international.org/publications/standards/Ecma-262.htm) contains the most in-depth, detailed and formalized information about JavaScript. It defines the language. + +But being that formalized, it's difficult to understand at first. So if you need the most trustworthy source of information about the language details, the specification is the right place. But it's not for everyday use. + +A new specification version is released every year. Between these releases, the latest specification draft is at . + +To read about new bleeding-edge features, including those that are "almost standard" (so-called "stage 3"), see proposals at . + +Also, if you're developing for the browser, then there are other specifications covered in the [second part](info:browser-environment) of the tutorial. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 - **MDN (Mozilla) JavaScript Reference** örnek ve kılavuzların yeraldığı bir diğer kaynaktır. İstediğiniz konular derinlemesine incelemek için harika bir kaynaktır. +<<<<<<< HEAD Buradan erişebilirsiniz: Google'da "MDN [term]" şeklinde aratırsanız aslında çok daha kolay erişebilirsiniz. Örneğin : `parseInt`'i aramak için kullanabilirsiniz. @@ -32,11 +49,29 @@ Ayrıca, tarayıcı için geliştirme yapıyorsanız, [ikinci bölümden](info:b JavaScript çok hızlı gelişen bir dildir, sürekli olarak yeni özellikler eklenir. Bunların tarayıcılarda desteklenip desteklenmediğini görmek için: +======= +- **MDN (Mozilla) JavaScript Reference** is the main manual with examples and other information. It's great to get in-depth information about individual language functions, methods etc. + + You can find it at . + +Although, it's often best to use an internet search instead. Just use "MDN [term]" in the query, e.g. to search for the `parseInt` function. + +## Compatibility tables +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 - - özellik bazlı tablo mevcuttur. Örneğin hangi JavaScript motorları cryptography özelliğini destekliyor sorusunun cevabını adresinden bulabilirsiniz. - - dil özelliğinin motorların hangisinde desteklenip hangisinde desteklenmediğini gösterir. +<<<<<<< HEAD Bunların hepsi günlük hayatta işinize yarayacak kaynaklardır. Dil detayları ve bunların destekleri ile alakalı detaylar bulunmaktadır. Lütfen belirli bir özelliği daha derinlemesine incelemek isterseniz bunları veya bu sayfayı hatırlayın. +======= +- - per-feature tables of support, e.g. to see which engines support modern cryptography functions: . +- - a table with language features and engines that support those or don't support. + +All these resources are useful in real-life development, as they contain valuable information about language details, their support, etc. + +Please remember them (or this page) for the cases when you need in-depth information about a particular feature. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md index 60c8791dd..30de0c3ad 100644 --- a/1-js/01-getting-started/3-code-editors/article.md +++ b/1-js/01-getting-started/3-code-editors/article.md @@ -12,11 +12,16 @@ TGO birçok dosyayı yükleyebilir ve bu dosyalar arasında geçişleri sağlar, Eğer henüz TGO seçmediyseniz aşağıdakilere göz atabilirsiniz: +<<<<<<< HEAD - IntelliJ Düzenleyicileri: [WebStorm](http://www.jetbrains.com/webstorm/) ön yüz geliştirmek için [PHPStorm (PHP)](http://www.jetbrains.com/phpstorm/), [IDEA (Java)](http://www.jetbrains.com/idea/), [RubyMine (Ruby)](http://www.jetbrains.com/ruby/) ve diğer programlama dilleri için olanları bulunmaktadır. - Eğer .NET Geliştiricisiyseniz Visual Studio iyi bir seçimdir. Ücretsiz versiyonunu [Visual Studio Community](https://www.visualstudio.com/vs/community/) adresinden indirebilirsiniz. - Eclipse tabanlı ürünler; örneğin [Aptana](http://www.aptana.com/) ve Zend Studio. - [Komodo IDE](http://www.activestate.com/komodo-ide) ücretsiz olan versiyonu sisteminize pek yük olmaz [Komodo Edit](http://www.activestate.com/komodo-edit). - [Netbeans](http://netbeans.org/). +======= +- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free). +- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid). +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Yukarıda bahsedilen tüm TGO'lar Windows ve macOS işletim sistemlerinde çalışmaktadır. Visual Studio haricindekiler ise Linux üzerinde de çalışabilmektedir. @@ -32,6 +37,7 @@ Genelde bir dosyayı hızlıca açıp düzenleme amacıyla kullanılırlar. Pratikte hafif düzenleyiciler birçok eklenti ile klasör bazında yazım, otomatik tamamlayıcı özelliklerine erişebilirler. Bundan dolayı TGO ile hafif düzenleyici arasındaki sınır çok belirgin değildir. +<<<<<<< HEAD Aşağıdaki hafif düzenleyiciler ilginizi çekebilir: - [Visual Studio Code](https://code.visualstudio.com/) (tüm işletim sistemlerinde çalışır, ücretsiz). @@ -39,6 +45,13 @@ Aşağıdaki hafif düzenleyiciler ilginizi çekebilir: - [Sublime Text](http://www.sublimetext.com) (tüm işletim sistemlerinde çalışır, ücretli). - [Notepad++](https://notepad-plus-plus.org/) (sadece Windows'ta çalışır, ücretsiz). - Vim ve Emacs gibi düzenleyiciler de oldukça iyidir fakat öğrenme süresi diğerler hafif düzenleyicilere göre daha uzundur. +======= +There are many options, for instance: + +- [Sublime Text](https://www.sublimetext.com/) (cross-platform, shareware). +- [Notepad++](https://notepad-plus-plus.org/) (Windows, free). +- [Vim](https://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Lütfen Tartışmayalım @@ -46,4 +59,13 @@ Yukarıda yazan düzenleyicileri ben veya birçok profesyonel arkadaşım mutlu Tabi bunlar haricinde nice harika editörler mevcuttur. Lütfen en çok hoşunuza gideni seçin. +<<<<<<< HEAD Editör seçimi de diğer araç seçimleri gibi kişisel, projeye göre, alışkanlıklara göre, kişisel tercihlere göre farklılık gösterebilir. +======= +The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences. + +The author's personal opinion: + +- I'd use [Visual Studio Code](https://code.visualstudio.com/) if I develop mostly frontend. +- Otherwise, if it's mostly another language/platform and partially frontend, then consider other editors, such as XCode (Mac), Visual Studio (Windows) or Jetbrains family (Webstorm, PHPStorm, RubyMine etc, depending on the language). +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md index a0fcc82ec..53f14bb41 100644 --- a/1-js/01-getting-started/4-devtools/article.md +++ b/1-js/01-getting-started/4-devtools/article.md @@ -20,17 +20,29 @@ Bu sayfada bulunan JavaScript kodunda bir hata var. Kullanıcı bunu göremiyor, Geliştirici araçları konsol paneliyle açılacaktır. Aşağıdaki ekranda ilk hatanızı göreceksiniz: -![chrome](chrome.png) +![chrome](chrome.webp) Chrome'un geliştirme aracı versiyona göre değişiklik gösterecektir. Fakat genel hatları itibariyle şu anda gördüğünüze benzeyecektir. - Konsol panelinde kırmızı renk ile hatayı görebilirsiniz. Bu durumda kodunuz bilinmeyen "lalala" komutunda hata vermiş. +<<<<<<< HEAD - Sağ tarafında hatanın hangi satırda olduğunu görebilirsiniz. Bu alan tıklanabilirdir. Şu anda hata `bug.html:12`'de bulunmaktadır. +======= +Below the error message, there is a blue `>` symbol. It marks a "command line" where we can type JavaScript commands. Press `key:Enter` to run them. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Hatanın altında `>` sembolünü görebilirsiniz. Bu, "komut satırı"'nı işaret eder. Komutunuzu yazdıktan sonra `key:Enter`'a basarak o satırdaki komutu çalıştırabilirsiniz. Birden fazla satır kod yazabilmek için ise `key:Shift+Enter` tuş kombinasyonunu kullanabilirsiniz. +<<<<<<< HEAD Başlangıç için hataları görmek yeterli olacaktır. Daha sonra geliştirme aracını bölümünde derinlemesine öğreneceksiniz. +======= +```smart header="Multi-line input" +Usually, when we put a line of code into the console, and then press `key:Enter`, it executes. + +To insert multiple lines, press `key:Shift+Enter`. This way one can enter long fragments of JavaScript code. +``` +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Firefox, Edge ve diğerleri @@ -40,12 +52,19 @@ Görüntü ve kullanım olarak çoğu birbirine benzer. Bir tanesini öğrendiğ ## Safari +<<<<<<< HEAD Safari (sadece macOS için desteklenmektedir) biraz özeldir. Geliştirici araçlarını kullanabilmek için önce "Geliştirici Menüsü"'nü aktif hale getirmeniz gerekmektedir. Bunun için özellikler sayfasını açıp "Gelişmiş" panelinden aşağıdaki gibi "Show Develop menu in menu bar"'ı işaretlemelisiniz. +======= +Safari (Mac browser, not supported by Windows/Linux) is a little bit special here. We need to enable the "Develop menu" first. + +Open Settings and go to the "Advanced" pane. There's a checkbox at the bottom: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ![safari](safari.png) Bu işlemi yaptıktan sonra `key:Cmd+Opt+C` ile geliştirici konsolunu açıp kapatabilirsiniz. Ayrıca dikkat ederseniz üst menüde "Develop" adında yeni bir başlık göreceksiniz. Buradan da birçok komutu çalıştırabilirsiniz. +<<<<<<< HEAD ## Multi-line input Genelde konsol ekranında `key:Enter` yaparsanız bulunduğu satırı çalıştırır. Birden fazla satırı yazmak istiyorsanız `key:Shift+Enter` kullanabilirsiniz. @@ -54,5 +73,8 @@ Genelde konsol ekranında `key:Enter` yaparsanız bulunduğu satırı çalışt - Geliştirici araçları hataları görmenizi, komutları çalıştırmanızı, değişkenleri takip etmenizi sağlar. - Windows işletim sisteminde `key:f12` tuşu ile açılır (Çoğu tarayıcıda bu tuş çalışır). macOS işletim sistemi için ise Google Chrome: `key:Cmd+Opt+J` ile Safari ise: `key:Cmd+Opt+C` tuşu ile açılır (Safari'de geliştirici modunu açmanız gerekmekte). +======= +## Summary +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Artık çalışma ortamınızı da ayarladığınıza göre JavaScript öğrenmeye başlayabilirsiniz. diff --git a/1-js/01-getting-started/4-devtools/chrome.png b/1-js/01-getting-started/4-devtools/chrome.png deleted file mode 100644 index 4cb3ea2f4..000000000 Binary files a/1-js/01-getting-started/4-devtools/chrome.png and /dev/null differ diff --git a/1-js/01-getting-started/4-devtools/chrome.webp b/1-js/01-getting-started/4-devtools/chrome.webp new file mode 100644 index 000000000..bdf067079 Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome.webp differ diff --git a/1-js/01-getting-started/4-devtools/chrome@2.webp b/1-js/01-getting-started/4-devtools/chrome@2.webp new file mode 100644 index 000000000..2aeca5898 Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome@2.webp differ diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html new file mode 100644 index 000000000..ff1d871b0 --- /dev/null +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md index e69de29bb..81552913b 100644 --- a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md @@ -0,0 +1,2 @@ + +[html src="index.html"] diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md index 8d930f700..31ac72959 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -1,6 +1,10 @@ # Merhaba Dünya +<<<<<<< HEAD Okuyacağınız bu konu Javascript'in özü hakkındadır, platform ile bağlantılı değildir. İleride Node.JS ve diğer platformlarda aynı şekilde kullanabilirsiniz. +======= +This part of the tutorial is about core JavaScript, the language itself. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Fakat kodlarımızın çalıştırılabilmesi için en azından bir ortam gerekli ve bu kitap tarayıcı üzerinden açılarak size bu ortamı yaratmış oluyor. Tarayıcı özel komutları ( `alert`) daha az tutulacak. Böylece eğer diğer platformlara yönelmek istiyorsanız bu komutlarla zaman geçirmenize gerek kalmayacak. Diğer yandan [sonraki](/ui) bölümde tarayıcı özellikleri daha derinlemesine incelenecektir. @@ -9,7 +13,11 @@ Fakat kodlarımızın çalıştırılabilmesi için en azından bir ortam gerekl ## Script etiketi +<<<<<<< HEAD Javascript programları html içerisine ` ``` +<<<<<<< HEAD Bu yorumların amacı ` ``` +<<<<<<< HEAD Buradaki `/kod/yolu/ana.js` site ana dizininden itibaren kesin (absolute) yol belirtir. Tabi göreceli (relative) yol belirtmek de mümkündür. Örneğin `src="script.js"` HTML dosyasının kayıt edildiği klasördeki `"script.js"`'yi al anlamına gelir. +======= +Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Tam URL vermek de mümkündür. Örneğin: ```html - + ``` Birkaç kod dosyası eklemek isterseniz aşağıdaki gibi yazabilirsiniz. diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md index 77178656b..eae7be915 100644 --- a/1-js/02-first-steps/02-structure/article.md +++ b/1-js/02-first-steps/02-structure/article.md @@ -45,7 +45,11 @@ alert(3 + + 2); ``` +<<<<<<< HEAD Yukarıdaki bloğun çıktısı `6` olacaktır çünkü JavaScript yeni satırda noktalı virgül eklememiştir. Buradan anlayabilirsiniz ki eğer satır `"+"` ile bitiyorsa ifade bitmiş sayılmaz ve noktalı virgül gereklidir. Bu durumda yukarıdaki kod beklendiği gibi çalışmaktadır. +======= +The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so a semicolon there would be incorrect. And in this case, that works as intended. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 **Fakat bazı durumlarda noktalı virgülün otomatik olarak konulması gerekirken JavaScript bunu yapmakta sorun yaşar** @@ -55,28 +59,45 @@ Böyle hataları bulmak oldukça zordur. Eğer böyle bir hata görmek istiyorsanız, aşağıdaki koda bir bakın ```js run -[1, 2].forEach(alert) +alert("Hello"); + +[1, 2].forEach(alert); ``` `[]` veya `forEach` in ne anlama geldiğini bilmenize şimdilik gerek yok daha sonra bu konuyu işleyeceğiz. Şu anda bilmeniz gereken önce 1 uyarısı alacaksınız sonra 2. +<<<<<<< HEAD Şimdi bu koddan önce noktalı virgül ile bitmeyen bir uyarı ifadesi yazın. ```js run no-beautify alert("Hata alacaksınız") +======= +No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them later. For now, just remember the result of running the code: it shows `Hello`, then `1`, then `2`. + +Now let's remove the semicolon after the `alert`: + +```js run no-beautify +alert("Hello") +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 -[1, 2].forEach(alert) +[1, 2].forEach(alert); ``` +<<<<<<< HEAD Eğer yukarıdaki kodu çalıştırırsanız sadece ilk uyarı mesajını görecek ve sonrasında hata alacaksınız. Fakat aşağıdaki gibi noktalı virgül kullanırsanız her şeyin beklenen şekilde çalıştığını göreceksiniz: ```js run alert("Şimdi ise beklendiği gibi hatasız"); +======= +The difference compared to the code above is only one character: the semicolon at the end of the first line is gone. -[1, 2].forEach(alert) -``` +If we run this code, only the first `Hello` shows (and there's an error, you may need to open the console to see it). There are no numbers any more. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 + +That's because JavaScript does not assume a semicolon before square brackets `[...]`. So, the code in the last example is treated as a single statement. +<<<<<<< HEAD Şimdi "Her şey yolunda" mesajını ve ardından `1` ve `2`'yi görüyoruz. İlk yazdığımız kod bloğunda hata olmasının sebebi JavaScript'in `[...]` den önce noktalı virgül gelmeyeceğini varsaymasından dolayı olmaktadır. @@ -88,10 +109,25 @@ alert("Bir hata gerçekleşecek")[1, 2].forEach(alert) ``` Fakat normalde sizin de bildiğiniz gibi bunu iki satır görmesi gerekmektedir. Bu ve bunun gibi hatalar ile kod yazdığınız sürece karşılaşabileceğiniz hatalardır. +======= +Here's how the engine sees it: + +```js run no-beautify +alert("Hello")[1, 2].forEach(alert); +``` + +Looks weird, right? Such merging in this case is just wrong. We need to put a semicolon after `alert` for the code to work correctly. + +This can happen in other situations also. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```` Eğer yeni satıra geçmek istiyorsanız önerilen yöntem noktalı virgül kullanmanızdır. Bu kural JavaScript toplumu tarafından benimsenmiştir. Tekrar belirtelim JavaScript yazarken noktalı virgül kullanmadan yeni satıra geçmek çoğu zaman -- *mümkündür* -- fakat başlangıçta noktalı virgül kullanmanız daha güvenlidir ve önerilir. +<<<<<<< HEAD +======= +## Comments [#code-comments] +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Yorum Satırları Zamanla yazdığınız programlar gittikçe karmaşıklaşır. Neyin ne için yapıldığını belirtmeniz için *yorum* yazmak kaçınılmaz olur. @@ -129,9 +165,14 @@ alert('Hello'); alert('Dünya'); ``` +<<<<<<< HEAD ```smart header="Klavye kısayollarını kullanın!" Çoğu editör `key:Ctrl+/` kısayolunu kullanarak tek satır veya `key:Ctrl+Shift+/` kullanarak çok satır yorum yapmanıza yardımcı olur. Mac için `key:Cmd` tuşu windows için ise `key:Ctrl` tuşudur. +======= +```smart header="Use hotkeys!" +In most editors, a line of code can be commented out by pressing the `key:Ctrl+/` hotkey for a single-line comment and something like `key:Ctrl+Shift+/` -- for multiline comments (select a piece of code and press the hotkey). For Mac, try `key:Cmd` instead of `key:Ctrl` and `key:Option` instead of `key:Shift`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ````warn header="Yorum satırı içerisinde ayrı bir yorum satırı yapılamaz!" diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md index d3dff0743..297481e12 100644 --- a/1-js/02-first-steps/03-strict-mode/article.md +++ b/1-js/02-first-steps/03-strict-mode/article.md @@ -4,7 +4,11 @@ Uzun süredir JavaScript uyumluluk sorunu olmadan gelişmeye devam etmektedir. Y Bu eski kodlarınızın çalışacağı garantisini verir. Kötü yanı ise JavaScript geliştiricileri tarafından eskiden verilen kötü bir kararın veya hatanın sürekli tekrar edilmesine neden olur. +<<<<<<< HEAD ECMAScript 5 (ES5) standardı 2009 yılında kabul edilmiştir. Bu standart yeni özellikler eklediği gibi eskide olanlardan bazılarını da düzenlemiştir. Eski kodun çalışabilirliğini garanti altına almak için çoğu düzenleme varsayılan olarak kapalı durumda gelir. Bunları açmak için `"use strict"` kullanılmalıdır. +======= +This was the case until 2009 when ECMAScript 5 (ES5) appeared. It added new features to the language and modified some of the existing ones. To keep the old code working, most such modifications are off by default. You need to explicitly enable them with a special directive: `"use strict"`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## "use strict" @@ -19,10 +23,14 @@ Bu direktif için kod dosyanızın başına `"use strict"` veya `'use strict'` y ... ``` +<<<<<<< HEAD Yakında fonksiyonları (komutları gruplama yolu) göreceksiniz. `"use strict"` birden çok fonksiyonda kullanılacağı gibi tek fonksiyon için de kullanılabilir. Fakat genelde tüm dosya için kullanılır. +======= +Quite soon we're going to learn functions (a way to group commands), so let's note in advance that `"use strict"` can be put at the beginning of a function. Doing that enables strict mode in that function only. But usually people use it for the whole script. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ````warn header="\"use strict\" in en üstte olduğuna emin olun" @@ -45,16 +53,30 @@ alert("Bazı kodlar"); ```warn header="`use strict`'i iptal eden bir direktif bulunmamaktadır" Modern JavaScript'i eski haline getiren `"no use strict"` gibi bir direktif bulunmamaktadır. +<<<<<<< HEAD Sıkı moda girdiğinizde artık eskiye dönüş yoktur. +======= +Once we enter strict mode, there's no going back. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ## Tarayıcı Konsolu +<<<<<<< HEAD İleride özellikleri test etmek için bir [geliştirici konsolu](info:devtools) kullandığınızda, lütfen tarayıcının varsayılan olarak `use strict` kullanmadığını unutmayın. +======= +When you use a [developer console](info:devtools) to run code, please note that it doesn't `use strict` by default. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bazen, `use strict` bir fark yarattığında, yanlış sonuçlar alırsınız. +<<<<<<< HEAD Birden çok satır girmek için `key:Shift+Enter` tuşlarına basmayı deneyebilir ve üstte `use strict` kullanmayı deneyebilirsiniz, örneğin: +======= +So, how to actually `use strict` in the console? + +First, you can try to press `key:Shift+Enter` to input multiple lines, and put `use strict` on top, like this: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js 'use strict'; @@ -64,12 +86,17 @@ Birden çok satır girmek için `key:Shift+Enter` tuşlarına basmayı deneyebil Çoğu tarayıcıda, yani Firefox ve Chrome'da çalışır. +<<<<<<< HEAD Aksi takdirde, `use strict` eklemenin en güvenilir yolu, kodu konsola şu şekilde girmek olacaktır: +======= +If it doesn't, e.g. in an old browser, there's an ugly, but reliable way to ensure `use strict`. Put it inside this kind of wrapper: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js (function() { 'use strict'; +<<<<<<< HEAD // ...sizin kodunuz... })() ``` @@ -86,3 +113,24 @@ Gelecek bölümlerde dilin özelliklerini öğrendikçe bu sıkı mod ile varsay 2. Sıkı moda dosyanın başına `"use strict"` direktifiyle geçilebilir. Bu bize "sınıf" veya "modül" gibi dil özelliklerini kazandırır. 3. Sıkı mod tüm modern tarayıcılar tarafından desteklenir. 4. Bundan sonra tersi söylenmedikçe her yazacağınız örneklerde `"use strict"` ile başlayacağınız varsayılmaktadır. +======= + // ...your code here... +})() +``` + +## Should we "use strict"? + +The question may sound obvious, but it's not so. + +One could recommend to start scripts with `"use strict"`... But you know what's cool? + +Modern JavaScript supports "classes" and "modules" - advanced language structures (we'll surely get to them), that enable `use strict` automatically. So we don't need to add the `"use strict"` directive, if we use them. + +**So, for now `"use strict";` is a welcome guest at the top of your scripts. Later, when your code is all in classes and modules, you may omit it.** + +As of now, we've got to know about `use strict` in general. + +In the next chapters, as we learn language features, we'll see the differences between the strict and old modes. Luckily, there aren't many and they actually make our lives better. + +All examples in this tutorial assume strict mode unless (very rarely) specified otherwise. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md index 683d72987..68310e1d1 100644 --- a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md +++ b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md @@ -1,4 +1,8 @@ +<<<<<<< HEAD Önce gezegenimizin isminin tutulduğu değişkeni oluşturun. +======= +## The variable for our planet +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Basit bir şekilde aşağıdaki gibi oluşturabilirsiniz: @@ -6,10 +10,16 @@ Basit bir şekilde aşağıdaki gibi oluşturabilirsiniz: let gezegenimizinIsmi = "Dünya"; ``` +<<<<<<< HEAD Dikkat edin daha kısa olabilirdi. Örneğin kısaca `gezegen` diyebilirdik fakat bu çok açıkça bizim gezegenimizin ismini ifade etmezdi. Değişken çok uzun olmadıkça açık olmakta fayda var. İkincisi şu anda siteyi ziyaret eden kullanıcının adı: +======= +Note, we could use a shorter name `planet`, but it might not be obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong. + +## The name of the current visitor +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let simdikiKullaniciAdi = "Ahmet"; diff --git a/1-js/02-first-steps/04-variables/3-uppercast-constant/solution.md b/1-js/02-first-steps/04-variables/3-uppercast-constant/solution.md index b11783cf6..39ffbeb0d 100644 --- a/1-js/02-first-steps/04-variables/3-uppercast-constant/solution.md +++ b/1-js/02-first-steps/04-variables/3-uppercast-constant/solution.md @@ -2,4 +2,8 @@ Genelde "sabit kodlanmış" sabitler için tamamen büyük harf kullanırız. Bi Bu kod cümlesinde `dogumGunu` tam da bu tanıma uymaktadır. Bundan dolayı büyük harf ile kullanılabilir. -Buna karşı `yaş` değişkeni bir fonksiyonun çıktısına göre değer almaktadır. Bugün diyelim ki 20 yaşındaysanız bir yıl sonra 21 yaşında olacaksınız demektir. Tabi bu kural kod çalıştığında değişmez. Yani yıla göre değer alacaktır cümlesi değişmeyecektir. Fakat değer değiştiğinden dolayı `dogumGunu` değişkenine göre daha az sabittir. Hesaplanan bir değerdir. Bundan dolayı bunu küçük harfle tutmanız gerekmektedir. \ No newline at end of file +<<<<<<< HEAD +Buna karşı `yaş` değişkeni bir fonksiyonun çıktısına göre değer almaktadır. Bugün diyelim ki 20 yaşındaysanız bir yıl sonra 21 yaşında olacaksınız demektir. Tabi bu kural kod çalıştığında değişmez. Yani yıla göre değer alacaktır cümlesi değişmeyecektir. Fakat değer değiştiğinden dolayı `dogumGunu` değişkenine göre daha az sabittir. Hesaplanan bir değerdir. Bundan dolayı bunu küçük harfle tutmanız gerekmektedir. +======= +In contrast, `age` is evaluated in run-time. Today we have one age, a year after we'll have another one. It is constant in a sense that it does not change through the code execution. But it is a bit "less of a constant" than `birthday`: it is calculated, so we should keep the lower case for it. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md index 3d8976dca..0944e9b99 100644 --- a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md +++ b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md @@ -12,12 +12,24 @@ const dogumGunu = '18.04.1982'; const yas = someCode(dogumGunu); ``` +<<<<<<< HEAD Gördüğünüz gibi `dogumGunu` adında bir tarih sabiti ve `yaş` adında `dogumGunu` değişkeninden hesaplanan bir değişken bulunmakta. ( Örneğin kısa olması açısından `someCode` fonksiyonu tamamlanmamıştır.) +======= +Here we have a constant `birthday` for the date, and also the `age` constant. + +The `age` is calculated from `birthday` using `someCode()`, which means a function call that we didn't explain yet (we will soon!), but the details don't matter here, the point is that `age` is calculated somehow based on the `birthday`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Sizce `dogumGunu` tamamı büyük harf olacak şekilde mi olmalı? yoksa `yaş` değişkeni mi büyük olmalı? Veya her ikisi de mi büyük harf olmalı? ```js +<<<<<<< HEAD const DOGUMGUNU = '18.04.1982'; // büyük harf mi olmalı? const YAS = someCode(DOGUMGUNU); // büyük harf mi olmalı? +======= +const BIRTHDAY = '18.04.1982'; // make birthday uppercase? + +const AGE = someCode(BIRTHDAY); // make age uppercase? +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index e7852079d..67c72e43c 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -14,6 +14,10 @@ JavaScript dilinde değişken `let` kelimesiyle üretilir. Aşağıdaki cümle "mesaj" isminde bir değişken üretir (diğer bir deyişle *tanımlar*): +<<<<<<< HEAD +======= +The statement below creates (in other words: *declares*) a variable with the name "message": +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let mesaj; @@ -24,7 +28,11 @@ Artık bunun içerisine bilgi koyulabilir. Bunu atama operatörü ile `=` yapabi let mesaj; *!* +<<<<<<< HEAD mesaj = 'Merhaba'; // Merhaba karakter dizisini mesaja atadınız +======= +message = 'Hello'; // store the string 'Hello' in the variable named message +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 */!* ``` @@ -61,7 +69,11 @@ let yas = 25; let mesaj = 'Merhaba'; ``` +<<<<<<< HEAD Bazı programcılar ise şu şekilde kullanmaktadırlar: +======= +Some people also define multiple variables in this multiline style: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js no-beautify let kullanici = 'Ahmet', @@ -79,29 +91,49 @@ let kullanici = 'Ahmet' Teknik olarak bu yazımların hepsi doğrudur. Gerisi sizin yazım tarzınıza kalmış. Her yiğidin yoğurt yiyişi farklıdır. +<<<<<<< HEAD ````smart header=" `let` yerine `var` kullanma" Eski kodlarda `let` yerine `var` kullanıldığını görürsünüz. +======= +````smart header="`var` instead of `let`" +In older scripts, you may also find another keyword: `var` instead of `let`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js *!*var*/!* mesaj = 'Merhaba'; ``` `var` kelimesi *neredeyse* `let` ile aynı anlama gelmektedir. `var` kelimesi de değişken üretmeye yarar fakat bunu eski tarzda yapar. +<<<<<<< HEAD `let` ile `var` arasında nüans farkı vardır. İkisi de istediğimizi yerine getirir. Bunun ile ilgili detaylı bilgi konusuna gelindiğinde verilecektir. +======= +The `var` keyword is *almost* the same as `let`. It also declares a variable but in a slightly different, "old-school" way. + +There are subtle differences between `let` and `var`, but they do not matter to us yet. We'll cover them in detail in the chapter . +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```` ## Gerçek hayat ile benzeşim "Değişken" konsepti "kutu" olarak tanımlanabilir. Her kutunun üzerinde farklı bir etiket yapıştırılmıştır. +<<<<<<< HEAD Örneğin `mesaj` değişkeni üzerinde `"mesaj"` yazısı olan ve değeri `"Merhaba!"` olan bir kutu olarak hayal edilebilir. +======= +For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ![](variable.svg) Kutuya istediğiniz değeri koyabilirsiniz. Ayrıca içerisindeki değeri istediğiniz kadar değiştirebilirsiniz. +<<<<<<< HEAD +======= +We can also change it as many times as we want: + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run let mesaj; @@ -115,7 +147,11 @@ Değer değiştiğinde, değişkenin eski değeri silinir. ![](variable-change.svg) +<<<<<<< HEAD Ayrıca iki değişken tanımlayıp içerilerindeki değerleri bir diğerine aktarabilirsiniz. +======= +![](variable-change.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run @@ -133,13 +169,36 @@ alert(merhaba); // Merhaba Dünya! alert(mesaj); // Merhaba Dünya! ``` +<<<<<<< HEAD ```smart header="Fonksiyonel Diller" +======= +````warn header="Declaring twice triggers an error" +A variable should be declared only once. + +A repeated declaration of the same variable is an error: + +```js run +let message = "This"; + +// repeated 'let' leads to an error +let message = "That"; // SyntaxError: 'message' has already been declared +``` +So, we should declare a variable once and then refer to it without `let`. +```` + +```smart header="Functional languages" +It's interesting to note that there exist so-called [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming languages, such as [Haskell](https://en.wikipedia.org/wiki/Haskell), that forbid changing variable values. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 İlginç bir bilgi olarak [Scala](http://www.scala-lang.org/) veya [Erlang](http://www.erlang.org/) gibi [fonksiyonel](https://tr.wikipedia.org/wiki/Fonksiyonel_programlama) diller değişkenin değerinin değiştirilmesine izin vermez. +<<<<<<< HEAD Böyle dillerde değer bir kutunun içerisinde sonsuza kadar saklanır. Eğer farklı bir değer kaydetmek istenirse bu diller bizi yeni bir kutu oluşturmaya iter. Eskisi yeniden kullanıp değeri değiştirilemez. İlk başta biraz garip gelse de, bu diller genel olarak ciddi işlerin yapılabildiği dillerdir. Değişkenlerin tekrar atanamaması kodların paralel bir şekilde çalışmasında oldukça etkin öneme sahiptir. Bu diller üzerine çalışmanız programlamaya farklı açılardan bakmanızı sağlar. +======= +Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ## Değişken isimlendirme [#degisken-isimlendirme] @@ -177,6 +236,7 @@ let 1a; // Rakam ile başlanılmaz. let my-name; // isimlendirmede '-' karakteri kullanılamaz. ``` +<<<<<<< HEAD ```smart header="Büyük küçük fark önemli" `elma` ve `Elma` iki farklı değişken tanımlar. Bu değişkenler birbirlerinden farklıdır. @@ -184,12 +244,25 @@ let my-name; // isimlendirmede '-' karakteri kullanılamaz. ````smart header="İngilizce harici harfler geçerlidir fakat önerilmez." Herhangi bir dili kullanmak mümkündür. Hatta aşağıdaki gibi resim yazısı bile kullanabilirsiniz: +======= +```smart header="Case matters" +Variables named `apple` and `APPLE` are two different variables. +``` + +````smart header="Non-Latin letters are allowed, but not recommended" +It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let имя = '...'; let 我 = '...'; ``` +<<<<<<< HEAD Teknik olarak bir hata olmamasına ve bu şekilde kullanıma izin verilesine rağmen genel olarak uluslararası gelenek olarak değişkenler İngilizce isimlendirilirler. En basit bir kod parçasının bile önünde uzun bir hayat olabilir. Diğer ülkedeki insanların bu kodları okuması gerekebilir. +======= + +Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it sometime. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```` ````warn header="Saklı tutulan isimler" @@ -237,20 +310,33 @@ Sabit(değişmeyen) tanımlamak için `let` yerine `const` kullanabilirsiniz. const benimDogumGunum = '18.04.1982'; ``` +<<<<<<< HEAD `const` ile tanımlanan değişkenler "constants" (Sabit) olarak tanımlanır. Bunlar değiştirilemezler, değiştirilmek istendiğinde hata alınır: +======= +Variables declared using `const` are called "constants". They cannot be reassigned. An attempt to do so would cause an error: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run const benimDogumGunum = '18.04.1982'; benimDogumGunum = '01.01.2001'; // hata, sabit'in değeri değiştirilemez! ``` +<<<<<<< HEAD Programcı değişkenin değerinin değişmeyeceğine eminse `const` bunu garantiler. Ayrıca bu kodu kullanan herkese bunun garantilendiğini bildirmiş olur. +======= + +When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and communicate that fact to everyone. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ### Sabitlerin Büyük Harf İle İsimlendirilmesi +<<<<<<< HEAD Genel kullanımda sabitler büyük harf ile isimlendirilirler. Eğer birden fazla kelimeden oluşuyorsa "_" ile bu kelimeleri ayırmak mümkündür. +======= +There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Örneğin: @@ -274,35 +360,63 @@ Yararları: Sabitler için ne zaman büyük harf kullanılmalı ne zaman kullanılmamalı ? +<<<<<<< HEAD "Sabit" değeri hiç değişmeyen demek. Fakat bazı değişkenler örneğin kırmızının hexadecimal karşılığı çalışmadan önce bilinirken bazıları çalışma zamanında hesaplanır fakat sonrasında değişmez. Örneğin +======= +Being a "constant" just means that a variable's value never changes. But some constants are known before execution (like a hexadecimal value for red) and some constants are *calculated* in run-time, during the execution, but do not change after their initial assignment. + +For instance: + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js const sayfaYuklenmeSuresi = /* Sayfanın yüklenme süresini tutar. */; ``` +<<<<<<< HEAD `sayfaYuklenmeSuresi` çalışmadan önce değeri bilinmeyen bir değerdir. Bundan dolayı normal isimlendirme kullanılır. Çalıştıktan sonra sadece bir defa tanımlanıp daha da değişmeyen bir değer olduğundan hâlâ "sabit" denilebilir. Diğer bir deyişle büyük harfle yazılan değişken isimleri sadece önceden bilinen değerleri tanımlamak için kullanılır. +======= +The value of `pageLoadTime` is not known before the page load, so it's named normally. But it's still a constant because it doesn't change after the assignment. + +In other words, capital-named constants are only used as aliases for "hard-coded" values. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## İsimlendirmeyi doğru yapmak İsimlendirmeden konuşuyorsak düzgün isimlendirmeyi atlamamak gereklidir. Aslında en önemli konu da budur. Eğer değişken için isim bulamıyorsanız lütfen biraz daha düşünüp mantıklı bir isim bulun. +<<<<<<< HEAD Proje daha karmaşıklaştıkça isimlendirmenin önemi daha da anlaşılır. Değişken isimlerine göre kodun yeni kodlamaya başlayan birisi tarafından mı yoksa tecrübeli birisi tarafından mı yazıldığını anlaşılabilir. Çoğu projede zaman var olan kodların değiştirilmesi, bu kodlardan yeni fonksiyonlar yapılması üzerinedir. Yeni bir şey yapılacağında çoğunlukla eskisinin üzerine yapılır. Eski kodlara baktığınızda değişkenlere bakarak konuyu anlamak daha kolay olacaktır. Lütfen değişkenleri isimlendirirken iyice düşünün sonrasında çok işinize yarayacak. +======= +A variable name should have a clean, obvious meaning, describing the data that it stores. + +Variable naming is one of the most important and complex skills in programming. A glance at variable names can reveal which code was written by a beginner versus an experienced developer. + +In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Birkaç kural şu şekildedir: - İnsan-okuyabilir değişken ismi verin `kullaniciAdi` veya `alisverisSepeti` gibi. - `a`, `b`, `c` gibi kısaltmaları kullanmayın. Tabi ne yaptığınızı kesin olarak biliyorsanız kullanabilirsiniz. +<<<<<<< HEAD - İsimlerin açıklayıcı olmasına önem verin. Örneğin `veri` ve `deger` adindaki değişkenler bir şey ifade etmezler. Tabi eğer kod bloğunda bunların bir anlamı var ise kullanılabilir. - Bazı tanımları kafanızda takımınızın kullandığı şekil ile uyumlu şekilde oturtun. Örneğin siteyi ziyaret eden kişi `kullanici` ise kullanıcı ile olan değişkenleri `anlikKullanici` veya `yeniKullanici` gibi kullanın fakat `yeniZiyaretci` veya `yeniCocuk` gibi kullanmayın. +======= +- Use human-readable names like `userName` or `shoppingCart`. +- Stay away from abbreviations or short names like `a`, `b`, and `c`, unless you know what you're doing. +- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing. +- Agree on terms within your team and in your mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Basit değil mi? Gerçekten öyle, fakat pratikte bu kadar da basit değil. Umarım bunu siz gerçekleştirirsiniz. @@ -323,8 +437,14 @@ Modern JavaScript sıkıştırıcılar ve tarayıcılar kodları oldukça iyi op Verileri saklamak için değişken tanımlayabilirsiniz. Bu işlemi `var` veya `let` veya `const` ile yapabilirsiniz. +<<<<<<< HEAD - `let` -- modern değişken tanımlama. Chrome üzerinde `let` ile değişken tanımlamak istiyorsanız sıkı modda (strict mode) çalışmanız gerekmekte. - `var` -- eski tip değişken tanımlama. Yeni kodlarda çok nadir kullanılır, belki yakında hiç kullanılmayacak. Bu konu ileride `let` ile `var` arasındaki nüans farkı bölümünde incelenecek. - `const` -- bu da `let` gibi fakat değeri değiştirilemez. +======= +- `let` -- is a modern variable declaration. +- `var` -- is an old-school variable declaration. Normally we don't use it at all, but we'll cover subtle differences from `let` in the chapter , just in case you need them. +- `const` -- is like `let`, but the value of the variable can't be changed. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Değişkenler bulundukları yerdeki anlamlarına göre isimlendirilmelidirler. diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index 9c4fe94eb..32ad18d13 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -1,6 +1,14 @@ # Veri Tipleri +<<<<<<< HEAD Bir JavaScript değişkeni her türlü veriyi tutabilir. Önce karakter dizisi (string) atansa da sonra sayısal değer alabilir: +======= +A value in JavaScript is always of a certain type. For example, a string or a number. + +There are eight basic data types in JavaScript. Here, we'll cover them in general and in the next chapters we'll talk about each of them in detail. + +We can put any type in a variable. For example, a variable can at one moment be a string and then store a number: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js // Hata yok @@ -8,11 +16,17 @@ let mesaj = "merhaba"; mesaj = 123456; ``` +<<<<<<< HEAD Bu şekilde olaylara izin veren tipteki dillere "dinamik tip" dil denir. Veri yapıları olsa bile değişkenler bu yapılara bağlı değildir. JavaScript dilinde sekiz farklı veri tipi bulunmaktadır. Şimdilik bu tiplerden bahsedeceğiz gelecek bölümlerde ise daha derinlemesine bu tipleri inceleyeceğiz. ## Number - Sayı +======= +Programming languages that allow such things, such as JavaScript, are called "dynamically typed", meaning that there exist data types, but variables are not bound to any of them. + +## Number +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let s = 123; @@ -42,13 +56,23 @@ Normal sayıların haricinde "özel sayısal değerler" de sayı olarak tanımla alert( "Sayı Değil ( Not a Number) " / 2 ); // NaN, böyle bir bölme işlemi yapılamaz. ``` +<<<<<<< HEAD `NaN` yapışkandır. `NaN` üzerinde yapılacak herhangi bir işlem yeniden `NaN` çıktısı verecektir: +======= + `NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run - alert( "not a number" / 2 + 5 ); // NaN + alert( NaN + 1 ); // NaN + alert( 3 * NaN ); // NaN + alert( "not a number" / 2 - 1 ); // NaN ``` +<<<<<<< HEAD Öyleyse matematiksel işlemlerin herhangi bir yerinde `NaN` alınıyorsa bu hesabın tamamını etkiler. +======= + So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result (there's only one exception to that: `NaN ** 0` is `1`). +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```smart header="Matematiksel hesapların güvenliği" JavaScript üzerinden matematik hesapları yapmak güvenlidir. Her işlemi yapabilirsiniz. 0'a bölme normal harf dizesini bir sayıya bölmeye çalışma vs. @@ -62,29 +86,100 @@ Kodunuzun tamamı hiç durmadan çalışacaktır. En kötü ihtimalle `NaN` sonu JavaScript'te "number" türü, şundan büyük tamsayı değerlerini temsil edemez (253-1) (bu `9007199254740991`), veya daha az -(253-1) negatifler için. Dahili temsillerinden kaynaklanan teknik bir sınırlamadır. +<<<<<<< HEAD Çoğu amaç için bu oldukça yeterlidir, ancak bazen gerçekten büyük sayılara ihtiyacımız olabilir, kriptografi veya mikrosaniye hassasiyetli zaman damgaları için. +======= +## BigInt [#bigint-type] + +In JavaScript, the "number" type cannot safely represent integer values larger than (253-1) (that's `9007199254740991`), or less than -(253-1) for negatives. + +To be really precise, the "number" type can store larger integers (up to 1.7976931348623157 * 10308), but outside of the safe integer range ±(253-1) there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored. + +For example, these two numbers (right above the safe range) are the same: + +```js +console.log(9007199254740991 + 1); // 9007199254740992 +console.log(9007199254740991 + 2); // 9007199254740992 +``` + +So to say, all odd integers greater than (253-1) can't be stored at all in the "number" type. + +For most purposes ±(253-1) range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps. + +`BigInt` type was recently added to the language to represent integers of arbitrary length. + +A `BigInt` value is created by appending `n` to the end of an integer: + +```js +// the "n" at the end means it's a BigInt +const bigInt = 1234567890123456789012345678901234567890n; +``` + +As `BigInt` numbers are rarely needed, we don't cover them here, but devoted them a separate chapter . Read it when you need such big numbers. + +## String +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Son zamanlarda, isteğe bağlı uzunluktaki tam sayıları temsil etmek için dile `BigInt` türü eklendi. Bir tamsayının sonuna `n` eklenerek `BigInt` değeri oluşturulur: ```js +<<<<<<< HEAD // Sondaki "n" bu değerin bir BigInt olduğu anlamına gelir const bigInt = 1234567890123456789012345678901234567890n; +======= +let str = "Hello"; +let str2 = 'Single quotes are ok too'; +let phrase = `can embed another ${str}`; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` `BigInt` sayılarına nadiren ihtiyaç duyulduğundan, onları burada ele almıyoruz, ancak onlara ayrı bir bölüm ayırdık. Bu kadar büyük sayılara ihtiyacınız olduğunda okuyun. +<<<<<<< HEAD ```smart header="Compatibility issues" Şu anda, `BigInt` Firefox/Chrome/Edge/Safari'de destekleniyor, ancak IE'de desteklenmiyor. +======= +Double and single quotes are "simple" quotes. There's practically no difference between them in JavaScript. + +Backticks are "extended functionality" quotes. They allow us to embed variables and expressions into a string by wrapping them in `${…}`, for example: + +```js run +let name = "John"; + +// embed a variable +alert( `Hello, *!*${name}*/!*!` ); // Hello, John! + +// embed an expression +alert( `the result is *!*${1 + 2}*/!*` ); // the result is 3 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` Bir tarayıcının hangi sürümlerinin desteklendiğini öğrenmek için [* MDN * BigInt uyumluluk tablosunu](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) kontrol edebilirsiniz. ## String - Karakter Dizisi +<<<<<<< HEAD JavaScript'te karakter dizileri çift tırnak içerisine alınmalıdır. +======= +We'll cover strings more thoroughly in the chapter . + +```smart header="There is no *character* type." +In some languages, there is a special "character" type for a single character. For example, in the C language and in Java it is called "char". + +In JavaScript, there is no such type. There's only one type: `string`. A string may consist of zero characters (be empty), one character or many of them. +``` + +## Boolean (logical type) + +The boolean type has only two values: `true` and `false`. + +This type is commonly used to store yes/no values: `true` means "yes, correct", and `false` means "no, incorrect". + +For instance: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let str = "Merhaba"; @@ -141,8 +236,12 @@ let yasKontrolu = false; // Yaş kontrolü yapılmadı. Ayrıca karşılaştırma sonuçları boolean verir. +<<<<<<< HEAD ```js run let buyuk = 4 > 1; +======= +The code above states that `age` is unknown. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 alert( buyuk ); // true (cevap görüldüğü gibi "doğru" çıkacaktır.) ``` @@ -174,34 +273,55 @@ Bir diğer özel değer ise `undefined`dır. Kendi başına `null` gibi bir değ Eğer bir değişken tanımlanmış fakat hiçbir değer atanmamışsa tam olarak bu değeri alır. ```js run -let x; +let age; +<<<<<<< HEAD alert(x); // "undefined" çıktısı verir. ``` Teknik olarak `undefined` değerini herhangi bir değişkene atamak mümkündür: +======= +alert(age); // shows "undefined" +``` + +Technically, it is possible to explicitly assign `undefined` to a variable: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run -let x = 123; +let age = 100; -x = undefined; +// change the value to undefined +age = undefined; -alert(x); // "undefined" +alert(age); // "undefined" ``` +<<<<<<< HEAD Fakat bu şekilde tanımlanmasa daha iyi olur. Normalde `null` kullanılarak değişkenin boş veya bilinmeyen olduğu tanımlanır, `undefined` değişkene bir değer atanmış mı? Sorusunu kontrol eder. +======= +...But we don't recommend doing that. Normally, one uses `null` to assign an "empty" or "unknown" value to a variable, while `undefined` is reserved as a default initial value for unassigned things. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Objeler ve Semboller `Obje` özel bir tiptir. Diğer tüm tipler "primitive" yani basit veya ilkel tiplerdir. Bu değişkenler sadece bir şey tutabilirler (karakter dizisi veya sayı). Buna karşılık objeler veri koleksiyonları (collections) veya karmaşık yapılar tutabilirler. konusunda Obje daha derinlemesine incelenecektir. +<<<<<<< HEAD `Symbol` objeler için benzersiz tanımlayıcılar oluşturmak için kullanılır. Bu konuyu objeleri öğrendikten sonra öğrenmek daha iyi olacaktır. ## typeof Operatörü [#type-typeof] `typeof` argüman tipini bildirir. Farklı tipler için farklı akışlarınız varsa bunu kullanabilirsiniz. +======= +All other types are called "primitive" because their values can contain only a single thing (be it a string or a number or whatever). In contrast, objects are used to store collections of data and more complex entities. + +Being that important, objects deserve a special treatment. We'll deal with them later in the chapter , after we learn more about primitives. + +The `symbol` type is used to create unique identifiers for objects. We have to mention it here for the sake of completeness, but also postpone the details till we know objects. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 İki türlü yazımı vardır: +<<<<<<< HEAD 1. Operatör olarak: `typeof x`. 2. Fonksiyonel tipte: `typeof(x)`. @@ -209,12 +329,19 @@ Diğer bir deyişle parantezli de çalışır parantez olmadan da çalışır. S `typeof x`'i çalıştırdığınızda bu fonksiyon karakter dizisi (string) döndürür: +======= +The `typeof` operator returns the type of the operand. It's useful when we want to process values of different types differently or just want to do a quick check. + +A call to `typeof x` returns a string with the type name: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js typeof undefined // "undefined" typeof 0 // "number" +typeof 10n // "bigint" + typeof true // "boolean" typeof "foo" // "string" @@ -236,15 +363,45 @@ typeof alert // "function" (3) Son üç satır diğerlerinden farklıdır. Şu şekilde; +<<<<<<< HEAD 1. `Math` matematiksel operasyonlar için kullanılacak JavaScript dilinde var olan bir objedir. konusunda buna değinilecektir. Burada sadece objenin örneklenmesi için kullanılmıştır. 2. `typeof null` sonucu `"object"` dir. Aslında yanlış. Bu `typeof` fonksiyonunun bilinen bir hatasıdır. Eski versiyonlara uygunluk açısından bu şekliyle bırakılmıştır. Yoksa `null` bir obje değildir. Kendine has bir tiptir. Tekrar söylemek gerekirse bu JavaScript dilinin bir hatasıdır. 3. `typeof alert` fonksiyondur. Çünkü `alert` dilde doğrudan var olan bir fonksiyondur. `Math` ile farklı gördüğünüz gibi. Bir sonraki bölümde fonksiyonlar anlatılacaktır. Fonksiyonlar obje tipine dahildir. Fakat `typeof` bunları farklı yorumlar. Resmi olarak yanlış olsa da pratikte çokça kullanılan bir özelliktir. +======= +1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter . Here, it serves just as an example of an object. +2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof`, coming from very early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own. The behavior of `typeof` is wrong here. +3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That also comes from the early days of JavaScript. Technically, such behavior isn't correct, but can be convenient in practice. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 + +```smart header="The `typeof(x)` syntax" +You may also come across another syntax: `typeof(x)`. It's the same as `typeof x`. + +To put it clear: `typeof` is an operator, not a function. The parentheses here aren't a part of `typeof`. It's the kind of parentheses used for mathematical grouping. +Usually, such parentheses contain a mathematical expression, such as `(2 + 2)`, but here they contain only one argument `(x)`. Syntactically, they allow to avoid a space between the `typeof` operator and its argument, and some people like it. + +Some people prefer `typeof(x)`, although the `typeof x` syntax is much more common. +``` ## Özet +<<<<<<< HEAD Javascript dilinde 8 tane basit tip bulunmaktadır. +======= +There are 8 basic data types in JavaScript. + +- Seven primitive data types: + - `number` for numbers of any kind: integer or floating-point, integers are limited by ±(253-1). + - `bigint` for integer numbers of arbitrary length. + - `string` for strings. A string may have zero or more characters, there's no separate single-character type. + - `boolean` for `true`/`false`. + - `null` for unknown values -- a standalone type that has a single value `null`. + - `undefined` for unassigned values -- a standalone type that has a single value `undefined`. + - `symbol` for unique identifiers. +- And one non-primitive data type: + - `object` for more complex data structures. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 - `number` her türlü sayı için (integer veya floating point) - `bigint` isteğe bağlı uzunluktaki tam sayılar içindir. @@ -255,9 +412,15 @@ Javascript dilinde 8 tane basit tip bulunmaktadır. - `object` daha karmaşık veri yapıları için. - `symbol` eşsiz tanımlamalar için. +<<<<<<< HEAD `typeof` operatörü değişkenin tipini verir. - İki türlü kullanılabilir: `typeof x` veya `typeof(x)` - Geriye karakter dizisi olarak değişkenin tipini döndürür. Örneğin: `"string"` - İstisna olarak `null` kontrolünde `"object"` çıktısı verir. Fakat bu dile ait bir hatadır. Normalde `null` obje değil, kendi başına bir tiptir. +======= +- Usually used as `typeof x`, but `typeof(x)` is also possible. +- Returns a string with the name of the type, like `"string"`. +- For `null` returns `"object"` -- this is an error in the language, it's not actually an object. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bir sonraki bölümde basit tiplere yoğunlaşılacaktır. Bu tipleri kullanmak alışkanlık haline geldiğinde objelere geçilebilir. diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md similarity index 100% rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md similarity index 100% rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/article.md b/1-js/02-first-steps/06-alert-prompt-confirm/article.md similarity index 61% rename from 1-js/02-first-steps/09-alert-prompt-confirm/article.md rename to 1-js/02-first-steps/06-alert-prompt-confirm/article.md index f61104855..af2a3a62d 100644 --- a/1-js/02-first-steps/09-alert-prompt-confirm/article.md +++ b/1-js/02-first-steps/06-alert-prompt-confirm/article.md @@ -1,5 +1,6 @@ # Etkileşim: alarm kutusu, kullanıcıdan bilgi isteme, onaylama +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md Bu bölüm JavaScript'i çevre bağımsız yani tarayıcı veya server farketmeksizin olduğu gibi kapsar. Fakat şu anda eğitimler tarayıcı üzerinde yapılmaktadır. Bundan dolayı en azından kullanıcı arayüzüne dair fonksiyon bilmenizde fayda var. Bu bölümde tarayıcıda çalışan `alert`, `prompt`, `confirm` fonksiyonları incelenecek. @@ -12,6 +13,13 @@ Yazımı: alert(mesaj); ``` Bu ekrana mesaj' değişkenini çıkarır ve önünüze gelen bu pop-up'da "OK" butonuna basmadan kodda bir sonraki adıma geçilmez. +======= +As we'll be using the browser as our demo environment, let's see a couple of functions to interact with the user: `alert`, `prompt` and `confirm`. + +## alert + +This one we've seen already. It shows a message and waits for the user to press "OK". +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md For example: @@ -20,7 +28,11 @@ alert("Merhaba"); ``` Ekrana çıkan küçük pencereye *modal pencere* denir. "Modal" sayfayı kullanan kişinin bu durumda sayfayla iletişime geçemeyeceğini, başka tuşlara basamayacağını sadece bu pencere ile etkileşim kurabileceğini ifade eder. Yani "OK"'e basması beklenir. +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md ## Kullanıcıdan bilgi isteme +======= +The mini-window with the message is called a *modal window*. The word "modal" means that the visitor can't interact with the rest of the page, press other buttons, etc, until they have dealt with the window. In this case -- until they press "OK". +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md Kullanıcıdan bilgi istemek için `prompt` fonksiyonu kullanılır. Bu fonksiyon iki tane argümana ihtiyaç duyar: @@ -30,13 +42,28 @@ result = prompt(başlık[, varsayılan]); ``` Modal penceresi içerisinde bir yazı ve OK/CANCEL butonlarını içerir. +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md `başlık` : Kullanıcıya gösterilecek yazı. +======= +It shows a modal window with a text message, an input field for the visitor, and the buttons OK/Cancel. + +`title` +: The text to show the visitor. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md `default` : Opsiyonel bir ikinci parametre, input alanı için varsayılan değeri içerir. +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md Kullanıcı ekrana çıkan veri girişi kutusuna istediğini yazar ve OK tuşuna basar. İsterse bunu CANCEL tuşuna basarak iptal edebilir. Veya `key:Esc` tuşu da aynı işlevi görür. +======= +```smart header="The square brackets in syntax `[...]`" +The square brackets around `default` in the syntax above denote that the parameter is optional, not required. +``` + +The visitor can type something in the prompt input field and press OK. Then we get that text in the `result`. Or they can cancel the input by pressing Cancel or hitting the `key:Esc` key, then we get `null` as the `result`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md Eğer kullanıcı değer girdiyse bunu dönderir, eğer girmediyse ve o ekrandan `key:Esc` veya CANCEL butonu ile çıktıysa `null` dönderir. @@ -73,7 +100,11 @@ result = confirm(soru); ``` `confirm` fonksiyonu içerisine yazdığımız `soru` ile OK ve CANCEL butonu olan bir pencere çıkarır. +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md Eğer OK'e basıldıysa `true`, CANCEL'a basıldıysa `false` dönderir. +======= +The function `confirm` shows a modal window with a `question` and two buttons: OK and Cancel. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md Örneğin: @@ -91,11 +122,18 @@ Bu bölümde 3 tane tarayıcı tabanlı ve kullanıcı ile etkileşimi sağlayan : Ekranda mesaj gösterir. `prompt` +<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md : Kullanıcıya bir mesaj ile soru sorar. Bir veri giriş kutusu ile cevap alır. Eğer kullanıcı bir yazı yazar ve `OK` tuşuna basarsa yazılan değeri döner. Eğer `CANCEL` veya `key:Esc`'ye basarsa bu durumda tarayıcıya `null` değeri döner. `confirm` : Kullanıcıdan "OK" veya "CANCEL"'a basmasını ister. Eğer kullanıcı "OK" basarsa `true`, CANCEL veya `key:Esc` durumunda false döner. +======= +: shows a message asking the user to input text. It returns the text or, if Cancel button or `key:Esc` is clicked, `null`. + +`confirm` +: shows a message and waits for the user to press "OK" or "Cancel". It returns `true` for OK and `false` for Cancel/`key:Esc`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/06-alert-prompt-confirm/article.md Tüm bu metodlar modaldır. Yani bu kod çalıştığında kullanıcı sayfanın başka bir yeriyle etkileşimde bulunamaz, taki bu pencereler kapatılana kadar. diff --git a/1-js/02-first-steps/06-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md similarity index 67% rename from 1-js/02-first-steps/06-type-conversions/article.md rename to 1-js/02-first-steps/07-type-conversions/article.md index 403b91670..20ca407bb 100644 --- a/1-js/02-first-steps/06-type-conversions/article.md +++ b/1-js/02-first-steps/07-type-conversions/article.md @@ -1,16 +1,30 @@ # Tip Dönüşümleri +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md Çoğu zaman operatörler ve fonksiyonlar otomatik olarak değeri doğru tipe dönüştürürler. Buna "tip dönüştürme" denir. +======= +Most of the time, operators and functions automatically convert the values given to them to the right type. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Örneğin `alert` otomatik olarak verilen tüm değerleri karakter dizisine çevirir ve ekranda gösterir. Matematiksel operatörler ise değerleri sayılara çevirir. Tabi bunun yanında doğrudan tipi sizin tarafınızdan değiştirilmesi gereken değişkenler vardır. +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md ```smart header="Objeler hakkında konuşulmayacak" Bu bölümde objeler hakkında bilgi verilmeyecektir. Önce ilkel tiplerin iyice öğrenilmesi lazım, sonra objelerin öğrenilmesi ve daha sonra bölümünde objelerin dönüştürülmesi öğrenilebilir. ``` ## toString +======= +```smart header="Not talking about objects yet" +In this chapter, we won't cover objects. For now, we'll just be talking about primitives. + +Later, after we learn about objects, in the chapter we'll see how objects fit in. +``` + +## String Conversion +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Bir değeri karakter dizisi olarak kullanmak istiyorsanız toString'i kullanabilirsiniz. @@ -29,9 +43,17 @@ Eğer `false` değeri karakter dizisi dönüştürme işlemine tabi tutarsanız ## Number +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md Sayısal dönüştürme işlemleri matematiksel operasyonlarda otomatik olarak gerçekleşir. Örneğin sayı olmayan iki değer `/` işlemine tutulduğunda: +======= +## Numeric Conversion + +Numeric conversion in mathematical functions and expressions happens automatically. + +For example, when division `/` is applied to non-numbers: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md ```js run alert( "6" / "2" ); // 3, karakterler sayılara dönüştürülür ve işlem öyle yapılır. @@ -61,8 +83,13 @@ Sayısal dönüştürme kuralları: |-------|-------------| |`undefined`|`NaN`| |`null`|`0`| +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md |true ve false | `1` veya `0` | | `string` | Önce başta ve sondaki whitespace'ler silinir. Sonra eğer kalan değerde hiçbir karakter yok ise sonuç `0`. Eğer içerisinde sayısal olmayan bir değer var ise bu durumda `NaN` değeri alınır. | +======= +|true and false | `1` and `0` | +| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. | +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Örnekler: @@ -75,6 +102,7 @@ alert( Number(false) ); // 0 Lütfen `null` ve `undefined`'ın aynı davranmadıklarını bilin. `null` 0 olurken `undefined` `NaN` yani sayı değildir. +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md ````smart header="Ekleme karakteri '+'" Neredeyse tüm matematiksel operasyonlar önce değerleri sayılara çevirmeye çalışır. Eğer bir taraf sayıya çevrilemediyse bu durumda karakter olarak diğeri ile birleştirme işlemi yapılır. @@ -90,6 +118,11 @@ Gördüğünüz gibi sadece bir tarafın karakter olması yeterlidir. Eğer iki ```` ## Boolean +======= +Most mathematical operators also perform such conversion, we'll see that in the next chapter. + +## Boolean Conversion +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Boolean dönüştürme en kolay olanıdır. @@ -120,14 +153,24 @@ alert( Boolean(" ") ); // içerisinde boşluk olan karakter dizisi true olur. ``` ```` +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md ## Özet +======= +## Summary +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Üç tane çok kullanılan tip dönüştürücü bulunmaktadır; karakter dizisine dönüştüren, sayıya dönüştüren ve boolean değere dönüştüren. +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md **`toString`** -- Bir çıktı verildiğinde otomatik olarak bu fonksiyon çalışır. `String(value)` kullanılarak da dönüştürme işlemi yapılabilir. **`Number`** -- Matematiksel operasyonlar otomatik olarak yaparlar. Ayrıca `Number(value)` ile de dönüştürme işlemi yapılabilir. +======= +**`String Conversion`** -- Occurs when we output something. Can be performed with `String(value)`. The conversion to string is usually obvious for primitive values. + +**`Numeric Conversion`** -- Occurs in math operations. Can be performed with `Number(value)`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Dönüştürme işlemi aşağıdaki kuralları kapsar: @@ -137,9 +180,15 @@ Dönüştürme işlemi aşağıdaki kuralları kapsar: |`undefined`|`NaN`| |`null`|`0`| |true / false | `1 / 0` | +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md | `string` | Önce başta ve sondaki whitespace'ler silinir. Sonra eğer kalan değerde hiçbir karakter yok ise sonuç `0`. Eğer içerisinde sayısal olmayan bir değer var ise bu durumda `NaN` değeri alınır. | **`ToBoolean`** -- Lojik operatörlerde otomatik çalışır ayrıca `Boolean(value)` ile de dönüştürme işlemi yapılabilir. +======= +| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. | + +**`Boolean Conversion`** -- Occurs in logical operations. Can be performed with `Boolean(value)`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/07-type-conversions/article.md Kuralları şu şekildedir: diff --git a/1-js/02-first-steps/07-operators/1-increment-order/solution.md b/1-js/02-first-steps/08-operators/1-increment-order/solution.md similarity index 100% rename from 1-js/02-first-steps/07-operators/1-increment-order/solution.md rename to 1-js/02-first-steps/08-operators/1-increment-order/solution.md diff --git a/1-js/02-first-steps/07-operators/1-increment-order/task.md b/1-js/02-first-steps/08-operators/1-increment-order/task.md similarity index 100% rename from 1-js/02-first-steps/07-operators/1-increment-order/task.md rename to 1-js/02-first-steps/08-operators/1-increment-order/task.md diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/solution.md b/1-js/02-first-steps/08-operators/2-assignment-result/solution.md similarity index 100% rename from 1-js/02-first-steps/07-operators/2-assignment-result/solution.md rename to 1-js/02-first-steps/08-operators/2-assignment-result/solution.md diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/task.md b/1-js/02-first-steps/08-operators/2-assignment-result/task.md similarity index 100% rename from 1-js/02-first-steps/07-operators/2-assignment-result/task.md rename to 1-js/02-first-steps/08-operators/2-assignment-result/task.md diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md similarity index 69% rename from 1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md index 7dd0d61c2..7370b66af 100644 --- a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md +++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md @@ -9,11 +9,11 @@ true + false = 1 "$" + 4 + 5 = "$45" "4" - 2 = 2 "4px" - 2 = NaN -7 / 0 = Infinity -" -9 " + 5 = " -9 5" // (3) -" -9 " - 5 = -14 // (4) +" -9 " + 5 = " -9 5" // (3) +" -9 " - 5 = -14 // (4) null + 1 = 1 // (5) undefined + 1 = NaN // (6) +" \t \n" - 2 = -2 // (7) ``` 1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied. @@ -22,3 +22,4 @@ undefined + 1 = NaN // (6) 4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it). 5. `null` becomes `0` after the numeric conversion. 6. `undefined` becomes `NaN` after the numeric conversion. +7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`. diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md similarity index 57% rename from 1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md index 009b59903..d29b6c8dd 100644 --- a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md +++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md @@ -16,11 +16,17 @@ true + false "$" + 4 + 5 "4" - 2 "4px" - 2 +<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md 7 / 0 " -9\n" + 5 " -9\n" - 5 +======= +" -9 " + 5 +" -9 " - 5 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md null + 1 undefined + 1 +" \t \n" - 2 ``` İyice düşünün, bir yere yazın ve sonra sonucunuzu doğru cevap ile karşılaştırın. diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md new file mode 100644 index 000000000..209a0702c --- /dev/null +++ b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md @@ -0,0 +1,32 @@ +The reason is that prompt returns user input as a string. + +So variables have values `"1"` and `"2"` respectively. + +```js run +let a = "1"; // prompt("First number?", 1); +let b = "2"; // prompt("Second number?", 2); + +alert(a + b); // 12 +``` + +What we should do is to convert strings to numbers before `+`. For example, using `Number()` or prepending them with `+`. + +For example, right before `prompt`: + +```js run +let a = +prompt("First number?", 1); +let b = +prompt("Second number?", 2); + +alert(a + b); // 3 +``` + +Or in the `alert`: + +```js run +let a = prompt("First number?", 1); +let b = prompt("Second number?", 2); + +alert(+a + +b); // 3 +``` + +Using both unary and binary `+` in the latest code. Looks funny, doesn't it? diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/task.md b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md new file mode 100644 index 000000000..b3ea4a3a3 --- /dev/null +++ b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md @@ -0,0 +1,18 @@ +importance: 5 + +--- + +# Fix the addition + +Here's a code that asks the user for two numbers and shows their sum. + +It works incorrectly. The output in the example below is `12` (for default prompt values). + +Why? Fix it. The result should be `3`. + +```js run +let a = prompt("First number?", 1); +let b = prompt("Second number?", 2); + +alert(a + b); // 12 +``` diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/08-operators/article.md similarity index 58% rename from 1-js/02-first-steps/07-operators/article.md rename to 1-js/02-first-steps/08-operators/article.md index d27c5a739..b55da35f8 100644 --- a/1-js/02-first-steps/07-operators/article.md +++ b/1-js/02-first-steps/08-operators/article.md @@ -1,8 +1,16 @@ +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md # Operatörler +======= +# Basic operators, maths +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Çoğu operatörü okuldan hatırlarsınız. Toplama `+`, çarpma `*`, çıkarma `-` vs. +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Bu bölümde okulda görmediğiniz aritmetiği işleyeceğiz. +======= +In this chapter, we’ll start with simple operators, then concentrate on JavaScript-specific aspects, not covered by school arithmetic. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ## Tanımlamalar: "unary", "binary", "operand" @@ -30,11 +38,70 @@ Başlamadan önce terminolojiyi öğrenmekte fayda var. Şeklen, iki operatörden konuşuyoruz. `unary` çıkarma ( tek operand işareti değiştirir) ve binary çıkarma ( iki operatör çıkarma ) +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md ## Karakter dizisi birleştirme, binary + JavaScript'te operatörlerin özel durumlarından birisi karakter dizilerinin `+` işareti ile birleştirilebilmesidir. Böylece `+` işaretinin amacının ötesinde bir işlem yapabildiğinin farkına varmış olmalısınız. +======= + Formally, in the examples above we have two different operators that share the same symbol: the negation operator, a unary operator that reverses the sign, and the subtraction operator, a binary operator that subtracts one number from another. + +## Maths + +The following math operations are supported: + +- Addition `+`, +- Subtraction `-`, +- Multiplication `*`, +- Division `/`, +- Remainder `%`, +- Exponentiation `**`. + +The first four are straightforward, while `%` and `**` need a few words about them. + +### Remainder % + +The remainder operator `%`, despite its appearance, is not related to percents. + +The result of `a % b` is the [remainder](https://en.wikipedia.org/wiki/Remainder) of the integer division of `a` by `b`. + +For instance: + +```js run +alert( 5 % 2 ); // 1, the remainder of 5 divided by 2 +alert( 8 % 3 ); // 2, the remainder of 8 divided by 3 +alert( 8 % 4 ); // 0, the remainder of 8 divided by 4 +``` + +### Exponentiation ** + +The exponentiation operator `a ** b` raises `a` to the power of `b`. + +In school maths, we write that as ab. + +For instance: + +```js run +alert( 2 ** 2 ); // 2² = 4 +alert( 2 ** 3 ); // 2³ = 8 +alert( 2 ** 4 ); // 2⁴ = 16 +``` + +Just like in maths, the exponentiation operator is defined for non-integer numbers as well. + +For example, a square root is an exponentiation by ½: + +```js run +alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root) +alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root) +``` + + +## String concatenation with binary + + +Let's meet the features of JavaScript operators that are beyond school arithmetics. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Normalde `+` iki sayıyı toplamaya yaparken eğer bir taraf karakter dizisi ise bu durumda birleştirmeye yarar. @@ -43,7 +110,11 @@ let s = "my" + "string"; alert(s); // mystring ``` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Dikkat edin eğer iki operand'dan birisi karakter dizisi ise diğeri ne olursan olsun karakter dizisine çevrilir. +======= +Note that if any of the operands is a string, then the other one is converted to a string too. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Örneğin: @@ -52,15 +123,36 @@ alert( '1' + 2 ); // "12" alert( 2 + '1' ); // "21" ``` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Gördüğünüz gibi, ilk operand veya ikinci operandın karakter dizisi olması bir şeyi değiştirmiyor. Kural basit, her iki taraftan birisi karakter dizisi ise diğerini de karakter dizisine çevir ve birleştir. Yani `"+"` işlemi hem birleştirme hem de tip değiştirme yapmaktadır. Bu sadece `"+"` operatörüne has bir olaydır. Örneğin çıkarma ve çarpmanın davranışı farklıdır: +======= +See, it doesn't matter whether the first operand is a string or the second one. + +Here's a more complex example: ```js run -alert( 2 - '1' ); // 1 -alert( '6' / '2' ); // 3 +alert(2 + 2 + '1' ); // "41" and not "221" +``` + +Here, operators work one after another. The first `+` sums two numbers, so it returns `4`, then the next `+` adds the string `1` to it, so it's like `4 + '1' = '41'`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md + +```js run +alert('1' + 2 + 2); // "122" and not "14" +``` +Here, the first operand is a string, the compiler treats the other two operands as strings too. The `2` gets concatenated to `'1'`, so it's like `'1' + 2 = "12"` and `"12" + 2 = "122"`. + +The binary `+` is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers. + +Here's the demo for subtraction and division: + +```js run +alert( 6 - '2' ); // 4, converts '2' to a number +alert( '6' / '2' ); // 3, converts both operands to numbers ``` ## Sayısal değer dönüştürme, unary + @@ -90,8 +182,14 @@ Aslında `Number(...)` işlemini yapar. Fakat daha kısa biçimyle. Karakter dizilerini sayılara çevirme gerekliliği sıklıkla önünüze gelir. Örneğin HTML form değerlerini alırken sadece karakter dizisi kullanır. Fakat ya siz bunları toplamak istiyorsanız ? +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Bildiğiniz gibi iki karakter dizisini `+` işareti ile toplarsanız birleştirme işlemi yapar: +======= +The need to convert strings to numbers arises very often. For example, if we are getting values from HTML form fields, they are usually strings. What if we want to sum them? + +The binary plus would add them as strings: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ```js run let elma = "2"; @@ -124,18 +222,31 @@ Neden önce "unary" işlemi gerçekleşiyor da "binary" işlemi gerçekleşmiyor Eğer bir ifade birden fazla operatör içeriyorsa. Bu ifade çalıştırılırken tanımlı *önceliklere* göre çalıştırılır, bir başka ifade ile öncelik sırasına göre çalıştırılır. +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Okuldan hepinizin hatırlayacağı gibi çarpma işlemi toplamadan önce yapılır `1 + 2 * 2`. Aslında *öncelik* tam olarakta budur. Çarpma işlemi toplama işleminden daha *yüksek önceliğe* sahiptir. +======= +If an expression has more than one operator, the execution order is defined by their *precedence*, or, in other words, the default priority order of operators. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Parantez, bu öncelikleri çiğner ve eğer bu *önceliklerden* memnun değilseniz bunları tekrar tanımlamanıza olanak verir. Örneğin `(1 + 2 ) * 2` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md JavaScript dilinde birçok operatör vardır. Her operatörün de bir önceliği. Yüksek öncelik sayısına sahip operatör önce çalışır. Eğer öncelik değerleri eşit ise soldan sağa doğru çalışır. +======= +Parentheses override any precedence, so if we're not satisfied with the default order, we can use them to change it. For example, write `(1 + 2) * 2`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md [öncelik tablosu](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) ( Ezberlemenize gerek yok sadece unary operatörlerin binary olanlara göre daha üstün olduğunu hatırlayın yeter). Yani `+elma + +portakal` işleminde önce unary ile `elma`'nın değerini sayı yapar sonra `portakal`'ın değerini sayı yapar ve en sonunda toplar. +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md +======= +Here's an extract from the [precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones): +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md | Öncelik | Adı | İşareti | |------------|------|------| | ... | ... | ... | +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md | 16 | unary toplama | `+` | | 16 | unary çıkarma | `-` | | 14 | çarpma | `*` | @@ -147,10 +258,30 @@ JavaScript dilinde birçok operatör vardır. Her operatörün de bir önceliği | ... | ... | ... | Görüleceği üzere "unary toplama" `16` ile normal toplama işlemi(binary toplama) `13` ün öncesindedir. +======= +| 14 | unary plus | `+` | +| 14 | unary negation | `-` | +| 13 | exponentiation | `**` | +| 12 | multiplication | `*` | +| 12 | division | `/` | +| 11 | addition | `+` | +| 11 | subtraction | `-` | +| ... | ... | ... | +| 2 | assignment | `=` | +| ... | ... | ... | + +As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ## Atama +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Atama operatörü `=` dir. Öncelik sırasında en altlarda yer almaktadır. Böylece `x = 2 * 2 + 1` ifadesi çalıştığında önce tüm işlemler yapılır ardından "=" çalıştırılarak sonuç `x` içerisinde tutulur. +======= +Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`. + +That's why, when we assign a variable, like `x = 2 * 2 + 1`, the calculations are done first and then the `=` is evaluated, storing the result in `x`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ```js let x = 2 * 2 + 1; @@ -158,11 +289,15 @@ let x = 2 * 2 + 1; alert( x ); // 5 ``` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Zincirleme atama yapmak şu şekilde mümkündür: +======= +### Assignment = returns a value +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md -```js run -let a, b, c; +The fact of `=` being an operator, not a "magical" language construct has an interesting implication. +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md *!* a = b = c = 2 + 2; */!* @@ -175,6 +310,9 @@ Zincirleme atama sağdan sola doğru olur. Önce en sağdaki değişkene değer ````smart header="`\"=\"` operatörü değer döndürür" +======= +All operators in JavaScript return a value. That's obvious for `+` and `-`, but also true for `=`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Operatör her zaman değer döndürür. Toplama `+` veya çarpma için `*` bu çok açıktır. Fakat ya atama ? Atama operatörü de aslında değer döndürür. @@ -193,6 +331,7 @@ alert( a ); // 3 alert( c ); // 0 ``` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Yukarıdaki örnekte, `(a = b+1)` in sonucu `a` ya atandıktan sonra(3) 3'den çıkarmak için kullanılıyor. Komik bi kod değil mi? Nasıl çalıştığını anlamanız lazım, bazen başka kütüphaneler kullandığınızda böyle şeyleri sizin yazmanız beklenmez. Böyle olaylar aslında kodun okunaklılığını azaltır. @@ -204,9 +343,21 @@ Komik bi kod değil mi? Nasıl çalıştığını anlamanız lazım, bazen başk Kalan `%` operatörü yüzde ile alakası olmayan bir operatördür. `a % b` a'nın b'ye bölümünden kalan değeri verir. +======= +In the example above, the result of expression `(a = b + 1)` is the value which was assigned to `a` (that is `3`). It is then used for further evaluations. + +Funny code, isn't it? We should understand how it works, because sometimes we see it in JavaScript libraries. + +Although, please don't write the code like that. Such tricks definitely don't make code clearer or readable. + +### Chaining assignments + +Another interesting feature is the ability to chain assignments: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Örneğin: ```js run +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md alert( 5 % 2 ); // 5'in 2 ile bölümünden kalan 1'dir. alert( 8 % 3 ); // 8'in 3 ile bölümünden kalan 2'dir. alert( 6 % 3 ); // 6'nın 3 ile bölümünden kalan 0'dır. @@ -219,40 +370,108 @@ alert( 6 % 3 ); // 6'nın 3 ile bölümünden kalan 0'dır. Doğal sayı olan `b` değeri için `a ** b` `a`'nın `b` defa kendisiyle çarpılması demektir. Örneğin: +======= +let a, b, c; -```js run -alert( 2 ** 2 ); // 4 (2 * 2) -alert( 2 ** 3 ); // 8 (2 * 2 * 2) -alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2) +*!* +a = b = c = 2 + 2; +*/!* + +alert( a ); // 4 +alert( b ); // 4 +alert( c ); // 4 +``` + +Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value. + +Once again, for the purposes of readability it's better to split such code into few lines: + +```js +c = 2 + 2; +b = c; +a = c; +``` +That's easier to read, especially when eye-scanning the code fast. + +## Modify-in-place +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md + +We often need to apply an operator to a variable and store the new result in that same variable. + +For example: + +```js +let n = 2; +n = n + 5; +n = n * 2; ``` Integer olmayan değerler için de aynı işlemi yapmak mümkün örneğin: +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md ```js run alert( 4 ** (1/2) ); // 2 ( 1/2 üstü karekökü anlamına da gelir.) alert( 8 ** (1/3) ); // 2 (1/3 üstü ise küp kök anlamına gelir. ) +======= +This notation can be shortened using the operators `+=` and `*=`: + +```js run +let n = 2; +n += 5; // now n = 7 (same as n = n + 5) +n *= 2; // now n = 14 (same as n = n * 2) + +alert( n ); // 14 +``` + +Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc. + +Such operators have the same precedence as a normal assignment, so they run after most other calculations: + +```js run +let n = 2; + +n *= 3 + 5; // right part evaluated first, same as n *= 8 + +alert( n ); // 16 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ``` ## Artırma/Azaltma +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Bir sayıyı artırmak veya azlatmak sayısal operasyonlarda önemli sayılabilecek bir düzeydedir. +======= + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Bunun için özel bir operatör yapılmıştır: - **Artırma** `++` değişkenin değerini 1 artırır: ```js run no-beautify +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md let sayac = 2; sayac++; // sayac = sayac + 1 ile aynı, fakat daha kısa alert( sayac ); // 3 +======= + let counter = 2; + counter++; // works the same as counter = counter + 1, but is shorter + alert( counter ); // 3 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ``` - **Azaltma** `--` değişkenin değerini bir azaltır: ```js run no-beautify +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md let sayac = 2; sayac--; // sayac = sayac - 1 ile aynı, fakat daha kısa alert( sayac ); // 1 +======= + let counter = 2; + counter--; // works the same as counter = counter - 1, but is shorter + alert( counter ); // 1 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ``` ```warn @@ -362,6 +581,7 @@ Operatörlerin listesi: - RIGHT SHIFT -- SAĞ KAYDIRMA ( `>>` ) - ZERO-FILL RIGHT SHIFT -- SIFIR DOLDURARAK SAĞ KAYDIRMA ( `>>>` ) +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Bu oparatörler çok nadir kullanılır. Onları anlamak için düşük seviyeli sayı temsiline girmemiz gerekiyor ve özellikle de yakın zamanda onlara ihtiyaç duymayacağımızdan şu anda bunu yapmak uygun olmayacaktır. Merak ediyorsanız, MDN ile ilgili [Bitwise Operators](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) makalesini okuyabilirsiniz. Gerçekten ihtiyacınız olduğunda bunu yapmak daha doğru olacaktır. ## Modify-in-place (Yerinde Değiştir) @@ -397,6 +617,9 @@ n *= 3 + 5; alert( n ); // 16 (önce sağ kısımda işlem yapıldı, n *= 8 gibi) ``` +======= +These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md ## Virgül @@ -419,10 +642,17 @@ Burada, ilk ifade olan `1 + 2` işleme giriyor fakat sonucu çöpe atılıyor. S ```smart header="Virgül operatörünün önceliği çok düşüktür" Unutmamak gerekir ki; virgül operatörü çok düşük bir önceliğe sahiptir, önceliği `=`'den bile daha düşüktür. Bu yüzden yukarıdaki örnekte gördüğümüz gibi parantezler çok önemlidir. +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Parantezler olmadan: `a = 1 + 2, 3 + 4` ifadesinde önce `+` işleme alınır, değerler toplanarak `a = 3, 7` ifadesine çevirilir, ondan sonra atama operatörü `=` ile `a = 7` ataması yapılır, ve sonuç olarak virgülden önceki sayı olan `3` işlenmeyerek yok sayılır. ``` Peki neden son kısım hariç her şeyi yok sayan bir operatöre ihtiyacımız var? +======= +Without them: `a = 1 + 2, 3 + 4` evaluates `+` first, summing the numbers into `a = 3, 7`, then the assignment operator `=` assigns `a = 3`, and the rest is ignored. It's like `(a = 1 + 2), 3 + 4`. +``` + +Why do we need an operator that throws away everything except the last expression? +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md Bazen bizler; bir satırda birkaç işlem yapılan karmaşık yapılarda bu operatörü kullanırız. @@ -435,4 +665,8 @@ for (*!*a = 1, b = 3, c = a * b*/!*; a < 10; a++) { } ``` +<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md Bu tarz numaralar birçok JavaScript frameworklerinde kullanılır. Bu yüzden bunlardan bahsettik. Ama genelde bunlar kodun okunabilirliğini azaltıyorlar. Bu yüzden kullanmadan önce iyi düşünmek gerekir. +======= +Such tricks are used in many JavaScript frameworks. That's why we're mentioning them. But usually they don't improve code readability so we should think well before using them. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/08-operators/article.md diff --git a/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md new file mode 100644 index 000000000..632b1cf4e --- /dev/null +++ b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md @@ -0,0 +1,21 @@ + + +```js no-beautify +5 > 4 → true +"apple" > "pineapple" → false +"2" > "12" → true +undefined == null → true +undefined === null → false +null == "\n0\n" → false +null === +"\n0\n" → false +``` + +Some of the reasons: + +1. Obviously, true. +2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`. +3. Again, dictionary comparison, first char `"2"` is greater than the first char `"1"`. +4. Values `null` and `undefined` equal each other only. +5. Strict equality is strict. Different types from both sides lead to false. +6. Similar to `(4)`, `null` only equals `undefined`. +7. Strict equality of different types. diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md similarity index 100% rename from 1-js/02-first-steps/08-comparison/1-comparison-questions/task.md rename to 1-js/02-first-steps/09-comparison/1-comparison-questions/task.md diff --git a/1-js/02-first-steps/08-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md similarity index 72% rename from 1-js/02-first-steps/08-comparison/article.md rename to 1-js/02-first-steps/09-comparison/article.md index 12aaa8509..67ddf7d3b 100644 --- a/1-js/02-first-steps/08-comparison/article.md +++ b/1-js/02-first-steps/09-comparison/article.md @@ -1,15 +1,34 @@ # Karşılaştırmalar +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md Çoğu karşılaştırma operatörlerini matematik derslerinden biliyorsunuzdur: - Büyüktür/küçüktür: a > b, a < b. - Büyük Eşit/Küçük Eşit: a >= b, a <= b. - Eşitlik kontrolü `a == b` (Dikkat ederseniz tek değil iki tane `'='` işaretinden oluşuyor.Tek olanı `a = b` atama anlamına geliyor). - Eşit değildir matematikte şu şekilde gösteriliyor , JavaScript'te ise eşittir öncesine ünlem işareti olarak kullanabilirsiniz a != b. +======= +We know many comparison operators from maths. + +In JavaScript they are written like this: + +- Greater/less than: a > b, a < b. +- Greater/less than or equals: a >= b, a <= b. +- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment. +- Not equals: In maths the notation is , but in JavaScript it's written as a != b. + +In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities. + +At the end you'll find a good recipe to avoid "JavaScript quirks"-related issues. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md ## Sonuç boolean olacaktır +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md Diğer operatörler gibi bunun sonucu da değer dönecektir. Dönen değer booleandır. +======= +All comparison operators return a boolean value: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md - `true` -- "evet", "dogru" veya "gerçek" demek. - `false` -- "no", "yanlış" veya "yalan" demektir. @@ -51,7 +70,13 @@ alert( 'Bee' > 'Be' ); // doğru ( true ) 4. Karakter dizilerinin sonuna kadar test et. 5. Eğer sonuna kadar tüm karakterler aynıysa uzun olanı daha büyüktür. +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md Örneğin birinci örnekte `'Z' > 'A'` dan büyüktür hemen true sonucu döner. +======= +In the first example above, the comparison `'Z' > 'A'` gets to a result at the first step. + +The second comparison `'Glow'` and `'Glee'` needs more steps as strings are compared character-by-character: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md İkincisinde `"Kum"` ve `"Kan"` karakter karakter karşılaştırılıyor: @@ -78,7 +103,13 @@ alert( '01' == 1 ); // doğru, karakter olan '01' sayıya çevrilerek 1 olmuştu ``` Boolan değerler için `true` `1` olur ve `false` `0` olur. +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md Örneğin: +======= +For boolean values, `true` becomes `1` and `false` becomes `0`. + +For example: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md ```js run alert( true == 1 ); // true ( doğru ) @@ -137,9 +168,16 @@ Sıkı eşitlik kontrolü biraz daha uzun yazıma sahip olsa da hataya yer bıra Daha uç noktalara bakarsanız, +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md `null` ile `undefined` başka değerler ile karşılaştırıldığında aralarında sezgisel olmayan davranışlar görülür. Sıkı eşitlik kontrolü için `===`: Bu değerler farklıdır, çünkü her biri kendine has bir tiptir. +======= +There's a non-intuitive behavior when `null` or `undefined` are compared to other values. + +For a strict equality check `===` +: These values are different, because each of them is a different type. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md ```js run alert( null === undefined ); // false @@ -191,6 +229,7 @@ Bu sonuçları şunlardan dolayı aldık Neden peki bu örnekleri yaptık? Bu şeyleri her zaman hatırlamamıza gerek var mı? Aslında haklısınız bu gibi özelliklere zamanla daha iyi alışabilirsiniz. Fakat bu problemlerden kaçınmanın bir yolu var. +<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md `undefined/null` eşitlik kontrollerinde sıkı eşitlik kontrolü `===` haricinde yaptığınız kontrollere dikkat etmeniz lazım. `>= > < <=` gibi karşılaştırmaları `null/undefined` değeri alabilecek değişkenler ile yapmayın, yaparsanız bile kesinlikle çok dikkatli olun. Eğer bir değişken `null/undefined` gibi değerler alabiliyorsa bunları ayrıca kontrol etmeniz gerekli. @@ -201,3 +240,19 @@ Neden peki bu örnekleri yaptık? Bu şeyleri her zaman hatırlamamıza gerek v - Karşılaştırmalarda eğer farklı tipler kullanılıyorsa bu işlem yapılmadan sayıya çevirilir. ( Eğer sıkı eşittir kullanıyorsanız çevirilmez) - `null` ve `undefined` eşittir. Bu değerler başka hiçbir değere eşit değildirler. - Değeri `null/undefined` olabilen bir değişken ile `>` veya `<` karşılaştırması yaparken dikkat edin. Ayrı bir `null/undefined` kontrolü yapmakta fayda var. +======= +### Avoid problems + +Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there's a solid way to avoid problems with them: + +- Treat any comparison with `undefined/null` except the strict equality `===` with exceptional care. +- Don't use comparisons `>= > < <=` with a variable which may be `null/undefined`, unless you're really sure of what you're doing. If a variable can have these values, check for them separately. + +## Summary + +- Comparison operators return a boolean value. +- Strings are compared letter-by-letter in the "dictionary" order. +- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check). +- The values `null` and `undefined` are equal `==` to themselves and each other, but do not equal any other value. +- Be careful when using comparisons like `>` or `<` with variables that can occasionally be `null/undefined`. Checking for `null/undefined` separately is a good idea. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/09-comparison/article.md diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md index 8a61ee5bf..2b08dcce8 100644 --- a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md +++ b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md @@ -6,9 +6,12 @@ importance: 2 `if..else` bloğu kullanarak "JavaScript\'in resmi ismi nedir?" sorusunu sorun. +<<<<<<< HEAD Eğer kullanıcı "ECMAScript" cevabı verirse "Doğru" diğer türlü "ECMAScript olduğunu bilmiyormusun?" yazısını alarm olarak gösterin. +======= +If the visitor enters "ECMAScript", then output "Right!", otherwise -- output: "You don't know? ECMAScript!" +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ![](ifelse_task2.svg) [demo src="ifelse_task2"] - diff --git a/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/solution.md b/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/solution.md index 4f6668cbe..57ebe10be 100644 --- a/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/solution.md +++ b/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/solution.md @@ -1,6 +1,10 @@ ```js +<<<<<<< HEAD let sonuc = (a + b < 4) ? 'Düşük' : 'Yüksek'; +======= +let result = (a + b < 4) ? 'Below' : 'Over'; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` diff --git a/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/task.md b/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/task.md index d6b74e063..78d5fb4bf 100644 --- a/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/task.md +++ b/1-js/02-first-steps/10-ifelse/5-rewrite-if-question/task.md @@ -4,13 +4,18 @@ importance: 5 # 'if' ile yazılan koşulu '?' çevirin. +<<<<<<< HEAD Aşağıdaki `if` cümlesini "üçlü" operatöre `'?`' olarak yazın: +======= +Rewrite this `if` using the conditional operator `'?'`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js +let result; + if (a + b < 4) { sonuc = 'Düşük'; } else { sonuc = 'Yüksek'; } ``` - diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md index 598b40c68..9d71c8864 100644 --- a/1-js/02-first-steps/10-ifelse/article.md +++ b/1-js/02-first-steps/10-ifelse/article.md @@ -1,11 +1,19 @@ +<<<<<<< HEAD # Koşul operatörleri: if, '?' +======= +# Conditional branching: if, '?' +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bazı durumlarda koşula göre farklı eylemler yapmak isteyebilirsiniz. `"?"` operatörü veya `if` cümlesi bu koşulları kontrol etmenizi sağlar. +<<<<<<< HEAD ## "if" cümlesi +======= +The `if(...)` statement evaluates a condition in parentheses and, if the result is `true`, executes a block of code. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 "if" cümlesi koşulu alır ve kontrol eder sonucunda `true` ise kodu çalıştırır. @@ -69,7 +77,23 @@ if (sonuc) { `if` cümlesi opsiyonel olarak "else" bloğu da içerebilir. Bu eğer `if` parantezi içerisinde yazdığımız kod yanlış ise çalışır. +<<<<<<< HEAD Örneğin: +======= +```js +let cond = (year == 2015); // equality evaluates to true or false + +if (cond) { + ... +} +``` + +## The "else" clause + +The `if` statement may contain an optional `else` block. It executes when the condition is falsy. + +For example: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run let yil = prompt('ECMAScript-2015 standarları hangi yıl yayınlanmıştır?', ''); @@ -183,6 +207,13 @@ alert( mesaj ); aynı `if..else` mantığı gibi +<<<<<<< HEAD +======= +1. The first question mark checks whether `age < 3`. +2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`. +3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`. +4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js @@ -214,6 +245,10 @@ Koşula göre `firma =='Netscape'`, soru işaretinden sonra birinci bölüm veya Sonucu bir değere atanmamıştır. Amaç duruma göre doğrudan kodu çalıştırmak. +<<<<<<< HEAD +======= +**It's not recommended to use the question mark operator in this way.** +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 **Soru işaretinin bu amaç doğrultusunda kullanılması önerilmez.** diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md index 827426e5b..7ddf12925 100644 --- a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md +++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md @@ -9,4 +9,12 @@ alert( alert(1) || 2 || alert(3) ); 2. Bu uyarı ekranından `undefined` döner bundan dolayı ikinci operand çalışır çünkü daha `doğru`'yu bulamadı. 3. İkinci operand `2` `doğru`'dur. Bundan dolayı değer sona erer. Tabi `2` döndüğünde bu defa dışarıda bulunan `alert` fonksiyonu çalışır ve ekranda `2` uyarısı görünür. +<<<<<<< HEAD `3` değeri ekrana çıkmayacaktır çünkü değerlendirme sonuncu operand'a `alert(3)` gelmeden bitmiştir. +======= +1. The first OR `||` evaluates its left operand `alert(1)`. That shows the first message with `1`. +2. The `alert` returns `undefined`, so OR goes on to the second operand searching for a truthy value. +3. The second operand `2` is truthy, so the execution is halted, `2` is returned and then shown by the outer alert. + +There will be no `3`, because the evaluation does not reach `alert(3)`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md index 0370e5b1f..ba4efa824 100644 --- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md +++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md @@ -1,5 +1,11 @@ Cevap: `null`. Çünkü `null` bu değerlendirme sıralamasındaki ilk `yanlış` değer. ```js run +<<<<<<< HEAD alert( 1 && null && 2 ); -``` \ No newline at end of file +``` +======= +alert(1 && null && 2); +``` + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md index d822a2c62..c1aa840e0 100644 --- a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md +++ b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md @@ -4,4 +4,10 @@ importance: 3 # Aralık kontrolü +<<<<<<< HEAD `yaş`'ı 14 ile 90 arası olanları kontrol eden `if` koşulunu yazınız? Not: 14 ve 90 dahil. +======= +Write an `if` condition to check that `age` is between `14` and `90` inclusively. + +"Inclusively" means that `age` can reach the edges `14` or `90`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md index 664ac0a7a..6afb12ef2 100644 --- a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md +++ b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md @@ -4,6 +4,10 @@ importance: 3 # Aralığın dışındaki değerleri yazınız. +<<<<<<< HEAD `yaş`'ı 14 ile 90 arasında olmayanları bulan `if` koşulunu yazınız. Not: 14 ve 90 dahil. +======= +Write an `if` condition to check that `age` is NOT between `14` and `90` inclusively. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bunu `!` kullanarak ve kullanmayarak iki şekilde yapın. diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md index b535650ec..604606259 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md @@ -3,19 +3,19 @@ ```js run demo let userName = prompt("Who's there?", ''); -if (userName == 'Admin') { +if (userName === 'Admin') { let pass = prompt('Password?', ''); - if (pass == 'TheMaster') { + if (pass === 'TheMaster') { alert( 'Welcome!' ); - } else if (pass == '' || pass == null) { - alert( 'Canceled.' ); + } else if (pass === '' || pass === null) { + alert( 'Canceled' ); } else { alert( 'Wrong password' ); } -} else if (userName == '' || userName == null) { +} else if (userName === '' || userName === null) { alert( 'Canceled' ); } else { alert( "I don't know you" ); diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/task.md b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md index 0728efad1..290a52642 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/task.md +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md @@ -6,13 +6,13 @@ importance: 3 Write the code which asks for a login with `prompt`. -If the visitor enters `"Admin"`, then `prompt` for a password, if the input is an empty line or `key:Esc` -- show "Canceled.", if it's another string -- then show "I don't know you". +If the visitor enters `"Admin"`, then `prompt` for a password, if the input is an empty line or `key:Esc` -- show "Canceled", if it's another string -- then show "I don't know you". The password is checked as follows: - If it equals "TheMaster", then show "Welcome!", - Another string -- show "Wrong password", -- For an empty string or cancelled input, show "Canceled." +- For an empty string or cancelled input, show "Canceled" The schema: diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 8462912dd..f291926ec 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -1,6 +1,10 @@ # Mantıksal Operatörler +<<<<<<< HEAD JavaScript dilinde üç tane mantıksal operatör bulunmaktadır: `||` (OR - VEYA ), `&&`(AND - VE ), `!` (NOT - DEĞİL ) +======= +There are four logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT), `??` (Nullish Coalescing). Here we cover the first three, the `??` operator is in the next article. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Mantıksal operatörler olarak adlandırılsalar bile, her tipteki değer için uygulanabilirler. Sadece boolean ( doğru-yanlış) değerleri için değil. Sonuçta her tipte olabilir. @@ -64,7 +68,11 @@ if (saat < 10 || saat > 18 || haftaSonu) { } ``` +<<<<<<< HEAD ## VEYA ilk doğru değeri arar +======= +## OR "||" finds the first truthy value [#or-finds-the-first-truthy-value] +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Yukarıda belirtilen mantık klasik mantıktır. JavaScript'in "ekstra" özelliklerine bakılacak olursa @@ -85,6 +93,7 @@ VEYA `"||"` operatörü şunları yapar: Eğer VEYA zincirinde bir tane doğru bulunursa o an dönülür. Eğer bulunamazsa sonuncusu döner. +<<<<<<< HEAD Örneğin: ```js run @@ -94,12 +103,26 @@ alert( true || 'önemsiz' ); // (true doğru) alert( null || 1 ); // 1 (1 tek doğru veri) alert( null || 0 || 1 ); // 1 (1 tek doğru veri) alert( undefined || null || 0 ); // 0 (Hepsi yanlış sonuncusunu döner) +======= +In other words, a chain of OR `||` returns the first truthy value or the last one if no truthy value is found. + +For instance: + +```js run +alert( 1 || 0 ); // 1 (1 is truthy) + +alert( null || 1 ); // 1 (1 is the first truthy value) +alert( null || 0 || 1 ); // 1 (the first truthy value) + +alert( undefined || null || 0 ); // 0 (all falsy, returns the last value) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` Bu klasik "boolean" VEYA tanımını aşarak ilginç kullanımlara neden olmaktadır. 1. **Değişken veya ifadeler dizisinde ilk doğru(true) değeri bulmak için** +<<<<<<< HEAD Düşünün bir diziniz var ve içinde `null/undefined` değerler barındırmakta. Siz ilk veriyi bulduğunuzda döndürmek istiyorsunuz. Bunun için `||` kullanabilirsiniz: @@ -150,6 +173,42 @@ Bu klasik "boolean" VEYA tanımını aşarak ilginç kullanımlara neden olmakta Çoğu zaman normal `if` yapısını kullanmanız daha iyidir çünkü kod daha anlaşılır olur. Fakat bazen kısa yoldan `if` yapmakta işinize yarayabilir. +======= + For instance, we have `firstName`, `lastName` and `nickName` variables, all optional (i.e. can be undefined or have falsy values). + + Let's use OR `||` to choose the one that has the data and show it (or `"Anonymous"` if nothing set): + + ```js run + let firstName = ""; + let lastName = ""; + let nickName = "SuperCoder"; + + *!* + alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder + */!* + ``` + + If all variables were falsy, `"Anonymous"` would show up. + +2. **Short-circuit evaluation.** + + Another feature of OR `||` operator is the so-called "short-circuit" evaluation. + + It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument. + + The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call. + + In the example below, only the second message is printed: + + ```js run no-beautify + *!*true*/!* || alert("not printed"); + *!*false*/!* || alert("printed"); + ``` + + In the first line, the OR `||` operator stops the evaluation immediately upon seeing `true`, so the `alert` isn't run. + + Sometimes, people use this feature to execute commands only if the condition on the left part is falsy. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## && (AND - VE ) @@ -188,7 +247,20 @@ if (1 && 0) { // true && false şeklinde değerlendirilmiştir. ## VE ilk `yanlış` değeri görür +<<<<<<< HEAD Aşağıda 3 tane AND işlemine sokulmuş değer bulunmaktadır: +======= +```js run +if (1 && 0) { // evaluated as true && false + alert( "won't work, because the result is falsy" ); +} +``` + + +## AND "&&" finds the first falsy value + +Given multiple AND'ed values: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js sonuc = deger1 && deger2 && deger3; @@ -240,7 +312,12 @@ alert( 5 || 1 && 0 ); // 5 ```` VEYA'da olduğu gibi VE'de de operatör bazen `if` yerine kullanılabilir. +<<<<<<< HEAD Örneğin: +======= +````warn header="Don't replace `if` with `||` or `&&`" +Sometimes, people use the AND `&&` operator as a "shorter way to write `if`". +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run @@ -256,13 +333,22 @@ Aslında aşağıdaki ile benzerdir: ```js run let x = 1; +<<<<<<< HEAD if (x > 0) { alert( 'Sıfırdan büyük!' ); } +======= +if (x > 0) alert( 'Greater than zero!' ); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` `&&` ile yazılan çeşidi daha kısa gibi görünse de aslında `if` ile yazılanın daha okunabilir olduğu açıktır. +<<<<<<< HEAD Bundan dolayı her yapıyı amacına göre kullanmanız önerilir. Eğer `if` kullanmak istiyorsanız `if` yazarak kullanın. Eğer VE kullanmak istiyorsnaız `&&` yazarak kullanın. +======= +Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want `if` and use `&&` if we want AND. +```` +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md new file mode 100644 index 000000000..0b2f092ab --- /dev/null +++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md @@ -0,0 +1,169 @@ +# Nullish coalescing operator '??' + +[recent browser="new"] + +The nullish coalescing operator is written as two question marks `??`. + +As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`. + +The result of `a ?? b` is: +- if `a` is defined, then `a`, +- if `a` isn't defined, then `b`. + +In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one. + +The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two. + +We can rewrite `result = a ?? b` using the operators that we already know, like this: + +```js +result = (a !== null && a !== undefined) ? a : b; +``` + +Now it should be absolutely clear what `??` does. Let's see where it helps. + +The common use case for `??` is to provide a default value. + +For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`: + +```js run +let user; + +alert(user ?? "Anonymous"); // Anonymous (user is undefined) +``` + +Here's the example with `user` assigned to a name: + +```js run +let user = "John"; + +alert(user ?? "Anonymous"); // John (user is not null/undefined) +``` + +We can also use a sequence of `??` to select the first value from a list that isn't `null/undefined`. + +Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values. + +We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`. + +Let's use the `??` operator for that: + +```js run +let firstName = null; +let lastName = null; +let nickName = "Supercoder"; + +// shows the first defined value: +*!* +alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder +*/!* +``` + +## Comparison with || + +The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value). + +For example, in the code above we could replace `??` with `||` and still get the same result: + +```js run +let firstName = null; +let lastName = null; +let nickName = "Supercoder"; + +// shows the first truthy value: +*!* +alert(firstName || lastName || nickName || "Anonymous"); // Supercoder +*/!* +``` + +Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time. + +On the other hand, the nullish coalescing operator `??` was added to JavaScript only recently, and the reason for that was that people weren't quite happy with `||`. + +The important difference between them is that: +- `||` returns the first *truthy* value. +- `??` returns the first *defined* value. + +In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result. + +In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set. + +For example, consider this: + +```js run +let height = 0; + +alert(height || 100); // 100 +alert(height ?? 100); // 0 +``` + +- The `height || 100` checks `height` for being a falsy value, and it's `0`, falsy indeed. + - so the result of `||` is the second argument, `100`. +- The `height ?? 100` checks `height` for being `null/undefined`, and it's not, + - so the result is `height` "as is", that is `0`. + +In practice, the zero height is often a valid value, that shouldn't be replaced with the default. So `??` does just the right thing. + +## Precedence + +The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). + +That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`. + +So we may need to add parentheses in expressions like this: + +```js run +let height = null; +let width = null; + +// important: use parentheses +let area = (height ?? 100) * (width ?? 50); + +alert(area); // 5000 +``` + +Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results. + +```js +// without parentheses +let area = height ?? 100 * width ?? 50; + +// ...works this way (not what we want): +let area = height ?? (100 * width) ?? 50; +``` + +### Using ?? with && or || + +Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses. + +The code below triggers a syntax error: + +```js run +let x = 1 && 2 ?? 3; // Syntax error +``` + +The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from `||` to `??`. + +Use explicit parentheses to work around it: + +```js run +*!* +let x = (1 && 2) ?? 3; // Works +*/!* + +alert(x); // 2 +``` + +## Summary + +- The nullish coalescing operator `??` provides a short way to choose the first "defined" value from a list. + + It's used to assign default values to variables: + + ```js + // set height=100, if height is null or undefined + height = height ?? 100; + ``` + +- The operator `??` has a very low precedence, only a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression. +- It's forbidden to use it with `||` or `&&` without explicit parentheses. diff --git a/1-js/02-first-steps/12-while-for/1-loop-last-value/solution.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/1-loop-last-value/solution.md rename to 1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md diff --git a/1-js/02-first-steps/12-while-for/1-loop-last-value/task.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/1-loop-last-value/task.md rename to 1-js/02-first-steps/13-while-for/1-loop-last-value/task.md diff --git a/1-js/02-first-steps/12-while-for/2-which-value-while/solution.md b/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/2-which-value-while/solution.md rename to 1-js/02-first-steps/13-while-for/2-which-value-while/solution.md diff --git a/1-js/02-first-steps/12-while-for/2-which-value-while/task.md b/1-js/02-first-steps/13-while-for/2-which-value-while/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/2-which-value-while/task.md rename to 1-js/02-first-steps/13-while-for/2-which-value-while/task.md diff --git a/1-js/02-first-steps/12-while-for/3-which-value-for/solution.md b/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/3-which-value-for/solution.md rename to 1-js/02-first-steps/13-while-for/3-which-value-for/solution.md diff --git a/1-js/02-first-steps/12-while-for/3-which-value-for/task.md b/1-js/02-first-steps/13-while-for/3-which-value-for/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/3-which-value-for/task.md rename to 1-js/02-first-steps/13-while-for/3-which-value-for/task.md diff --git a/1-js/02-first-steps/12-while-for/4-for-even/solution.md b/1-js/02-first-steps/13-while-for/4-for-even/solution.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/4-for-even/solution.md rename to 1-js/02-first-steps/13-while-for/4-for-even/solution.md diff --git a/1-js/02-first-steps/12-while-for/4-for-even/task.md b/1-js/02-first-steps/13-while-for/4-for-even/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/4-for-even/task.md rename to 1-js/02-first-steps/13-while-for/4-for-even/task.md diff --git a/1-js/02-first-steps/12-while-for/5-replace-for-while/solution.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/5-replace-for-while/solution.md rename to 1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md diff --git a/1-js/02-first-steps/12-while-for/5-replace-for-while/task.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/5-replace-for-while/task.md rename to 1-js/02-first-steps/13-while-for/5-replace-for-while/task.md diff --git a/1-js/02-first-steps/12-while-for/6-repeat-until-correct/solution.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md similarity index 58% rename from 1-js/02-first-steps/12-while-for/6-repeat-until-correct/solution.md rename to 1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md index f28ecc8b3..d2459d2cc 100644 --- a/1-js/02-first-steps/12-while-for/6-repeat-until-correct/solution.md +++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md @@ -9,8 +9,13 @@ do { `do..while` ile her iki koşul da doğru olana kadar kontrol edin: +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/6-repeat-until-correct/solution.md 1. `sayi <=100` -- girilen değerin hala `100` den büyük olmadığını gösterir. 1. `&& sayi` `sayi` `null` veya boş bir değer olduğunda `false` dönderir. Tabi `while` döngüsü de burada sona erer. +======= +1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`. +2. The check `&& num` is false when `num` is `null` or an empty string. Then the `while` loop stops too. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md NOT: Eğer `sayi` `null` ise ` num<=100` `true` olur. Yani ikinci kontrol olmadan kullanıcı IPTAL tuşuna bassa bile döngü durmayacaktır. İki koşul da gereklidir. diff --git a/1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md rename to 1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md diff --git a/1-js/02-first-steps/12-while-for/7-list-primes/solution.md b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md similarity index 53% rename from 1-js/02-first-steps/12-while-for/7-list-primes/solution.md rename to 1-js/02-first-steps/13-while-for/7-list-primes/solution.md index 9ff0663d7..b4b64b6fa 100644 --- a/1-js/02-first-steps/12-while-for/7-list-primes/solution.md +++ b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md @@ -26,4 +26,4 @@ for (let i = 2; i <= n; i++) { // for each i... } ``` -There's a lot of space to opimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc. +There's a lot of space to optimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc. diff --git a/1-js/02-first-steps/12-while-for/7-list-primes/task.md b/1-js/02-first-steps/13-while-for/7-list-primes/task.md similarity index 100% rename from 1-js/02-first-steps/12-while-for/7-list-primes/task.md rename to 1-js/02-first-steps/13-while-for/7-list-primes/task.md diff --git a/1-js/02-first-steps/12-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md similarity index 67% rename from 1-js/02-first-steps/12-while-for/article.md rename to 1-js/02-first-steps/13-while-for/article.md index 16a2aff7b..4d7f2d790 100644 --- a/1-js/02-first-steps/12-while-for/article.md +++ b/1-js/02-first-steps/13-while-for/article.md @@ -6,7 +6,24 @@ *Döngü* aynı kod parçacığının birden fazla defa çalıştırılmasına denir. +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md ## "while" döngüsü +======= +```smart header="The for..of and for..in loops" +A small announcement for advanced readers. + +This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`. + +If you came to this article searching for other types of loops, here are the pointers: + +- See [for..in](info:object#forin) to loop over object properties. +- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects. + +Otherwise, please read on. +``` + +## The "while" loop +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md `while` döngüsü aşağıdaki gibi bir yazıma sahiptir: @@ -17,7 +34,11 @@ while (koşul) { } ``` +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md `koşul` `doğru` iken(while), `döngü gövdesinde` bulunan kod çalıştırılır. +======= +While the `condition` is truthy, the `code` from the loop body is executed. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md Örneğin, aşağıdaki kod `i < 3` `iken` çalışır. @@ -82,7 +103,11 @@ Bu şekilde döngü yazımı çok nadir olarak kullanılır. Kullanılmasının ## "for" döngüsü +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md `for` döngüsü en fazla kullanılan döngüdür. +======= +The `for` loop is more complex, but it's also the most commonly used loop. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md Aşağıdaki şekilde kullanıma sahiptir: @@ -107,7 +132,18 @@ Bölüm bölüm inceleyecek olursak | adım | `i++` | Gövdenin tekerrür etmesinden sonra fakat koşuldan önce çalışır | | gövde | `alert(i)` | koşul doğru olduğu sürece durmadan çalışır | +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md Genel döngü algoritması aşağıdaki gibidir: +======= +| part | | | +|-------|----------|----------------------------------------------------------------------------| +| begin | `let i = 0` | Executes once upon entering the loop. | +| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. | +| body | `alert(i)`| Runs again and again while the condition is truthy. | +| step| `i++` | Executes after the body on each iteration. | + +The general loop algorithm works like this: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ``` Çalışmaya başlar @@ -117,9 +153,15 @@ Genel döngü algoritması aşağıdaki gibidir: → ... ``` +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md Eğer döngüleri yeni görüyorsanız, belki geri dönüp bu olanları sırasıyla kağıda yazarak takip ederseniz sizin için daha iyi olacaktır. Yukarıdaki kodda tam olarak ne oluyor peki: +======= +That is, `begin` executes once, and then it iterates: after each `condition` test, `body` and `step` are executed. + +If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ```js @@ -156,12 +198,15 @@ for (i = 0; i < 3; i++) { // var olan değişkeni kullan alert(i); // 3, görünür halde çünkü değişken döngünün dışında tanımlandı. ``` - ```` +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md ### Bazı bölümlerin pas geçilmesi `for` döngüsünün her bölümü pas geçilebilir. +======= +### Skipping parts +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md Örneğin `başlangıç` bölümüne ihtiyaç yoksa pas geçilebilir. @@ -202,8 +247,13 @@ Fakat bazı durumlarda bu döngü `kırılabilir` ( break ). Örneğin, kullanıcıdan bir dizi sayı girmesini istediniz eğer boş bir değer girerse döngüyü kırabilirsiniz. +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md ```js let toplam = 0; +======= +```js run +let sum = 0; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md while (true) { @@ -245,7 +295,7 @@ for (let i = 0; i < 10; i++) { Tek değerler gösteren döngü aşağıdaki gibi de yazılabilir: -```js +```js run for (let i = 0; i < 10; i++) { if (i % 2) { @@ -258,6 +308,10 @@ Teknik açısından birbiri ile aynıdırlar. Her zaman `continue` bloğunun yer Tabi bunun yan etkisi döngü gövdesi içinde bir tane daha `if` kullanarak okunabilirliği düşürmektir. +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md +======= +But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ```` ````warn header=" 'if' yerine '?' kullanılıyorsa sağ tarafa 'continue/break' yazılmaz." @@ -273,19 +327,28 @@ if (i > 5) { ``` Yukarıdaki döngü `?` ile yazılacak olursa: - ```js no-beautify (i > 5) ? alert(i) : *!*continue*/!*; // `continue` burada kullanılamaz!!! ``` +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md ... sonrasında çalışmayı durdurur. Böyle kodlar yazım hatası verir. Bu da `'?'` işaretini `if` yerine kullanmamak için ayrı bir neden. +======= +...it stops working: there's a syntax error. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ```` ## break/continue için etiket tanımlanması ( Label ) +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md +======= +Sometimes we need to break out from multiple nested loops at once. + +For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(2,2)`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md Bazen birden fazla döngü içinden tek bir break ile çıkılma ihtiyacı duyulabilir. Örneğin aşağıdaki kodda döngü `i` ve `j` kordinatlarını ekranda gösterir: @@ -296,8 +359,12 @@ for (let i = 0; i < 3; i++) { let deger = prompt(`Kordinattaki değer (${i},${j})`, ''); +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md // Burada döngüden çıkmak istersem ne yapmalıyım? +======= + // what if we want to exit from here to Done (below)? +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md } } @@ -306,10 +373,17 @@ alert('Bitti!'); Eğer kullanıcı iptale basarsa döngü iptal edilmelidir. +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md Normalde içerideki döngü için `deger`'e değer atadıktan sonra duruma göre içteki döngü kırılabilir. Fakat bu yeterli değildir. Bu gibi durumlarda `Labels` veya `etiket` ile sorun çözülebilir. *etiket* döngüden önce bir kolon ile döngüyü tanımlamak için kullanılır. +======= +The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue! + +A *label* is an identifier with a colon before a loop: + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ```js etiketAdi: for (...) { ... @@ -333,7 +407,12 @@ Aşağıdaki gibi: // değer ile bir şeyler yap. } } +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md alert('Bitti!'); +======= + +alert('Done!'); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ``` Yukarıdaki kodda `break ust_dongu` adımına gelirse üste doğru `ust_dongu` aranır ve bulunduğu yerde kırılır. @@ -349,6 +428,7 @@ for (let i = 0; i < 3; i++) { ... } `continue` talimatı da etiket ile kullanılabilir. Bu durumda etiketin yazılı olduğu yere atlar. +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md ````warn header="Etiketler \"goto\" değildir." Etiketler ile kodun herhangi bir yerine atlamak mümkün değildir. @@ -356,10 +436,36 @@ Etiketler ile kodun herhangi bir yerine atlamak mümkün değildir. Örneğin aşağıdaki kod çalışmaz. ```js break etiket; // etikete atlar değil mi?. +======= +````warn header="Labels do not allow to \"jump\" anywhere" +Labels do not allow us to jump into an arbitrary place in the code. + +For example, it is impossible to do this: + +```js +break label; // jump to the label below (doesn't work) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md etiket: for (...) ``` +<<<<<<< HEAD:1-js/02-first-steps/12-while-for/article.md `break/continue` sadece döngünün içerisinde çalışabilir, ve doğal olarak etiketler de üst tarafa yazılmalıdırlar. +======= + +A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.: + +```js +label: { + // ... + break label; // works + // ... +} +``` + +...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above. + +A `continue` is only possible from inside a loop. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/13-while-for/article.md ```` ## Özet diff --git a/1-js/02-first-steps/14-function-basics/function_basics.png b/1-js/02-first-steps/14-function-basics/function_basics.png deleted file mode 100644 index f5e6f9418..000000000 Binary files a/1-js/02-first-steps/14-function-basics/function_basics.png and /dev/null differ diff --git a/1-js/02-first-steps/14-function-basics/function_basics@2x.png b/1-js/02-first-steps/14-function-basics/function_basics@2x.png deleted file mode 100644 index c31b2636a..000000000 Binary files a/1-js/02-first-steps/14-function-basics/function_basics@2x.png and /dev/null differ diff --git a/1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/solution.md b/1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/solution.md similarity index 100% rename from 1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/solution.md rename to 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/solution.md diff --git a/1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/task.md b/1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/task.md similarity index 100% rename from 1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/task.md rename to 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/task.md diff --git a/1-js/02-first-steps/13-switch/2-rewrite-if-switch/solution.md b/1-js/02-first-steps/14-switch/2-rewrite-if-switch/solution.md similarity index 100% rename from 1-js/02-first-steps/13-switch/2-rewrite-if-switch/solution.md rename to 1-js/02-first-steps/14-switch/2-rewrite-if-switch/solution.md diff --git a/1-js/02-first-steps/13-switch/2-rewrite-if-switch/task.md b/1-js/02-first-steps/14-switch/2-rewrite-if-switch/task.md similarity index 100% rename from 1-js/02-first-steps/13-switch/2-rewrite-if-switch/task.md rename to 1-js/02-first-steps/14-switch/2-rewrite-if-switch/task.md diff --git a/1-js/02-first-steps/13-switch/article.md b/1-js/02-first-steps/14-switch/article.md similarity index 84% rename from 1-js/02-first-steps/13-switch/article.md rename to 1-js/02-first-steps/14-switch/article.md index c66e0ca38..0d05c8a2b 100644 --- a/1-js/02-first-steps/13-switch/article.md +++ b/1-js/02-first-steps/14-switch/article.md @@ -75,7 +75,12 @@ switch (a) { case 4: alert( 'Kesinlikle!' ); case 5: +<<<<<<< HEAD:1-js/02-first-steps/13-switch/article.md alert( 'Çok büyük' ); +======= + alert( 'Too big' ); + break; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/14-switch/article.md default: alert( "Böyle bir değeri bilmiyorum." ); */!* @@ -117,7 +122,7 @@ Gövdesinde aynı kodu çalıştıran birden fazla `case` gruplanabilir. Örneğin, diyelim ki `case 3` ve `case 5` için aynı kodu çalıştırmak istedik: ```js run no-beautify -let a = 2 + 2; +let a = 3; switch (a) { case 4: @@ -125,7 +130,11 @@ switch (a) { break; *!* +<<<<<<< HEAD:1-js/02-first-steps/13-switch/article.md case 3: // (*) iki "case" gruplandı +======= + case 3: // (*) grouped two cases +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/14-switch/article.md case 5: alert('Yanlış!'); alert("Neden matematik dersi almıyorsun?"); @@ -139,8 +148,12 @@ switch (a) { `3` ve `5` aynı mesajı gösterecek. +<<<<<<< HEAD:1-js/02-first-steps/13-switch/article.md Aslında "gruplama" `switch/case`'in break olmadan çalıştırılmış halidir. Yan etki de denebilir. `case 3` `(*)`'dan başlar ve arada `break` olmadığından `case 5` ile devam eder. +======= +The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/14-switch/article.md ## Tipler önemlidir diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md new file mode 100644 index 000000000..e3a0df77c --- /dev/null +++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md @@ -0,0 +1,3 @@ +No difference! + +In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy. \ No newline at end of file diff --git a/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md similarity index 100% rename from 1-js/02-first-steps/14-function-basics/1-if-else-required/task.md rename to 1-js/02-first-steps/15-function-basics/1-if-else-required/task.md diff --git a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md similarity index 51% rename from 1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md rename to 1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md index 6dbbdbe5b..e7449069e 100644 --- a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md +++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md @@ -14,4 +14,8 @@ function yasKontrolu(yas) { } ``` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md `age > 18` etrafındaki parantezler aslında zorunlu değildir. Fakat okunurluğu artırır. +======= +Note that the parentheses around `age > 18` are not required here. They exist for better readability. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md diff --git a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md similarity index 66% rename from 1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md rename to 1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md index a0dfadfb0..a7b81752d 100644 --- a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md +++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md @@ -13,7 +13,11 @@ function yasKontrolu(yas) { if (yas > 18) { return true; } else { +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md return confirm('Ebeveynlerin izin verdi mi?'); +======= + return confirm('Did parents allow you?'); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md } } ``` diff --git a/1-js/02-first-steps/14-function-basics/3-min/solution.md b/1-js/02-first-steps/15-function-basics/3-min/solution.md similarity index 100% rename from 1-js/02-first-steps/14-function-basics/3-min/solution.md rename to 1-js/02-first-steps/15-function-basics/3-min/solution.md diff --git a/1-js/02-first-steps/14-function-basics/3-min/task.md b/1-js/02-first-steps/15-function-basics/3-min/task.md similarity index 100% rename from 1-js/02-first-steps/14-function-basics/3-min/task.md rename to 1-js/02-first-steps/15-function-basics/3-min/task.md diff --git a/1-js/02-first-steps/14-function-basics/4-pow/solution.md b/1-js/02-first-steps/15-function-basics/4-pow/solution.md similarity index 55% rename from 1-js/02-first-steps/14-function-basics/4-pow/solution.md rename to 1-js/02-first-steps/15-function-basics/4-pow/solution.md index d4d152114..c502258f0 100644 --- a/1-js/02-first-steps/14-function-basics/4-pow/solution.md +++ b/1-js/02-first-steps/15-function-basics/4-pow/solution.md @@ -13,10 +13,14 @@ function usAl(x, n) { let x = prompt("x?", ''); let n = prompt("n?", ''); +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/4-pow/solution.md if (n <= 1) { alert(` ${n} için üs alınamamktadır. 0'dan büyük doğal sayı kullanınız.`); +======= +if (n < 1) { + alert(`Power ${n} is not supported, use a positive integer`); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/4-pow/solution.md } else { alert( usAl(x, n) ); } ``` - diff --git a/1-js/02-first-steps/14-function-basics/4-pow/task.md b/1-js/02-first-steps/15-function-basics/4-pow/task.md similarity index 100% rename from 1-js/02-first-steps/14-function-basics/4-pow/task.md rename to 1-js/02-first-steps/15-function-basics/4-pow/task.md diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md similarity index 70% rename from 1-js/02-first-steps/14-function-basics/article.md rename to 1-js/02-first-steps/15-function-basics/article.md index c3683fa27..f7517e6b9 100644 --- a/1-js/02-first-steps/14-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -19,9 +19,17 @@ function mesajGoster() { } ``` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md `function` kelimesi önce yazılır, ardından *fonksiyonun adı* ve sonra parametrelerin yazılacağı parantez açılır ve ihtiyaç duyulan parametreler yazılır, sonrasında ise kapatılıp süslü parantez ile *fonksiyon gövdesi*ne başlanır. +======= +The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above, we'll see examples later) and finally the code of the function, also named "the function body", between curly braces. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md -![](function_basics.png) +```js +function name(parameter1, parameter2, ... parameterN) { + // body +} +``` Yeni fonksyion ismiyle şu şekilde çağırılır: `mesajGoster()`. @@ -135,6 +143,7 @@ Genelde fonksiyonlar yapacakları işe ait tüm değişkenleri tanımlarlar, glo ## Parametreler Parametrelere isteğe bağlı olarak veri paslanabilir. Bunlara *fonksiyon argümanları* da denir. +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md Aşağıdaki fonksiyon iki tane parametreye sahiptir. `gonderen` ve `metin` ```js run @@ -146,13 +155,25 @@ function mesajGoster(*!*gonderen, metin*/!*) { // argümanlar: gonderen, metin mesajGoster('Ahmet', 'Merhaba!'); // Ahmet: Merhaba! (*) mesajGoster('Mehmet', "Naber?"); // Mehmet: Naber? (**) */!* +======= +We can pass arbitrary data to functions using parameters. + +In the example below, the function has two parameters: `from` and `text`. + +```js run +function showMessage(*!*from, text*/!*) { // parameters: from, text + alert(from + ': ' + text); +} + +*!*showMessage('Ann', 'Hello!');*/!* // Ann: Hello! (*) +*!*showMessage('Ann', "What's up?");*/!* // Ann: What's up? (**) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md ``` Eğer fonksiyonlar `(*)` ve `(**)` deki gibi yazılırsa doğrudan fonksiyonda `gonderen` ve `metin` yerel değişkenlerine atanırlar. Sonrasında fonksiyon bunları kullanabilir. Aşağıda `gonderen` değişkeni fonksiyona paslanmakta. Dikkat ederseniz fonksiyon içerisinde `gonderen` değişse bile bu dışarıda bulunan değişkeni etkilememekte. Çünkü fonksiyon bu değişkenin her zaman kopyasını kullanır: - ```js run function mesajGoster(gonderen,metin) { @@ -171,9 +192,27 @@ mesajGoster(gonderen, "Merhaba"); // *Mahmut*: Merhaba alert( gonderen ); // Mahmut ``` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md ### Varsayılan Değerler Eğer fonksiyon argümanına bir değer gönderilmemişse fonksiyon içerisinde bu değişken `undefined` olur. +======= +When a value is passed as a function parameter, it's also called an *argument*. + +In other words, to put these terms straight: + +- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term). +- An argument is the value that is passed to the function when it is called (it's a call time term). + +We declare functions listing their parameters, then call them passing arguments. + +In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`". + + +## Default values + +If a function is called, but an argument is not provided, then the corresponding value becomes `undefined`. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md Örneğin `mesajGoster(gonderen,metin)` fonksiyonu tek argüman ile de çağırılabilir. @@ -182,7 +221,13 @@ mesajGoster("Mahmut"); ``` Bu bir hata değildir. Fonksiyon eğer bu şekilde çağırılırsa, yani `metin` yoksa, `metin == undefined` varsayılır. Yukarıdaki fonksiyon çağırıldığında sonuç "Mahmut: undefined" olacaktır. +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md Eğer "varsayılan" olarak `metin` değeri atamak istiyorsanız, `=` işareti ile tanımlamanız gerekmekte. +======= +That's not an error. Such a call would output `"*Ann*: undefined"`. As the value for `text` isn't passed, it becomes `undefined`. + +We can specify the so-called "default" (to use if omitted) value for a parameter in the function declaration, using `=`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md ```js run function mesajGoster(gonderen, *!*metin = "metin gönderilmedi"*/!*) { @@ -193,7 +238,19 @@ mesajGoster("Mahmut"); // Mahmut: metin gönderilmedi ``` Eğer `metin` değeri paslanmazsa, `"metin gönderilmedi"` çıktısı alınır. +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md `"metin gönderilmedi"` şu anda karakter dizisidir. Fakat daha karmaşık yapılar olabilir. Sadece parametre gönderilmez ise bu değer atanır. Aşağıdaki kullanım da pekala doğrudur. +======= +Now if the `text` parameter is not passed, it will get the value `"no text given"`. + +The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this: + +```js +showMessage("Ann", undefined); // Ann: no text given +``` + +Here `"no text given"` is a string, but it can be a more complex expression, which is only evaluated and assigned if the parameter is missing. So, this is also possible: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md ```js run function mesajGoster(gonderen, metin = digerFonksiyon()) { @@ -201,9 +258,26 @@ function mesajGoster(gonderen, metin = digerFonksiyon()) { } ``` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md ````smart header="Eski tip varsayılan parametreler" Eski tip JavaScript varsayılan parametreleri desteklememekteydi. Bundan dolayı farklı yöntemler geliştirdi. Eğer eskiden yazılmış kodları okursanız bu kodlara rastlayabilirsiniz. +======= +```smart header="Evaluation of default parameters" +In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. + +In the example above, `anotherFunction()` isn't called at all, if the `text` parameter is provided. + +On the other hand, it's independently called every time when `text` is missing. +``` + +````smart header="Default parameters in old JavaScript code" +Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them. + +Nowadays, we can come across them in old scripts. + +For example, an explicit check for `undefined`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md Örneğin doğrudan `undefined` kontrolü: ```js @@ -219,20 +293,77 @@ function mesajGoster(gonderen, metin) { ``` ...Veya `||` operatörü: +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md ```js function mesajGoster(gonderen, metin) { // eğer metin yanlış değer ise( bu durumda undefined yanlış değerdir hatırlarsanız ) 'metin gönderilmedi' ata. text = text || 'metin gönderilmedi'; +======= +...Or using the `||` operator: + +```js +function showMessage(from, text) { + // If the value of text is falsy, assign the default value + // this assumes that text == "" is the same as no text at all + text = text || 'no text given'; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md ... } ``` - - ```` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md ## Değer döndürme +======= +### Alternative default parameters + +Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration. + +We can check if the parameter is passed during the function execution, by comparing it with `undefined`: + +```js run +function showMessage(text) { + // ... + +*!* + if (text === undefined) { // if the parameter is missing + text = 'empty message'; + } +*/!* + + alert(text); +} + +showMessage(); // empty message +``` + +...Or we could use the `||` operator: + +```js +function showMessage(text) { + // if text is undefined or otherwise falsy, set it to 'empty' + text = text || 'empty'; + ... +} +``` + +Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when most falsy values, such as `0`, should be considered "normal": + +```js run +function showCount(count) { + // if count is undefined or null, show "unknown" + alert(count ?? "unknown"); +} + +showCount(0); // 0 +showCount(null); // unknown +showCount(); // unknown +``` + +## Returning a value +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md Fonksiyon çağırıldığı yere değer döndürebilir. @@ -252,8 +383,13 @@ alert( sonuc ); // 3 Bir fonksiyon içerisinde birden fazla `return` fonksiyonu da olabilir. ```js run +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md function yasKontrolu(yas) { if (yas > 18) { +======= +function checkAge(age) { + if (age >= 18) { +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md *!* return true; */!* @@ -325,8 +461,24 @@ Bu çalışmaz, çünkü JavaScript `return` kelimesinden sonra `;` varsayar ve return*!*;*/!* (bazı + uzun + ifade + veya + baska + birsey * f(a) + f(b)) ``` +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md Bundan dolayı, tam olarak boş return olur. Geri döndüreceğimiz değer ile return aynı satırda olmalıdır. +======= + +So, it effectively becomes an empty return. + +If we want the returned expression to wrap across multiple lines, we should start it at the same line as `return`. Or at least put the opening parentheses there as follows: + +```js +return ( + some + long + expression + + or + + whatever * f(a) + f(b) + ) +``` +And it will work just as we expect it to. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md ```` ## Fonksiyonu isimlendirme [#fonksiyon-isimlendirme] @@ -382,9 +534,16 @@ Bunlar istisnadır. Genel olarak fonksiyon isimleri kısa ve açıklayıcı olma ## Fonksiyonlar == Yorumlar +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md Fonksiyonlar kısa olmalı ve sadece bir şeyi yapmalıdırlar. Eğer uzun ise bu durumda ayırıp yeni bir fonksiyon yapmanız daha iyi olabilir. Bazen bu kuralı takip etmek zor olabilir. Fakat kesinlikle iyi bir şeydir. Farklı fonksiyon daha kolay bir şekilde çalışması kontrol edilebilir. Varlığı harika bir yorumdur. +======= +For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`. + +These are exceptions. Generally function names should be concise and descriptive. +``` +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md Örneğin, aşağıdaki iki `asalGoster(n)` fonksiyonunu karşılaştırın. [Asal Sayı](https://tr.wikipedia.org/wiki/Asal_say%C4%B1) @@ -440,7 +599,11 @@ function fonksiyon ismi(parametreler, virgül , ile, ayrilirlar) { Kodun daha anlaşılır ve okunabilir olması için, fonksiyonlar içerisinde yerel değişken kullanılması önerilir. Dış değişkenler kullanılması önerilmez. +<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md Eğer fonksiyon parametre ile değer alır ve bu değer üzerinde çalışıp değer geri döndürürse anlaşılırlığı artar. Fakat eğer fonksiyon hiçbir parametre almadan sadece dışarıdaki değişkenleri değiştiriyor ise kodun anlaşılırlığı büyük ölçüde azalır. +======= +It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/02-first-steps/15-function-basics/article.md Fonksiyon isimlendirme: diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md new file mode 100644 index 000000000..c6dd891bd --- /dev/null +++ b/1-js/02-first-steps/16-function-expressions/article.md @@ -0,0 +1,380 @@ +# Function expressions + +In JavaScript, a function is not a "magical language structure", but a special kind of value. + +The syntax that we used before is called a *Function Declaration*: + +```js +function sayHi() { + alert( "Hello" ); +} +``` + +There is another syntax for creating a function that is called a *Function Expression*. + +It allows us to create a new function in the middle of any expression. + +For example: + +```js +let sayHi = function() { + alert( "Hello" ); +}; +``` + +Here we can see a variable `sayHi` getting a value, the new function, created as `function() { alert("Hello"); }`. + +As the function creation happens in the context of the assignment expression (to the right side of `=`), this is a *Function Expression*. + +Please note, there's no name after the `function` keyword. Omitting a name is allowed for Function Expressions. + +Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable `sayHi`". + +In more advanced situations, that we'll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous. + +## Function is a value + +Let's reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the `sayHi` variable. + +We can even print out that value using `alert`: + +```js run +function sayHi() { + alert( "Hello" ); +} + +*!* +alert( sayHi ); // shows the function code +*/!* +``` + +Please note that the last line does not run the function, because there are no parentheses after `sayHi`. There are programming languages where any mention of a function name causes its execution, but JavaScript is not like that. + +In JavaScript, a function is a value, so we can deal with it as a value. The code above shows its string representation, which is the source code. + +Surely, a function is a special value, in the sense that we can call it like `sayHi()`. + +But it's still a value. So we can work with it like with other kinds of values. + +We can copy a function to another variable: + +```js run no-beautify +function sayHi() { // (1) create + alert( "Hello" ); +} + +let func = sayHi; // (2) copy + +func(); // Hello // (3) run the copy (it works)! +sayHi(); // Hello // this still works too (why wouldn't it) +``` + +Here's what happens above in detail: + +1. The Function Declaration `(1)` creates the function and puts it into the variable named `sayHi`. +2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself. +3. Now the function can be called as both `sayHi()` and `func()`. + +We could also have used a Function Expression to declare `sayHi`, in the first line: + +```js +let sayHi = function() { // (1) create + alert( "Hello" ); +}; + +let func = sayHi; //(2) +// ... +``` + +Everything would work the same. + + +````smart header="Why is there a semicolon at the end?" +You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not: + +```js +function sayHi() { + // ... +} + +let sayHi = function() { + // ... +}*!*;*/!* +``` + +The answer is simple: a Function Expression is created here as `function(…) {…}` inside the assignment statement: `let sayHi = …;`. The semicolon `;` is recommended at the end of the statement, it's not a part of the function syntax. + +The semicolon would be there for a simpler assignment, such as `let sayHi = 5;`, and it's also there for a function assignment. +```` + +## Callback functions + +Let's look at more examples of passing functions as values and using function expressions. + +We'll write a function `ask(question, yes, no)` with three parameters: + +`question` +: Text of the question + +`yes` +: Function to run if the answer is "Yes" + +`no` +: Function to run if the answer is "No" + +The function should ask the `question` and, depending on the user's answer, call `yes()` or `no()`: + +```js run +*!* +function ask(question, yes, no) { + if (confirm(question)) yes() + else no(); +} +*/!* + +function showOk() { + alert( "You agreed." ); +} + +function showCancel() { + alert( "You canceled the execution." ); +} + +// usage: functions showOk, showCancel are passed as arguments to ask +ask("Do you agree?", showOk, showCancel); +``` + +In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story. + +**The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.** + +The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer. + +We can use Function Expressions to write an equivalent, shorter function: + +```js run no-beautify +function ask(question, yes, no) { + if (confirm(question)) yes() + else no(); +} + +*!* +ask( + "Do you agree?", + function() { alert("You agreed."); }, + function() { alert("You canceled the execution."); } +); +*/!* +``` + +Here, functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask` (because they are not assigned to variables), but that's just what we want here. + +Such code appears in our scripts very naturally, it's in the spirit of JavaScript. + +```smart header="A function is a value representing an \"action\"" +Regular values like strings or numbers represent the *data*. + +A function can be perceived as an *action*. + +We can pass it between variables and run when we want. +``` + + +## Function Expression vs Function Declaration + +Let's formulate the key differences between Function Declarations and Expressions. + +First, the syntax: how to differentiate between them in the code. + +- *Function Declaration:* a function, declared as a separate statement, in the main code flow: + + ```js + // Function Declaration + function sum(a, b) { + return a + b; + } + ``` +- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`: + + ```js + // Function Expression + let sum = function(a, b) { + return a + b; + }; + ``` + +The more subtle difference is *when* a function is created by the JavaScript engine. + +**A Function Expression is created when the execution reaches it and is usable only from that moment.** + +Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on. + +Function Declarations are different. + +**A Function Declaration can be called earlier than it is defined.** + +For example, a global Function Declaration is visible in the whole script, no matter where it is. + +That's due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an "initialization stage". + +And after all Function Declarations are processed, the code is executed. So it has access to these functions. + +For example, this works: + +```js run refresh untrusted +*!* +sayHi("John"); // Hello, John +*/!* + +function sayHi(name) { + alert( `Hello, ${name}` ); +} +``` + +The Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it. + +...If it were a Function Expression, then it wouldn't work: + +```js run refresh untrusted +*!* +sayHi("John"); // error! +*/!* + +let sayHi = function(name) { // (*) no magic any more + alert( `Hello, ${name}` ); +}; +``` + +Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late. + +Another special feature of Function Declarations is their block scope. + +**In strict mode, when a Function Declaration is within a code block, it's visible everywhere inside that block. But not outside of it.** + +For instance, let's imagine that we need to declare a function `welcome()` depending on the `age` variable that we get during runtime. And then we plan to use it some time later. + +If we use Function Declaration, it won't work as intended: + +```js run +let age = prompt("What is your age?", 18); + +// conditionally declare a function +if (age < 18) { + + function welcome() { + alert("Hello!"); + } + +} else { + + function welcome() { + alert("Greetings!"); + } + +} + +// ...use it later +*!* +welcome(); // Error: welcome is not defined +*/!* +``` + +That's because a Function Declaration is only visible inside the code block in which it resides. + +Here's another example: + +```js run +let age = 16; // take 16 as an example + +if (age < 18) { +*!* + welcome(); // \ (runs) +*/!* + // | + function welcome() { // | + alert("Hello!"); // | Function Declaration is available + } // | everywhere in the block where it's declared + // | +*!* + welcome(); // / (runs) +*/!* + +} else { + + function welcome() { + alert("Greetings!"); + } +} + +// Here we're out of curly braces, +// so we can not see Function Declarations made inside of them. + +*!* +welcome(); // Error: welcome is not defined +*/!* +``` + +What can we do to make `welcome` visible outside of `if`? + +The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility. + +This code works as intended: + +```js run +let age = prompt("What is your age?", 18); + +let welcome; + +if (age < 18) { + + welcome = function() { + alert("Hello!"); + }; + +} else { + + welcome = function() { + alert("Greetings!"); + }; + +} + +*!* +welcome(); // ok now +*/!* +``` + +Or we could simplify it even further using a question mark operator `?`: + +```js run +let age = prompt("What is your age?", 18); + +let welcome = (age < 18) ? + function() { alert("Hello!"); } : + function() { alert("Greetings!"); }; + +*!* +welcome(); // ok now +*/!* +``` + + +```smart header="When to choose Function Declaration versus Function Expression?" +As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared. + +That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching". + +...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used. +``` + +## Summary + +- Functions are values. They can be assigned, copied or declared in any place of the code. +- If the function is declared as a separate statement in the main code flow, that's called a "Function Declaration". +- If the function is created as a part of an expression, it's called a "Function Expression". +- Function Declarations are processed before the code block is executed. They are visible everywhere in the block. +- Function Expressions are created when the execution flow reaches them. + +In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable. + +So we should use a Function Expression only when a Function Declaration is not fit for the task. We've seen a couple of examples of that in this chapter, and will see more in the future. diff --git a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md new file mode 100644 index 000000000..041db18bc --- /dev/null +++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md @@ -0,0 +1,17 @@ + +```js run +function ask(question, yes, no) { + if (confirm(question)) yes(); + else no(); +} + +ask( + "Do you agree?", +*!* + () => alert("You agreed."), + () => alert("You canceled the execution.") +*/!* +); +``` + +Looks short and clean, right? diff --git a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md new file mode 100644 index 000000000..e18c08a83 --- /dev/null +++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md @@ -0,0 +1,17 @@ + +# Rewrite with arrow functions + +Replace Function Expressions with arrow functions in the code below: + +```js run +function ask(question, yes, no) { + if (confirm(question)) yes(); + else no(); +} + +ask( + "Do you agree?", + function() { alert("You agreed."); }, + function() { alert("You canceled the execution."); } +); +``` diff --git a/1-js/02-first-steps/17-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md new file mode 100644 index 000000000..50c0d475d --- /dev/null +++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md @@ -0,0 +1,111 @@ +# Arrow functions, the basics + +There's another very simple and concise syntax for creating functions, that's often better than Function Expressions. + +It's called "arrow functions", because it looks like this: + +```js +let func = (arg1, arg2, ..., argN) => expression; +``` + +This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result. + +In other words, it's the shorter version of: + +```js +let func = function(arg1, arg2, ..., argN) { + return expression; +}; +``` + +Let's see a concrete example: + +```js run +let sum = (a, b) => a + b; + +/* This arrow function is a shorter form of: + +let sum = function(a, b) { + return a + b; +}; +*/ + +alert( sum(1, 2) ); // 3 +``` + +As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result. + +- If we have only one argument, then parentheses around parameters can be omitted, making that even shorter. + + For example: + + ```js run + *!* + let double = n => n * 2; + // roughly the same as: let double = function(n) { return n * 2 } + */!* + + alert( double(3) ); // 6 + ``` + +- If there are no arguments, parentheses are empty, but they must be present: + + ```js run + let sayHi = () => alert("Hello!"); + + sayHi(); + ``` + +Arrow functions can be used in the same way as Function Expressions. + +For instance, to dynamically create a function: + +```js run +let age = prompt("What is your age?", 18); + +let welcome = (age < 18) ? + () => alert('Hello!') : + () => alert("Greetings!"); + +welcome(); +``` + +Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure. + +They are very convenient for simple one-line actions, when we're just too lazy to write many words. + +## Multiline arrow functions + +The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them. + +Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does). + +Like this: + +```js run +let sum = (a, b) => { // the curly brace opens a multiline function + let result = a + b; +*!* + return result; // if we use curly braces, then we need an explicit "return" +*/!* +}; + +alert( sum(1, 2) ); // 3 +``` + +```smart header="More to come" +Here we praised arrow functions for brevity. But that's not all! + +Arrow functions have other interesting features. + +To study them in-depth, we first need to get to know some other aspects of JavaScript, so we'll return to arrow functions later in the chapter . + +For now, we can already use arrow functions for one-line actions and callbacks. +``` + +## Summary + +Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors: + +1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`. +2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something. diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md new file mode 100644 index 000000000..e7ddacac4 --- /dev/null +++ b/1-js/02-first-steps/18-javascript-specials/article.md @@ -0,0 +1,284 @@ +# JavaScript specials + +This chapter briefly recaps the features of JavaScript that we've learned by now, paying special attention to subtle moments. + +## Code structure + +Statements are delimited with a semicolon: + +```js run no-beautify +alert('Hello'); alert('World'); +``` + +Usually, a line-break is also treated as a delimiter, so that would also work: + +```js run no-beautify +alert('Hello') +alert('World') +``` + +That's called "automatic semicolon insertion". Sometimes it doesn't work, for instance: + +```js run +alert("There will be an error after this message") + +[1, 2].forEach(alert) +``` + +Most codestyle guides agree that we should put a semicolon after each statement. + +Semicolons are not required after code blocks `{...}` and syntax constructs with them like loops: + +```js +function f() { + // no semicolon needed after function declaration +} + +for(;;) { + // no semicolon needed after the loop +} +``` + +...But even if we can put an "extra" semicolon somewhere, that's not an error. It will be ignored. + +More in: . + +## Strict mode + +To fully enable all features of modern JavaScript, we should start scripts with `"use strict"`. + +```js +'use strict'; + +... +``` + +The directive must be at the top of a script or at the beginning of a function body. + +Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior. + +Some modern features of the language (like classes that we'll study in the future) enable strict mode implicitly. + +More in: . + +## Variables + +Can be declared using: + +- `let` +- `const` (constant, can't be changed) +- `var` (old-style, will see later) + +A variable name can include: +- Letters and digits, but the first character may not be a digit. +- Characters `$` and `_` are normal, on par with letters. +- Non-Latin alphabets and hieroglyphs are also allowed, but commonly not used. + +Variables are dynamically typed. They can store any value: + +```js +let x = 5; +x = "John"; +``` + +There are 8 data types: + +- `number` for both floating-point and integer numbers, +- `bigint` for integer numbers of arbitrary length, +- `string` for strings, +- `boolean` for logical values: `true/false`, +- `null` -- a type with a single value `null`, meaning "empty" or "does not exist", +- `undefined` -- a type with a single value `undefined`, meaning "not assigned", +- `object` and `symbol` -- for complex data structures and unique identifiers, we haven't learnt them yet. + +The `typeof` operator returns the type for a value, with two exceptions: +```js +typeof null == "object" // error in the language +typeof function(){} == "function" // functions are treated specially +``` + +More in: and . + +## Interaction + +We're using a browser as a working environment, so basic UI functions will be: + +[`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) +: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel". + +[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) +: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`. + +[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert) +: Output a `message`. + +All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until they answer. + +For instance: + +```js run +let userName = prompt("Your name?", "Alice"); +let isTeaWanted = confirm("Do you want some tea?"); + +alert( "Visitor: " + userName ); // Alice +alert( "Tea wanted: " + isTeaWanted ); // true +``` + +More in: . + +## Operators + +JavaScript supports the following operators: + +Arithmetical +: Regular: `* + - /`, also `%` for the remainder and `**` for power of a number. + + The binary plus `+` concatenates strings. And if any of the operands is a string, the other one is converted to string too: + + ```js run + alert( '1' + 2 ); // '12', string + alert( 1 + '2' ); // '12', string + ``` + +Assignments +: There is a simple assignment: `a = b` and combined ones like `a *= 2`. + +Bitwise +: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) when they are needed. + +Conditional +: The only operator with three parameters: `cond ? resultA : resultB`. If `cond` is truthy, returns `resultA`, otherwise `resultB`. + +Logical operators +: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped (not necessary `true`/`false`). Logical NOT `!` converts the operand to boolean type and returns the inverse value. + +Nullish coalescing operator +: The `??` operator provides a way to choose a defined value from a list of variables. The result of `a ?? b` is `a` unless it's `null/undefined`, then `b`. + +Comparisons +: Equality check `==` for values of different types converts them to a number (except `null` and `undefined` that equal each other and nothing else), so these are equal: + + ```js run + alert( 0 == false ); // true + alert( 0 == '' ); // true + ``` + + Other comparisons convert to a number as well. + + The strict equality operator `===` doesn't do the conversion: different types always mean different values for it. + + Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else. + + Greater/less comparisons compare strings character-by-character, other types are converted to a number. + +Other operators +: There are few others, like a comma operator. + +More in: , , , . + +## Loops + +- We covered 3 types of loops: + + ```js + // 1 + while (condition) { + ... + } + + // 2 + do { + ... + } while (condition); + + // 3 + for(let i = 0; i < 10; i++) { + ... + } + ``` + +- The variable declared in `for(let...)` loop is visible only inside the loop. But we can also omit `let` and reuse an existing variable. +- Directives `break/continue` allow to exit the whole loop/current iteration. Use labels to break nested loops. + +Details in: . + +Later we'll study more types of loops to deal with objects. + +## The "switch" construct + +The "switch" construct can replace multiple `if` checks. It uses `===` (strict equality) for comparisons. + +For instance: + +```js run +let age = prompt('Your age?', 18); + +switch (age) { + case 18: + alert("Won't work"); // the result of prompt is a string, not a number + break; + + case "18": + alert("This works!"); + break; + + default: + alert("Any value not equal to one above"); +} +``` + +Details in: . + +## Functions + +We covered three ways to create a function in JavaScript: + +1. Function Declaration: the function in the main code flow + + ```js + function sum(a, b) { + let result = a + b; + + return result; + } + ``` + +2. Function Expression: the function in the context of an expression + + ```js + let sum = function(a, b) { + let result = a + b; + + return result; + }; + ``` + +3. Arrow functions: + + ```js + // expression on the right side + let sum = (a, b) => a + b; + + // or multi-line syntax with { ... }, need return here: + let sum = (a, b) => { + // ... + return a + b; + } + + // without arguments + let sayHi = () => alert("Hello"); + + // with a single argument + let double = n => n * 2; + ``` + + +- Functions may have local variables: those declared inside its body or its parameter list. Such variables are only visible inside the function. +- Parameters can have default values: `function sum(a = 1, b = 2) {...}`. +- Functions always return something. If there's no `return` statement, then the result is `undefined`. + +Details: see , . + +## More to come + +That was a brief list of JavaScript features. As of now we've studied only basics. Further in the tutorial you'll find more specials and advanced features of JavaScript. diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md index 4adb5da20..81919e549 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -1,29 +1,52 @@ +<<<<<<< HEAD # Chrome ile Hata Ayıklama +======= +# Debugging in the browser +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Daha karmaşık kodlara geçmeden, hata ayıklama hakkında konuşmamız gerekmekte. +<<<<<<< HEAD Çoğu modern tarayıcı "hata ayıklama"(debugging) özelliğine sahiptir -- bu özel arayüz kod yazarken hata bulunmasını ve düzeltilmesini kolaylaştırır. Geliştirici özellikleri en iyi olan tarayıcı Chrome olduğundan bu tarayıcı ile çalışacağız. ## "Kaynak" paneli +======= +[Debugging](https://en.wikipedia.org/wiki/Debugging) is the process of finding and fixing errors within a script. All modern browsers and most other environments support debugging tools -- a special UI in developer tools that makes debugging much easier. It also allows to trace the code step by step to see what exactly is going on. + +We'll be using Chrome here, because it has enough features, most other browsers have a similar process. + +## The "Sources" panel +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Şu anda sizin kullandığınız Chrome biraz farklı olabilir. Fakat bu panel kesinlikle orada biryerde olmalı +<<<<<<< HEAD - [Örnek Sayfayı](debugging/index.html) Chrome ile açın. - Geliştirici araçlarını `key:F12` (Mac: `key:Cmd+Opt+I`) ile açabilirsiniz. - `kaynak` panelini seçin. +======= +- Open the [example page](debugging/index.html) in Chrome. +- Turn on developer tools with `key:F12` (Mac: `key:Cmd+Opt+I`). +- Select the `Sources` panel. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Eğer ilk defa bu işlemi yapıyorsanız görmeniz gereken ekran şudur: ![](chrome-open-sources.svg) +<<<<<<< HEAD Sol tarafta bulunan açma kapama butonu size dosyaları gösteren bir tab açar. +======= +The toggler button opens the tab with files. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu panelde `hello.js` i seçtiğinizde aşağıdaki gibi bir ekran görmeniz gerekir. ![](chrome-tabs.svg) +<<<<<<< HEAD Bu bölüm üçe ayrılmıştır: 1. **Dosya Gezgini**: Html, javascript, css ve diğer dosyalar görseller de dahil olmak üzere açılan sayfaya ait olan kaynakları gösterir. Chrome eklentileri de burada yer alabilir. 2. **Kod Editörü** burası ise kaynak kodu gösterir. @@ -32,6 +55,15 @@ Bu bölüm üçe ayrılmıştır: Şimdi geliştirici araçlarının sol köşesinde bulunan açma kapama bölümünü kullanarak kendinize biraz yer açabilirsiniz. ## Konsol +======= +The Sources panel has 3 parts: + +1. The **File Navigator** pane lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too. +2. The **Code Editor** pane shows the source code. +3. The **JavaScript Debugging** pane is for debugging, we'll explore it soon. + +Now you could click the same toggler again to hide the resources list and give the code some space. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Eğer `Esc` tuşuna basarsanız altta `konsol` açılır. Buraya komutları yazıp `key:Enter` ile çalıştırabilirsiniz. @@ -39,9 +71,15 @@ Komut çalıştıktan sonra sonucunu hemen altında gösterir. Örneğin burada `1+2` `3` çıktısını verir. `hello("debugger")` dediğinizde hiçbir şey bulamadığından `undefined` döndürür. +<<<<<<< HEAD ![](chrome-sources-console.svg) ## Kesme Noktası +======= +For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`: + +![](chrome-sources-console.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 [Örnek Kod](debugging/index.html) içerisinde ne olduğunu incelenecek olursa. `hello.js` içerisinde `4.` satıra tıklayın. Evet `4` e tıklayın koda değil. @@ -51,25 +89,46 @@ Aşağıdaki gibi görünmeli. (tıkladığınız yerler mavi olmalı) ![](chrome-sources-breakpoint.svg) +<<<<<<< HEAD *kesme noktası* JavaScript çalışırken çalışmasını o noktada durdurmasını sağlar. +======= +![](chrome-sources-breakpoint.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Kod durdurulduğunda, o anki değişken değerlerini inceleyebilir veya konsoldan kod çalıştırabilirsiniz. Diğer bir deyişle *hata ayıklayabilirsiniz* Oluşturulan bu kesme noktalarını sağ taraftaki panelde list halinde görmek mümkündür. Bu farklı dosyalarda eğer kesme noktaları varsa bunları görme açısından yararlı bir özelliktir. Eğer birçok dosyada kesme noktası varsa bu panel vasıtasıyla: +<<<<<<< HEAD - İstenilen herhangi bir kesme noktasına doğrudan üstüne tıklayarak gidilebilir. - Geçici olarak kesme noklarını devre dışı bırakılabilir. - Sağ tıklayıp Sil'e tıkladığınızda bu kesme noktalarını silebilirsiniz. ```smart header="Koşullu kesme noktaları" Satır sayılarının yazıldığı yere sağ tıklayarak *Koşullu Kesme Noktası* oluşturabilirsiniz. Eğer ifadeniz doğruysa bu kesme noktası çalışır ve JavaScript çalışması durur. +======= +We can always find a list of breakpoints in the right panel. That's useful when we have many breakpoints in various files. It allows us to: +- Quickly jump to the breakpoint in the code (by clicking on it in the right panel). +- Temporarily disable the breakpoint by unchecking it. +- Remove the breakpoint by right-clicking and selecting Remove. +- ...And so on. + +```smart header="Conditional breakpoints" +*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Belirli değişken değerlerine veya parametre değerlerine göre çalışma durdurulmak istendiğinde yararlı bir özelliktir. ``` +<<<<<<< HEAD ## Debugger komutu Ayrıca `debugger` kodu ile de hata ayıklama işlemini yapmak mümkündür. +======= +## The command "debugger" + +We can also pause the code by using the `debugger` command in it, like this: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js function merhaba(adi) { @@ -83,6 +142,7 @@ function merhaba(adi) { } ``` +<<<<<<< HEAD Bu kod, siz editörde kod yazarken tekrar tarayıcıya geçip, kodu bulup kesme noktası koyma sürecini ortadan kaldırıyor. ## Dur ve ne olduğuna bak @@ -117,15 +177,26 @@ Artık *iz sürme* safhasına geçebilirsiniz. Sağ panelin üstünde sadece bu işe has butonlar bulunmaktadır. +======= +Such command works only when the development tools are open, otherwise the browser ignores it. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 -- çalışmaya devam et, `key:F8`. : Çalışmaya devam edilmesini sağlar. Eğer ayrı bir kesme noktası yoksa çalışma kod bitene kadar devam eder. +<<<<<<< HEAD Üzerine bir defa tıkladığınızda aşağıdaki gibi olur. +======= +In our example, `hello()` is called during the page load, so the easiest way to activate the debugger (after we've set the breakpoints) is to reload the page. So let's press `key:F5` (Windows, Linux) or `key:Cmd+R` (Mac). +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ![](chrome-sources-debugger-trace-1.svg) +<<<<<<< HEAD Çalışmaya devam edildi, `yaz()` fonksiyonunun içerisinde tekrar durdu. Dikkat ederseniz "Call stack" çağrısını bu işlem bir artırdı. +======= +![](chrome-sources-debugger-pause.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 -- adım at (bir sonraki komutu çalıştır), fakat *fonksiyonun içine girme*, `key:F10`. : Eğer buna şimdi tıklarsanız `alert` çalışır. Önemli olan şey `alert` yerine farklı bir fonksiyon da olsa çalışma bu fonksiyonun içinde ne yaptığına önem vermez ve "üstünden atlar". @@ -133,31 +204,108 @@ Sağ panelin üstünde sadece bu işe has butonlar bulunmaktadır. -- adım at, `key:F11`. : Bir öncekinin aynısı, bir adım gider fakat bu defa eğer bir fonksiyon varsa onun "içine girer"(step into). +<<<<<<< HEAD -- içinde bulunulan fonksiyonun sonuna kadar devam et, `key:Shift+F11`. : Çalışma içinde bulunan fonksiyonun sonuna gelir ve orada durur.Yanlışlıkla iç içe çağrının içine girilirse çıkmak için kullanışlı bir özelliktir., +======= + You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 -- Tüm kesme noktalarını etkinleştirme/devre dışı bırakma. -- Hata olduğu anda otomatik olarak durdurmayı açma kapama butonu : Etkinleştirildiğinde, kodda herhangi bir hata olduğunda çalışma otomatik olarak durdurulur. Bu noktada analizlerinizi yapabilirsiniz. Eğer hata varsa hata ayıklama ekranını açabilir ve bu özelliği etkinleştirerek hatanın nerede olduğunu bulabilirsiniz. +<<<<<<< HEAD ```smart header="Buradan devam edin" Satır numaralarına sağ tıklayıp "Buradan devam et" özelliği ile kodu bir kaç adım ileriden devam etmesini sağlayabilirsiniz. Böylece yeniden bir kesme noktası oluşturmanıza gerek kalmaz. +======= + If you click on a stack item (e.g. "anonymous"), the debugger jumps to the corresponding code, and all its variables can be examined as well. +3. **`Scope` -- current variables.** + + `Local` shows local function variables. You can also see their values highlighted right over the source. + + `Global` has global variables (out of any functions). + + There's also `this` keyword there that we didn't study yet, but we'll do that soon. + +## Tracing the execution + +Now it's time to *trace* the script. + +There are buttons for it at the top of the right panel. Let's engage them. + + -- "Resume": continue the execution, hotkey `key:F8`. +: Resumes the execution. If there are no additional breakpoints, then the execution just continues and the debugger loses control. + + Here's what we can see after a click on it: + + ![](chrome-sources-debugger-trace-1.svg) + + The execution has resumed, reached another breakpoint inside `say()` and paused there. Take a look at the "Call Stack" at the right. It has increased by one more call. We're inside `say()` now. + + -- "Step": run the next command, hotkey `key:F9`. +: Run the next statement. If we click it now, `alert` will be shown. + + Clicking this again and again will step through all script statements one by one. + + -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`. +: Similar to the previous "Step" command, but behaves differently if the next statement is a function call (not a built-in, like `alert`, but a function of our own). + + If we compare them, the "Step" command goes into a nested function call and pauses the execution at its first line, while "Step over" executes the nested function call invisibly to us, skipping the function internals. + + The execution is then paused immediately after that function call. + + That's good if we're not interested to see what happens inside the function call. + + -- "Step into", hotkey `key:F11`. +: That's similar to "Step", but behaves differently in case of asynchronous function calls. If you're only starting to learn JavaScript, then you can ignore the difference, as we don't have asynchronous calls yet. + + For the future, just note that "Step" command ignores async actions, such as `setTimeout` (scheduled function call), that execute later. The "Step into" goes into their code, waiting for them if necessary. See [DevTools manual](https://developers.google.com/web/updates/2018/01/devtools#async) for more details. + + -- "Step out": continue the execution till the end of the current function, hotkey `key:Shift+F11`. +: Continue the execution and stop it at the very last line of the current function. That's handy when we accidentally entered a nested call using , but it does not interest us, and we want to continue to its end as soon as possible. + + -- enable/disable all breakpoints. +: That button does not move the execution. Just a mass on/off for breakpoints. + + -- enable/disable automatic pause in case of an error. +: When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment. + +```smart header="Continue to here" +Right click on a line of code opens the context menu with a great option called "Continue to here". + +That's handy when we want to move multiple steps forward to the line, but we're too lazy to set a breakpoint. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ## Loglama +<<<<<<< HEAD Konsola basit bir şey yazdıracağınız zaman `console.log` fonksiyonunu kullanabilirsiniz. Aşağıdaki örnekte ekrana 0 ile 4 arasındaki değerler yazılır. +======= +To output something to console from our code, there's `console.log` function. + +For instance, this outputs values from `0` to `4` to console: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run // çalışmasını görmek için lütfen geliştirici konsolunu açınız. for (let i = 0; i < 5; i++) { +<<<<<<< HEAD console.log("deger", i); +======= + console.log("value,", i); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 } ``` Normal kullanıcı bu çıktıyı ekranda göremez, bunun için geliştirici konsoluna girmesi gerekir. +<<<<<<< HEAD Eğer kodunuzun içerisinde yeterli derecede log varsa hata ayıklamanıza gerek yoktur. +======= +Regular users don't see that output, it is in the console. To see it, either open the Console panel of developer tools or press `key:Esc` while in another panel: that opens the console at the bottom. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Özet @@ -166,10 +314,25 @@ Bahsettiğimiz gibi çalışan kodu durdurmanın üç farklı yönü vardır. Bu 2. `debugger` kelimesi ile durdurma 3. Eğer hata olduğunda aç/kapa butonu aktifse çalışmada hata olduğunda durdurma +<<<<<<< HEAD Bunların sonucunda çalışmada ne gibi hatalar olduğunu görebilirsiniz. Bunlara ek olarak adresinden daha geniş ve yeni bilgilere ulaşabilirsiniz. +======= +As we can see, there are three main ways to pause a script: +1. A breakpoint. +2. The `debugger` statements. +3. An error (if dev tools are open and the button is "on"). + +When paused, we can debug: examine variables and trace the code to see where the execution goes wrong. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu bölümdeki bilgiler sizin hata ayıklama işlemine başlamanızda yardımcı olacaktır. Fakat tarayıcı ile alakalı çok fazla işlem yapıyorsanız bu durumda geliştirici derinlemesine incelemeniz gerekmektedir. +<<<<<<< HEAD Tabi bunun yanında deneme yanılma yöntemi ile de geliştirici araçlarının özelliklerini keşfedebilirsiniz. Unutmayın sağ tıklayarak farklı bölgelerde farklı fonksiyonları görebilirsiniz. +======= +The information from this chapter is enough to begin debugging, but later, especially if you do a lot of browser stuff, please go there and look through more advanced capabilities of developer tools. + +Oh, and also you can click at various places of dev tools and just see what's showing up. That's probably the fastest route to learn dev tools. Don't forget about the right click and context menus! +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg index a3c7db6ec..2db8527ec 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg @@ -1 +1,5 @@ -open sources \ No newline at end of file +<<<<<<< HEAD +open sources +======= +open sources +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg index 6e7b60f85..fbc664fc6 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg @@ -1 +1,5 @@ -here's the listbreakpoints \ No newline at end of file +<<<<<<< HEAD +here's the listbreakpoints +======= +here's the listbreakpoints +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg index d5d2a0b93..8d4d9c434 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg @@ -1 +1,5 @@ - \ No newline at end of file +<<<<<<< HEAD + +======= + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg index 83468fddb..10dff7123 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg @@ -1 +1,5 @@ -213see the outer call detailswatch expressionscurrent variables \ No newline at end of file +<<<<<<< HEAD +213see the outer call detailswatch expressionscurrent variables +======= +213see the outer call detailswatch expressionscurrent variables +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg index 23937e0d6..055f164dd 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg @@ -1 +1,5 @@ -nested calls \ No newline at end of file +<<<<<<< HEAD +nested calls +======= +nested calls +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg index 41a3d8784..6e4b358f1 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg @@ -1 +1,5 @@ -213 \ No newline at end of file +<<<<<<< HEAD +213 +======= +213 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/03-code-quality/01-debugging-chrome/head.html b/1-js/03-code-quality/01-debugging-chrome/head.html index f219b0af1..615326c08 100644 --- a/1-js/03-code-quality/01-debugging-chrome/head.html +++ b/1-js/03-code-quality/01-debugging-chrome/head.html @@ -1,8 +1,8 @@ diff --git a/1-js/03-code-quality/01-debugging-chrome/largeIcons.svg b/1-js/03-code-quality/01-debugging-chrome/largeIcons.svg new file mode 100644 index 000000000..83303365b --- /dev/null +++ b/1-js/03-code-quality/01-debugging-chrome/largeIcons.svg @@ -0,0 +1,1472 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a + b + c + d + e + f + g + h + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + + + + + + + + + + + + + + + + + diff --git a/1-js/03-code-quality/01-debugging-chrome/toolbarButtonGlyphs.svg b/1-js/03-code-quality/01-debugging-chrome/toolbarButtonGlyphs.svg deleted file mode 100644 index 5bdf20a83..000000000 --- a/1-js/03-code-quality/01-debugging-chrome/toolbarButtonGlyphs.svg +++ /dev/null @@ -1,1035 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md index 610d9be86..961d1dd0c 100644 --- a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md +++ b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md @@ -10,12 +10,21 @@ function ust(x,n) // <- argümanlar arasında boşluk bulunmamakta. return sonuc; } +<<<<<<< HEAD let x=prompt("x?",''), n=prompt("n?",'') // <-- teknik olarka mümkün, // fakat iki satır yapmak daha iyi, ayrıca boşluk ve ; kullanılmamış. if (n<0) // <- (n < 0) olmalı, arada boşluk kullanılmamış { // <- süslü parantez yeni satırda // Aşağıdaki uzun metin iki satırda yazılsa daha iyi olabilir alert(`${n} üssü alınamadı, kullandığınız sayı 0'dan küçük olamaz. Lütfen doğal sayıları kullanınız.`); +======= +let x=prompt("x?",''), n=prompt("n?",'') // <-- technically possible, +// but better make it 2 lines, also there's no spaces and missing ; +if (n<=0) // <- no spaces inside (n <= 0), and should be extra line above it +{ // <- figure bracket on a separate line + // below - long lines can be split into multiple lines for improved readability + alert(`Power ${n} is not supported, please enter an integer number greater than zero`); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 } else // <- tek satırda "} else {" şeklinde kullanılabilir. { @@ -39,9 +48,15 @@ function ust(x, n) { let x = prompt("x?", ""); let n = prompt("n?", ""); +<<<<<<< HEAD if (n < 0) { alert(`${n} üssü alınamadı, kullandığınız sayı 0'dan küçük olamaz. Lütfen doğal sayıları kullanınız.`); +======= +if (n <= 0) { + alert(`Power ${n} is not supported, + please enter an integer number greater than zero`); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 } else { alert( ust(x, n) ); } diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md index c2184dfc2..ca25b090f 100644 --- a/1-js/03-code-quality/02-coding-style/article.md +++ b/1-js/03-code-quality/02-coding-style/article.md @@ -2,15 +2,24 @@ Kodunuz olabildiğince okunaklı ve temiz olmalıdır. +<<<<<<< HEAD Aslında bu programlama sanatıdır -- karmaşık bir görevi alın ve bunu olabildiğince doğru ve okunaklı bir şekle getirin. +======= +That is actually the art of programming -- to take a complex task and code it in a way that is both correct and human-readable. A good code style greatly assists in that. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Buna yardımcı olan bir şey de iyi kodlama stilidir. +<<<<<<< HEAD ## Yazım Kodlar için yazılmış bir kopya kağıdı (detayları aşağıda): +======= +Here is a cheat sheet with some suggested rules (see below for more details): + +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ![](code-style.svg) - memory-user-john.svg - Created with sketchtool. - - - - user - - - - name: "John" - - - Object - - - - - <global> - - - - \ No newline at end of file diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md new file mode 100644 index 000000000..e80f748ab --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -0,0 +1,325 @@ +# Object references and copying + +One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value". + +That's easy to understand if we look a bit under the hood of what happens when we copy a value. + +Let's start with a primitive, such as a string. + +Here we put a copy of `message` into `phrase`: + +```js +let message = "Hello!"; +let phrase = message; +``` + +As a result we have two independent variables, each one storing the string `"Hello!"`. + +![](variable-copy-value.svg) + +Quite an obvious result, right? + +Objects are not like that. + +**A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.** + +Let's look at an example of such a variable: + +```js +let user = { + name: "John" +}; +``` + +And here's how it's actually stored in memory: + +![](variable-contains-reference.svg) + +The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it. + +We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it. + +When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object. + +Now here's why it's important. + +**When an object variable is copied, the reference is copied, but the object itself is not duplicated.** + +For instance: + +```js no-beautify +let user = { name: "John" }; + +let admin = user; // copy the reference +``` + +Now we have two variables, each storing a reference to the same object: + +![](variable-copy-reference.svg) + +As you can see, there's still one object, but now with two variables that reference it. + +We can use either variable to access the object and modify its contents: + +```js run +let user = { name: 'John' }; + +let admin = user; + +*!* +admin.name = 'Pete'; // changed by the "admin" reference +*/!* + +alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference +``` + +It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents. + +## Comparison by reference + +Two objects are equal only if they are the same object. + +For instance, here `a` and `b` reference the same object, thus they are equal: + +```js run +let a = {}; +let b = a; // copy the reference + +alert( a == b ); // true, both variables reference the same object +alert( a === b ); // true +``` + +And here two independent objects are not equal, even though they look alike (both are empty): + +```js run +let a = {}; +let b = {}; // two independent objects + +alert( a == b ); // false +``` + +For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake. + +````smart header="Const objects can be modified" +An important side effect of storing objects as references is that an object declared as `const` *can* be modified. + +For instance: + +```js run +const user = { + name: "John" +}; + +*!* +user.name = "Pete"; // (*) +*/!* + +alert(user.name); // Pete +``` + +It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change. + +In other words, the `const user` gives an error only if we try to set `user=...` as a whole. + +That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter . +```` + +## Cloning and merging, Object.assign [#cloning-and-merging-object-assign] + +So, copying an object variable creates one more reference to the same object. + +But what if we need to duplicate an object? + +We can create a new object and replicate the structure of the existing one, by iterating over its properties and copying them on the primitive level. + +Like this: + +```js run +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = {}; // the new empty object + +// let's copy all user properties into it +for (let key in user) { + clone[key] = user[key]; +} +*/!* + +// now clone is a fully independent object with the same content +clone.name = "Pete"; // changed the data in it + +alert( user.name ); // still John in the original object +``` + +We can also use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign). + +The syntax is: + +```js +Object.assign(dest, ...sources) +``` + +- The first argument `dest` is a target object. +- Further arguments is a list of source objects. + +It copies the properties of all source objects into the target `dest`, and then returns it as the result. + +For example, we have `user` object, let's add a couple of permissions to it: + +```js run +let user = { name: "John" }; + +let permissions1 = { canView: true }; +let permissions2 = { canEdit: true }; + +*!* +// copies all properties from permissions1 and permissions2 into user +Object.assign(user, permissions1, permissions2); +*/!* + +// now user = { name: "John", canView: true, canEdit: true } +alert(user.name); // John +alert(user.canView); // true +alert(user.canEdit); // true +``` + +If the copied property name already exists, it gets overwritten: + +```js run +let user = { name: "John" }; + +Object.assign(user, { name: "Pete" }); + +alert(user.name); // now user = { name: "Pete" } +``` + +We also can use `Object.assign` to perform a simple object cloning: + +```js run +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = Object.assign({}, user); +*/!* + +alert(clone.name); // John +alert(clone.age); // 30 +``` + +Here it copies all properties of `user` into the empty object and returns it. + +There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial. + +## Nested cloning + +Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. + +Like this: +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +alert( user.sizes.height ); // 182 +``` + +Now it's not enough to copy `clone.sizes = user.sizes`, because `user.sizes` is an object, and will be copied by reference, so `clone` and `user` will share the same sizes: + +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +let clone = Object.assign({}, user); + +alert( user.sizes === clone.sizes ); // true, same object + +// user and clone share sizes +user.sizes.width = 60; // change a property from one place +alert(clone.sizes.width); // 60, get the result from the other one +``` + +To fix that and make `user` and `clone` truly separate objects, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning. + + +### structuredClone + +The call `structuredClone(object)` clones the `object` with all nested properties. + +Here's how we can use it in our example: + +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +*!* +let clone = structuredClone(user); +*/!* + +alert( user.sizes === clone.sizes ); // false, different objects + +// user and clone are totally unrelated now +user.sizes.width = 60; // change a property from one place +alert(clone.sizes.width); // 50, not related +``` + +The `structuredClone` method can clone most data types, such as objects, arrays, primitive values. + +It also supports circular references, when an object property references the object itself (directly or via a chain or references). + +For instance: + +```js run +let user = {}; +// let's create a circular reference: +// user.me references the user itself +user.me = user; + +let clone = structuredClone(user); +alert(clone.me === clone); // true +``` + +As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well. + +Although, there are cases when `structuredClone` fails. + +For instance, when an object has a function property: + +```js run +// error +structuredClone({ + f: function() {} +}); +``` + +Function properties aren't supported. + +To handle such complex cases we may need to use a combination of cloning methods, write custom code or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com). + +## Summary + +Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself. + +All operations via copied references (like adding/removing properties) are performed on the same single object. + +To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). diff --git a/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg new file mode 100644 index 000000000..267f04578 --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg @@ -0,0 +1 @@ +username \ No newline at end of file diff --git a/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg new file mode 100644 index 000000000..a847fb200 --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg @@ -0,0 +1 @@ +useradminname \ No newline at end of file diff --git a/1-js/04-object-basics/02-object-copy/variable-copy-value.svg b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg new file mode 100644 index 000000000..0d6ca67bc --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg @@ -0,0 +1 @@ +"Hello!"message"Hello!"phrase \ No newline at end of file diff --git a/1-js/04-object-basics/02-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md similarity index 57% rename from 1-js/04-object-basics/02-garbage-collection/article.md rename to 1-js/04-object-basics/03-garbage-collection/article.md index 9fa73c653..d9a275110 100644 --- a/1-js/04-object-basics/02-garbage-collection/article.md +++ b/1-js/04-object-basics/03-garbage-collection/article.md @@ -18,15 +18,26 @@ Basit bir şekilde; *erişilebilir* değerler yararlıdır mantığı vardır. B - Global değişkenler. - (dahili değişkenler.) +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Bu değerlere *kökler* veya *roots* denir. 2. Eğer kökten herhangi bir değişkene erişilebiliyorsa, bu zincirleme referanslarla veya referanslarla olabilir, bu durumda o değişken *erişilebilir*dir. +======= + - The currently executing function, its local variables and parameters. + - Other functions on the current chain of nested calls, their local variables and parameters. + - Global variables. + - (there are some other, internal ones as well) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md Örneğin, yerel bir obje özellikleri içinde başka bir obje kullanırsa, o kullandığı obje de erişilibilir olmaktadır. Eğer referans verilen obje de başka bir objeye referans verirse o da erişilebilir olur. Detaylı bir örneği aşağıdaki gibidir. JavaScript arka planda [Çöp Toplama](https://tr.wikipedia.org/wiki/%C3%87%C3%B6p_toplama_(bilgisayar_bilimi)) işlemini çalıştırır. Bu tüm erişelemeyen objeleri silme işini yapar. +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md ## Basit bir örnek +======= + For instance, if there's an object in a global variable, and that object has a property referencing another object, *that* object is considered reachable. And those that it references are also reachable. Detailed examples to follow. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md En basit örnek şu şekildedir: @@ -74,7 +85,11 @@ kullanici = null; ``` ... Obje hala `yonetici` vasıtasıyla erişilebilir durumdadır. Öyleyse Çöp Toplama(Garbage Collector) bu objeyi silmeyecektir. Fakat `yonetici` değişkeninin de üzerine yazılırsa bu durumda objeye refans kalmayacağından hafızadan silinecektir. +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md ## Birbirine bağlı objeler. +======= +...Then the object is still reachable via `admin` global variable, so it must stay in memory. If we overwrite `admin` too, then it can be removed. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md Şimdiki örnek ise biraz daha karmaşık: @@ -101,7 +116,11 @@ Son tahlilde hafıza haritası şu şekildedir: ![](family.svg) +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Şu anda tüm objeler erişilebilir durumdadır. +======= +![](family.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md İki referans silinirse: @@ -137,7 +156,11 @@ Hafızadaki görüntüsü şu şekilde olur: ![](family-no-family.svg) +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Bu örnek erişilebilirliğin ne kadar önemli bir konsept olduğunu gösterir. +======= +![](family-no-family.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md `İhsan` ve `Macide`'nin hala birbirine bağlantısı vardır. Fakat bunlar sadece kendi aralarındadır ve yeterli değildir. @@ -155,7 +178,15 @@ Aşağıdaki Çöp Toplama işlemleri düzenli olarak yapılır: - ... Bu şekilde ziyaret edilmemiş ziyaret edilmemiş referanslar bulunur. - İşaretlenmemiş olanlar silinir. +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Diyelimki obje yapısı aşağıdaki gibi olsun: +======= +- The garbage collector takes roots and "marks" (remembers) them. +- Then it visits and "marks" all references from them. +- Then it visits marked objects and marks *their* references. All visited objects are remembered, so as not to visit the same object twice in the future. +- ...And so on until every reachable (from the roots) references are visited. +- All objects except marked ones are removed. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md ![](garbage-collection-1.svg) @@ -166,34 +197,67 @@ Diyelimki obje yapısı aşağıdaki gibi olsun: ![](garbage-collection-2.svg) +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Sonra bunların referansları: ![](garbage-collection-3.svg) ...Sonra eğer mümkün ise referansların referansları: +======= +Then we follow their references and mark referenced objects: + +![](garbage-collection-3.svg) + +...And continue to follow further references, while possible: + +![](garbage-collection-4.svg) +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md ![](garbage-collection-4.svg) +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Son adım olarak ziyaret edilmeyen objeler "ulaşılamaz" addedilip silinir: ![](garbage-collection-5.svg) JavaScript motoru bunu hızlıca çalıştırmak ve kodun çalışmasını etkilememek için birçok optimizsyon yapar. +======= +![](garbage-collection-5.svg) + +We can also imagine the process as spilling a huge bucket of paint from the roots, that flows through all references and marks all reachable objects. The unmarked ones are then removed. + +That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not introduce any delays into the code execution. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md Bazı Optimizasyonlar: - **Jenerason Koleksiyonu** -- objeler iki kümeye ayrılır: "yeni olanlar" ve "eski olanlar". Çoğu obje birden var olur, işini hızlı bir şekilde yapar ve hızlıca ölür, bunların hemen silinmesi gerekir. Eğer silinemediler ise bu defa eskiler kümesine girerler ve daha az sıklıkla silinirler. +======= +- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". In typical code, many objects have a short life span: they appear, do their job and die fast, so it makes sense to track new objects and clear the memory from them if that's the case. Those that survive for long enough, become "old" and are examined less often. +- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine splits the whole set of existing objects into multiple parts. And then clear these parts one after another. There are many small garbage collections instead of a total one. That requires some extra bookkeeping between them to track changes, but we get many tiny delays instead of a big one. +- **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution. + +There exist other optimizations and flavours of garbage collection algorithms. As much as I'd like to describe them here, I have to hold off, because different engines implement different tweaks and techniques. And, what's even more important, things change as engines develop, so studying deeper "in advance", without a real need is probably not worth that. Unless, of course, it is a matter of pure interest, then there will be some links for you below. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md - **Artımlı Koleksiyon** -- Eğer çok fazla sayıda obje varsa bu objeleri bir seferde dolaşmak çok fazla zaman alacaktır. Kod çalışırken belki biraz yavaşlamaya neden olabilir. Bundan dolayı motorlar genelde çöp toplama işini bölümlere ayırırlar. Bu bölümleri ayrı ayrı çalışır. Tabi kendileri arasında bir şekilde değişiklikleri bildirmeleri gerekir, fakat bir tane büyük yerine bu şekilde küçük küçük işlemler hızı artırmaktadık. +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md - **Boş zaman Koleksiyonu** -- Çöp toplayıcı genelde CPU kullanılmadığı zamanlarda çalışır, böylece kodun çalışmasına olan etki en aza iner. +======= +- Garbage collection is performed automatically. We cannot force or prevent it. +- Objects are retained in memory while they are reachable. +- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md Bunlarla birlikte başka optimizasyon ve çöp toplama algoritmaları bulunmaktadır. Her motor kendine göre farklı optimizasyonu beraberinde getirir. Daha da önemlisi motor geliştikçe bakış açıları değişir. Analizler artar. Eğer gerçekten ilginizi çekiyorsa bu konu aşağıdaki linkler size yol gösterecektir. +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/article.md ## Özet Bilinmesi gereken temeller: @@ -211,3 +275,10 @@ Eğer alt seviye diller ile aranız iyi ise, daha derinlemesine bilgiyi aşağı [V8 blog](http://v8project.blogspot.com/) Arada bir hafıza yönetimi hakkında belge yayınlamaktadır. Doğal olarak, çöp toplama hakkında bilgi sahibi olunmak isteniyorsa dahili yapıların bilinmesi gerekmektedir. Bu yapılar [Vyacheslav Egorov](http://mrale.ph) takip edilerek öğrenilebilir. Kendisi "V8" motoru mühendislerindendir. "V8"in önerilmesinin nedeni internette hakkında çokça bilgi bulunabilmesinden dolayıdır. Diğer motorlar için çoğu yaklaşım benzerdir fakat çöp toplama birçok yönden farklılık gösterir. Alt-seviye optimizasyonu istendiğinde derinlemesine bilgi sahibi olunması gerekmektedir. JavaScript dilini öğrendikten sonra bu yolda ilerlenmesi daha mantıklı olur. +======= +If you are familiar with low-level programming, more detailed information about V8's garbage collector is in the article [A tour of V8: Garbage Collection](https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection). + +The [V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn more about garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](https://mrale.ph) who worked as one of the V8 engineers. I'm saying: "V8", because it is best covered by articles on the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects. + +In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/article.md diff --git a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg similarity index 55% rename from 1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg rename to 1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg index a67ffc3cc..cab9ca8d5 100644 --- a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg @@ -53,4 +54,7 @@ - \ No newline at end of file + +======= +<global variable>ObjectObjectwifefamilyname: "John"name: "Ann"motherObjectfatherhusband +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg similarity index 60% rename from 1-js/04-object-basics/02-garbage-collection/family-no-family.svg rename to 1-js/04-object-basics/03-garbage-collection/family-no-family.svg index df8601215..c8a838f66 100644 --- a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/family-no-family.svg @@ -54,4 +55,7 @@ - \ No newline at end of file + +======= +<global>ObjectObjectfatherwifename: "John"name: "Ann"motherObjecthusbandfamily: null +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/family-no-family.svg diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg similarity index 52% rename from 1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg rename to 1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg index 502785902..956f7af74 100644 --- a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg @@ -30,4 +31,7 @@ - \ No newline at end of file + +======= +Objectfamilyname: "Ann"motherObject<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg similarity index 61% rename from 1-js/04-object-basics/02-garbage-collection/family-no-father.svg rename to 1-js/04-object-basics/03-garbage-collection/family-no-father.svg index 9837ced82..069405e14 100644 --- a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/family-no-father.svg @@ -47,4 +48,7 @@ - \ No newline at end of file + +======= +ObjectObjectwifefamilyname: "John"name: "Ann"motherObject<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/family-no-father.svg diff --git a/1-js/04-object-basics/02-garbage-collection/family.svg b/1-js/04-object-basics/03-garbage-collection/family.svg similarity index 54% rename from 1-js/04-object-basics/02-garbage-collection/family.svg rename to 1-js/04-object-basics/03-garbage-collection/family.svg index 6c66e8569..6b8d34e98 100644 --- a/1-js/04-object-basics/02-garbage-collection/family.svg +++ b/1-js/04-object-basics/03-garbage-collection/family.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/family.svg @@ -49,4 +50,7 @@ - \ No newline at end of file + +======= +ObjectObjectfatherwifefamilyname: "John"name: "Ann"motherObjecthusband<global variable> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/family.svg diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg similarity index 59% rename from 1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg rename to 1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg index d3bc5ce94..739610740 100644 --- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg @@ -159,4 +160,7 @@ - \ No newline at end of file + +======= +<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg similarity index 62% rename from 1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg rename to 1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg index c7311022a..dc382a133 100644 --- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg @@ -175,4 +176,7 @@ - \ No newline at end of file + +======= +<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg similarity index 63% rename from 1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg rename to 1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg index a0ce257e3..19a1e246b 100644 --- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg @@ -187,4 +188,7 @@ - \ No newline at end of file + +======= +<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg similarity index 63% rename from 1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg rename to 1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg index bc5a035c7..aef55f972 100644 --- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg @@ -191,4 +192,7 @@ - \ No newline at end of file + +======= +<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg similarity index 64% rename from 1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg rename to 1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg index 150aa9265..b8c73922b 100644 --- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg @@ -209,4 +210,7 @@ - \ No newline at end of file + +======= +<global>unreachables +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg similarity index 51% rename from 1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg rename to 1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg index bc7a23d33..949b38c8a 100644 --- a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg @@ -26,4 +27,7 @@ - \ No newline at end of file + +======= +username: "John"Objectadmin<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg similarity index 61% rename from 1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg rename to 1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg index 78009e310..6b417596f 100644 --- a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg @@ -1,3 +1,4 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg @@ -27,4 +28,7 @@ - \ No newline at end of file + +======= +name: "John"Objectuser: null<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg diff --git a/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg new file mode 100644 index 000000000..522c1dfeb --- /dev/null +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg @@ -0,0 +1,29 @@ +<<<<<<< HEAD:1-js/04-object-basics/02-garbage-collection/memory-user-john.svg + + + + memory-user-john.svg + Created with sketchtool. + + + + user + + + + name: "John" + + + Object + + + + + <global> + + + + +======= +username: "John"Object<global> +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533:1-js/04-object-basics/03-garbage-collection/memory-user-john.svg diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index 4008245f1..293c9a5a0 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -7,7 +7,7 @@ function kullaniciOlustur() { isim: "İhsan", ref: this }; -}; +} let kullanici = kullaniciOlustur(); @@ -21,7 +21,24 @@ Ve objet tanımının `this`'e doğrudan bir etkisi yoktur. `this` tüm fonksiyo Öyleyse, `ref: this` aslında fonksiyonun `thsi` değerini alır. +<<<<<<< HEAD Şimdi tersi bir duruma bakalım: +======= +So `ref: this` actually takes current `this` of the function. + +We can rewrite the function and return the same `this` with `undefined` value: + +```js run +function makeUser(){ + return this; // this time there's no object literal +} + +alert( makeUser().name ); // Error: Cannot read property 'name' of undefined +``` +As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example. + +Here's the opposite case: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run function kullaniciOlustur() { @@ -33,7 +50,7 @@ function kullaniciOlustur() { } */!* }; -}; +} let kullanici = kullaniciOlustur(); diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index a3f261239..2a007bb45 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -14,7 +14,7 @@ function kullaniciOlustur() { isim: "İhsan", ref: this }; -}; +} let kullanici = kullaniciOlustur(); diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js index 20cd39aec..c97704a5e 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js @@ -15,6 +15,11 @@ describe("hesapMakinesi", function () { afterEach(function () { prompt.restore(); }); + + it('the read get two values and saves them as object properties', function () { + assert.equal(calculator.a, 2); + assert.equal(calculator.b, 3); + }); it("toplam 5", function () { assert.equal(hesapMakinesi.topla(), 5); diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index 9e6ce5f97..0118cb43b 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -6,9 +6,15 @@ importance: 5 `hesapMakinesi` objesini aşağıdaki üç metod ile oluşturunuz: +<<<<<<< HEAD - `oku()` veri giriş ekranı gösterir ve iki değeri objenin özelliklerine kaydeder. - `topla()` kaydedilen değerlerin toplamını döner. - `carp()` kaydedilen değerlerin çarpımını döner. +======= +- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. +- `sum()` returns the sum of saved values. +- `mul()` multiplies saved values and returns the result. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let hesapMakinesi = { @@ -21,4 +27,3 @@ alert( hesapMakinesi.carp() ); ``` [demo] - diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js index a552d87c1..4eff1e92a 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js @@ -9,8 +9,14 @@ let merdiven = { this.adim--; return this; }, +<<<<<<< HEAD adimiGoster: function () { alert(this.adim); +======= + showStep: function() { + alert(this.step); + return this; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 } }; diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index f6be774b2..2cd4038e6 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -33,8 +33,22 @@ describe('merdiven', function () { assert.equal(merdiven.asagi().yukari().yukari().yukari().adim, 2); }); +<<<<<<< HEAD after(function () { merdiven.adim = 0; alert.kaydet(); +======= + it('showStep() should return this', function() { + assert.equal(ladder.showStep(), ladder); + }); + + it('up().up().down().showStep().down().showStep()', function () { + assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0) + }); + + after(function() { + ladder.step = 0; + alert.restore(); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 }); }); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 974564b82..9aeb38daf 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -21,9 +21,13 @@ let merdiven = { return this; */!* } -} +}; +<<<<<<< HEAD merdiven.yukari().yukari().asagi().yukari().asagi().adimiGoster();//1 +======= +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` Ayrıca her satır için tek çağrı da yazılabilir. Uzun zincirleme fonksiyonlar için bu daha okunabilirdir. @@ -33,6 +37,14 @@ merdiven .yukari() .asagi() .up() +<<<<<<< HEAD .asagi() .adimiGoster(); // 1 +======= + .up() + .down() + .showStep() // 1 + .down() + .showStep(); // 0 +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index 05c8b3c75..1b96f3a37 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -4,7 +4,11 @@ importance: 2 # Zincirleme +<<<<<<< HEAD `merdiven` objesi yukarı aşağı harekete izin vermektedir: +======= +There's a `ladder` object that allows you to go up and down: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let merdiven = { @@ -20,6 +24,7 @@ let merdiven = { } }; ``` +<<<<<<< HEAD Eğer aşağıdaki gibi ard arda çağrı yapılırsa: ```js @@ -36,3 +41,24 @@ merdiven.yukari().yukari().asagi().adimiGoster(); // 1 ``` Bu yaklaşım çoğu JavaScript kütüphanesinde yaygın olarak kullanılmaktadır. +======= + +Now, if we need to make several calls in sequence, we can do it like this: + +```js +ladder.up(); +ladder.up(); +ladder.down(); +ladder.showStep(); // 1 +ladder.down(); +ladder.showStep(); // 0 +``` + +Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this: + +```js +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 +``` + +Such an approach is widely used across JavaScript libraries. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 5daae66ca..d34702195 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -36,11 +36,19 @@ kullanici.selamVer(); // Merhaba ``` Burada Fonksiyon ifadesi ile fonksiyon yaratıldı ve `kullanici.selamVer` özelliğine atandı. +<<<<<<< HEAD Ardından bu metod çağırıldı ve kullanıcı selam verdi. Bir objenin özelliği olan fonksiyona *metod* denir. Öyleyse `kullanici` objesinin `selamVer` metodu bulunmaktadır. +======= +Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object. + +Then we can call it as `user.sayHi()`. The user can now speak! + +A function that is a property of an object is called its *method*. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Tabii ki metodları önceden tanımlanmış fonksiyonlarla da oluşturabilirsiniz. Örneğin: @@ -50,10 +58,17 @@ let kullanici = { }; *!* +<<<<<<< HEAD // önce tanımla function selamVer() { alert("Merhaba!"); }; +======= +// first, declare +function sayHi() { + alert("Hello!"); +} +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 // Sonra bunu metod olarak objeye ekle kullanici.selamVer = selamVer; @@ -62,11 +77,18 @@ kullanici.selamVer = selamVer; kullanici.selamVer(); // Merhaba! ``` +<<<<<<< HEAD ```smart header="Nesne Tabanlı Programlama" Varlıkların obje olarak tanımlandığı dillere [obje tabanlı diller](https://en.wikipedia.org/wiki/Object-oriented_programming), kısaca: "OOP"(Objet-Oriented Programming) OOP kendi başına kitaplar dolusu anlatılacak bir konudur. Nasıl doğru varlıklar seçilmeli? Bu varlıklar arasında nasıl bir iletişim olmalı? Mimarisi nasıl olmalı, gibi konuların her birisi ile ilgili ayrı ayrı kitaplar bulunmaktadır. Örneğin "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, vs. Bu kitapta sadece başlangıç seviyesinde anlatılacaktır. +======= +```smart header="Object-oriented programming" +When we write our code using objects to represent entities, that's called [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". + +OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E. Gamma, R. Helm, R. Johnson, J. Vissides or "Object-Oriented Analysis and Design with Applications" by G. Booch, and more. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` ### Metod Kısayolu @@ -84,7 +106,11 @@ let kullanici = { // kısa yolu daha güzel görünüyor değil mi? let kullanici = { *!* +<<<<<<< HEAD selamVer() { // "selamVer: function()" ile aynı +======= + sayHi() { // same as "sayHi: function(){...}" +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 */!* alert("Merhaba"); } @@ -93,7 +119,11 @@ let kullanici = { Yukarıda da gösterildiği gibi `"function"` pas geçilerek sadece `selamVer()` yazılabilir. +<<<<<<< HEAD Doğrusunu söylemek gerekirse iki fonksiyonda birbiri ile aynı. Altta yatan farklılık ise kalıtım ile alakalı ki bu da şimdilik bir sorun teşkil etmiyor. Çoğu durumda kısa yazım tercih edilmektedir. +======= +To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ## Metodlarda `this` kullanımı @@ -113,7 +143,12 @@ let kullanici = { selamVer() { *!* +<<<<<<< HEAD alert(this.isim); +======= + // "this" is the "current object" + alert(this.name); +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 */!* } @@ -158,17 +193,29 @@ let kullanici = { let yonetici = kullanici; kullanici = null; +<<<<<<< HEAD yonetici.selamVer(); // `selamVer()` içerisinde `kullanici` kullanıldığından dolayı hata verecektir. +======= +*!* +admin.sayHi(); // TypeError: Cannot read property 'name' of null +*/!* +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` Eğer `kullanici.isim` yerine `this.isim` yazmış olsaydınız kod çalışacaktı. +<<<<<<< HEAD ## "this" bağımsız bir şekilde kullanılabilir. Diğer dillerden farklı olarak "this" kelimesi yer gözetmeksizin kullanılabilir. Her fonksiyonun içinde kullanılabilir. Aşağıdaki kodda bir yazım hatası yoktur: +======= +In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. + +There's no syntax error in the following example: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js function selamVer() { @@ -176,7 +223,11 @@ function selamVer() { } ``` +<<<<<<< HEAD `this`'in değeri çalışma anında değerlendirilir. Her şey olabilir. +======= +The value of `this` is evaluated during the run-time, depending on the context. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Örneğin `this` farklı objelerden çağırıldıklarında değerler alabilirler: @@ -217,11 +268,16 @@ Sıkı modda `this` `undefined` döndürür. Eğer `this.isim` yazılırsa hata Normal modda ise ( `use strict` unutulursa) `this` değeri *global obje* olur. Tarayıcı için bu `window`dur. Bu konuya daha sonra değinilecektir. +<<<<<<< HEAD Obje olmadan `this` çağırmak normal değildir, bir programlama hatasıdır. Eğer fonksiyon `this` içeriyorsa, o objenin dahilinde çağırılabileceği anlamı çıkar. +======= +Usually such call is a programming error. If there's `this` inside a function, it expects to be called in an object context. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```` ```smart header="Sınırsız `this` kullanmanın yan etkileri" +<<<<<<< HEAD Diğer programlama dillerinden geliyorsanız, "bağımlı `this`" kullanımına alışmış olmalısınız. Metod içerisinde kullanılan `this` her zaman o objeye referans olur. JavaScript'te `this` bağımsızdır. Değeri çalışma anında belirlenir, hangi metodda yazıldığı önemli değildir, önemli olan "noktadan önceki" objedir. @@ -320,6 +376,16 @@ Bundan dolayı `this` in çalışabilmesi için metodun doğrudan `obj.metod()` ## Ok fonksiyonlarında "this" bulunmamaktadır. Ok fonksiyonları özeldir: Kendilerinin `this`'i bulunmaz. Eğer yine de `this` kullanırsanız ok fonksiyonu dışındaki bölümü `this` olarak alır. +======= +In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is "before the dot". + +The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, the greater flexibility creates more possibilities for mistakes. + +Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and avoid problems. +``` + +## Arrow functions have no "this" +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Örneğin aşağıdaki `ok()` dışarıda bulunan `kullanici.selamVer()` metodunu kullanmaktadır: @@ -348,4 +414,17 @@ Bu ok fonksiyonlarının bir özelliğidir. Ayrı bir `this` kullanmak yerine he - O fonksiyon objeler arasında kopyalanabilir. - Fonksiyon metod yazım şekliyle çağırıldığında `obje.metod()`, `this`'in değeri bu çağrı boyunca `obje`'dir. +<<<<<<< HEAD Ok fonksiyonlarında `this` bulunmamaktadır. Eğer bu fonksiyonlar içerisinde `this` çağırılırsa bunun değeri dışarıdan alınır. +======= +- Functions that are stored in object properties are called "methods". +- Methods allow objects to "act" like `object.doSomething()`. +- Methods can reference the object as `this`. + +The value of `this` is defined at run-time. +- When a function is declared, it may use `this`, but that `this` has no value until the function is called. +- A function can be copied between objects. +- When a function is called in the "method" syntax: `object.method()`, the value of `this` during the call is `object`. + +Please note that arrow functions are special: they have no `this`. When `this` is accessed inside an arrow function, it is taken from outside. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md index 7901fd216..8a35f032b 100644 --- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md +++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md @@ -4,14 +4,18 @@ importance: 2 # İki fonksiyon - bir obje +<<<<<<< HEAD `new A() == new B()` şeklinde `A` ve `B` fonksiyonları yaratmak mümkün müdür? +======= +Is it possible to create functions `A` and `B` so that `new A() == new B()`? +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js no-beautify function A() { ... } function B() { ... } -let a = new A; -let b = new B; +let a = new A(); +let b = new B(); alert( a == b ); // true ``` diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js index 9049ae240..8ca6cfe73 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js @@ -10,6 +10,11 @@ describe("hesapMakinesi", function () { hesapMakinesi = new HesapMakinesi(); hesapMakinesi.oku(); }); + + it("the read method asks for two values using prompt and remembers them in object properties", function() { + assert.equal(calculator.a, 2); + assert.equal(calculator.b, 3); + }); it("2 ile 3 toplanınca sonuç 5 çıkar.", function () { assert.equal(hesapMakinesi.topla(), 5); diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md index 1f80bbcea..833275516 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md @@ -6,6 +6,12 @@ importance: 5 Yapıcı `HesapMakinesi` fonksiyonunu yazınız ve aşağıdaki üç fonksiyonu buna uygulayınız: +<<<<<<< HEAD +======= +- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. +- `sum()` returns the sum of these properties. +- `mul()` returns the multiplication product of these properties. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 - `oku()` veri giriş ekranı gösterir ve iki değeri objenin özelliklerine kaydeder. - `topla()` kaydedilen değerlerin toplamını döner. diff --git a/1-js/04-object-basics/06-constructor-new/3-accumulator/task.md b/1-js/04-object-basics/06-constructor-new/3-accumulator/task.md index c79681552..33624e931 100644 --- a/1-js/04-object-basics/06-constructor-new/3-accumulator/task.md +++ b/1-js/04-object-basics/06-constructor-new/3-accumulator/task.md @@ -16,10 +16,19 @@ Diğer bir deyişle `deger` özelliği tüm kullanıcıların girdiği değerler Aşağıda bir demosunu görmektesiniz: ```js +<<<<<<< HEAD let toplayici = new Toplayici(1); // toplayıcıya 1 ile başla. toplayici.oku(); // kullanıcının girdiği değeri toplar. toplayici.oku(); // kullanıcının girdiği değeri toplar. alert(toplayici.deger); // toplamı gösterir. +======= +let accumulator = new Accumulator(1); // initial value 1 + +accumulator.read(); // adds the user-entered value +accumulator.read(); // adds the user-entered value + +alert(accumulator.value); // shows the sum of these values +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` [demo] diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md index 5713e853d..a67ab7bd5 100644 --- a/1-js/04-object-basics/06-constructor-new/article.md +++ b/1-js/04-object-basics/06-constructor-new/article.md @@ -1,6 +1,10 @@ # Yapıcı, "new" operatörü +<<<<<<< HEAD `{ ... }` yazımı bir objenin yaratılmasına yarar. Fakat bir objenin benzeri farklı objeler yaratmak istenebilir. Örneğin farklı kullanıcılar, farklı menü değerleri. +======= +The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Bu yapıcı fonksiyon ve `"new"` operatörü ile yapılabilir. @@ -30,9 +34,13 @@ alert(kullanici.yoneticiMi); // false ``` Fonksiyon `new Kullanici(...)` şeklinde çalıştığında, aşağıdaki adımlar izlenir: +<<<<<<< HEAD 1. Yeni bir obje yaratılır ve `this` bu obje olur. 2. Fonksiyon gövdesi çalışır. Genelde `this` modifiye edilir ve yeni özellikler eklenir. 3. `this` değeri dönderilir. +======= +When a function is executed with `new`, it does the following steps: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 Diğer bir deyişle, `new Kullanici(...)` şöyle yapar: @@ -52,7 +60,11 @@ function Kullanici(isim) { } ``` +<<<<<<< HEAD Öyleyse `new Kullanici("İhsan") objesi aşağıdaki gibidir: +======= +So `let user = new User("Jack")` gives the same result as: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let kullanici = { @@ -64,6 +76,7 @@ Eğer başka bir kullanici oluşturmak istiyorsanız, yapmanız gereken `new Kul Yapıcı fonksiyonların amacı -- tekrar kullanılabilecek objeleri yaratan kodun uygulanmasıdır. +<<<<<<< HEAD Dikkat edecek olursanız, herhangi bir fonksiyon yapıcı fonksiyon olarabilir. Her fonksiyon `new` ile çalıştırılabilir, ve yukarda anlatılan algoritmaya göre çalışır. "Yapıcı fonksiyon isimleri büyük harfle başlamalıdır" aslında genel bir ittifaktır, bunu daha da açıklayıcı yapmak için bu fonksiyonlar `new` ile çağırılmalıdır. ````smart header="new function() { ... }" @@ -73,12 +86,31 @@ Eğer birçok satırdan oluşan kodda amacınız sadece karmaşık bir obje yapm let kullanici = new function() { this.isim = "İhsan"; this.yonetici = false; +======= +That's the main purpose of constructors -- to implement reusable object creation code. + +Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`. + +````smart header="new function() { ... }" +If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this: + +```js +// create a function and immediately call it with new +let user = new function() { + this.name = "John"; + this.isAdmin = false; +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 // diğer karmaşık yapılar // mantıklar veya yerel değişkenler }; ``` +<<<<<<< HEAD Yapıcı fonksiyon tekrar çağırılamaz çünkü hiçbir yere kayıt edilmemiştir, sadece yaratılır ve çağırılır. Böylece yapıcı metod ilerde tekrar kullanılmayacağına garanti verir. +======= + +This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse. +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```` ## Yapıcı modu testi: new.target @@ -89,7 +121,11 @@ Bu olay çok nadir kullanılır. Eğer her şeyi öğrenmek istemiyorsanız bura Fonksiyon içinde, bu fonksiyon `new` ile mi yoksa `new` olmadan mı çağırılmış bu `new.target` özelliği kullanılarak anlaşılabilir. +<<<<<<< HEAD Normal çağrılarda bunun içerisi boştur fakat `new` ile çağrılırsa: +======= +It is undefined for regular calls and equals the function if called with `new`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run function Kullanici() { @@ -130,17 +166,33 @@ Fakat `return` sözcüğü var ise kurallar basittir: Diğer bir deyişle, obje ile `return` kullanıldığında obje döner, diğer tüm hallerde `this` döner. +<<<<<<< HEAD Örneğin aşağıda `return` edilen obje `this` yerine dönderilir. +======= +- If `return` is called with an object, then the object is returned instead of `this`. +- If `return` is called with a primitive, it's ignored. + +In other words, `return` with an object returns that object, in all other cases `this` is returned. + +For instance, here `return` overrides `this` by returning an object: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js run function BuyukKullanici() { this.isim = "İhsan"; +<<<<<<< HEAD return { isim: "Muhsin" }; // <-- obje dönderir } alert( new BuyukKullanici().isim ); // Muhsin, objeyi aldık ^^ +======= + return { name: "Godzilla" }; // <-- returns this object +} + +alert( new BigUser().name ); // Godzilla, got that object +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ``` Şimdi ise boş bir `return` cümlesi yazalım( eğer ilkel bir tipte kullanılsa bir şey değiştirmez) @@ -149,8 +201,12 @@ function KucukKullanici() { this.isim = "İhsan"; +<<<<<<< HEAD return; // çalışmayı bitirir ve `this`'i döndürür. +======= + return; // <-- returns this +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 } alert( new KucukKullanici().isim ); // İhsan @@ -159,7 +215,12 @@ Genelde yapıcılar `return` sözcüğü kullanmazlar. Buarada amaç bütünlü ````smart header="Parantezlerin yazılmaması" +<<<<<<< HEAD Bu arada `new`'den sonra eğer bir argüman yoksa parantez kullanmasanız da olur: +======= +````smart header="Omitting parentheses" +By the way, we can omit parentheses after `new`: +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 ```js let kullanici = new Kullanici; // <-- parantez yok @@ -200,7 +261,13 @@ ihsan = { */ ``` +<<<<<<< HEAD ## Özet +======= +To create complex objects, there's a more advanced syntax, [classes](info:classes), that we'll cover later. + +## Summary +>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533 - Yapıcı fonksiyonlar, veya kısaca yapıcılar, normal fonksiyonlardır. Fakat baş haflerinin büyük olmasıyla ilgili ortak bir kullanım vardır. - Bu fonksiyonlar sadece `new` kullanılarak çağırılmalıdır. Böyle çağrılar önce boş bir `this` yaratır ve buna değerler eklendikten sonra bu `this`'i geri gönderir. diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md new file mode 100644 index 000000000..4c6029423 --- /dev/null +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -0,0 +1,233 @@ + +# Optional chaining '?.' + +[recent browser="new"] + +The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist. + +## The "non-existing property" problem + +If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common. + +As an example, let's say we have `user` objects that hold the information about our users. + +Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them. + +In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error: + +```js run +let user = {}; // a user without "address" property + +alert(user.address.street); // Error! +``` + +That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error. + +In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street"). + +...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element. + +```js run +// document.querySelector('.elem') is null if there's no element +let html = document.querySelector('.elem').innerHTML; // error if it's null +``` + +Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal