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 5c6a93cff..3c940bab8 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -24,26 +24,44 @@ Browser punya engine yang tertanam didalamnya yang disebut "JavaScript virtual m
Tiap engine punya *codename*-nya sendiri. Misalnya:
+<<<<<<< HEAD
- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- di Chrome dan Opera.
- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- di Firefox.
- ...Ada juga codename lain seperti "Trident" dan "Chakra" untuk versi berbeda dari IE, "ChakraCore" untuk Microsoft Edge, "Nitro" dan "SquirrelFish" untuk Safari, dll.
Istilah di atas sebaiknya diingat karena akan sering digunakan dalam artikel para developer di internet. Kita akan menggunakannya juga. Misalnya, jika "fitur X didukung V8", kemungkinan ia bisa jalan di Chrome dan Opera.
+=======
+- [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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Bagaimana engine bekerja?"
Engine sangat rumit. Tapi basicnya mudah.
+<<<<<<< HEAD
1. Engine (tertanam jika ia sebuah browser)bisa membaca ("memparsing") script.
2. Lalu ia mengkonversi ("mengkompilasi") script tersebut menjadi bahasa mesin.
3. Dan kemudian kode mesin berjalan, lumayan cepat.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Engine melakukan optimisasi di setiap langkah proses. Dia bahkan memperhatikan script yang telah dikompilasi saat sedang berjalan, menganalisa data yang mengalir di dalam, dan melakukan optimisasi ke kode mesin berdasarkan pengetahuan itu.
```
## Apa yang bisa dilakukan *in-browser JavaScript*?
+<<<<<<< HEAD
JavaScript modern merupakan bahasa pemrograman yang "aman". Ia tidak menyebabkan akses tingkat-rendah ke memory atau CPU, karena memang awalnya dibuat untuk browser, yang tentunya tidak membutuhkan hal tersebut.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kemampuan JavaScript sangat tergantung pada lingkungan tempat ia berjalan. Misalnya, [Node.js](https://wikipedia.org/wiki/Node.js) mendukung function yang memungkingkan JavaScript melakukan baca/tulis file apapun, melakukan permintaan jaringan, dsb.
@@ -59,7 +77,11 @@ Misalnya, *in-browser JavaScript* mampu:
## Apa yang TIDAK BISA dilakukan *in-browser JavaScript*?
+<<<<<<< HEAD
Kemampuan JavaScript yang ada di dalam browser terbatas demi keamanan pengguna. Tujuannya supaya mencegah halaman web berbahya mengakses informasi pribadi atau merusak data pengguna.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh keterbatasan tersebut meliputi:
@@ -67,6 +89,7 @@ Contoh keterbatasan tersebut meliputi:
Browser-browser modern memperbolehkan JavaScript mengakses file, tapi aksesnya dibatasi dan tersedia hanya jika pengguna melakukan hal tertentu, misalnya seperti "menjatuhkan" file ke dalam jendela browser atau memilih file via tag ``.
+<<<<<<< HEAD
Ada beberapa cara untuk berinteraksi dengan kamera/mikrofon dan perangkat-perangkat lainnya, namun mereka butuh ijin khusus pengguna. Jadi sebuah halaman yang memiliki JavaScript tidak bisa mengaktifkan web-camera, memantau sekeliling dan mengirim informasinya ke [NSA] secara diam-diam(https://en.wikipedia.org/wiki/National_Security_Agency).
- Tab/jendela yang berbeda umumnya tidak ada hubungan sama sekali. Terkadang jendela yang berbeda bisa saling berhubungan juga, misalnya ketika satu jendela menggunakan JavaScript untuk membuka jendela lainnya. Tapi meski demikian, JavaScript dari suatu halaman tak boleh mengakses halaman lainnya jika mereka berasal dari situs yang berbeda (dari domain, protokol, atau port berbeda).
@@ -78,21 +101,44 @@ Contoh keterbatasan tersebut meliputi:

Pembatasan macam ini tidak ada jika JavaScript digunakan di luar browser, misalnya di server. Browser-browser modern juga memperbolehkan plugin/ekstensi yang membutuhkan ijin tambahan.
+=======
+ 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.
+
+
+
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Apa yang membuat JavaScript unik?
Paling tidak ada *tiga* hal unik dari JavaScript:
```compare
+<<<<<<< HEAD
+ Integrasi penuh dengan HTML/CSS.
+ Hal sederhana diselesaikan dengan sederhana.
+ Dukungan dari mayoritas web browser dan aktif secara default.
+=======
++ Full integration with HTML/CSS.
++ Simple things are done simply.
++ Supported by all major browsers and enabled by default.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
JavaScript merupakan satu-satunya teknologi browser yang mengkombinasikan ketiga poin di atas.
Itulah yang membuat JavaScript unik. Itulah kenapa JavaScript menjadi alat yang paling sering untuk membuat antarmuka browser.
+<<<<<<< HEAD
Katanya, JavaScript juga bisa dipakai untuk membuat aplikasi server, mobile, dsb.
+=======
+That said, JavaScript can be used to create servers, mobile applications, etc.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Bahasa "di atas" JavaScript
@@ -100,12 +146,17 @@ Sintaks JavaScript tidak memenuhi kebutuhan setiap orang. Masing-masing orang in
Itu wajar, karena proyek dan persyaratan tiap orang berbeda-beda.
+<<<<<<< HEAD
Akhir-akhir ini muncul banyak bahasa baru, yang *ditranspile* (dikonversi) ke JavaScript sebelum dijalankan di browser.
+=======
+So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tools modern membuat transpilasi sangat cepat dan transparan, yang memungkinkan para developer menulis kodenya dalam bahasa lain dan mengautokonversi itu "di balik layar".
Contoh bahasa yang dimaksud:
+<<<<<<< HEAD
- [CoffeeScript](http://coffeescript.org/) merupakan "syntactic sugar" dari JavaScript. Dia memperkenalkan syntax yang lebih pendek, memungkingkan kita menulis kode lebih bersih dan lebih presisi. Biasanya, Ruby devs menyukainya.
- [TypeScript](http://www.typescriptlang.org/) berfokus pada penambahan "strict data typing" yang menyederhanakan pengembangan dan dukungan sistem yang komplex. Ia dikembangkan oleh Microsoft.
- [Flow](http://flow.org/) juga menambahkan data typing, tapi dalam cara berbeda. Dikembangkan oleh Facebook.
@@ -114,9 +165,25 @@ Contoh bahasa yang dimaksud:
- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) adalah sebuah bahasa pemograman modern, ringkas dan aman yang dapat ditargetkan untuk browser atau Node.
Masih banyak lagi. Tentunya, jika kita menggunakan salah satu bahasa yang ditranspile tersebut, kita sebaiknya juga paham JavaScript untuk mengerti apa yang mereka lakukan.
+=======
+- [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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Kesimpulan
+<<<<<<< HEAD
- JavaScript awalnya diciptakan sebagai bahasa khusus browser, namun sekarang banyak digunakan di lingkungan lain.
- Sekarang, JavaScript mempunyai posisi unik sebagai bahasa browser paling banyak diadopsi dengan integrasi penuh dengan HTML/CSS.
- Ada banyak bahasa yang "ditranspile" ke JavaScript dan menyediakan fitur tertentu. Disarankan untuk mempelajari mereka juga, minimal sebentar, setelah menguasai JavaScript.
+=======
+- 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
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 b725ae550..febd875b6 100644
--- a/1-js/01-getting-started/2-manuals-specifications/article.md
+++ b/1-js/01-getting-started/2-manuals-specifications/article.md
@@ -2,7 +2,11 @@
Buku ini adalah _tutorial_. Tujuannya membantu kamu memahami bahasa ini (Javascript) pelan-pelan. Tapi sekali kamu akrab atau familiar dengan dasarnya, kamu juga membutuhkan dari sumber-sumber lain.
+<<<<<<< HEAD
## Spesifikasi
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
[Spesifikasi ECMA-262](https://www.ecma-international.org/publications/standards/Ecma-262.htm) berisi informasi formal, detil, and mendalam tentang JavaScript. Ia mendefisikan bahasa ini.
@@ -10,7 +14,11 @@ Tapi karena menjadi formal, ia sulit dipahami di awal. Jadi jika kamu butuh sumb
Versi spesifikasi baru dirilis tiap tahun. Di antara rilis ini, draft spesifikasi terakhir ada di .
+<<<<<<< HEAD
Untuk membaca tentang fitur terkini, termasuk yang "hampir menjadi standar" (disebut "stage 3"), lihat proposalnya di .
+=======
+A new specification version is released every year. Between these releases, the latest specification draft is at .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Juga, jika kamu dalam pengembangan untuk peramban, maka ada spek lain yang dibahas di [bagian kedua](info:browser-environment) di tutorial ini.
@@ -20,9 +28,15 @@ Juga, jika kamu dalam pengembangan untuk peramban, maka ada spek lain yang dibah
Kamu bisa cari di .
+<<<<<<< HEAD
Meski, sering lebih bagus menggunakan pencarian internet. Pakai "MDN [term]" di query, misal untuk mencari fungsi `parseInt`.
- **MSDN** – Manual Microsoft dengan banyak informasi, termasuk JavaScript (sering dirujuk sebagai JScript). Jika kamu butuh sesuatu yang spesifik ke Internet Explorer, lebih baik pergi ke: .
+=======
+ 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Juga, kamu bisa menggunakan pencarian internet dengan frasa seperti "RegExp MSDN" atau "RegExp MSDN jscript".
@@ -30,10 +44,17 @@ Juga, jika kamu dalam pengembangan untuk peramban, maka ada spek lain yang dibah
JavaScript merupakan bahasa berkembang, fitur baru ditambah secara reguler.
+<<<<<<< HEAD
Untuk melihat dukungan mereka pada engine berbasis peramban dan lainnya, lihat:
- - tabel dukungan per-fitur, misal untuk melihat engine mana yang mendukung fungsi kryptografi modern: .
- - tabel dengan fitur dan engine bahasa yang mendukung atau yang tidak mendukung.
+=======
+- - 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Semua sumber ini berguna di pengembangan nyata, karena mereka berisi informasi berharga tentang detil bahasa, dukungan mereka dll.
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 6bb78d36f..c3d44c490 100644
--- a/1-js/01-getting-started/3-code-editors/article.md
+++ b/1-js/01-getting-started/3-code-editors/article.md
@@ -12,8 +12,13 @@ Satu IDE meload proyek (yang bisa berupa banyak file), memungkingkan navigasi an
Jika kamu belum memilih satu IDE, pertimbangkan opsi-opsi berikut:
+<<<<<<< HEAD
- [Visual Studio Code](https://code.visualstudio.com/) (lintas-platform, gratis).
- [WebStorm](http://www.jetbrains.com/webstorm/) (lintas-platform, berbayar).
+=======
+- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
+- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Untuk Windows, ada juga "Visual Studio", jangan dipusingkan dengan "Visual Studio Code." "Visual Studio" merupakan editor khusus Windows yang keren dan berbayar, sangat cocok untuk platform .NET. Ia bagus juga untuk JavaScript. Lalu ada juga versi gratisnya [Visual Studio Community](https://www.visualstudio.com/vs/community/).
@@ -29,6 +34,7 @@ Perbedaan utama antara "editor ringan" dan "IDE" adalah IDE bekerja pada level p
Pada praktiknya, editor ringan bisa punya banyak plugin termasuk syntax analyzers dan autocompleters level direktori, jadi tak ada batasan ketat antara editor ringan dan IDE.
+<<<<<<< HEAD
Opsi-opsi berikut patut anda perhatikan:
- [Atom](https://atom.io/) (lintas-platform, gratis).
@@ -36,6 +42,13 @@ Opsi-opsi berikut patut anda perhatikan:
- [Sublime Text](http://www.sublimetext.com) (lintas-platform, shareware).
- [Notepad++](https://notepad-plus-plus.org/) (Windows, gratis).
- [Vim](http://www.vim.org/) dan [Emacs](https://www.gnu.org/software/emacs/) sangat keren juga jika kamu tahu cara pakainya.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Jangan berdebat
@@ -43,4 +56,13 @@ Daftar editor di atas merupakan barang yang sudah biasa saya atau teman-teman sa
Ada banyak editor bagus lainnya di dunia kita yang besar ini. Silakan pilih satu yang paling kamu suka.
+<<<<<<< HEAD
Pilihan editor, sama seperti tool lainnya, bersifat individual dan tergantung pada proyek, kebiasaan, dan preferensi personal.
+=======
+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).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
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 99c41f1f3..91c043f18 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -73,7 +73,11 @@ File script ditempel ke HTML dengan atribut `src`:
```
+<<<<<<< HEAD
Di sini, `/path/to/script.js` adalah jalur absolut ke file script dari root sitius. Kamu juga bisa menyediakan jalur relatif dari laman ini. Misalnya, `src="script.js"` berarti file `"script.js"` dalam folder saat ini.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kamu bisa memasang URL penuh juga. Misalnya:
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 65bc298cc..5942eb447 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,13 +12,24 @@ const birthday = '18.04.1982';
const age = someCode(birthday);
```
+<<<<<<< HEAD
Di sini kita punya konstan tanggal `birthday` dan `age` dikalkulasi dari `birthday` dengan batuan beberapa kode (tidak tersedia yang pendek-pendek, dan karena detail tidak masalah di sini).
+=======
+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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Apakah tepat menggunakan huruf kapital untuk `birthday`? Untuk `age`? Atau bahkan untuk keduanya?
```js
+<<<<<<< HEAD
const BIRTHDAY = '18.04.1982'; // buat huruf kapital?
const AGE = someCode(BIRTHDAY); // buat huruf kapital?
-```
+=======
+const BIRTHDAY = '18.04.1982'; // make birthday uppercase?
+const AGE = someCode(BIRTHDAY); // make age uppercase?
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
+```
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 0bcb35ec6..386b15566 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -24,7 +24,11 @@ Kini, kita bisa menaruh beberapa data ke dalamnya dengan menggunakan operator pe
let message;
*!*
+<<<<<<< HEAD
message = 'Hello'; // simpan string
+=======
+message = 'Hello'; // store the string 'Hello' in the variable named message
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
*/!*
```
@@ -63,7 +67,12 @@ let age = 25;
let message = 'Hello';
```
+<<<<<<< HEAD
Beberapa orang juga mendefinisi variabel ganda dalam gaya multibaris ini:
+=======
+Some people also define multiple variables in this multiline style:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js no-beautify
let user = 'John',
age = 25,
@@ -88,22 +97,37 @@ Di script jadul, kamu mungkin juga menemukan katakunci lain: `var` ketimbang `le
*!*var*/!* message = 'Hello';
```
+<<<<<<< HEAD
Katakunci `var` *hampir* sama dengan `let`. Gunanya untuk mendeklarasi variabel, tapi caranya agak sedikit beda, "jadul".
Ada perbedaan halus antara `let` dan `var`, tapi itu tak masalah buat kita sekarang ini. Kita akan mengcover mereka lebih detil di bab .
+=======
+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 .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
## Analogy kehidupan nyata
Kita bisa dengan mudah memahami konsep "variabel" jika kita membayangkannya sebagai "box" untuk data, dengan stiker nama yang unik.
+<<<<<<< HEAD
Misalnya, variabel `message` bisa dibayangkan sebagai box berlabel `"message"` dengan nilai `"Hello!"` di dalamnya:
+=======
+For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6

Kita bisa menaruh nilai apapun di dalam box.
+<<<<<<< HEAD
Kita juga bisa mengubahnya sebanyak yang kita mau:
+=======
+We can also change it as many times as we want:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let message;
@@ -150,12 +174,21 @@ let message = "That"; // SyntaxError: 'message' has already been declared
Jadi, kita harus mendeklarasikan variabel sekali dan menggunakan variabel tersebut tanpa menggunakan 'let'.
````
+<<<<<<< HEAD
```smart header="Bahasa fungsional"
Ini sangat menarik untuk diperhatikan bahwa ada bahasa pemrograman [fungsional](https://en.wikipedia.org/wiki/Functional_programming), seperti [Scala](http://www.scala-lang.org/) atau [Erlang](http://www.erlang.org/) yang melarang merubah nilai dari variabel.
+=======
+```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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Di dalam bahasa macam ini, sekali nilai disimpan "dalam box", ia akan di sana selamanya. Jika kita harus menyimpan sesuatu yang lain, bahasa tersebut memaksa kita membuat box baru (mendeklarasi variabel baru). Kita tak bisa menggunakan ulang yang lama.
+<<<<<<< HEAD
Meski kelihatan sedikit aneh saat pandangan pertama, bahasa-bahasa ini ternyata mumpuni untuk pengembangan yang serius. Lebih dari itu, ada area seperti komputasi paralel di mana keterbatasan ini memberikan keuntungan tertentu. Disarankan mempelajari bahasa macam ini (meski jika kamu tak berencana menggunakannya segera) untuk meningkatkan wawasan.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Penamaan variabel [#variable-naming]
@@ -193,19 +226,32 @@ let 1a; // cannot start with a digit
let my-name; // hyphens '-' aren't allowed in the name
```
+<<<<<<< HEAD
```smart header="Case berpengaruh"
Variabel dengan nama `apple` dan `AppLE` adalah dua variabel yang berbeda.
```
````smart header="Huruf non-Latin diperbolehkan, namun tak direkomendasikan"
Boleh menggunakan bahasa apapun, termasuk huruf cyrillic atau bahkan hieroglyphs, seperti ini:
+=======
+```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:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let имя = '...';
let 我 = '...';
```
+<<<<<<< HEAD
Secara teknis, tak ada error di sini, nama-nama begitu boleh digunakan, tapi ada tradisi internasional untuk menggunakan bahasa Inggris dalam nama variabel. Meski jika kita menulis script kecil, kemungkinan variabelnya akan digunakan terus-menerus. Dan juga orang-orang dari negara lain mungkin harus membaca beberapa kali.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
````warn header="Nama-nama yang dikecualikan"
@@ -260,12 +306,20 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // error, tak bisa menetapkan-ulang konstan!
```
+<<<<<<< HEAD
Ketika programmer yakin bahwa variabel tak akan berubah, mereka bisa mendeklarasikan `const` untuk menjamin hal itu dan memberitahu semua orang.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
### Konstan huruf-besar
+<<<<<<< HEAD
Ada kebiasaan umum untuk menggunakan konstan sebagai alias untuk nilai yang sulit dihafal yang akan diketahui sebelum dieksekusi.
+=======
+There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Konstan macam ini dinamai dengan huruf kapital dan underscore.
@@ -290,16 +344,29 @@ Keuntungan:
Kapan kita sebaiknya menggunakan kapital untuk konstan dan kapan itu dinamai dengan normal? Ayo kita perjelas.
+<<<<<<< HEAD
Menjadi "konstan" hanya berarti jika nilai variable tak pernah berubah. Tapi ada konstan yang diketahui sebelum eksekusi (seperti nilai hexadecimal untuk merah) dan ada konstan yang *dikalkulasi* dalam run-time, selama eksekusi, tapi tak berubah setelah penetapan inisial mereka.
Misalnya:
+=======
+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:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
const pageLoadTime = /* waktu yang dibutuhkan laman web untuk meload */;
```
+<<<<<<< HEAD
Nilai `pageLoadTime` tidak diketahui sebelum laman diload, jadi itu dinamai dengan normal. Tapi ia masih konstan karena ia tak berubah setelah penetapan.
Dengan kata lain, konstan berhuruf kapital hanya digunakan sebagai alias untuk nilai yang "dihard-code".
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Namai dengan benar
@@ -307,18 +374,31 @@ Berbicara tentang variabel, ada satu hal yang sangat penting.
Nama variabel sebaiknya punya arti yang bersih dan jelas, yang menjelaskan data yang ia simpan.
+<<<<<<< HEAD
Penamaan variabel adalah salah satu keahlian yang penting dan rumit dalam pemrograman. Pandangan sekilas pada nama variabel bisa menyingkap kode yang ditulis oleh pengembang pemula versus pengembang berpengalaman.
Di proyek nyata, kebanyakan waktu dihabiskan untuk modifikasi dan mengextend code base ketimbang menulis sesuatu yang benar-benar baru dari awal. Ketika kita kembali ke beberapa kode setelah melakukan sesuatu yang lain untuk sementara, akan lebih mudah menemukan informasi yang labelnya tepat. Atau, dengan kata lain, ketika variabel punya nama yang baik.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tolong renungkan tentang nama yang baik untuk variabel sebelum mendeklarasinya. Itu baik untukmu.
Beberapa aturan yang baik untuk ditiru:
+<<<<<<< HEAD
- Gunakan nama yang manusiawi seperti `userName` atau `shoppingCart`.
- Jauhi singkatan atau nama pendek seperti `a`, `b`, `c`, kecuali jika kamu benar-benar tau apa yang kamu lakukan.
- Buat nama sedeskriptif dan sejelas mungkin. Contoh nama yang jelek ialah `data` dan `value`. Nama semacam ini tidak punya makna dan hanya OK untuk menggunakannya jika data atau nilai variabel yang mengacu kontex kodenya luar biasa jelas.
- Sepakat dalam hal-hal yang ada di dalam timmu dan pikiranmu. Jika pengunjung situs disebut "user" maka kita sebaiknya menamai variabel terkait `currentUser` atau `newUser` ketimbang `currentVisitor` atau `newManInTown`.
+=======
+- 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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kedengaran simpel kan? Jelas saja, tapi membuat nama variabel descriptif dan jelas pada praktiknya tidak mudah. Coba lakukan.
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index 114947d9a..5b87531c2 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -46,13 +46,23 @@ Selain angka reguler, ada yang disebut "nilai numerik spesial" yang juga bagian
alert( "not a number" / 2 ); // NaN, pembagian macam ini keliru
```
+<<<<<<< HEAD
`NaN` itu lengket. Operasi lanjutan apapun pada `NaN` menghasilkan `NaN`:
+=======
+ `NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```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
Jadi, jika ada `NaN` di manapun di expresi matematika, ia mempropagasi hasil keseluruhan.
+=======
+ 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`).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Operasi matematika itu aman"
Melakukan matematika itu "aman" dalam JavaScript. Kita bisa melakukan apapun: pembagian dengan nol, memperlakukan string non-numerik sebagai angka, dll.
@@ -66,9 +76,26 @@ Kita akan melihat lebih tentang cara bekerja dengan angka di bab .
## BigInt [#bigint-type]
+<<<<<<< HEAD
Didalam Javascript, tipe data "number" tidak bisa mengandung nilai lebih dari (253-1)
(sama dengan `9007199254740991`) atau kurang dari -(253-1)
. Itu adalah batasan teknik yang dibuat.
Untuk kebanyakan kebutuhan sebenarnya sudah cukup, dan terkadang kita membutuhkan nilai yang lebih besar, contohnya untuk kriptografy atau perhitungan waktu microsecond.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tipe data `BigInt` lalu ditambahkan kedalam Javascript untuk menampilkan nilai *integer* yang sangat panjang.
@@ -81,6 +108,7 @@ const bigInt = 1234567890123456789012345678901234567890n;
Sebenarnya `BigInt` jarang dibutuhkan, kita tidak akan mempelajarinya disini, tetapi akan dipisahkan didalam bagian . Baca saja saat kamu membutuhkan nilai *integer* yang sangat panjang.
+<<<<<<< HEAD
```smart header="Masalah Kompabilitas"
Sekarang `BigInt` sudah didukung oleh Firefox/Chrome/Edge, tapi tidak didalam Safari/Internet Explorer.
@@ -88,6 +116,8 @@ Sekarang `BigInt` sudah didukung oleh Firefox/Chrome/Edge, tapi tidak didalam Sa
You can check [*MDN* BigInt compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) to know which versions of a browser are supported.
+=======
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## String
String di JavaScript harus dikelilingi petik.
@@ -211,6 +241,7 @@ Tipe `symbol` digunakan untuk menciptakan identifier unik untuk sebuah objek. Un
## Operator typeof [#type-typeof]
+<<<<<<< HEAD
Operator `typeof` mengembalikan tipe argumen. Berguna ketika kita ingin memproses nilai dari tipe berbeda secara berbeda atau cuma ingin mengecek sekilas.
Ia mendukung dua bentuk syntax:
@@ -221,6 +252,11 @@ Ia mendukung dua bentuk syntax:
Dengan kata lain, ia berjalan dengan atau tanpa kurung. Hasilnya sama saja.
Panggilan ke `typeof x` mengembalikan string dengan nama tipenya:
+=======
+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:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
typeof undefined // "undefined"
@@ -250,14 +286,33 @@ typeof alert // "function" (3)
Tiga baris terakhir mungkin butuh penjelasan tambahan:
+<<<<<<< HEAD
1. `Math` ialah objek built-in yang menyediakan operasi matematik. Kita akan belajar itu di bab . Di sini, ia cuma sekedar contoh dari objek.
2. Hasil `typeof null` yaitu `"object"`. Itu salah. Ia merupakan error yang terkenal resmi dalam `typeof`, yang dijaga untuk kompatibilitas. Tentu saja, `null` bukanlah objek. Ia merupakan nilai spesial dengan tipe terpisah miliknya sendiri. Jadi, lagi, ini merupakan error dalam bahasa.
3. Hasil dari `typeof alert` yaitu `"function"`, karena `alert` merupakan fungsi. Kita akan belajar fungsi di bab berikutnya di mana kita juga akan melihat bahwa tak ada tipe "fungsi" spesial di JavaScript. Fungsi merupakan bagian dari tipe objek. Tapi `typeof` memperlakukan mereka secara berbeda, yang mengembalikan `"fungsi"`. Itu tak sepenuhnya benar, tapi sangat nyaman pada praktiknya.
## Kesimpulan
+=======
+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.
+
+```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.
+```
+
+## Summary
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ada 7 tipe data dasar dalam JavaScript.
+<<<<<<< HEAD
- `number` untuk nomor dengan bentuk apapun: integer ataupun nilai yang memiliki nilai desimal, batas dari integer adalah ±253.
- `bigint` untuk nomor integer yang sangat panjang.
- `string` untuk string. Sebuah string mungkin memiliki 0 atau lebih karakter, tidak ada tipe data untuk string yang memiliki panjang 1 karakter.
@@ -266,11 +321,29 @@ Ada 7 tipe data dasar dalam JavaScript.
- `undefined` untuk nilai yang tidak ada atau tidak diberikan nilai -- sebuah tipe data mandiri yang memiliki satu nilai yaitu `null`.
- `object` untuk struktur data yang lebih rumit.
- `symbol` untuk identifier atau pengenal yang unik.
+=======
+- 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Operator `typeof` memungkinkan kita melihat tipe mana yang disimpan dalam variable.
+<<<<<<< HEAD
- Dua form: `typeof x` atau `typeof(x)`.
- Mengembalikan string dengan nama tipe, seperti `"string"`.
- Untuk `null` mengembalikan `"object"` -- ada error dalam bahasa, yang sebenarnya bukan objek.
+=======
+- 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Di bab berikutnya, kita akan fokus pada nilai primitive dan sekali kita familiar dengan mereka, kita akan lanjut ke objek.
diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md
index 3f86aff0b..1cbe1edfa 100644
--- a/1-js/02-first-steps/07-type-conversions/article.md
+++ b/1-js/02-first-steps/07-type-conversions/article.md
@@ -6,8 +6,13 @@ Misalnya, `alert` otomatis mengkonversi nilai apapun ke string untuk menampilkan
Ada juga kasus di mana kita harus explisit mengkonversi nilai ke tipe yang diharapkan.
+<<<<<<< HEAD
```smart header="Belum bicara objek dulu"
Di bab ini, kita takkan mengcover objek. Daripada itu, kita akan belajar primitives dulu.
+=======
+```smart header="Not talking about objects yet"
+In this chapter, we won't cover objects. For now, we'll just be talking about primitives.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Lalu, setelah kita belajar tentang objek, kita akan lihat cara konversi objek bekerja di bab .
```
@@ -34,7 +39,11 @@ Konversi string kebanyakan jelas. `false` menjadi `"false"`, `null` menjadi `"nu
## Konversi Numerik
+<<<<<<< HEAD
Konversi numerik terjadi otomatis dalam fungsi dan expresi matematis.
+=======
+Numeric conversion in mathematical functions and expressions happens automatically.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya, ketika pembagian `/` dilakukan ke non-angka:
@@ -69,8 +78,13 @@ Aturan konversi numerik:
|-------|-------------|
|`undefined`|`NaN`|
|`null`|`0`|
+<<<<<<< HEAD
|true dan false
| `1` and `0` |
| `string` | Whitespaces dari awal dan akhir dibuang. Jika string sisanya kosong, hasilnya `0`. Sebaliknya, angkanya "dibaca" dari stringnya. Error memberikan `NaN`. |
+=======
+|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`. |
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya:
@@ -130,7 +144,11 @@ Konversinya mengikuti aturan ini:
|`undefined`|`NaN`|
|`null`|`0`|
|true / false
| `1 / 0` |
+<<<<<<< HEAD
| `string` | Stringnya dibaca "apa adanya", whitespace dari kedua sisi diabaikan. String kosong menjadi `0`. Error memberikan `NaN`. |
+=======
+| `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`. |
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
**`Konversi Boolean`** -- Terjadi di operasi logika. Bisa berjalan dengan `Boolean(value)`.
diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
index 5b8875c4d..38032fde6 100644
--- a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
@@ -16,6 +16,7 @@ undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```
+<<<<<<< HEAD
1. Penambahan dengan string `"" + 1` mengkonversi `1` ke string: `"" + 1 = "1"`, dan kita punya `"1" + 0`, aturan yang sama berlaku.
2. Pengurangan `-` (seperti kebanyakan operasi matematika) cuma berjalan dengan angka, ia mengkonversi string kosong `""` ke `0`.
3. Penambahan dengan string mengappend angka `5` ke string.
@@ -23,3 +24,12 @@ undefined + 1 = NaN // (6)
5. `null` menjadi `0` setelah konversi numerik.
6. `undefined` menjadi `NaN` setelah konversi numerik.
7. Karakter spasi, ialah string yang depan dan belakangnya ditrim ketika string dikonversi ke angka. Berikut seluruh string berisi karakter spasi, seperti `\t`, `\n` dan spasi "reguler" di antaranya. Jadi, serupa dengan string kosong, ia menjadi `0`.
+=======
+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.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md
index ca00ba647..9339f75d8 100644
--- a/1-js/02-first-steps/08-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -50,8 +50,14 @@ Hasil dari `a % b` adalah [nilai sisa](https://en.wikipedia.org/wiki/Remainder)
Contoh
```js run
+<<<<<<< HEAD
alert( 5 % 2 ); // 1, sisa dari pembagian antara 5 dibagi 2
alert( 8 % 3 ); // 2, sisa dari pembagian antara 8 dibagi 3
+=======
+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
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
### Eksponensial **
@@ -65,7 +71,11 @@ alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
```
+<<<<<<< HEAD
Sama seperti dalam matematika, operator eksponensial juga didefinisikan untuk bilangan non-bilangan bulat.
+=======
+Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya, akar kuadrat adalah eksponensial dengan :
@@ -77,7 +87,11 @@ alert( 8 ** (1/3) ); // 2 (pangkat 1/3 sama dengan akar kubik)
## Penambahan string dengan +
+<<<<<<< HEAD
Ayo kita bertemu dengan fitur dari operator Javascript yang berada diatas aritmatika di sekolah.
+=======
+Let's meet the features of JavaScript operators that are beyond school arithmetics.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Biasanya, operator plus `+` menambah angka.
@@ -193,6 +207,7 @@ Di sini adalah extrak dari [tabel presedensi](https://developer.mozilla.org/en/J
| Presedensi | Nama | Tanda |
|------------|------|------|
| ... | ... | ... |
+<<<<<<< HEAD
| 17 | plus unary | `+` |
| 17 | negasi unary | `-` |
| 16 | akar pangkat | `**` |
@@ -205,10 +220,28 @@ Di sini adalah extrak dari [tabel presedensi](https://developer.mozilla.org/en/J
| ... | ... | ... |
Seperti yang kita lihat, "plus unary" punya prioritas `17` yang lebih tinggi dari `13` "penambahan" (plus binary). Itulah kenapa, dalam expresi `"+apples + +oranges"`, plus unary bekerja sebelum penambahan.
+=======
+| 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Penetapan
+<<<<<<< HEAD
Mari ingat bahwa penetapan `=` juga merupakan operator. Ia terdaftar di tabel presedensi dengan prioritas sangat rendah `3`.
+=======
+Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Itulah kenapa, ketika kita tetapkan variabel, seperti `x = 2 * 2 + 1`, kalkulasinya dilakukan pertama dan kemudian `=` dievaluasi, menyimpan hasilnya dalam in `x`.
@@ -302,9 +335,13 @@ Operator semacam itu memiliki hak dengan tingkat yang sama dengan assignment yan
```js run
let n = 2;
-n *= 3 + 5;
+n *= 3 + 5; // right part evaluated first, same as n *= 8
+<<<<<<< HEAD
alert( n ); // 16 (bagian paling kanan dievaluasi terlebih dahulu, sama seperti n *= 8)
+=======
+alert( n ); // 16
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Inkremen/dekremen
@@ -436,7 +473,11 @@ Daftar operator:
- RIGHT SHIFT ( `>>` )
- ZERO-FILL RIGHT SHIFT ( `>>>` )
+<<<<<<< HEAD
Operator seperti diatas sangat jarang digunakan, ketika kita membutuhkan untuk memainkan angka di level paling rendah (bitwise). Kita tidak akan membutuhkan operator seperti ini dalam waktu dekat, sebagaimana dalam pengembangan web penggunaan operator seperti itu lebih sedikit, tetapi di area yang spesial, seperti kriptographi, operator seperti itu sangan dibutuhkan. Kamu bisa membaca artikel [Bitwise Operators](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) di MDN ketika kamu membutuhkannya.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Koma
diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
index 8ce32da7d..889c2ceb9 100644
--- a/1-js/02-first-steps/09-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -4,10 +4,17 @@ Kita tahu beberapa operator pembanding dari matematika.
Didalam Javascript operator-operator itu ditulis seperi ini:
+<<<<<<< HEAD
- Lebih besar/kurang dari: a > b
, a < b
.
- Lebih besar/kurang dari atau sama: a >= b
, a <= b
.
- Sama dengan: `a == b`, perhatikan tanda dua `=` digunakan untuk test persamaan, jika menggunakan satu `=` seperti `a = b` itu adalah sebuah asignment atau memasukan nilai kedalam variabel.
- Tidak sama dengan: Didalam matematika notasinya seperti ≠
, tetapi didalam Javascript ditulis seperti a != b
.
+=======
+- 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
.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Didalam artikel ini kita akan belajar lebih lanjut tentang perbedaan tipe dari perbandingan, bagaimana cara Javascript membuatnya, termasuk sifat-sifat penting.
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index 284100848..800e967fb 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -69,7 +69,11 @@ if (kondisi) {
## Klausa "else"
+<<<<<<< HEAD
Pernyataan `if` dapat berisi blok opsional "else" opsional. Block "else" dijalankan ketika semua kondisi di atas blok "else" salah (false) semua.
+=======
+The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contohnya:
```js run
@@ -181,10 +185,17 @@ alert( message );
Mungkin sulit pada awalnya untuk memahami apa yang terjadi. Tetapi setelah melihat lebih dekat, kita dapat melihat bahwa itu hanya serangkaian tes biasa:
+<<<<<<< HEAD
1. Tanda tanya pertama memeriksa apakah `age < 3`.
2. Jika benar -- `'Hi, baby!'` akan dikembalikan. Jika tidak, kode akan melanjutkan ke ekspresi setelah titik dua '":"', memeriksa apakah `age < 18`.
3. Jika itu benar -- `'Hello!'` akan dikembalikan. . Jika tidak, kode akan melanjutkan ke ekspresi setelah titik dua berikutnya '":"', memeriksa `age < 100`.
4. Jika itu benar -- `'Greetings!'` akan dikembalikan. Jika tidak, kode akan melanjutkan ke ekspresi setelah titik dua terakhir '":"', dan akhirnya akan mengembalikan `'What an unusual age!'`.
+=======
+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!'`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kode bawah ini memperlihatkan apabila menggunakan `if..else` untuk kode di atas:
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 deeb75059..3c19879ce 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,6 +1,6 @@
Jawabannya: `null`, karena `null` adalah nilai falsy pertama yang ada di daftar.
```js run
-alert( 1 && null && 2 );
+alert(1 && null && 2);
```
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 e79a5ced8..521c47599 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -123,7 +123,11 @@ Hal ini menjadikan penggunaan yang menarik dibanding "OR booleanpure, classical,
Itu berarti bahwa `||` memproses argumennya sampai nilai pertama bersifat truthy tercapai, lalu nilainya dikembalikan langsung, bahkan tanpa menyentuh argumen lainnya.
+<<<<<<< HEAD
Pentingnya dari fitur ini menjadi jelas jika sebuah operan bukan hanya sebuah nilai, tapi sebuah ekspresi yang melakukan aksi, seperti assignment sebuah variabel atau sebuah pemanggilan fungsi.
+=======
+ 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Didalam contoh dibawah, hanya pesan kedua yang di jalankan:
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
index 869e3c471..819496195 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -4,7 +4,11 @@
Operator penggabungan nullish ditulis sebagai dua tanda tanya `??`.
+<<<<<<< HEAD
Karena memperlakukan `null` dan `undefined` sama, kita akan menggunakan istilah khusus di sini, di artikel ini. Kami akan mengatakan bahwa ekspresi adalah "didefinisikan" ketika itu bukan `null` atau `undefined`.
+=======
+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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Hasil dari `a?? b` adalah:
- jika `a` didefinisikan, maka `a`,
@@ -22,14 +26,24 @@ result = (a !== null && a !== undefined) ? a : b;
Sekarang harus benar-benar jelas apa yang dilakukan `??`. Mari kita lihat di mana itu membantu.
+<<<<<<< HEAD
Kasus penggunaan umum untuk `??` adalah memberikan nilai default untuk variabel yang berpotensi tidak terdefinisi.
Misalnya, di sini kami menampilkan `pengguna` jika didefinisikan, jika tidak `Anonim`:
+=======
+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`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js dijalankan
biarkan pengguna;
+<<<<<<< HEAD
alert(pengguna ?? "Anonim"); // Anonim (pengguna tidak ditentukan)
+=======
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Berikut ini contoh dengan `pengguna` ditetapkan ke sebuah nama:
@@ -37,14 +51,24 @@ Berikut ini contoh dengan `pengguna` ditetapkan ke sebuah nama:
```js dijalankan
biarkan pengguna = "John";
+<<<<<<< HEAD
alert(pengguna ?? "Anonim"); // John (ditentukan pengguna)
+=======
+alert(user ?? "Anonymous"); // John (user is not null/undefined)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Kita juga dapat menggunakan urutan `??` untuk memilih nilai pertama dari daftar yang bukan `null/undefined`.
+<<<<<<< HEAD
Katakanlah kita memiliki data pengguna dalam variabel `FirstName`, `lastName` atau `nickName`. Semuanya mungkin tidak ditentukan, jika pengguna memutuskan untuk tidak memasukkan nilai.
Kami ingin menampilkan nama pengguna menggunakan salah satu variabel ini, atau menampilkan "Anonim" jika semuanya tidak ditentukan.
+=======
+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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Mari kita gunakan operator `??` untuk itu:
@@ -76,7 +100,11 @@ alert(Namadepan || Nama Belakang || Nama Panggilan || "Anonim"); // kode super
*/!*
```
+<<<<<<< HEAD
Secara historis, operator OR `||` ada terlebih dahulu. Itu ada sejak awal JavaScript, jadi pengembang menggunakannya untuk tujuan seperti itu untuk waktu yang lama.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Di sisi lain, operator penggabungan nullish `??` baru saja ditambahkan ke JavaScript, dan alasannya adalah karena orang-orang tidak terlalu senang dengan `||`.
@@ -106,11 +134,19 @@ Dalam praktiknya, ketinggian nol seringkali merupakan nilai yang valid, yang tid
## Prioritas
+<<<<<<< HEAD
Prioritas operator `??` hampir sama dengan `||`, hanya sedikit lebih rendah. Ini sama dengan `5` di [tabel MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table), sedangkan `||` adalah `6` .
+=======
+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).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Artinya, seperti halnya `||`, operator penggabungan nullish `??` dievaluasi sebelum `=` dan `?`, tetapi setelah sebagian besar operasi lain, seperti `+`, `*`.
+<<<<<<< HEAD
Jadi, jika kita ingin memilih nilai dengan `??` dalam ekspresi dengan operator lain, pertimbangkan untuk menambahkan tanda kurung:
+=======
+So we may need to add parentheses in expressions like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js dijalankan
biarkan tinggi = nol;
@@ -128,8 +164,13 @@ Jika tidak, jika kita menghilangkan tanda kurung, maka karena `*` memiliki prior
// tanpa tanda kurung
misal luas = tinggi?? 100 * lebar ?? 50;
+<<<<<<< HEAD
// ...berfungsi sama seperti ini (mungkin bukan yang kita inginkan):
misal luas = tinggi?? (100 * lebar) ?? 50;
+=======
+// ...works this way (not what we want):
+let area = height ?? (100 * width) ?? 50;
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
### Menggunakan ?? dengan && atau ||
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
index 34a529171..695a9acea 100644
--- a/1-js/02-first-steps/13-while-for/article.md
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -6,7 +6,24 @@ Contohnya, Mengeluarkan barang dari sebuah daftar satu per satu atau hanya menja
*Perulangan* adalah sebuah cara untuk mengulangi kode yang sama beberapa kali.
+<<<<<<< HEAD
## Perulangan "while"
+=======
+```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
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Perulangan `while` memiliki sintaks sebagai berikut:
@@ -106,10 +123,17 @@ Mari bahas pernyataan `for` bagian demi bagian:
| bagian | | |
|-------|----------|----------------------------------------------------------------------------|
+<<<<<<< HEAD
| begin | `i = 0` | Jalankan sekali masuk ke loop. |
| condition | `i < 3`| Cek sebelum tiap iterasi loop. Jika salah, loop berhenti. |
| body | `alert(i)`| Jalankan lagi dan lagi selama kondisi bernilai truthy. |
| step | `i++` | Exekusi setelah badan di tiap iterasi. |
+=======
+| 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. |
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Cara kerja algoritma perulangan umum seperti ini:
@@ -162,11 +186,14 @@ for (i = 0; i < 3; i++) { // gunakan variabel yang sudah ada
alert(i); // 3, terlihat, karena dideklarasikan diluar dari perulangan
```
-
````
+<<<<<<< HEAD
### Melewatkan bagian
+=======
+### Skipping parts
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Bagian apapun dari `for` dapat dilewati.
@@ -268,7 +295,11 @@ for (let i = 0; i < 10; i++) {
Dari sudut pandang teknis, ini identik dengan contoh diatas. Tentunya, kita dapat membungkus kode dalam sebuah blok `if` daripada menggunakan `continue`.
+<<<<<<< HEAD
Tapi sebagai efeknya, hal ini akan menciptakan kode lebih dalam satu tingkat (pemanggilan `alert` didalam kurung kurawal). Jika kode didalam `if` lebih panjang beberapa baris, hal itu akan membuat tingkat keterbacaan kode menjadi berkurang.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
````warn header="Tidak ada `break/continue` ke sisi kanan '?'"
@@ -286,7 +317,6 @@ if (i > 5) {
...dan tulis ulang menggunakan sebuah tanda tanya:
-
```js no-beautify
(i > 5) ? alert(i) : *!*continue*/!*; // continue tidak diperbolehkan disini
```
@@ -320,7 +350,12 @@ Kita butuh cara untuk menghentikan proses jika pengguna membatalkan input.
`break` biasa setelah `input` hanya akan menghentikan perulangan dalam. Itu tidak cukup--label, datang untuk menyelamatkan!
+<<<<<<< HEAD
Label adalah sebuah pengidentifikasi dengan sebuah titik dua sebelum perulangan:
+=======
+A *label* is an identifier with a colon before a loop:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
labelName: for (...) {
...
@@ -342,6 +377,7 @@ Pernyataan `break ` di dalam loop di bawah menghentikan pada label:
// lakukan sesuatu dengan nilai...
}
}
+
alert('Done!');
```
@@ -361,14 +397,24 @@ Perintah `continue` dapat juga digunakan dengan sebuah label. pada kasus ini, ek
````warn header="Label tidak mengizinkan \"lompat\" ke manapun"
Label tidak mengizinkan kita untuk lompat ke sembarang tempat dalam kode.
+<<<<<<< HEAD
Misalnya, mustahil melakukan ini:
+=======
+For example, it is impossible to do this:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
break label; // tidak lompak ke label di bawah
label: for (...)
```
+<<<<<<< HEAD
Direktif `break` harus berada di dalam blok kode. Secara teknis, setiap blok kode berlabel akan dilakukan, contoh.:
+=======
+A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
label: {
// ...
@@ -377,7 +423,11 @@ label: {
}
```
+<<<<<<< HEAD
...Meskipun, 99,9% dari waktu `break` yang digunakan adalah loop dalam, seperti yang telah kita lihat pada contoh di atas.
+=======
+...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
`continue` hanya dimungkinkan dari dalam loop.
````
diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md
index 99c67de94..6f97d6d9b 100644
--- a/1-js/02-first-steps/14-switch/article.md
+++ b/1-js/02-first-steps/14-switch/article.md
@@ -139,7 +139,11 @@ switch (a) {
Sekarang baik `3` maupun `5` menampilkan pesan yang sama.
+<<<<<<< HEAD
Kemampuan "mengelompokkan" case adalah efek samping dari bagaimana `switch/case` bekerja tanpa `break`. Di sini exekusi dari `case 3` mulai dari baris `(*)` dan tembus ke `case 5`, karena tidak ada `break`.
+=======
+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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Tipe berpengaruh
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
index ace44886a..8b93517ce 100644
--- 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
@@ -1 +1,7 @@
-Tidak ada perbedaan.
\ No newline at end of file
+<<<<<<< HEAD
+Tidak ada perbedaan.
+=======
+No difference!
+
+In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md
index fe07d4fbb..f62dccd75 100644
--- a/1-js/02-first-steps/15-function-basics/article.md
+++ b/1-js/02-first-steps/15-function-basics/article.md
@@ -24,7 +24,7 @@ Katakunci `fungsi` ditulis duluan, lalu *nama fungsinya*, kemudian daftar semua
```js
function name(parameter1, parameter2, ... parameterN) {
- ...body...
+ // body
}
```
@@ -178,12 +178,21 @@ Ketika sebuah nilai dilewatkan sebagai parameter fungsi, itu juga disebut *argum
Dengan kata lain, untuk meluruskan istilah-istilah ini:
+<<<<<<< HEAD
- Parameter adalah variabel yang tercantum di dalam tanda kurung dalam deklarasi fungsi (ini adalah istilah waktu deklarasi)
- Argumen adalah nilai yang diteruskan ke fungsi saat dipanggil (ini adalah istilah waktu panggilan).
+=======
+- 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).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kami mendeklarasikan fungsi yang mencantumkan parameternya, lalu memanggilnya lewat argumen.
+<<<<<<< HEAD
Dalam contoh di atas, seseorang mungkin mengatakan: "fungsi `sayMessage` dideklarasikan dengan dua parameter, kemudian dipanggil dengan dua argumen: `from` dan `"Hello"`".
+=======
+In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Nilai default
@@ -208,7 +217,17 @@ function showMessage(from, *!*text = "no text given"*/!*) {
showMessage("Ann"); // Ann: tidak diberikan teks
```
+<<<<<<< HEAD
Sekarang, jika parameter `text` tidak ditentukan, parameter tersebut akan mengambil nilai `"no text give"`
+=======
+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
+```
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Disini `"no text give"` adalah string, tapi ia bisa menjadi suatu expresi nilai lebih kompleks, yang hanya dievaluasi dan ditetapkan jika tak ada nilai pada parameter. Jadi, ini juga mungkin ditetapkan:
@@ -228,9 +247,47 @@ Di sisi lain, itu dipanggil secara independen setiap kali `teks` hilang.
```
+<<<<<<< HEAD
### Alternatif nilai default parameter
Terkadang akan dapat dimengerti untuk memberikan nilai default untuk variabel bukan didalam deklarasi fungsi, tapi di tahap selanjutnya, didalam proses eksekusinya.
+=======
+````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`:
+
+```js
+function showMessage(from, text) {
+*!*
+ if (text === undefined) {
+ text = 'no text given';
+ }
+*/!*
+
+ alert( from + ": " + text );
+}
+```
+
+...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';
+ ...
+}
+```
+````
+
+
+### Alternative default parameters
+
+Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Untuk memeriksa parameter yang tidak ada, kita bisa membandingkannya dengan `undefined`:
@@ -250,7 +307,11 @@ function showMessage(text) {
showMessage(); // empty message
```
+<<<<<<< HEAD
...Atau kita bisa menggunakan operator `||`:
+=======
+...Or we could use the `||` operator:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// jika teks parameter tidak ada atau "", set variabel ke 'empty'
@@ -427,7 +488,11 @@ Pada contoh-contoh ini diasumsikan arti-arti umum pada kata awalan. Kamu dan tim
```smart header="Ultrashort function names"
Fungsi yang *digunakan secara sering* kadang-kadang memiliki nama yang sangat pendek.
+<<<<<<< HEAD
Sebagai contoh, framework [jQuary](http://jquary.com) mendefinisikan fungsi dengan simbol `$`. Library [Lodash](https://lodash.com) memiliki fungsi inti yang dinamakan dengan `_`.
+=======
+For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Hal-hal tersebut adalah pengecualian. Secara umum, nama fungsi sebaiknya ringkas dan menjelaskan maksudnya.
```
@@ -495,7 +560,11 @@ function name(parameters, delimited, by, comma) {
Untuk membuat kode yang bersih dan mudah untuk dipahami, sangat dianjurkan untuk menggunakan variabel lokal dan parameter pada fungsi, tidak mengguunakan variabel luar / variabel global.
+<<<<<<< HEAD
Akan menjadi hal yang mudah untuk dipahami pada fungsi yang mendapatkan parameter, yang bekerja dengan parameter tersebut dan mengembalikan nilainya daripada fuungsi yang tidak memilki parameter, tetapi melakukan modifikasi terhadap variabel luar akan memiliki efek samping.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Penamaan fungsi:
diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md
index c8d104b84..4dbf02ba9 100644
--- a/1-js/02-first-steps/16-function-expressions/article.md
+++ b/1-js/02-first-steps/16-function-expressions/article.md
@@ -12,7 +12,13 @@ function sayHi() {
Ada syntax lain untuk membuat fungsi yang disebut *Expresi Fungsi*.
+<<<<<<< HEAD
Rupanya seperti ini:
+=======
+It allows us to create a new function in the middle of any expression.
+
+For example:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let sayHi = function() {
@@ -20,9 +26,25 @@ let sayHi = function() {
};
```
+<<<<<<< HEAD
Di sini, fungsi dibuat dan diisi variabel secara explisit, seperti nilai lain manapun. Tak peduli bagaimana fungsi didefinisi, ia hanya suatu nilai yang disimpan dalam variabel `sayHi`.
Arti dari sampel kode ini sama: "buatlah fungs dan taruhlah di dalam variabel `sayHi`".
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kita bahkan bisa mencetak nilai itu menggunakan `alert`:
@@ -63,22 +85,31 @@ Inilah yang terjadi di atas secara detil:
2. Baris `(2)` mengkopinya ke variabel `func`. Tolong ingat lagi: tak ada tanda kurung setelah `sayHi`. Jika ada, maka `func = sayHi()` akan menulis *hasil panggilan* `sayHi()` ke `func`, bukan *fungsi* `sayHi` itu sendiri.
3. Sekarang fungsi bisa dipanggil baik sebagai `sayHi()` maupun `func()`.
+<<<<<<< HEAD
Catat bahwa kita jusa bisa menggunakan Expresi Fungsi untuk mendeklarasi `sayHi`, di baris pertama:
+=======
+We could also have used a Function Expression to declare `sayHi`, in the first line:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
-let sayHi = function() {
+let sayHi = function() { // (1) create
alert( "Hello" );
};
-let func = sayHi;
+let func = sayHi; //(2)
// ...
```
Semua akan berjalan sama.
+<<<<<<< HEAD
````smart header="Kenapa ada semicolon di akhir?"
Kamu mungkin penasaran, kenapa Expresi Fungsi punya semicolon `;` di akhir, tapi Deklarasi Fungsi tidak:
+=======
+````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:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
function sayHi() {
@@ -90,9 +121,15 @@ let sayHi = function() {
}*!*;*/!*
```
+<<<<<<< HEAD
Jawabannya simpel:
- `;` tidak dibutuhkan di akhir blok kode dan struktur syntax yang memakai mereka seperti `if { ... }`, `for { }`, `function f { }` dll.
- Expresi Fungsi digunakan di dalam pernyataan: `let sayHi = ...;`, sebagai nilai. Ia bukan blok kode, tapi lebih ke penetapan. Semicolon `;` disarankan di akhir pernyataan, tak peduli nilainya apa. Jadi semicolon di sini tak ada hubungannya dengan Expresi Fungsi itu sendiri, ia hanya menstop pernyataan.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
## Fungsi callback
@@ -132,13 +169,21 @@ function showCancel() {
ask("Do you agree?", showOk, showCancel);
```
+<<<<<<< HEAD
Pada praktiknya, fungsi macam ini agak berguna. Perbedaan besar antara `ask` kehidupan-nyata dan contoh di atas adalah fungsi kehidupan-nyata memakai cara komplex untuk berinteraksi dengan pengguna daripada sekedar `confirm`. Di peramban, fungsi macam ini biasanya menarik window pertanyaan menarik. Tapi itu cerita lain lagi.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
**Argumen `showOk` dan `showCancel` dari `ask` dipanggil *fungsi callback* atau hanya *callback*.**
Idenya adalah kita mengoper fungsi dan berharap ia "dipanggil kembali" kemudian jika dibutuhkan. Pada kasus kita, `showOk` menjadi callback untuk jawaban "yes", dan `showCancel` untuk jawaban "no".
+<<<<<<< HEAD
Kita bisa memakai Expresi Fungsi untuk menulis fungsi yang sama lebih pendek:
+=======
+We can use Function Expressions to write an equivalent, shorter function:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run no-beautify
function ask(question, yes, no) {
@@ -174,7 +219,11 @@ Mari kita rumuskan kunci perbedaan antara Deklarasi dan Expresi Fungsi.
Pertama, syntax: bagaimana membedakan antara mereka dalam kode.
+<<<<<<< HEAD
- *Deklarasi Fungsi:* fungsi, yang dideklarasi sebagai pernyataan terpisah, dalam aliran kode utama.
+=======
+- *Function Declaration:* a function, declared as a separate statement, in the main code flow:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// Deklarasi Fungsi
@@ -182,7 +231,11 @@ Pertama, syntax: bagaimana membedakan antara mereka dalam kode.
return a + b;
}
```
+<<<<<<< HEAD
- *Expresi Fungsi:* fungsi, yang dibuat dalam expresi atau dalam konstruksi syntax lain. Di sini, fungsi dibuat pada sisi kanan dari "expresi penetapan" `=`:
+=======
+- *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" `=`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// Expresi Fungsi
@@ -279,9 +332,15 @@ if (age < 18) {
welcome(); // \ (berjalan)
*/!*
// |
+<<<<<<< HEAD
function welcome() { // |
alert("Hello!"); // | Deklarasi Fungsi tersedia
} // | di manapun dalam blok kode tempat dia dideklarasi
+=======
+ function welcome() { // |
+ alert("Hello!"); // | Function Declaration is available
+ } // | everywhere in the block where it's declared
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
// |
*!*
welcome(); // / (berjalan)
@@ -289,7 +348,7 @@ if (age < 18) {
} else {
- function welcome() {
+ function welcome() {
alert("Greetings!");
}
}
@@ -347,8 +406,13 @@ welcome(); // sekarang ok
```
+<<<<<<< HEAD
```smart header="Kapan harus memilih Deklarasi Fungsi versus Expresi Fungsi?"
Sebagai aturan praktis, saat kita harus mendeklarasi fungsi, hal pertama yang kita pertimbangkan ialah syntax Deklarasi Fungsi. Ia memberi kebebasan lebih dalam bagaimana mengorganisir kode kita, karena kita bisa memanggil fungsi macam ini sebelum mereka dideklarasi.
+=======
+```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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Itu juga untuk keterbacaan yang lebih baik, karena lebih mudah melihat `function f(…) {…}` dalam kode ketimbang `let f = function(…) {…}`. Deklarasi Fungsi lebih "eye-catching".
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
index 4a50a1c29..2598972c1 100644
--- a/1-js/02-first-steps/17-arrow-functions-basics/article.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md
@@ -5,10 +5,14 @@ Terdapat sintaks lain yang sangat sederhana dan ringkas untuk membuat fungsi-fun
Disebut sebagai "fungsi *arrow* (panah)", karena sintaks fungsinya terlihat seperti ini:
```js
-let func = (arg1, arg2, ..., argN) => expression
+let func = (arg1, arg2, ..., argN) => expression;
```
+<<<<<<< HEAD
...Ini membuat sebuah fungsi `func` yang menerima argumen `arg1..argN`, kemudian mengevaluasi `expression` yang ada di sisi kanan serta kegunaannya dan mengembalikan hasilnya.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Dalam kata lain, fungsi tersebut adalah versi yang lebih pendek dari:
@@ -33,7 +37,11 @@ let sum = function(a, b) {
alert( sum(1, 2) ); // 3
```
+<<<<<<< HEAD
Seperti yang bisa dilihat, perhatikan `(a, b) => a + b` berarti sebuah fungsi yang menerima dua argumen yang diberinama `a` dan `b`. Ketika eksekusi, fungsi tersebut mengevaluasi ekpresi `a + b` dan mengembalikan hasilnya.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Jika kita memiliki satu argumen saja, maka *parentheses* di sekitar parameter bisa diabaikan, membuat sintaksnya jadi semakin pendek.
@@ -48,7 +56,11 @@ Seperti yang bisa dilihat, perhatikan `(a, b) => a + b` berarti sebuah fungsi ya
alert( double(3) ); // 6
```
+<<<<<<< HEAD
- Jika tidak ada argumen, *parentheses* akan kosong(tapi harus ditunjukkan):
+=======
+- If there are no arguments, parentheses are empty, but they must be present:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let sayHi = () => alert("Hello!");
@@ -64,7 +76,7 @@ Untuk membuat sebuah fungsi secara dinamis contohnya:
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
- () => alert('Hello') :
+ () => alert('Hello!') :
() => alert("Greetings!");
welcome();
@@ -76,9 +88,15 @@ Fungsi *arrow* sangat memudahkan untuk sintaks-sintaks sederhana, saat kita terl
## Fungsi *arrow* multi-baris
+<<<<<<< HEAD
Contoh-contoh di atas mengambil argumen dari sisi kiri dari `=>` dan mengevaluasi ekpresi di sisi kanan.
Terkadang kita memerlukan sesuatu yang agak sedikit rumit, seperti ekspresi atau pernyataan (*statement*) multi-baris (berbaris-baris). Hal tidaklah tidak mungkin, tapi kita harus menutup ekspresi atau pernyataan tersebut dengan tanda kurung kurawal. Kemudian menggunakan sebuah `return` normal diantaranya.
+=======
+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).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Seperti ini:
@@ -86,7 +104,11 @@ Seperti ini:
let sum = (a, b) => { // tanda kurung kurawal membuka fungsi multi-baris
let result = a + b;
*!*
+<<<<<<< HEAD
return result; // jika kita menggunakan kurung kurawal, selajutnya kita perlu menuliskan "return"
+=======
+ return result; // if we use curly braces, then we need an explicit "return"
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
*/!*
};
@@ -105,7 +127,14 @@ Untuk sekarang, kita sudah bisa menggunakan fungsi arrow untuk sintaks-sintaks s
## Ringkasan
+<<<<<<< HEAD
Fungsi-fungsi *arrow* itu memudahkan untuk sintaks-sintaks yang hanya sebaris. Fungsi *arrow* juga hadir dengan dua cara:
1. Tanpa tanda kurung kurawal: `(...args) => expression` -- sisi kanan adalah sebuah ekspresi: fungsi tersebut mengevaluasi ekspresi dan mengembalikan hasilnya.
2. Dengan tanda kurung kurawal: `(...args) => { body }` -- tanda kurung kurawal membuat kita bisa menuliskan pernyataan-pernyataan berbaris-baris/multi-baris dalam fungsi tersebut, tapi kita perlu untuk menulsikan `return` untuk mengembalikan (hasil) sesuatu.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md
index 27f4b963e..7ad8dc841 100644
--- a/1-js/02-first-steps/18-javascript-specials/article.md
+++ b/1-js/02-first-steps/18-javascript-specials/article.md
@@ -55,7 +55,11 @@ Untuk mengaktifkan penuh semua fitur modern JavaScript, kita sebaiknya mulai scr
Directive ini harus ada di paling atas script atau di awal badan fungsi.
+<<<<<<< HEAD
Tanpa `"use strict"`, apapun akan bekerja, tapi beberapa fitur bersikap dengan cara kuno, "kompatibel". Secara umum kita akan pilih sikap modern.
+=======
+Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Beberapa fitur modern bahasa ini (seperti kelas yang akan kita pelajari di kemudian) mengaktifkan mode ketat secara implisit.
@@ -103,6 +107,7 @@ Lebih lanjut di: and .
Kita menggunakan peramban sebagai lingkungan kerja, jadi fungsi UI dasar akan menjadi:
+<<<<<<< HEAD
[`prompt(question, [default])`](mdn:api/Window/prompt)
: Menanyakan `question`, dan mengembalikan apa yang pengunjung isikan atau `null` jika mereka mengklik "cancel".
@@ -111,6 +116,16 @@ Kita menggunakan peramban sebagai lingkungan kerja, jadi fungsi UI dasar akan me
[`alert(message)`](mdn:api/Window/alert)
: Menampilkan a `message`.
+=======
+[`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`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Semua fungsi ini adalah *modal*, mereka menyela exekusi kode dan mencegah pengunjung dari berinteraksi dengan laman hingga mereka menjawab.
@@ -144,7 +159,11 @@ Penetapan
: Ada penetapan simpel: `a = b` dan penetapan kombinasi seperti `a *= 2`.
Bitwise
+<<<<<<< HEAD
: Operator bitwise bekerja dengan integer 32-bit di bit-level paling kecil: lihat [docs](mdn:/JavaScript/Reference/Operators/Bitwise_Operators) ketika mereka dibutuhkan.
+=======
+: 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kondisional
: Satu-satunya operator dengan tiga parameter: `cond ? resultA : resultB`. Jika `cond` truthy, mengembalikan `resultA`, jika tidak `resultB`.
@@ -256,7 +275,11 @@ Kita meliput tiga cara membuat fungsi di JavaScript:
3. Fungsi panah:
```js
+<<<<<<< HEAD
// expresi di sisi kanan
+=======
+ // expression on the right side
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
let sum = (a, b) => a + b;
// atau syntax baris-ganda dengan { ... }, butuh kembalian di sini:
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 46318c4fd..0c467d657 100644
--- a/1-js/03-code-quality/01-debugging-chrome/article.md
+++ b/1-js/03-code-quality/01-debugging-chrome/article.md
@@ -38,7 +38,11 @@ Jika kita menekan `key:Esc`, maka konsol terbuka di bawah. Kita bisa mengetik co
Setelah pernyataan diexekusi, hasilnya ditampilkan di bawah.
+<<<<<<< HEAD
Misalnya, `1+2` menghasilkan `3`, dan `hello("debugger")` tak mengembalikan apa-apa, jadi hasilnya `undefined`:
+=======
+For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6

@@ -62,13 +66,22 @@ Kita selalu bisa menemukan daftar breakpoint di panel kanan. Ini berguna ketika
- Buang breakpoint dengan mengklik-kanan dan memilik Remove.
- ...Dan banyak lagi.
+<<<<<<< HEAD
```smart header="Breakpoint kondisional"
*Klik kanan* di nomor baris bisa membuat breakpoint *kondisional*. Ia hanya terpicu saat expresi yang diberikan truthy.
+=======
+```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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ini praktis saat kita harus berhenti cuma untuk nilai variabel tertentu atau untuk parameter fungsi tertentu.
```
+<<<<<<< HEAD
## Command debugger
+=======
+## The command "debugger"
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kita juga bisa menjeda kode menggunakan command `debugger` di dalamnya, seperti ini:
@@ -84,8 +97,12 @@ function hello(name) {
}
```
+<<<<<<< HEAD
Ini sangat nyaman saat kita di dalam editor kode dan tak ingin berubah ke peramban dan mencari script di developer tools untuk mengeset breakpoint.
+=======
+Such command works only when the development tools are open, otherwise the browser ignores it.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Jeda dan lihat sekitar
@@ -99,7 +116,11 @@ Silakan buka dropdown informasional ke kanan (dilabeli panah). Mereka membolehka
1. **`Watch` -- menampilkan nilai sekarang untuk expresi apapun.**
+<<<<<<< HEAD
Kamu bisa mengklik `+` dan menginput expresi. Debugger akan menampilkan nilainya kapan saja, otomatis merekalkulasi itu di proses exekusi.
+=======
+ You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
2. **`Call Stack` -- menampilkan rantai panggilan bersarang.**
@@ -134,12 +155,21 @@ Ada tombol untuk itu di ujung atas panel kanan. Ayo kita ikuti mereka.
Mengklik ini akan melangkahi semua aksi script satu-satu.
+<<<<<<< HEAD
-- "Langkahi atas": jalankan command berikutnya, tapi *jangan masuk ke fungsi*, hotkey `key:F10`.
: Serupa dengan command "Step" sebelumnya, tapi berbeda jika pernyataan berikutnya berupa panggilan fungsi. Yaitu: bukan built-in, seperti `alert`, tapi fungsi kita sendiri.
Command "Langkahi" masuk ke dalam dan menjeda exekusi di baris pertama, sedangkan "Kangkangi" mengexekusi panggilan fungsi bersarang secara tak terlihat, mengabaikan internal fungsi.
Exekusi kemudian segera dijeda setelah fungsi itu.
+=======
+ -- "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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Itu baik jika kita tak tertarik mencaritahu ada apa di dalam panggilan fungsi.
@@ -154,8 +184,13 @@ Ada tombol untuk itu di ujung atas panel kanan. Ayo kita ikuti mereka.
-- nyalakan/matikan semua breakpoint.
: Tombol itu tidak menggerakkan exekusi. Cuma on/off massal untuk breakpoint.
+<<<<<<< HEAD
-- nyalakan/matikan jeda otomatis jika ada galat.
: Ketika menyala, dan developer tools terbuka, galat script otomatis menjeda exekusi. Lalu kita bisa menganalisa variabel untuk melihat apa yang salah. Jadi jika script kita mati karena galat, kita bisa buka debugger, menyalakan opsi ini dan memuat-ulang laman untuk melihat di mana ia mati dan apa kontexnya saat itu.
+=======
+ -- 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Lanjut ke sini"
Klilk kanan di satu baris kode membuka context menu dengan opsi hebat yang disebut "Lanjut ke sini".
@@ -187,7 +222,11 @@ Seperti yang kita lihat, ada tiga cara utama untuk menjeda script:
2. Pernyataan `debugger`.
3. Galat (jika dev tools terbuka dan tombol "menyala").
+<<<<<<< HEAD
Ketika terjeda, kita bisa mendebug - periksa variabel dan menjejak kode untuk melihat di mana terjadi kesalahan exekusi.
+=======
+When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ada banyak lebih opsi di developer tool dari yang diliput di sini. Manual lengkap ada di .
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 1ba318295..067615a6d 100644
--- a/1-js/03-code-quality/02-coding-style/article.md
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -301,11 +301,15 @@ Yang keren dari ini ialah pengecekan gaya sekaligus menemukan bug., like typos i
Berikut beberapa linting tool terkenal:
-- [JSLint](http://www.jslint.com/) -- one of the first linters.
-- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
-- [ESLint](http://eslint.org/) -- probably the newest one.
+- [JSLint](https://www.jslint.com/) -- one of the first linters.
+- [JSHint](https://jshint.com/) -- more settings than JSLint.
+- [ESLint](https://eslint.org/) -- probably the newest one.
+<<<<<<< HEAD
Semuanya bisa melakukan itu. Penulis ini menggunakan [ESLint](http://eslint.org/).
+=======
+All of them can do the job. The author uses [ESLint](https://eslint.org/).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kebanyakan linter terintegrasi dengan banyak editor populer: cuma mengaktifkan plugin di editor dan mengkonfigurasi gayanya.
@@ -335,7 +339,11 @@ Berikut contoh file `.eslintrc`:
Di sini directive `"extends"` menunjukkan bahwa konfigurasinya berdasarkan set pengaturan "eslint:recommended". Setelah itu, kita spesifikasikan punya kita sendiri.
+<<<<<<< HEAD
Selain itu, dimungkinkan juga mengunduh set aturan gaya dari web dan mengextend mereka. Lihat untuk detil lebih tentang instalasi.
+=======
+It is also possible to download style rule sets from the web and extend them instead. See for more details about installation.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Juga IDE tertentu punya linting built-in, yang nyaman tapi tak bisa dikustomisasi seperti ESLint.
diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md
index 11f0027c8..499dbc1d5 100644
--- a/1-js/03-code-quality/03-comments/article.md
+++ b/1-js/03-code-quality/03-comments/article.md
@@ -143,7 +143,11 @@ Parameter dan kegunaan fungsi dokumen
Oya, banyak editor seperti [WebStorm](https://www.jetbrains.com/webstorm/) bisa memahami mereka juga dan memakai mereka untuk menyediakan autocomplete dan beberapa pengecekan-kode otomatis.
+<<<<<<< HEAD
Juga, Ada tool seperti [JSDoc 3](https://github.com/jsdoc3/jsdoc) yang bisa menggenerate dokumentasi-HTML dari komentar. Kamu bisa baca informasi lebih tentang JSDoc di .
+=======
+Also, there are tools like [JSDoc 3](https://github.com/jsdoc/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kenapa tugas ini diselesaikan begini?
: Apa yang tertulis itu penting. Tapi apa yang *tak* tertilis mungkin lebih penting lagi untuk memahami yang terjadi. Kenapa tugas ini diselesaikan tepat seperti ini? Kodenya tak memberikan jawaban.
diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md
index ba58d4078..d0908e70e 100644
--- a/1-js/03-code-quality/05-testing-mocha/article.md
+++ b/1-js/03-code-quality/05-testing-mocha/article.md
@@ -48,7 +48,12 @@ describe("pow", function () {
Spek punya tiga blok bangunan utama yang bisa kamu lihat di bawah:
+<<<<<<< HEAD
`describe("title", function() { ... })` : Fungsionalitas apa yang kita jelaskan. Di kasus ini kita akan menjelaskan fungsi `pow`. Dipakai untuk mengelompokkan "pekerja" -- blok `it`.
+=======
+`describe("title", function() { ... })`
+: What functionality we're describing? In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
`it("use case description", function() { ... })` : Di judul `it` kita _dalam bahasa manusia_ menjelaskan use case tertentu, dan argumen kedua ialah fungsi yang mengetes itu.
@@ -62,6 +67,7 @@ Spesifikasi ini bisa diexekusi, dan ia akan menjalankan tes yang dispesifikasi d
Alur pengembangan biasanya seperti ini:
+<<<<<<< HEAD
1. Spek inisial ditulis, dengan tes untuk kebanyakan fungsionalitas dasar.
2. Implementatsi inisial dibuat.
3. Untuk mengecek apakah ia bekerja, kita jalankan framework pengetesan [Mocha](http://mochajs.org/) (detil lebih segera) yang menjalankan spek. Saat fungsionalitas tak lengkap, galat ditampilkan. Kita buat koreksi hingga semuanya bekerja.
@@ -69,20 +75,39 @@ Alur pengembangan biasanya seperti ini:
5. Kita tambah use case lain ke spek, mungkin belum didukung implementasinya. Tes mulai gagal.
6. Pergi ke 3, perbaharui implementasinya hingga tes tak memberikan galat.
7. Ulangi langkah 3-6 hingga fungsionalitasnya siap.
+=======
+1. An initial spec is written, with tests for the most basic functionality.
+2. An initial implementation is created.
+3. To check whether it works, we run the testing framework [Mocha](https://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
+4. Now we have a working initial implementation with tests.
+5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail.
+6. Go to 3, update the implementation till tests give no errors.
+7. Repeat steps 3-6 till the functionality is ready.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi, pengembangannya _iteratif_. Kita tulis spek, implementasikan, memastikan tes lulus, lalu menulis tes lainnya, memastikan mereka bekerja dll. Akhirnya kita punya implementasi yang bekerja dan tes untuk itu.
Ayo lihat alur pengembangan ini di kasus praktik kita.
+<<<<<<< HEAD
Langkap pertama sudah lengkap: kita punya spek inisial untuk `pow`. Sekarang, sebelum membuat implementasinya, ayo pakai beberapa librari JavaScript untuk menjalankan tes, hanya untuk melihat mereka bekerja (mereka semua akan gagal).
+=======
+The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use a few JavaScript libraries to run the tests, just to see that they are working (they will all fail).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Spec dalam aksi
Di sini di tutorial ini kita akan memakai librari JavaScript untuk tes:
+<<<<<<< HEAD
- [Mocha](http://mochajs.org/) -- inti framework: menyediakan fungsi testing umum `describe` dan `it` dan fungsi utama yang menjalankan test.
- [Chai](http://chaijs.com) -- librari dengan banyak penambahan. Ini membuatmu bisa untuk menggunakan banyak penambahan yang berbeda, untuk sekarang kita hanya membutuhkan `assert.equal`.
- [Sinon](http://sinonjs.org/) -- sebuah librari untuk memata-matai fungsi, meniru fungsi bawaan dan lainnya, kita akan butuh ini nanti.
+=======
+- [Mocha](https://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
+- [Chai](https://www.chaijs.com/) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
+- [Sinon](https://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Librari ini cocok baik untuk pengetesan in-browser dan server-side. Di sini kita akan mempertimbangkan varian peramban.
@@ -329,6 +354,7 @@ Tes yang baru ditambahkan gagal, karena implementasi kita tak mendukung mereka.
```smart header="Assersi lain"
Tolong catat assersi `assert.isNaN`: ia melakukan ecek terhadap `NaN`.
+<<<<<<< HEAD
Ada assersi lain di [Chai](http://chaijs.com) juga, misalnya:
- `assert.equal(value1, value2)` -- mengecek ekualitas `value1 == value2`.
@@ -337,6 +363,16 @@ Ada assersi lain di [Chai](http://chaijs.com) juga, misalnya:
- `assert.isTrue(value)` -- mengecek apa `value === true`
- `assert.isFalse(value)` -- mengecek apa `value === false`
- ...daftar lengkapnya ada di [docs](http://chaijs.com/api/assert/)
+=======
+There are other assertions in [Chai](https://www.chaijs.com/) as well, for instance:
+
+- `assert.equal(value1, value2)` -- checks the equality `value1 == value2`.
+- `assert.strictEqual(value1, value2)` -- checks the strict equality `value1 === value2`.
+- `assert.notEqual`, `assert.notStrictEqual` -- inverse checks to the ones above.
+- `assert.isTrue(value)` -- checks that `value === true`
+- `assert.isFalse(value)` -- checks that `value === false`
+- ...the full list is in the [docs](https://www.chaijs.com/api/assert/)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Jadi kita harus tambah beberapa baris `pow`:
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 88074673d..d57d1ce85 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -2,13 +2,23 @@
JavaScript secara konsisten terus berevolusi. Proposal-proposal untuk menambah fitur-fitur baru terus bermunculan. Proposal-proposal ini akan didaftarkan pada jika memang berpotensi dan layak untuk ditambahkan dalam standard dalam bahasa pemrograman JavaScript. Kemudian proposal-proposal yang telah diterima akan dimasukkan dalam [daftar spesifikasi](http://www.ecma-international.org/publications/standards/Ecma-262.htm) JavaScript.
+<<<<<<< HEAD
Tim yang mengurus JavaScript mengerti dan akan mengusulkan mana dari proposal-proposal ini yang akan diimplementasikan terlebih dahulu. Tim ini boleh saja nanti memasukkan proposal-proposal ini kedalam kategori 'draft / dalam perancangan' atau 'postpone / tunda' karena mungkin menurut mereka proposal-proposal ini menarik untuk didiskusikan lebih dalam atau sulit untuk direalisasikan.
+=======
+The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at and then progress to the [specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sangat wajar jika kebanyakan dari browser-browser yang ada hanya mengimplementasikan bagian-bagian yang tidak terlalu sulit.
+<<<<<<< HEAD
Sebuah halaman yang bagus untuk melihat kondisi terkini dari fitur yang didukung oleh bahasa ini ialah (isinya banyak, kita masih banyak yang belum dipelajari)
Sebagai programmer, kita suka untuk menggunakan fitur yang terbaru. lebih banyak fitur bagus - lebih baik lagi!
+=======
+So it's quite common for an engine to implement only part of the standard.
+
+A good page to see the current state of support for language features is (it's big, we have a lot to study yet).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
di sisi lain, bagaimana membuat kodingan modern bekerja di mesin yang lama yang tidak mengetahui fitur-fitur terbaru ?
@@ -21,7 +31,11 @@ di chapter ini, tujuan kita adalah untuk mendapatkan intisari cara kerjanya, dan
## Transpilers
+<<<<<<< HEAD
Sebuah [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) adalah perangkat lunak khusus yang dapat mengurai ("membaca dan memahami") kode modern, dan menulis ulang menggunakan konstruksi sintaks yang lebih lama, sehingga hasilnya akan sama.
+=======
+A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya. JavaScript sebelum tahun 2020 tidak memiliki "nullish coalescing operator" `??`. Jadi, jika pengunjung menggunakan browser yang sudah ketinggalan zaman, ia mungkin gagal memahami kode seperti `height = height ?? 100`
@@ -39,9 +53,15 @@ Sekarang kode yang ditulis ulang cocok untuk mesin JavaScript lama.
Biasanya, pengembang menjalankan transpiler di komputer mereka sendiri, dan kemudian menyebarkan kode yang ditranspilasi ke server.
+<<<<<<< HEAD
Berbicara tentang nama, [Babel](https://babeljs.io) adalah salah satu transpiler paling terkenal di luar sana.
Sistem pembangunan proyek modern, seperti [webpack](http://webpack.github.io/), menyediakan sarana untuk menjalankan transpiler secara otomatis pada setiap perubahan kode, sehingga sangat mudah untuk diintegrasikan ke dalam proses pengembangan.
+=======
+Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there.
+
+Modern project build systems, such as [webpack](https://webpack.js.org/), provide a means to run a transpiler automatically on every code change, so it's very easy to integrate into the development process.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Polyfills
@@ -68,17 +88,23 @@ if (!Math.trunc) { // kalo ga ada fungsi seperti ini
}
```
+<<<<<<< HEAD
JavaScript adalah bahasa yang sangat dinamis, skrip dapat menambah / memodifikasi fungsi apa pun, bahkan termasuk yang sudah ada di dalamnya.
Dua library polyfill yang menarik adalah:
- [core js](https://github.com/zloirock/core-js) yang mendukung banyak hal, memungkinkan untuk kita memasukkan hanya fitur yang dibutuhkan.
- [polyfill.io](http://polyfill.io) layanan yang menyediakan skrip dengan polyfills, bergantung pada fitur dan browser pengguna.
+=======
+JavaScript is a highly dynamic language. Scripts may add/modify any function, even built-in ones.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
+One interesting polyfill library is [core-js](https://github.com/zloirock/core-js), which supports a wide range of features and allows you to include only the ones you need.
## Kesimpulan
Di bab ini, kami ingin memotivasi Anda untuk mempelajari fitur bahasa modern dan bahkan "yang paling mutakhir", meskipun fitur tersebut belum didukung dengan baik oleh mesin JavaScript.
+<<<<<<< HEAD
Jangan lupa untuk menggunakan transpiler (jika menggunakan sintaks atau operator modern) dan polyfill (untuk menambahkan fungsi yang mungkin hilang). Dan mereka akan memastikan bahwa kodenya berfungsi.
Misalnya, nanti saat Anda sudah terbiasa dengan JavaScript, Anda dapat menyiapkan sistem pembuatan kode berdasarkan [webpack](http://webpack.github.io/) dengan [babel-loader](https://github.com/babel/babel-loader).
@@ -86,5 +112,16 @@ Misalnya, nanti saat Anda sudah terbiasa dengan JavaScript, Anda dapat menyiapka
Sumber daya bagus yang menunjukkan status dukungan saat ini untuk berbagai fitur:
- - untuk JavaScript murni.
- - untuk fungsi terkait dengan browser.
+=======
+Just don't forget to use a transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). They'll ensure that the code works.
+
+For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](https://webpack.js.org/) with the [babel-loader](https://github.com/babel/babel-loader) plugin.
+
+Good resources that show the current state of support for various features:
+- - for pure JavaScript.
+- - for browser-related functions.
+
+P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
P.S. Google Chrome biasanya paling mutakhir dengan fitur bahasa, coba saja jika demo tutorial gagal. Sebagian besar demo tutorial berfungsi dengan browser modern apa pun.
\ No newline at end of file
diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md
index e570cf995..c0371a23b 100644
--- a/1-js/04-object-basics/01-object/article.md
+++ b/1-js/04-object-basics/01-object/article.md
@@ -44,7 +44,11 @@ Hasil objek `user` bisa dibayangkan sebagai kabinet dengan dua file bertanda den

+<<<<<<< HEAD
Kita bisa tambah, hapus dan baca file darinya kapanpun.
+=======
+We can add, remove and read files from it at any time.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Nilai properti bisa diakses memakai notasi dot:
@@ -62,7 +66,11 @@ user.isAdmin = true;

+<<<<<<< HEAD
Untuk menghapus properti, kita bisa pakai operator `delete`:
+=======
+To remove a property, we can use the `delete` operator:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
delete user.age;
@@ -201,13 +209,21 @@ let bag = {
};
```
+<<<<<<< HEAD
Bracket kotak jauh lebih kuat dari notasi dot. Mereka membolehkan variabel dan nama properti apapun. Tapi mereka juga lebih rumit untuk ditulis.
+=======
+Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi seringnya, saat nama properti diketahui dan simpel, dot dipakai. Dan jika kita butuh sesuatu yang rumit, maka kita ganti ke bracket kotak.
## Singkatan nilai properti
+<<<<<<< HEAD
Di kode riil kita sering memakai variabel sebagai nilai untuk nama properti.
+=======
+In real code, we often use existing variables as values for property names.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya:
@@ -252,7 +268,11 @@ let user = {
## Batasan nama properti
+<<<<<<< HEAD
Seperti yang sudah kita tahu, sebuah variabel tidak bisa memiliki nama yang sama dengan salah satu "kata yang telah dimiliki bahasa pemrograman" seperti "for", "let", "return" dan lainnya.
+=======
+As we already know, a variable cannot have a name equal to one of the language-reserved words like "for", "let", "return" etc.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tapi dari sebuah properti objek, tidak ada batasan seperti itu:
@@ -325,7 +345,11 @@ alert( "blabla" in user ); // false, user.blabla tak ada
Tolong ingat bahwa di sebelah kiri `in` harus ada *nama properti*. Itu biasanya string yang dikuotasi.
+<<<<<<< HEAD
Jika kita menghilangkan kutipnya, berarti sebuah variabel, itu haruslah mengandung nama yang akan dites. Contoh:
+=======
+If we omit quotes, that means a variable should contain the actual name to be tested. For instance:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let user = { age: 30 };
@@ -357,7 +381,11 @@ Di contoh kode di atas, properti `obj.test` ada secara teknis. Tapi operator `in
Situasi seperti ini jarang terjadi, karena `undefined` biasanya tak ditetapkan. Kita sering memakai `null` untuk nilai "unknown" atau "empty". Jadi operator `in` merupakan tamu exotik dalam kode.
````
+<<<<<<< HEAD
## "for..in"
+=======
+## The "for..in" loop [#forin]
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Untuk mengitari semua kunci objek, ada bentuk spesial dari loop: `for..in`. Ini sangat berbeda dari konstruksi `for(;;)` yang kita pelajari sebelumnya.
@@ -415,7 +443,11 @@ for (let code in codes) {
*/!*
```
+<<<<<<< HEAD
Objek ini digunakan untuk mensugesti daftar opsi ke pengguna. Jika kita membuat situs khusus untuk audiensi Jerman maka kita kemungkinan mau `49` jadi yang pertama.
+=======
+The object may be used to suggest a list of options to the user. If we're making a site mainly for a German audience then we probably want `49` to be the first.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tapi jika kita menjalankan kodenya, kita lihat potret yang berbeda:
@@ -427,9 +459,14 @@ Kode telpon berurut secara ascending, karena mereka integer. Jadi kita lihat `1,
````smart header="Properti integer? Apa itu?"
Istilah "properti integer" di sini artinya string yang bisa dikonversi ke-dan-dari integer tanpa perubahan.
+<<<<<<< HEAD
Jadi, "49" nama properti integer, karena mereka ditransform ke angka integer dan kebalikannya, ia masih sama saja. Tapi "+49" dan "1.2" tidak:
+=======
+So, `"49"` is an integer property name, because when it's transformed to an integer number and back, it's still the same. But `"+49"` and `"1.2"` are not:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
+// Number(...) explicitly converts to a number
// Math.trunc is a built-in function that removes the decimal part
alert( String(Math.trunc(Number("49"))) ); // "49", sama, properti integer
alert( String(Math.trunc(Number("+49"))) ); // "49", tidak sama "+49" ⇒ bukan properti integer
@@ -482,9 +519,15 @@ Objek menyimpan properti (pasangan key-value), dimana:
- kunci/key properti haruslah sebuah string atau simbol (biasanya string).
- Nilai bisa tipe apapun.
+<<<<<<< HEAD
Untuk mengakses properti, kita bisa gunakan:
- Notasi dot: `obj.properti`.
- Notasi kurung siku `obj["properti"]`. Kurung siku memperbolehkan mengambil key dari sebuah variabel, seperti `obj[varDenganKey]`.
+=======
+To access a property, we can use:
+- The dot notation: `obj.property`.
+- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Operator tambahan:
- Untuk menghapus properti: `delete obj.prop`.
diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md
index 13918ab93..ad1b520ca 100644
--- a/1-js/04-object-basics/02-object-copy/article.md
+++ b/1-js/04-object-basics/02-object-copy/article.md
@@ -37,7 +37,11 @@ Dan ini bagaimana kita menyimpannya di dalam memory:
Objek disimpan di suatu tempat di memori (di sebelah kanan gambar), sedangkan variabel `user` (di sebelah kiri) memiliki" referensi "padanya.
+<<<<<<< HEAD
Kita mungkin menganggap variabel objek, seperti `pengguna`, seperti selembar kertas dengan alamat objek di atasnya.
+=======
+We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Saat kita melakukan tindakan dengan objek, misalnya: mengambil properti `user.name`, mesin JavaScript melihat apa yang ada di alamat itu dan melakukan operasi pada objek sebenarnya.
@@ -103,6 +107,7 @@ alert( a == b ); // false
Untuk perbandingan seperti `obj1 > obj2` atau untuk perbandingan dengan sebuah nilai primitif `obj == 5`, objek akan diubah dahulu menjadi primitif. Kita akan belajar bagaimana perubahan objek sebentar lagi, akan tetapi sebenarnya, perbandingan seperti itu muncul sangat jarang, biasanya hanya sebuah hasil dari kesalahan koding.
+<<<<<<< HEAD
## Penggandaan dan penggabungan, Object.assign [#cloning-and-merging-object-assign]
Jadi, menyalin sebuah variabel objek akan menciptakan satu lagi referensi kepada objek yang sama.
@@ -237,6 +242,8 @@ Untuk membenarkan hal itu, kita harus menggunakan perulangan kloning yang memeri
We can use recursion to implement it. 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).
+=======
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````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.
@@ -261,6 +268,202 @@ Dengan kata lain, `const user` memberikan kesalahan hanya jika kita mencoba meny
yang berarti, jika kita benar-benar perlu membuat properti objek konstan, itu juga mungkin, tetapi menggunakan metode yang sama sekali berbeda. Kita akan membahasnya di bab .
````
+<<<<<<< HEAD
+=======
+## 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
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Ringkasan
@@ -273,3 +476,7 @@ Untuk membuat "salinan asli" (kloning) kita dapat menggunakan `Object.assign` un
+<<<<<<< HEAD
+=======
+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).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/04-object-basics/03-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md
index ab5a46e6f..47bc99f39 100644
--- a/1-js/04-object-basics/03-garbage-collection/article.md
+++ b/1-js/04-object-basics/03-garbage-collection/article.md
@@ -74,7 +74,11 @@ Sekarang jika kita melakukan hal yang sama:
user = null;
```
+<<<<<<< HEAD
...Maka objek "John" tersebut masih bisa dijangkau lewat variabel global `admin`, jadi masih ada di memori. Jika kita menimpa `admin` juga, barulah dapat dihilangkan.
+=======
+...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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Objek-objek yang saling terkait
@@ -169,11 +173,19 @@ Langkah pertama menandai _roots_-nya:

+<<<<<<< HEAD
Kemudian rujukkannya ditandai:

...Dan kemudian rujukkan dalamnya juga, jika masih ada:
+=======
+Then we follow their references and mark referenced objects:
+
+
+
+...And continue to follow further references, while possible:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6

@@ -183,13 +195,23 @@ Sekarang objek-objek yang tak dapat dikunjungi selama proses berlangsung diangga
Kita juga bisa membayangkan proses tersebut sebagai menumpahkan ember cat dari _roots_, yang mengalir ke semua rujukkan dan menandai semua objek yang terjangkau. Yang tidak tertandai akan dihapus.
+<<<<<<< HEAD
Itu merupakan konsep dari bagaimana cara kerja _garbage collection_. _Engines_ JavaScript menerapkan banyak optimisasi untuk membuatnya berjalan lebih cepat dan tanpa mempengaruhi eksekusi.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Beberapa optimisasi:
+<<<<<<< HEAD
- **Generational collection** -- objek-objek dibagi kedalam dua set: "yang baru" dan "yang lama". Kebanyakan objek muncul, melakukan tugasnya dan mati dengan cepat, mereka dapat dibersihkan secara agresif. Mereka yang bertahan cukup lama, akan menjadi "yang lama" dan tak akan sering diperiksa.
- **Incremental collection** -- Jika terdapat banyak objek-objek, dan kita mencoba menapaki sambil menandai keseluruhan set objek sekaligus, itu dapat memakan waktu dan menimbulkan keterlambatan yang terlihat dalam eksekusi. Jadi _engine_ akan mencoba untuk memecah proses _garbage collection_ menjadi bagian-bagian kecil. Kemudian bagian-bagian kecil tersebut akan dieksekusi satu-persatu, secara terpisah. Itu memerlukan pencatatan ekstra diantara mereka untuk melacak perubahan, tetapi jadinya kta hanya mengalami keterlambatan kecil yang banyak daripada satuan yang besar.
- **Idle-time collection** -- _garbage collector_ akan mencoba untuk jalan hanya ketika _CPU_ sedang _idle_, untuk mengurangi kemungkinan efek pada eksekusi.
+=======
+- **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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Terdapat optimisasi-optimisasi dan tipe-tipe lain dari algoritma _garbage collection_. Sebesar apapun keinginan untuk menjelaskannya disini, harus kutahan, karena _engines_ yang berbeda mengimplementasikan teknik dan _tweaks_ yang berbeda pula. Dan, yang lebih penting, hal-hal tersebut akan berubah seiring dengan pengembangan _engine_, jadi mempelajarinya lebih dalam "di awal", tanpa kebutuhan yang berarti mungkin akan sia-sia. Kecuali, tentu saja, jika itu merupakan murni masalah ketertarikan, maka ada beberapa tautan untukmu dibawah.
@@ -197,16 +219,30 @@ Terdapat optimisasi-optimisasi dan tipe-tipe lain dari algoritma _garbage collec
Hal utama yang perlu diketahui:
+<<<<<<< HEAD
- Pengumpulan sampah (_Garbage collection_) dilakukan secara otomatis. Kita tidak bisa memaksa ataupun mencegahnya.
- Objek-objek dipertahankan dalam memori selagi mereka terjangkau (_reachable_).
- Menjadi yang dirujuk tidak sama dengan menjadi terjangkau (dari sebuah _root_): sekumpulan objek yang saling terkait dapat menjadi tak terjangkau sebagai keseluruhan.
+=======
+- 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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
_Engine_ modern mengimplementasikan algoritma _garbage collection_ canggih (_advance_).
Buku "The Garbage Collection Handbook: The Art of Automatic Memory Management" (R. Jones et al) mencakup beberapanya.
+<<<<<<< HEAD
Jika kamu familiar dengan pemrograman _low-level_, informasi mendalam tentang _garbage collector_ V8 terdapat pada artikel [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
[V8 blog](https://v8.dev/) juga mempublikasikan artikel-artikel tentang ubahan-ubahan dalam manajemen memori dari waktu ke waktu. Tentu saja, untuk belajar proses _garbage collection_, kamu lebih baik mempersiapkan diri dengan belajar tentang _internals_ V8 secara umum dan membaca blog [Vyacheslav Egorov](http://mrale.ph) yang merupakan salah seorang _engineer_ V8. Saya bilang: "V8", karena merupakan yang paling komprehensif di _cover_ oleh artikel-artikel di internet. Untuk _engine_ lainnya, pendekatannya kebanyakan mirip-mirip, tetapi _garbage collection_ berbeda dalam banyak aspek.
Pengetahuan mendalam mengenai _engines_ itu bagus ketika membutuhkan optimisasi _low-level_. Tapi akan lebih bijak untuk merencanakan itu sebagai langkah selanjutnya setelah kamu akrab dengan bahasanya (JavaScript).
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
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 9ac8ad785..e742e18c0 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
Buatlah sebuah objek `calculator` dengan tiga metode:
+<<<<<<< HEAD
- `read()` mendorong kedua nilai dan menyimpan nilai-nilai tersebut sebagai properti objek.
- `sum()` mengembalikan jumlah dari nilai-nilai yang disimpan.
- `mul()` mengalikan nilai-nilai yang disimpan dan mengembalikan hasilnya.
+=======
+- `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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let calculator = {
@@ -21,4 +27,3 @@ alert( calculator.mul() );
```
[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 e98fe6410..a35c009cc 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
@@ -11,5 +11,6 @@ let ladder = {
},
showStep: function() {
alert(this.step);
+ return this;
}
};
\ No newline at end of file
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 a2b17fcc4..b4f2459b7 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
@@ -32,6 +32,14 @@ describe('Ladder', function() {
it('down().up().up().up() ', function() {
assert.equal(ladder.down().up().up().up().step, 2);
});
+
+ 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;
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 14a735840..364c0006e 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
@@ -23,7 +23,7 @@ let ladder = {
}
};
-ladder.up().up().down().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```
Kita juga bisa menuliskan sebuah panggilan di setiap baris. Untuk rantai kode yang panjang jadi lebih mudah dibaca seperti ini:
@@ -33,7 +33,7 @@ ladder
.up()
.up()
.down()
- .up()
+ .showStep() // 1
.down()
- .showStep(); // 1
+ .showStep(); // 0
```
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 305b6daf6..359f1bd49 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
# *Chaining* (merantaikan)
+<<<<<<< HEAD
Ada sebuah objek layaknya tangga (`ladder`) yang dapat naik dan turun:
+=======
+There's a `ladder` object that allows you to go up and down:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let ladder = {
@@ -21,19 +25,33 @@ let ladder = {
};
```
+<<<<<<< HEAD
Kini, jika kita perlu untuk membuat beberapa panggilan secara berurutan, bisa dilakukan dengan cara seperti ini:
+=======
+Now, if we need to make several calls in sequence, we can do it like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
ladder.up();
ladder.up();
ladder.down();
ladder.showStep(); // 1
+ladder.down();
+ladder.showStep(); // 0
```
+<<<<<<< HEAD
Modifikasi kode `up`, `down` dan `showStep` untuk membuat panggilan-panggilan tersebut dapat dirantaikan satu sama lain, seperti ini:
+=======
+Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
-ladder.up().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```
+<<<<<<< HEAD
Pendekatan demikian digunakan secara luas di banyak *library* JavaScript.
+=======
+Such an approach is widely used across JavaScript libraries.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
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 7f0eef898..76ac22c4f 100644
--- a/1-js/04-object-basics/04-object-methods/article.md
+++ b/1-js/04-object-basics/04-object-methods/article.md
@@ -51,7 +51,7 @@ let user = {
// pertama, deklarasi
function sayHi() {
alert("Hello!");
-};
+}
// lalu tambbahkan sebagai sebuah metodes
user.sayHi = sayHi;
@@ -90,7 +90,11 @@ user = {
Seperti yang didemonstrasikan, kita bisa mengabaikan `"function"` dan hanya menuliskan `sayHi()`.
+<<<<<<< HEAD
Sebenarnya, notasi-notasi tersebut tidak sepenuhnya sama. Ada beberapa perbedaan kecil yang berhubungan dengan *object inheritance* atau pewarisan objek (akan dibahas nanti), tetapi untuk sekarang hal-hal tersebut tidak terlalu penting. Dalam hampir kebanyakan kasus sintaks ringkas lebih disukai.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## "this" dalam metode
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 c6d8318fd..0c0df9577 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
# Dua fungsi – satu objek
+<<<<<<< HEAD
Apakah mungkin untuk membuat fungsi `A` dan fungsi `B` seperti `new A()==new B()`?
+=======
+Is it possible to create functions `A` and `B` so that `new A() == new B()`?
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```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/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
index 043bddc01..d86eaa2d6 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,9 +6,15 @@ importance: 5
Buatlah sebuah fungsi konstruktor `Calculator` yang membuat objek dengan 3 method:
+<<<<<<< HEAD
- `read()` tanyakan dua nilai menggunakan `prompt dan masukan mereka kedalam properti objek.
- `sum()` mengembalikan jumlah dari properti-properti.
- `mul()` mengembalikan perkalian produk dari properti-properti.
+=======
+- `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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh:
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 8580997c6..74c05aa87 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 @@
# Konstruktor, operator "new"
+<<<<<<< HEAD
Sintaks reguler `{...}` memungkinkan kita untuk membuat satu objek. Tapi seringkali kita perlu untuk membuat banyak objek-objek serupa, seperti pengguna atau *item* menu berganda dan sebagainya.
+=======
+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.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Hal tersebut dapat diselesaikan dengan menggunakan fungsi konstruktor dan operator `"new"`.
@@ -170,8 +174,13 @@ alert( new SmallUser().name ); // John
Biasanya konstruktor tidak memiliki sebuah pernyataan `return`. Di sini kita menyebutkan perilaku khusus dengan cara mengembalikan objek dengan tujuan utamanya yakni hanya untuk melengkapi saja.
+<<<<<<< HEAD
````smart header="Mengabaikan parentheses"
Omong-omong, kita bisa mengabaikan parentheses setelah `new`, jika tidak memiliki argumen:
+=======
+````smart header="Omitting parentheses"
+By the way, we can omit parentheses after `new`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let user = new User; // <-- tanpa parentheses
diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md
index 7a0a0ff23..14afa1f39 100644
--- a/1-js/04-object-basics/07-optional-chaining/article.md
+++ b/1-js/04-object-basics/07-optional-chaining/article.md
@@ -25,14 +25,14 @@ That's the expected result. JavaScript works like this. As `user.address` is `un
In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
-...And another example. In the 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.
+...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` of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
+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, we'd like to avoid the error and just accept `html = null` as the result.
How can we do this?
@@ -44,11 +44,19 @@ let user = {};
alert(user.address ? user.address.street : undefined);
```
-It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. For more deeply nested properties, that becomes a problem as more repetitions are required.
+It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code.
-E.g. let's try getting `user.address.street.name`.
+Here's how the same would look for `document.querySelector`:
-We need to check both `user.address` and `user.address.street`:
+```js run
+let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
+```
+
+We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good.
+
+For more deeply nested properties, it becomes even uglier, as more repetitions are required.
+
+E.g. let's get `user.address.street.name` in a similar fashion.
```js
let user = {}; // user has no address
@@ -58,7 +66,7 @@ alert(user.address ? user.address.street ? user.address.street.name : null : nul
That's just awful, one may even have problems understanding such code.
-Don't even care to, as there's a better way to write it, using the `&&` operator:
+There's a little better way to write it, using the `&&` operator:
```js run
let user = {}; // user has no address
@@ -92,6 +100,12 @@ alert( user?.address?.street ); // undefined (no error)
The code is short and clean, there's no duplication at all.
+Here's an example with `document.querySelector`:
+
+```js run
+let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element
+```
+
Reading the address with `user?.address` works even if `user` object doesn't exist:
```js run
@@ -108,9 +122,9 @@ E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/un
```warn header="Don't overuse the optional chaining"
We should use `?.` only where it's ok that something doesn't exist.
-For example, if according to our coding logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
+For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
-So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
+Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug.
```
````warn header="The variable before `?.` must be declared"
@@ -127,7 +141,7 @@ The variable must be declared (e.g. `let/const/var user` or as a function parame
As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.
-So, if there are any further function calls or side effects, they don't occur.
+So, if there are any further function calls or operations to the right of `?.`, they won't be made.
For instance:
@@ -135,7 +149,7 @@ For instance:
let user = null;
let x = 0;
-user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
+user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++
alert(x); // 0, value not incremented
```
@@ -162,13 +176,13 @@ userAdmin.admin?.(); // I am admin
*/!*
*!*
-userGuest.admin?.(); // nothing (no such method)
+userGuest.admin?.(); // nothing happens (no such method)
*/!*
```
-Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the user object exists, so it's safe read from it.
+Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it.
-Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
+Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
@@ -179,7 +193,7 @@ let user1 = {
firstName: "John"
};
-let user2 = null;
+let user2 = null;
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
@@ -192,17 +206,16 @@ delete user?.name; // delete user.name if user exists
```
````warn header="We can use `?.` for safe reading and deleting, but not writing"
-The optional chaining `?.` has no use at the left side of an assignment.
+The optional chaining `?.` has no use on the left side of an assignment.
For example:
```js run
let user = null;
user?.name = "John"; // Error, doesn't work
-// because it evaluates to undefined = "John"
+// because it evaluates to: undefined = "John"
```
-It's just not that smart.
````
## Summary
@@ -217,4 +230,8 @@ As we can see, all of them are straightforward and simple to use. The `?.` check
A chain of `?.` allows to safely access nested properties.
-Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
\ No newline at end of file
+<<<<<<< HEAD
+Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
+=======
+Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md
index 1f42cb775..ac2bf7359 100644
--- a/1-js/04-object-basics/08-symbol/article.md
+++ b/1-js/04-object-basics/08-symbol/article.md
@@ -1,9 +1,22 @@
# Tipe simbol
+<<<<<<< HEAD
Menurut spesifikasi spesifikasi, properti-properti kunci objek bisa saja bertipe *string*, atau bertipe simbol. Bukan angka (*number*), bukan *boolean*, hanya *string* atau simbol-simbol, kedua tipe ini.
Hingga kini kita telah menggunakan *string* saja. Mari kita lihat keuntungan-keuntungan apa saja dari simbol yang bisa diberikan ke kita.
+=======
+By specification, only two primitive types may serve as object property keys:
+
+- string type, or
+- symbol type.
+
+Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`.
+
+Until now we've been using only strings.
+
+Now let's explore symbols, see what they can do for us.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Simbol-simbol
@@ -12,18 +25,29 @@ Sebuah "simbol" merepresentasikan sebuah pengidentifikasi yang unik.
Nilai dari tipe ini dapat dibuat menggunakan `Symbol()`:
```js
+<<<<<<< HEAD
// id adalah sebuah simbol baru
let id = Symbol();
```
Selama penyusunan, kita bisa memberikan simbol sebuah deskripsi (juga disebut sebagai nama simbol), kebanyakan berguna untuk tujuan-tujuan *debugging*:
+=======
+let id = Symbol();
+```
+
+Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// id adalah simbol dengan deskripsi "id"
let id = Symbol("id");
```
+<<<<<<< HEAD
Simbol-simbol sudah pasti unik. Bahkan jika kita membuat banyak simbol dengan deskripsi yang, mereka memiliki nilai-nilai yang berbeda. Deskripsi hanyalah sebuah label yang tidak mempengaruhi apapun.
+=======
+Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, berikut ini ada dua simbol dengan deskripsi yang sama -- keduanya tidak sama:
@@ -38,8 +62,15 @@ alert(id1 == id2); // false
Jika kamu tidak asing dengan Ruby atau bahasa pemrograman lain yang juga memiliki hal seperti "simbol" -- tolong jangan sampai keliru. Simbol-simbol (di) JavaScript itu berbeda.
+<<<<<<< HEAD
````warn header="Simbol-simbol tidak dikonversi otomatis menjadi string"
Kebanyakan nilai-nilai dalam JavaScript mendukung konversi implisit menjadi sebuah string. Contohnya, kita bisa memberi `alert` pada hampir nilai apapun, dan masih akan berfungsi. Simbol itu istimewa. Mereka tidak terkonversi otomatis.
+=======
+So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them.
+
+````warn header="Symbols don't auto-convert to a string"
+Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, `alert` ini akan memunculkan sebuah error:
@@ -52,7 +83,12 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string
Hal tersebut adalah sebuah "garda bahasa pemrograman" untuk menghadapi adanya kekacauan, karena string dan simbol itu berbeda secara fundamental dan sudah seharusnya tidak akan terkonversi dari satu ke lainnya secara tidak sengaja.
+<<<<<<< HEAD
Jika kita benar-benar ingin menunjukkan sebuah simbol, kita perlu secara eskplisit memanggil `.toString()` sintaks tersebut, seperti berikut ini:
+=======
+If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let id = Symbol("id");
*!*
@@ -60,7 +96,12 @@ alert(id.toString()); // Symbol(id), sekarang berfungsi
*/!*
```
+<<<<<<< HEAD
Atau mengambil properti `symbol.description` untuk menunjuukan deskripsinya saja:
+=======
+Or get `symbol.description` property to show the description only:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let id = Symbol("id");
*!*
@@ -72,7 +113,12 @@ alert(id.description); // id
## Properti "tersembunyi" (*hidden*)
+<<<<<<< HEAD
Simbol memungkinkan kita untuk membuat properti-properti yang "tersembunyi" (*hidden*) dari sebuah objek, yang mana tidak akan ada bagian lain dari kode yang bisa mengakses atau meng-*overwrite* tanpa sengaja.
+=======
+
+Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, jika kita bekerja dengan objek-objek `user`, yang dimiliki oleh sebuah kode pihak ketiga. Kita akan menambahkan pengidentifikasi pada objek-objek tersebut.
@@ -92,9 +138,15 @@ alert( user[id] ); // kita bisa mengakses data menggunakan simbol sebagai kunci
Apa keuntungan dari menggunakan `Symbol("id")` daripada sebuah *string* `"id"`?
+<<<<<<< HEAD
Sebagaimana objek-objek `user` adalah milik kode lain, dan kode itu juga berfungsi dengan objek-objek tadi, kita seharusnya tidak hanya menambahkan ruang apapun di situ. Hal tersebut tidak aman. Tetapi sebuah simbol tidak bisa diakses tanpa sengaja, kode pihak ketiga bahkan tidak akan melihatnya, jadi mungkin tidak masalah jika demikian.
Juga, bayangkan *script* lain ingin memiliki pengidentifikasi sendiri dalam objek `user`, untuk tujuannya masing-masing. Hal tersebut bisa saja *library* JavaScript lainnya, jadi *script-script* tersebut benar-benar tidak menyadari satu sama lainnya.
+=======
+As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects.
+
+Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kemudian *script* tersebut bisa membuat `Symbol("id")`-nya sendiri, seperti berikut ini:
@@ -157,11 +209,19 @@ let user = {
for (let key in user) alert(key); // name, age (bukan simbol)
*/!*
+<<<<<<< HEAD
// akses langsung dengan simbol, berfungsi
alert( "Direct: " + user[id] );
```
`Object.keys(user)` juga mengabaikannya. Itu adalah bagian dari prinsip umum "menyembunyikan properti simbolis" (*hiding symbolic properties*). Jika *script* lain atau sebuah *library* melakukan pengulanagn pada objek kita, hal tersebut tidak akan mengakses sebuah properti simbolis tanpa diduga.
+=======
+// the direct access by the symbol works
+alert( "Direct: " + user[id] ); // Direct: 123
+```
+
+[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebaliknya, [Object.assign](mdn:js/Object/assign) menyalin baik *string* properti maupun simbol properti:
@@ -206,12 +266,20 @@ Simbol-simbol di dalam catatan (*registry*) disebut sebagai *simbol-simbol globa
```smart header="Simbol global itu seperti dalam Ruby"
Dalam beberapa bahasa pemrograman, seperti Ruby, hanya ada satu simbol per nama.
+<<<<<<< HEAD
Dalam JavaScript, seperti yang bisa kita lihat, yakni simbol-simbol global.
+=======
+In JavaScript, as we can see, that's true for global symbols.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
### Symbol.keyFor
+<<<<<<< HEAD
Untuk simbol-simbol global, tidak hanya `Symbol.for(key)` yang mengembalikan sebuah simbol berdasarkan nama, tetapi ada sebuah panggilan sebaliknya: `Symbol.keyFor(sym)`, sintaks tersebut melakukan hal sebaliknya tadi: mengembalikan sebuah nama berdasarkan sebuah simbol global.
+=======
+We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contohnya:
@@ -227,7 +295,11 @@ alert( Symbol.keyFor(sym2) ); // id
`Simbol.keyFor` secara internal menggunakan simbol registry global untuk mencari key/kunci dari simbolnya. Jadi itu tidak akan bekerja dengan simbol non-global. Jika simbolnya bukan global, itu tidak akan bisa menemukannya dan akan mengembalikan `undefined`.
+<<<<<<< HEAD
Seperti yang dikatakan, simbol apapun memiliki properti `description`.
+=======
+That said, all symbols have the `description` property.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contohnya:
@@ -267,11 +339,21 @@ Simbols selalu berbeda nilainya, bahkan jika mereka memiliki nama yang sama. Jik
Simbol memiliki dua alasan utama pada pemakaiannya:
+<<<<<<< HEAD
1. Properti objek yang "tersembunyi".
Jika kita ingin menambahkan sebuah properti ke dala sebuah objek yang "dimiliki" oleh *script* lain atau sebuah *library*, kita bisa membuat sebuah simbol dan menggunakannya sebagai sebuah kunci properti. Sebuah properti simbolis tidak muncul dalam `for..in`, jadi hal tersbeut tidak akan tanpa sengaja terproses bersama properti-properti lain. Juga, simbol tidak akan diakses secara langsung, karena *script* tidak memiliki simbol kita. Jadi properti akan terlindungi dari penggunaan yang tak disengaja maupun tertimpa (*overwrite*).
+=======
+1. "Hidden" object properties.
+
+ If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi kita bisa "secara terselubung" menyembunyikan sesuatu ke dalam objek yang kita inginkan, tetapi tidak bisa diliha oleh pihak lain, menggunakn properti simbolis.
2. Terdapat banyak simbol sistem yang digunakan oleh oleh JavaScript yang mana dapat diakses sebagai `Symbol.*`. Kita bisa menggunakan simbol-simbol tersebut untuk mengubah beberapa perilaku bawaan (*built-in*). Sebagai contohnya, di tutorial selanjutnya kita akan menggunakan `Symbol.iterator` untuk [*iterables*](info:iterable), `Symbol.toPrimitive` untuk mengatur [konversi objek-ke-primitif](info:object-toprimitive) dan sebagainya.
+<<<<<<< HEAD
Secara teknis, simbol-simbol tidak 100% tersembunyi. Ada sebuah metode bawaan [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) yang membuat kita dapat mendapatkan semua simbol. Juga terdapat sebuah metode yang dinamakan [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) yang mengembalikan *semua* kunci dari sebuah objek termasuk yang kunci yang simbolik. Jadi simbol-simbol tersebut tidak sepenuhnya tersembunyi. Namun untuk sebagian besar *library*, fungsi-fungsi bawaan dan kontruksi sintaks constructs tidak menggunakan metode-metode ini.
+=======
+Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md
index d0de05b0e..ae59d9d92 100644
--- a/1-js/04-object-basics/09-object-toprimitive/article.md
+++ b/1-js/04-object-basics/09-object-toprimitive/article.md
@@ -4,15 +4,27 @@ Apa yang terjadi ketika objek ditambahkan `obj1 + obj2`, dikurangi `obj1 - obj2`
JavaScript tidak benar-benar memungkinkan untuk menyesuaikan cara operator bekerja pada objek. Tidak seperti beberapa bahasa pemrograman lain, seperti Ruby atau C++, kami tidak dapat mengimplementasikan metode objek khusus untuk menangani penambahan (atau operator lain).
+<<<<<<< HEAD
Dalam kasus operasi seperti itu, objek secara otomatis dikonversi ke primitif, dan kemudian operasi dilakukan di atas primitif ini dan menghasilkan nilai primitif.
+=======
+JavaScript doesn't allow you to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle addition (or other operators).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Itu batasan penting, karena hasil dari `obj1 + obj2` tidak bisa menjadi objek lain!
+<<<<<<< HEAD
Misalnya. kita tidak dapat membuat objek yang mewakili vektor atau matriks (atau pencapaian atau apa pun), menambahkannya dan mengharapkan objek "dijumlahkan" sebagai hasilnya. Prestasi arsitektur seperti itu secara otomatis "di luar papan".
Jadi, karena kita tidak bisa berbuat banyak di sini, tidak ada matematika dengan objek dalam proyek nyata. Ketika itu terjadi, biasanya karena kesalahan pengkodean.
Dalam bab ini kita akan membahas bagaimana sebuah objek dikonversi ke primitif dan bagaimana menyesuaikannya.
+=======
+That's an important limitation: the result of `obj1 + obj2` (or another math operation) can't be another object!
+
+E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
+
+So, because we can't technically do much here, there's no maths with objects in real projects. When it happens, with rare exceptions, it's because of a coding mistake.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kami memiliki dua tujuan:
@@ -27,6 +39,7 @@ Dalam bab kita telah melihat aturan untuk konversi numer
2. Konversi numerik terjadi ketika kita mengurangi objek atau menerapkan fungsi matematika. Misalnya, objek `Tanggal` (akan dibahas dalam bab ) dapat dikurangi, dan hasil dari `tanggal1 - tanggal2` adalah perbedaan waktu antara dua tanggal.
3. Untuk konversi string -- biasanya terjadi ketika kita mengeluarkan objek seperti `alert(obj)` dan dalam konteks yang serupa.
+<<<<<<< HEAD
Kita dapat menyempurnakan konversi string dan numerik, menggunakan metode objek khusus.
Ada tiga varian konversi tipe, yang terjadi dalam berbagai situasi.
@@ -35,6 +48,24 @@ Mereka disebut "petunjuk", seperti yang dijelaskan dalam [spesifikasi](https://t
`"tali"`
: Untuk konversi objek-ke-string, saat kita melakukan operasi pada objek yang mengharapkan string, seperti `alert`:
+=======
+1. There's no conversion to boolean. All objects are `true` in a boolean context, as simple as that. There exist only numeric and string conversions.
+2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter ) can be subtracted, and the result of `date1 - date2` is the time difference between two dates.
+3. As for the string conversion -- it usually happens when we output an object with `alert(obj)` and in similar contexts.
+
+We can implement string and numeric conversion by ourselves, using special object methods.
+
+Now let's get into technical details, because it's the only way to cover the topic in-depth.
+
+## Hints
+
+How does JavaScript decide which conversion to apply?
+
+There are three variants of type conversion, that happen in various situations. They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
+
+`"string"`
+: For an object-to-string conversion, when we're doing an operation on an object that expects a string, like `alert`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// keluaran
@@ -59,10 +90,16 @@ Mereka disebut "petunjuk", seperti yang dijelaskan dalam [spesifikasi](https://t
biarkan lebih besar = pengguna1 > pengguna2;
```
+ Most built-in mathematical functions also include such conversion.
+
`"default"`
: Terjadi dalam kasus yang jarang terjadi ketika operator "tidak yakin" jenis apa yang diharapkan.
+<<<<<<< HEAD
Misalnya, biner plus `+` dapat bekerja baik dengan string (menggabungkannya) dan angka (menambahkannya), jadi string dan angka bisa digunakan. Jadi jika biner plus mendapatkan objek sebagai argumen, ia menggunakan petunjuk `"default"` untuk mengonversinya.
+=======
+ For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them). So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Selain itu, jika suatu objek dibandingkan menggunakan `==` dengan string, angka, atau simbol, konversi mana yang harus dilakukan juga tidak jelas, sehingga petunjuk `"default"` digunakan.
@@ -76,6 +113,7 @@ Mereka disebut "petunjuk", seperti yang dijelaskan dalam [spesifikasi](https://t
Operator perbandingan yang lebih besar dan lebih kecil, seperti `<` `>`, dapat bekerja dengan string dan angka juga. Namun, mereka menggunakan petunjuk `"number"`, bukan `"default"`. Itu karena alasan historis.
+<<<<<<< HEAD
Namun dalam praktiknya, kita tidak perlu mengingat detail aneh ini, karena semua objek bawaan kecuali satu kasus (objek `Tanggal`, kita akan mempelajarinya nanti) mengimplementasikan konversi `"default"` dengan cara yang sama seperti ` "nomor"`. Dan kita bisa melakukan hal yang sama.
```smart header="Tidak ada petunjuk `\"boolean\"`"
@@ -83,19 +121,213 @@ Harap dicatat -- hanya ada tiga petunjuk. Sesederhana itu.
Tidak ada petunjuk "boolean" (semua objek `benar` dalam konteks boolean) atau yang lainnya. Dan jika kita memperlakukan `"default"` dan `"number"` sama, seperti kebanyakan built-in, maka hanya ada dua konversi.
```
+=======
+In practice though, things are a bit simpler.
+
+All built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we probably should do the same.
+
+Still, it's important to know about all 3 hints, soon we'll see why.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
**Untuk melakukan konversi, JavaScript mencoba menemukan dan memanggil tiga metode objek:**
+<<<<<<< HEAD
1. Panggil `obj[Symbol.toPrimitive](hint)` - metode dengan kunci simbolis `Symbol.toPrimitive` (simbol sistem), jika metode tersebut ada,
2. Sebaliknya jika petunjuknya adalah `"string"`
- coba `obj.toString()` dan `obj.valueOf()`, apa pun yang ada.
3. Jika petunjuknya adalah `"number"` atau `"default"`
- coba `obj.valueOf()` dan `obj.toString()`, apa pun yang ada.
+=======
+1. Call `obj[Symbol.toPrimitive](hint)` - the method with the symbolic key `Symbol.toPrimitive` (system symbol), if such method exists,
+2. Otherwise if hint is `"string"`
+ - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
+3. Otherwise if hint is `"number"` or `"default"`
+ - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Symbol.toPrimitive
Mari kita mulai dari cara pertama. Ada simbol bawaan bernama `Symbol.toPrimitive` yang harus digunakan untuk menamai metode konversi, seperti ini:
```js
+<<<<<<< HEAD
obj[Simbol.toPrimitif] = fungsi(petunjuk) {
- // dia
\ No newline at end of file
+ // dia
+=======
+obj[Symbol.toPrimitive] = function(hint) {
+ // here goes the code to convert this object to a primitive
+ // it must return a primitive value
+ // hint = one of "string", "number", "default"
+};
+```
+
+If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed.
+
+For instance, here `user` object implements it:
+
+```js run
+let user = {
+ name: "John",
+ money: 1000,
+
+ [Symbol.toPrimitive](hint) {
+ alert(`hint: ${hint}`);
+ return hint == "string" ? `{name: "${this.name}"}` : this.money;
+ }
+};
+
+// conversions demo:
+alert(user); // hint: string -> {name: "John"}
+alert(+user); // hint: number -> 1000
+alert(user + 500); // hint: default -> 1500
+```
+
+As we can see from the code, `user` becomes a self-descriptive string or a money amount, depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases.
+
+## toString/valueOf
+
+If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`:
+
+- For the `"string"` hint: call `toString` method, and if it doesn't exist or if it returns an object instead of a primitive value, then call `valueOf` (so `toString` has the priority for string conversions).
+- For other hints: call `valueOf`, and if it doesn't exist or if it returns an object instead of a primitive value, then call `toString` (so `valueOf` has the priority for maths).
+
+Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
+
+These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method).
+
+By default, a plain object has following `toString` and `valueOf` methods:
+
+- The `toString` method returns a string `"[object Object]"`.
+- The `valueOf` method returns the object itself.
+
+Here's the demo:
+
+```js run
+let user = {name: "John"};
+
+alert(user); // [object Object]
+alert(user.valueOf() === user); // true
+```
+
+So if we try to use an object as a string, like in an `alert` or so, then by default we see `[object Object]`.
+
+The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
+
+Let's implement these methods to customize the conversion.
+
+For instance, here `user` does the same as above using a combination of `toString` and `valueOf` instead of `Symbol.toPrimitive`:
+
+```js run
+let user = {
+ name: "John",
+ money: 1000,
+
+ // for hint="string"
+ toString() {
+ return `{name: "${this.name}"}`;
+ },
+
+ // for hint="number" or "default"
+ valueOf() {
+ return this.money;
+ }
+
+};
+
+alert(user); // toString -> {name: "John"}
+alert(+user); // valueOf -> 1000
+alert(user + 500); // valueOf -> 1500
+```
+
+As we can see, the behavior is the same as the previous example with `Symbol.toPrimitive`.
+
+Often we want a single "catch-all" place to handle all primitive conversions. In this case, we can implement `toString` only, like this:
+
+```js run
+let user = {
+ name: "John",
+
+ toString() {
+ return this.name;
+ }
+};
+
+alert(user); // toString -> John
+alert(user + 500); // toString -> John500
+```
+
+In the absence of `Symbol.toPrimitive` and `valueOf`, `toString` will handle all primitive conversions.
+
+### A conversion can return any primitive type
+
+The important thing to know about all primitive-conversion methods is that they do not necessarily return the "hinted" primitive.
+
+There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for the hint `"number"`.
+
+The only mandatory thing: these methods must return a primitive, not an object.
+
+```smart header="Historical notes"
+For historical reasons, if `toString` or `valueOf` returns an object, there's no error, but such value is ignored (like if the method didn't exist). That's because in ancient times there was no good "error" concept in JavaScript.
+
+In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, otherwise there will be an error.
+```
+
+## Further conversions
+
+As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers.
+
+If we pass an object as an argument, then there are two stages of calculations:
+1. The object is converted to a primitive (using the rules described above).
+2. If necessary for further calculations, the resulting primitive is also converted.
+
+For instance:
+
+```js run
+let obj = {
+ // toString handles all conversions in the absence of other methods
+ toString() {
+ return "2";
+ }
+};
+
+alert(obj * 2); // 4, object converted to primitive "2", then multiplication made it a number
+```
+
+1. The multiplication `obj * 2` first converts the object to primitive (that's a string `"2"`).
+2. Then `"2" * 2` becomes `2 * 2` (the string is converted to number).
+
+Binary plus will concatenate strings in the same situation, as it gladly accepts a string:
+
+```js run
+let obj = {
+ toString() {
+ return "2";
+ }
+};
+
+alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation
+```
+
+## Summary
+
+The object-to-primitive conversion is called automatically by many built-in functions and operators that expect a primitive as a value.
+
+There are 3 types (hints) of it:
+- `"string"` (for `alert` and other operations that need a string)
+- `"number"` (for maths)
+- `"default"` (few operators, usually objects implement it the same way as `"number"`)
+
+The specification describes explicitly which operator uses which hint.
+
+The conversion algorithm is:
+
+1. Call `obj[Symbol.toPrimitive](hint)` if the method exists,
+2. Otherwise if hint is `"string"`
+ - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
+3. Otherwise if hint is `"number"` or `"default"`
+ - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
+
+All these methods must return a primitive to work (if defined).
+
+In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
index 6292b0f55..00b6cdf91 100644
--- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
+++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
@@ -15,4 +15,8 @@ str.test = 5;
alert(str.test);
```
-Bagaimana menurutmu, akankah itu bekerja? apa yang akan muncul?
\ No newline at end of file
+<<<<<<< HEAD
+Bagaimana menurutmu, akankah itu bekerja? apa yang akan muncul?
+=======
+What do you think, will it work? What will be shown?
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md
index c20885756..57dd3c0fd 100644
--- a/1-js/05-data-types/01-primitives-methods/article.md
+++ b/1-js/05-data-types/01-primitives-methods/article.md
@@ -39,7 +39,11 @@ Objek lebih "berat" dari primitif. Dan mereka membutuhkan sumber daya tambahan u
Ini adalah paradoks yang dihadapi dari pencipta Javascript:
+<<<<<<< HEAD
- Terdapat banyak hal yang harus dilakukan dengan primitif seperti string atau angka. Akan menjadi lebih baik jika mereka bisa diakses sebagai method.
+=======
+- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Primitives must be as fast and lightweight as possible.
- Sebisa mungkin primitif haruslah cepat dan ringan.
@@ -49,7 +53,11 @@ Solusinya terlihat sedikit aneh, tapi inilah solusinya:
2. Bahasanya membolehkan untuk mengakses method dan properti dari string, number, boolean dan symbols.
3. Untuk membuat itu bekerja, "objek pembungkus" spesial yang menyediakan fungsionalitas tambahan dibuat, dan lalu dihancurkan.
+<<<<<<< HEAD
"Objek pembungkus" berbeda untuk setiap tipe primitif dan dipanggil: `String`, `Number`, `Boolean` dan `Symbol`. Lalu, mereka menyediakan metode-metode yang berbeda.
+=======
+The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh, ada methode string [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) yang mengembalikan string `str` yang telah diubah menjadi huruf kapital.
@@ -105,9 +113,16 @@ if (zero) { // zero adalah true, karena itu adalah sebuah objek
}
```
+<<<<<<< HEAD
Disisi lain, menggunakan fungsi yang sama `String/Number/Boolean` tanpa `new` adalah hal yang masuk akal dan hal yang berguna. Mereka mengubah nilai kedalam tipe yang sesuai: kedalam sebuah string, sebuah number, atau sebuah boolean(primitif).
Contoh, hal ini sepenuhnya valid:
+=======
+On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).
+
+For example, this is entirely valid:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let num = Number("123"); // mengubah string menjadi angka
```
diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
index 13e7cc2a7..425f5576b 100644
--- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
+++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
@@ -28,6 +28,6 @@ Perhatikan bahwa `63.5` tidak memiliki kehilangan presisi sama sekali. Itu karen
```js run
-alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
+alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
```
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 5abc8df8f..9b89cc104 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -2,9 +2,15 @@
Dalam JavaScript modern, ada dua tipe angka:
+<<<<<<< HEAD
1. Angka regular di JavaScript yang disimpan dalam format 64-bit [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), juga dikenal sebagai "angka double precision floating point". Inilah angka yang kita paling sering kita pakai, dan kita akan bahas tentang mereka di bab ini.
2. Angka BigInt, untuk mewakili integer dengan panjang sembarang. Mereka kadang dibutuhkan, karena angka regular tak bisa lebih dari 253
atau kurang dari -253
. Karena bigint dipakai di sedikit area spesial, kita khususkan mereka bab spesial .
+=======
+1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
+
+2. BigInt numbers represent integers of arbitrary length. They are sometimes needed because a regular integer number can't safely exceed (253-1)
or be less than -(253-1)
, as we mentioned earlier in the chapter . As bigints are used in a few special areas, we devote them to a special chapter .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi di sini kita akan bahas angka regular. Ayo perluas pengetahuan kita tentang mereka.
@@ -22,7 +28,11 @@ Kita juga bisa menggunakan `_` sebagai pemisahnya:
let billion = 1_000_000_000;
```
+<<<<<<< HEAD
Di sini, garis bawah `_` memainkan peran sebagai "syntactic sugar", ini membuat angka lebih mudah dibaca. Mesin JavaScript mengabaikan `_` di antara digit, jadi nilainya sama persis dengan satu miliar di atas.
+=======
+Here the underscore `_` plays the role of the "[syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tapi di kehidupan nyata, kita biasanya menghindari menulis string nol yang panjang karena rentan terjadi kesalahan. Selain itu, kita malas. Kita biasanya akan menulis sesuatu seperti `"1bn"` untuk milyar atau `"7.3bn"` untuk 7 milyar 300 juta. Sama halnya dengan angka besar lainnya.
@@ -37,16 +47,21 @@ alert( 7.3e9 ); // 7.3 milyar (7,300,000,000)
Dengan kata lain, `"e"` kalikan angkanya dengan `1` dengan jumlah nol yang diberikan.
```js
-1e3 = 1 * 1000 // e3 means *1000
-1.23e6 = 1.23 * 1000000 // e6 means *1000000
+1e3 === 1 * 1000; // e3 means *1000
+1.23e6 === 1.23 * 1000000; // e6 means *1000000
```
+<<<<<<< HEAD
Sekarang ayo tulis sesuatu lebih kecil. Katakan, 1 microsecond (sepersejuta second):
+=======
+Now let's write something very small. Say, 1 microsecond (one-millionth of a second):
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
-let ms = 0.000001;
+let mсs = 0.000001;
```
+<<<<<<< HEAD
Sama seperti sebelumnya, memakai `"e"` bisa membantu. Jika kita ingin menghindari menulis nol eksplisit, kita bisa katakan hal yang sama:
```js
@@ -54,15 +69,35 @@ let ms = 1e-6; // enam nol di sebelah kiri dari 1
```
Jika kita hitung nol di `0.000001`, ada 6 dari mereka. Jadi alaminya `1e-6`.
+=======
+Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could write the same as:
+
+```js
+let mcs = 1e-6; // five zeroes to the left from 1
+```
+
+If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Dengan kata lain, angka negatif setelah `"e"` artinya pembagian 1 dengan jumlah nol yang diberikan:
```js
+<<<<<<< HEAD
// -3 membagi 1 dengan 3 nol
1e-3 = 1 / 1000 (=0.001)
// -6 membagi 1 dengan 6 nol
1.23e-6 = 1.23 / 1000000 (=0.00000123)
+=======
+// -3 divides by 1 with 3 zeroes
+1e-3 === 1 / 1000; // 0.001
+
+// -6 divides by 1 with 6 zeroes
+1.23e-6 === 1.23 / 1000000; // 0.00000123
+
+// an example with a bigger number
+1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
### Hex, angka binary dan octal
@@ -100,13 +135,23 @@ alert( num.toString(16) ); // ff
alert( num.toString(2) ); // 11111111
```
+<<<<<<< HEAD
`base` bisa bervariasi dari `2` hingga `36`. Defaultnya `10`.
+=======
+The `base` can vary from `2` to `36`. By default, it's `10`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Penggunaan umumnya ialah:
+<<<<<<< HEAD
- **base=16** dipakai untuk warna hex, character encoding dll, digit bisa `0..9` atau `A..F`.
- **base=2** paling banyak untuk mendebug operasi bitwise, digit bisa `0` atau `1`.
- **base=36** ini maximum, digit bisa `0..9` atau `A..Z`. Seluruh alfabet latin dipakai untuk merepresentasi angka. Hal lucu, tapi berguna untuk `36` ialah saat kita harus mengubah identifier numerik panjang ke dalam sesuatu yang lebih pendek, misalnya untuk membuat url pendek. Bisa direpresentasikan dalam sistem `36`:
+=======
+- **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`.
+- **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`.
+- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole Latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example, to make a short url. Can simply represent it in the numeral system with base `36`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
alert( 123456..toString(36) ); // 2n9c
@@ -115,9 +160,16 @@ Penggunaan umumnya ialah:
```warn header="Dua dot untuk memanggil metode"
Tolong ingat bahwa dua dot di `123456..toString(36)` bukan typo. Jika kita mau memanggil langsung metode pada angka, seperti `toString` di contoh di atas, maka kita harus menaruh dua dot `..` setelahnya.
+<<<<<<< HEAD
Jika kita menaruh dot tunggal: `123456.toString(36)`, maka akan ada galat, karena syntax JavaScript berimplikasi bahwa bagian desimal setelah dot pertama. Dan jika kita menaruh satu dot lagi, maka JavaScript tahu bahwa bagian desimal kosong dan sekarang pergi ke metode.
Juga bisa menulis `(123456).toString(36)`.
+=======
+If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now uses the method.
+
+Also could write `(123456).toString(36)`.
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Pembulatan
@@ -133,7 +185,11 @@ Ada beberapa fungsi built-in untuk pembulatan:
: Membulat ke atas: `3.1` menjadi `4`, dan `-1.1` menjadi `-1`.
`Math.round`
+<<<<<<< HEAD
: Membulatkan ke bilangan bulat terdekat: `3.1` menjadi` 3`, `3.6` menjadi` 4`, huruf tengah: `3.5` juga dibulatkan ke atas menjadi` 4`.
+=======
+: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`. In the middle cases `3.5` rounds up to `4`, and `-3.5` rounds up to `-3`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
`Math.trunc` (tidak didukung oleh Internet Explorer)
: Menghapus apa pun setelah koma desimal tanpa pembulatan: `3.1` menjadi` 3`, `-1.1` menjadi` -1`.
@@ -143,8 +199,10 @@ Ini tabel untuk meringkas perbedaan di antara mereka:
| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
|---|---------|--------|---------|---------|
|`3.1`| `3` | `4` | `3` | `3` |
+|`3.5`| `3` | `4` | `4` | `3` |
|`3.6`| `3` | `4` | `4` | `3` |
|`-1.1`| `-2` | `-1` | `-1` | `-1` |
+|`-1.5`| `-2` | `-1` | `-1` | `-1` |
|`-1.6`| `-2` | `-1` | `-2` | `-1` |
@@ -156,7 +214,11 @@ Ada dua cara melakukannya:
1. Kali-dan-bagi.
+<<<<<<< HEAD
Misalnya, untuk membulatkan angka ke digit kedua setelah desimal, kita bisa mengalikan angkanya dengan `100` (atau sebuah pangkat dari 10), panggil fungsi pembulatan lalu membagi itu kembali.
+=======
+ For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100`, call the rounding function and then divide it back.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let num = 1.23456;
@@ -177,20 +239,34 @@ Ada dua cara melakukannya:
alert( num.toFixed(1) ); // "12.4"
```
+<<<<<<< HEAD
Silakan catat hasil dari `toFixed` ialah string. Jika bagian desimal lebih pendek dari yang dibutuhkan, nol ditambahkan di akhir:
+=======
+ Please note that the result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let num = 12.34;
alert( num.toFixed(5) ); // "12.34000", tambah nol supaya tepat 5 digit
```
+<<<<<<< HEAD
Kita bisa mengkonversi itu ke angka menggunakan unary plus atau panggilan `Number()`: `+num.toFixed(5)`.
+=======
+ We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Kalkulasi yang tidak tepat
+<<<<<<< HEAD
Secara internal, angka direpresentasikan dalam format 64-bit [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), jadi ada tepat 64 bit untuk menyimpan angka: 52 di antaranya digunakan untuk menyimpan angka, 11 di antaranya menyimpan posisi titik desimal (nol untuk angka bilangan bulat), dan 1 bit untuk tanda.
Jika angka terlalu besar, itu akan meluapkan penyimpanan 64-bit, berpotensi memberikan infinity:
+=======
+Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point, and 1 bit is for the sign.
+
+If a number is really huge, it may overflow the 64-bit storage and become a special numeric value `Infinity`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
alert( 1e500 ); // Infinity
@@ -198,7 +274,11 @@ alert( 1e500 ); // Infinity
Yang mungkin agak kurang jelas, tetapi sering terjadi adalah hilangnya ketepatan.
+<<<<<<< HEAD
Pertimbangkan (falsy!) tes ini:
+=======
+Consider this (falsy!) equality test:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
@@ -212,13 +292,27 @@ Aneh! Kenapa hasilnya itu dan tidak `0.3`?
alert( 0.1 + 0.2 ); // 0.30000000000000004
```
+<<<<<<< HEAD
Aduh! Ada lebih banyak konsekuensi daripada perbandingan yang salah di sini. Bayangkan Anda membuat situs e-shopping dan pengunjung memasukkan barang-barang `$ 0,10` dan` $ 0,20` ke troli mereka. Total pesanan akan `$ 0,30000000000000004`. Itu akan mengejutkan siapa pun.
+=======
+Ouch! Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tetapi kenapa hal ini bisa terjadi?
Sebuah angka disimpan di memori dalam bentuk binary, sebuah urutan dari bits - satu dan nol. Tetapi bilangan pecahan seperti `0.1`, `0.2` yang terlihat sederhana dalam sistem angka desimal sebenarnya adalah pecahan tak berujung dalam bentuk binernya.
+<<<<<<< HEAD
Dengan kata lain, apa itu `0,1`? Ini adalah satu dibagi dengan sepuluh `1 / 10`, sepersepuluh. Dalam sistem angka desimal, angka-angka seperti itu mudah diwakili. Bandingkan dengan sepertiga: `1 / 3`. Ini menjadi pecahan yang tak berujung `0,33333 (3)`.
+=======
+```js run
+alert(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101
+alert(0.2.toString(2)); // 0.001100110011001100110011001100110011001100110011001101
+alert((0.1 + 0.2).toString(2)); // 0.0100110011001100110011001100110011001100110011001101
+```
+
+What is `0.1`? It is one divided by ten `1/10`, one-tenth. In the decimal numeral system, such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi, pembagian dengan kekuatan `10` dijamin bekerja dengan baik dalam sistem desimal, tetapi pembagian dengan `3` tidak. Untuk alasan yang sama, dalam sistem angka biner, pembagian dengan kekuatan `2` dijamin bekerja, tetapi `1 / 10` menjadi fraksi biner tanpa akhir.
@@ -238,14 +332,18 @@ Itu sebabnya `0,1 + 0,2` tidak sepenuhnya` 0,3`.
```smart header="Tidak hanya JavaScript"
Masalah yang sama ada di banyak bahasa pemrograman lainnya.
+<<<<<<< HEAD
PHP, Java, C, Perl, Ruby memberikan hasil yang sama persis, karena mereka didasarkan pada format numerik yang sama.
+=======
+PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Bisakah kita mengatasi masalah ini? Tentu, metode yang paling dapat diandalkan adalah melengkapi hasilnya dengan bantuan metode [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
```js run
let sum = 0.1 + 0.2;
-alert( sum.toFixed(2) ); // 0.30
+alert( sum.toFixed(2) ); // "0.30"
```
Harap dicatat bahwa `toFixed` selalu mengembalikan string. Ini memastikan bahwa ia memiliki 2 digit setelah titik desimal. Itu sebenarnya nyaman jika kita memiliki e-shopping dan perlu menunjukkan `$ 0,30`. Untuk kasus lain, kita dapat menggunakan plus unary untuk memaksanya menjadi nomor:
@@ -262,7 +360,11 @@ alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
```
+<<<<<<< HEAD
Jadi, pendekatan perkalian/pembagian mengurangi kesalahan, tetapi tidak menghapusnya sama sekali.
+=======
+So, the multiply/divide approach reduces the error, but doesn't remove it totally.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Terkadang kita bisa mencoba menghindari pecahan sama sekali. Seperti jika kita berurusan dengan toko, maka kita dapat menyimpan harga dalam sen, bukan dalam dolar. Tetapi bagaimana jika kita menerapkan diskon 30%? Dalam praktiknya, menghindari pecahan sama sekali jarang dimungkinkan. Hanya bulatkan mereka untuk memotong "ekor" bila diperlukan.
@@ -284,7 +386,11 @@ Konsekuensi lucu yang lain dari representasi internal dari angka adalah adanya d
Itu karena sebuah tanda diwakili oleh satu bit, sehingga dapat diatur atau tidak diatur untuk angka apa pun termasuk nol.
+<<<<<<< HEAD
Dalam kebanyakan kasus perbedaannya tidak terlalu mencolok, karena operator cocok untuk memperlakukan mereka sebagai sesuatu yang sama.
+=======
+In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Tests: isFinite dan isNaN
@@ -304,7 +410,11 @@ Mereka termasuk dalam tipe `angka`, tetapi bukan angka "normal", jadi ada fungsi
alert( isNaN("str") ); // true
```
+<<<<<<< HEAD
Tetapi apakah kita membutuhkan fungsi ini? Tidak bisakah kita menggunakan perbandingan `=== NaN`? Maaf, tapi jawabannya adalah tidak. Nilai `NaN` unik karena tidak sama dengan apa pun, termasuk dirinya sendiri:
+=======
+ But do we need this function? Can't we just use the comparison `=== NaN`? Unfortunately not. The value `NaN` is unique in that it does not equal anything, including itself:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
alert( NaN === NaN ); // false
@@ -328,6 +438,7 @@ let num = +prompt("Enter a number", '');
alert( isFinite(num) );
```
+<<<<<<< HEAD
Harap dicatat bahwa string kosong atau spasi-saja diperlakukan sebagai `0` dalam semua fungsi numerik termasuk` isFinite`.
```smart header="Dibandingkan dengan `Object.is`"
@@ -336,10 +447,52 @@ Ada metode bawaan khusus [Object.is](mdn:js/Object/is) yang membandingkan nilai
1. Ini bekerja dengan `NaN`: `Object.is(NaN, NaN) === true`, itu hal yang bagus.
2. Nilai `0` and `-0` adalah berbeda: `Object.is(0, -0) === false`, secara teknis adalah benar, karena secara internal nomor tersebut memiliki bit tanda yang mungkin berbeda bahkan jika semua bit lainnya nol.
+=======
+Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
+
+````smart header="`Number.isNaN` and `Number.isFinite`"
+[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) and [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) methods are the more "strict" versions of `isNaN` and `isFinite` functions. They do not autoconvert their argument into a number, but check if it belongs to the `number` type instead.
+
+- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`.
+
+ ```js run
+ alert( Number.isNaN(NaN) ); // true
+ alert( Number.isNaN("str" / 2) ); // true
+
+ // Note the difference:
+ alert( Number.isNaN("str") ); // false, because "str" belongs to the string type, not the number type
+ alert( isNaN("str") ); // true, because isNaN converts string "str" into a number and gets NaN as a result of this conversion
+ ```
+
+- `Number.isFinite(value)` returns `true` if the argument belongs to the `number` type and it is not `NaN/Infinity/-Infinity`. In any other case, it returns `false`.
+
+ ```js run
+ alert( Number.isFinite(123) ); // true
+ alert( Number.isFinite(Infinity) ); // false
+ alert( Number.isFinite(2 / 0) ); // false
+
+ // Note the difference:
+ alert( Number.isFinite("123") ); // false, because "123" belongs to the string type, not the number type
+ alert( isFinite("123") ); // true, because isFinite converts string "123" into a number 123
+ ```
+
+In a way, `Number.isNaN` and `Number.isFinite` are simpler and more straightforward than `isNaN` and `isFinite` functions. In practice though, `isNaN` and `isFinite` are mostly used, as they're shorter to write.
+````
+
+```smart header="Comparison with `Object.is`"
+There is a special built-in method `Object.is` that compares values like `===`, but is more reliable for two edge cases:
+
+1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
+2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's correct because internally the number has a sign bit that may be different even if all other bits are zeroes.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Pada kasus lain, `Object.is(a, b)` adalah sama dengan `a === b`.
+<<<<<<< HEAD
Cara perbandingan ini sering digunakan dalam spesifikasi JavaScript. Ketika suatu algoritma internal perlu membandingkan dua nilai untuk menjadi persis sama, ia menggunakan `Object.is` (secara internal disebut [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
+=======
+We mention `Object.is` here, because it's often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
@@ -353,7 +506,11 @@ alert( +"100px" ); // NaN
Satu-satunya pengecualian adalah spasi di awal atau di akhir string, karena diabaikan.
+<<<<<<< HEAD
Tetapi dalam kehidupan nyata kita sering memiliki nilai dalam satuan, seperti `"100px"` atau `"12pt"` dalam CSS. Juga di banyak negara simbol mata uang mengikuti jumlah, jadi kita memiliki `"€19"` dan ingin mengekstraksi nilai numerik dari itu.
+=======
+But in real life, we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries, the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Untuk itulah `parseInt` dan` parseFloat` ada.
@@ -399,8 +556,13 @@ Beberapa contoh:
alert( Math.random() ); // ... (angka aca apa saja)
```
+<<<<<<< HEAD
`Math.max(a, b, c...)` / `Math.min(a, b, c...)`
: Mengembalikan argumen terbesar / terkecil dari jumlah argumen yang arbitrer.
+=======
+`Math.max(a, b, c...)` and `Math.min(a, b, c...)`
+: Returns the greatest and smallest from the arbitrary number of arguments.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
alert( Math.max(3, 5, -10, 0, 1) ); // 5
@@ -429,7 +591,18 @@ Untuk sistem angka yang berbeda:
- `parseInt(str, base)` mem-parsing string `str` menjadi bilangan bulat dalam sistem angka dengan diberikan `base`, `2 ≤ base ≤ 36`.
- `num.toString(base)` mengonversi angka menjadi string dalam sistem angka dengan diberikan `base`.
+<<<<<<< HEAD
Untuk mengkonversi nilai seperti `12pt` dan `100px` menjadi sebuah angka:
+=======
+For regular number tests:
+
+- `isNaN(value)` converts its argument to a number and then tests it for being `NaN`
+- `Number.isNaN(value)` checks whether its argument belongs to the `number` type, and if so, tests it for being `NaN`
+- `isFinite(value)` converts its argument to a number and then tests it for not being `NaN/Infinity/-Infinity`
+- `Number.isFinite(value)` checks whether its argument belongs to the `number` type, and if so, tests it for not being `NaN/Infinity/-Infinity`
+
+For converting values like `12pt` and `100px` to a number:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Gunakan `parseInt/parseFloat` untuk konversi "lembut", dimana membaca sebuah angka dari string dan mengembalikan nilai yang bisa dibaca sebelum terjadi kesalahan.
@@ -440,4 +613,8 @@ Untuk pecahan:
Lebih banyak fungsi matematika:
+<<<<<<< HEAD
- Lihat objek [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) ketika Anda membutuhkannya. Perpustakaannya sangat kecil, tetapi dapat memenuhi kebutuhan dasar.
+=======
+- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small but can cover basic needs.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/03-string/1-ucfirst/solution.md b/1-js/05-data-types/03-string/1-ucfirst/solution.md
index 15f7bb241..3a51a936d 100644
--- a/1-js/05-data-types/03-string/1-ucfirst/solution.md
+++ b/1-js/05-data-types/03-string/1-ucfirst/solution.md
@@ -8,12 +8,16 @@ let newStr = str[0].toUpperCase() + str.slice(1);
Tetapi ada sedikit masalah. Jika `str` bernilai kosong, maka `str[0]` bernilai `undefined`, dan `undefined` tidak memiliki method `toUpperCase()`. Hal tersebut yang menyebabkan error.
+<<<<<<< HEAD
Ada dua cara di sini:
1. Gunakan `str.charAt(0)`, karena method ini selalu mengembalikan string (mungkin kosong).
2. Tambahkan pengecekan string kosong.
Berikut adalah cara yang kedua:
+=======
+The easiest way out is to add a test for an empty string, like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run demo
function ucFirst(str) {
diff --git a/1-js/05-data-types/03-string/3-truncate/task.md b/1-js/05-data-types/03-string/3-truncate/task.md
index ee6262ab3..56d2eeb17 100644
--- a/1-js/05-data-types/03-string/3-truncate/task.md
+++ b/1-js/05-data-types/03-string/3-truncate/task.md
@@ -11,7 +11,7 @@ Hasil kembalian dari fungsi seharusnya string yang dipotong (jika diperlukan).
Sebagai contoh:
```js
-truncate("What I'd like to tell on this topic is:", 20) = "What I'd like to te…"
+truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to te…"
-truncate("Hi everyone!", 20) = "Hi everyone!"
+truncate("Hi everyone!", 20) == "Hi everyone!"
```
diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md
index a385c03ad..39a1acbc4 100644
--- a/1-js/05-data-types/03-string/article.md
+++ b/1-js/05-data-types/03-string/article.md
@@ -48,9 +48,15 @@ let guestList = "Guests: // Error: Unexpected token ILLEGAL
* John";
```
+<<<<<<< HEAD
Petik satu dan petik dua berasal dari masa lalu saat bahasa pemrograman dibuat, dimana kebutuhan untuk string lebih dari satu baris belum dipikirkan. Backtick muncul di kemudian hari, dan lebih fleksibel.
Backtick juga memperbolehkan kita untuk menspesifikasi "fungsi template" sebelum backtick pertama. Syntaxnya yaitu: func`string`
. Fungsi `func` dipanggil secara otomatis, menerima string dan ekspresi yang berada di dalamnya dan bisa memproses mereka. Ini disebut "tagged templates". Fitur ini membuat implementasi kustom templating lebih mudah, tapi jaran dipakai dalam praktik. Kamu bisa membaca lebih tentang ini di [manual](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+=======
+Single and double quotes come from ancient times of language creation, when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile.
+
+Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`
. The function `func` is called automatically, receives the string and embedded expressions and can process them. This feature is called "tagged templates", it's rarely seen, but you can read about it in the MDN: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Karakter spesial
@@ -59,10 +65,17 @@ Masih mungkin untuk membuat string dengan banyak baris menggunakan petik satu at
```js run
let guestList = "Guests:\n * John\n * Pete\n * Mary";
+<<<<<<< HEAD
alert(guestList); // list tamu yang dipisahkan per baris
```
Sebagai contoh, kedua baris berikut sama saja, hanya ditulis dengan cara yang berbeda:
+=======
+alert(guestList); // a multiline list of guests, same as above
+```
+
+As a simpler example, these two lines are equal, just written differently:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let str1 = "Hello\nWorld"; // dua baris menggunakan "simbol baris baru"
@@ -74,6 +87,7 @@ World`;
alert(str1 == str2); // true
```
+<<<<<<< HEAD
Ada karakter spesial lain, tetapi mereka jarang digunakan
Berikut adalah daftar lengkapnya:
@@ -101,6 +115,28 @@ alert( "\u{1F60D}" ); // 😍, sebuah simbol wajah tersenyum (unicode panjang la
Karakter-karakter spesial yang diawali dengan karakter backslash `\` kadang dipanggil dengan sebutan "escape character".
Kita kadang dapat menggunakannya apabila kita ingin menggunakan petik di dalam string.
+=======
+There are other, less common special characters:
+
+| Character | Description |
+|-----------|-------------|
+|`\n`|New line|
+|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. |
+|`\'`, `\"`, \\`
|Quotes|
+|`\\`|Backslash|
+|`\t`|Tab|
+|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- mentioned for completeness, coming from old times, not used nowadays (you can forget them right now). |
+
+As you can see, all special characters start with a backslash character `\`. It is also called an "escape character".
+
+Because it's so special, if we need to show an actual backslash `\` within the string, we need to double it:
+
+```js run
+alert( `The backslash: \\` ); // The backslash: \
+```
+
+So-called "escaped" quotes `\'`, `\"`, \\`
are used to insert a quote into the same-quoted string.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya:
@@ -113,9 +149,10 @@ Seperti yang kita lihat, kita harus menambahkan backslash di depan petik yang di
Tentu saja, hanya jenis petik yang sama dengan penutup string yang perlu di "escape". Jadi, solusi yang lebih elegan yaitu mengganti petik satu menjadi petik dua atau backtick:
```js run
-alert( `I'm the Walrus!` ); // I'm the Walrus!
+alert( "I'm the Walrus!" ); // I'm the Walrus!
```
+<<<<<<< HEAD
Ingat bahwa backslash `\` hanya dipakai untuk Javascript agar dapat membaca string dengan benar. Di dalam memori, string tidak memiliki `\`. Anda dapat melihatnya secara langsung pada contoh `alert` di atas.
Tetapi bagaimana jika kita ingin menampilkan backslash `\` di dalam sebuah string?
@@ -125,6 +162,9 @@ Hal tersebut bisa dilakukan, tetapi kita harus menulisnya dua kali seperti ini `
```js run
alert( `The backslash: \\` ); // The backslash: \
```
+=======
+Besides these special characters, there's also a special notation for Unicode codes `\u…`, it's rarely used and is covered in the optional chapter about [Unicode](info:unicode).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Panjang string
@@ -139,33 +179,55 @@ Perlu diingat bahwa `\n` adalah sebuah karakter spesial, jadi panjang dari strin
```warn header="`length` adalah sebuah properti"
Orang dengan latar belakang di bahasa pemrograman lain kadang salah mengetik `str.length()` alih-alih `str.length`. Hal tersebut tidak bekerja.
+<<<<<<< HEAD
Perlu diingat bahwa `str.length` adalah properti numerik, bukan sebuah fungsi. Tidak perlu menambahkan kurung di belakangnya.
+=======
+Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it. Not `.length()`, but `.length`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Mengakses karakter di dalam string
+<<<<<<< HEAD
Untuk mengakses karakter pada posisi `pos`, digunakan kurung kotak `[pos]` atau dengan method [str.charAt(pos)](mdn:js/String/charAt). Karakter pertama dimulai dari posisi ke-0:
+=======
+To get a character at position `pos`, use square brackets `[pos]` or call the method [str.at(pos)](mdn:js/String/at). The first character starts from the zero position:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let str = `Hello`;
// karakter pertama
alert( str[0] ); // H
-alert( str.charAt(0) ); // H
+alert( str.at(0) ); // H
// karakter terakhir
alert( str[str.length - 1] ); // o
+alert( str.at(-1) );
```
+<<<<<<< HEAD
Kurung kotak adalah cara modern untuk mengakses sebuah karakter, sementara `charAt` ada karena alasan historis.
Perbedaan satu-satunya di antara mereka adalah apabila tidak ada karakter yang ditemukan, `[]` mengembalikan `undefined`, dan `charAt` mengembalikan string kosong:
+=======
+As you can see, the `.at(pos)` method has a benefit of allowing negative position. If `pos` is negative, then it's counted from the end of the string.
+
+So `.at(-1)` means the last character, and `.at(-2)` is the one before it, etc.
+
+The square brackets always return `undefined` for negative indexes, for instance:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let str = `Hello`;
+<<<<<<< HEAD
alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (string kosong)
+=======
+alert( str[-2] ); // undefined
+alert( str.at(-2) ); // l
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Kita juga bisa mengakses karakter per karakter menggunakan sintaks `for..of`:
@@ -214,7 +276,7 @@ alert( 'Interface'.toLowerCase() ); // interface
Atau, apabila kita hanya ingin sebuah karakter yang diubah menjadi huruf kecil:
-```js
+```js run
alert( 'Interface'[0].toLowerCase() ); // 'i'
```
@@ -310,6 +372,7 @@ if (str.indexOf("Widget") != -1) {
}
```
+<<<<<<< HEAD
#### Trik bitwise NOT
Salah satu trik lama yang digunakan disini adalah operator [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) `~`. Operator ini mengubah angka menjadi integer 32-bit (menghilangkan bagian desimal jika ada) lalu menegasikan semua bit pada representasi binernya.
@@ -349,6 +412,8 @@ Untuk lebih detail, karena bilangan yang besar dipotong menjadi 32-bit oleh oper
Kita dapat melihat bahwa trik ini hanya digunakan di kode yang kuno, karena Javascript modern menyediakan method `.includes` (lihat di bawah).
+=======
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
### includes, startsWith, endsWith
Method yang lebih modern [str.includes(substr, pos)](mdn:js/String/includes) mengembalikan `true/false` tergantung dengan apakah `str` mengandung `substr` di dalamnya.
@@ -371,8 +436,13 @@ alert( "Widget".includes("id", 3) ); // false, dari posisi 3 tidak ditemukan "id
Method [str.startsWith](mdn:js/String/startsWith) dan [str.endsWith](mdn:js/String/endsWith) melakukan fungsi seperti namanya:
```js run
+<<<<<<< HEAD
alert( "Widget".startsWith("Wid") ); // true, "Widget" diawali oleh "Wid"
alert( "Widget".endsWith("get") ); // true, "Widget" diakhiri oleh "get"
+=======
+alert( "*!*Wid*/!*get".startsWith("Wid") ); // true, "Widget" starts with "Wid"
+alert( "Wid*!*get*/!*".endsWith("get") ); // true, "Widget" ends with "get"
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Mengambil substring
@@ -407,9 +477,15 @@ Ada 3 cara untuk mengambil sebuah substring di Javascript: `substring`, `substr`
```
`str.substring(start [, end])`
+<<<<<<< HEAD
: Mengembalikan bagian dari string *di antara* `start` dan `end`.
Method ini hampir sama dengan `slice`, tetapi nilai `start` boleh lebih besar daripada `end`.
+=======
+: Returns the part of the string *between* `start` and `end` (not including `end`).
+
+ This is almost the same as `slice`, but it allows `start` to be greater than `end` (in this case it simply swaps `start` and `end` values).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh:
@@ -445,18 +521,36 @@ Ada 3 cara untuk mengambil sebuah substring di Javascript: `substring`, `substr`
alert( str.substr(-4, 2) ); // gi, dari posisi ke-4 ambil 2 karakter
```
+<<<<<<< HEAD
Mari kita review cara-cara tersebut untuk menghindari kebingungan:
+=======
+ This method resides in the [Annex B](https://tc39.es/ecma262/#sec-string.prototype.substr) of the language specification. It means that only browser-hosted Javascript engines should support it, and it's not recommended to use it. In practice, it's supported everywhere.
+
+Let's recap these methods to avoid any confusion:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
| method | mengambil... | negatives |
|--------|-----------|-----------|
+<<<<<<< HEAD
| `slice(start, end)` | dari `start` sampai `end` (tidak termasuk `end`) | nilai negatif diperbolehkan |
| `substring(start, end)` | antara `start` dan `end` | nilai negatif berarti mean `0` |
| `substr(start, length)` | dari `start` ambil `length` karakter | `start` negatif diperbolehkan |
+=======
+| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives |
+| `substring(start, end)` | between `start` and `end` (not including `end`)| negative values mean `0` |
+| `substr(start, length)` | from `start` get `length` characters | allows negative `start` |
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Cara mana yang harus kita gunakan?"
Semuanya dapat melakukan pekerjaannya. Secara formal, `substr` memiliki kekurangan: fungsi ini tidak tercantum di spesifikasi inti Javascript, tetapi di Annex B, yang mencakup hanya fitur browser yang ada karena alasan historis. Jadi, environment non-browser mungkin gagal untuk mendukungnya. Tetapi dalam praktik fungsi ini bekerja di mana saja.
+<<<<<<< HEAD
Dibandingkan dengan dua varian yang lain, `slice` lebih fleksibel, karena memperbolehkan parameter negatif dan lebih pendek untuk ditulis. Jadi, dari ketiga cara sudah cukup untuk mengingat `slice`.
+=======
+Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write.
+
+So, for practical use it's enough to remember only `slice`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Membandingkan string
@@ -479,6 +573,7 @@ Akan tetapi, ada beberapa pengecualian.
Hal ini dapat menyebabkan hasil yang aneh apabila kita mengurutkan nama-nama negara. Biasanya orang mengharapkan `Zealand` muncul setelah `Österreich` di daftar.
+<<<<<<< HEAD
Untuk memahami apa yang terjadi, mari kita review representasi internal string di Javascript.
Semua string menggunakan encoding [UTF-16](https://en.wikipedia.org/wiki/UTF-16). Yaitu: setiap karakter memiliki masing-masing kode numerik. Ada method spesial yang memperbolehkan kita untuk mengambil karakter dari kode dan sebaliknya.
@@ -489,7 +584,20 @@ Semua string menggunakan encoding [UTF-16](https://en.wikipedia.org/wiki/UTF-16)
```js run
// karakter dengan case yang berbeda memiliki kode berbeda
alert( "z".codePointAt(0) ); // 122
+=======
+To understand what happens, we should be aware that strings in Javascript are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). That is: each character has a corresponding numeric code.
+
+There are special methods that allow to get the character for the code and back:
+
+`str.codePointAt(pos)`
+: Returns a decimal number representing the code for the character at position `pos`:
+
+ ```js run
+ // different case letters have different codes
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
alert( "Z".codePointAt(0) ); // 90
+ alert( "z".codePointAt(0) ); // 122
+ alert( "z".codePointAt(0).toString(16) ); // 7a (if we need a hexadecimal value)
```
`String.fromCodePoint(code)`
@@ -497,6 +605,7 @@ Semua string menggunakan encoding [UTF-16](https://en.wikipedia.org/wiki/UTF-16)
```js run
alert( String.fromCodePoint(90) ); // Z
+<<<<<<< HEAD
```
Kita juga dapat membuat karakter unicode dengan kode mereka menggunakan `\u` yang diikuti oleh kode heksadesimal:
@@ -504,6 +613,9 @@ Semua string menggunakan encoding [UTF-16](https://en.wikipedia.org/wiki/UTF-16)
```js run
// 90 bernilai 5a di dalam sistem heksadesimal
alert( '\u005a' ); // Z
+=======
+ alert( String.fromCodePoint(0x5a) ); // Z (we can also use a hex value as an argument)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Sekarang mari kita lihat karakter dengan kode di antara `65..220` (alfabet latin dan sedikit tambahan) dengan membuat string yang terdiri dari mereka:
@@ -515,6 +627,7 @@ for (let i = 65; i <= 220; i++) {
str += String.fromCodePoint(i);
}
alert( str );
+// Output:
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
// ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜ
```
@@ -534,7 +647,11 @@ Algoritma yang "benar" untuk melakukan perbandingan string lebih kompleks dari k
Jadi, browser harus tahu bahasa yang digunakan untuk perbandingan.
+<<<<<<< HEAD
Beruntungnya, semua browser modern (IE10- memerlukan library tambahan [Intl.JS](https://github.com/andyearnshaw/Intl.js/)) mendukung standar internasionalisasi [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf).
+=======
+Luckily, modern browsers support the internationalization standard [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Hal tersebut menyediakan cara spesial untuk membandingkan stringi di berbeda bahasa, mengikuti peraturan mereka.
@@ -552,6 +669,7 @@ alert( 'Österreich'.localeCompare('Zealand') ); // -1
Method ini sebenarnya menerima 2 argumen tambahan yang disebutkan di [dokumentasi](mdn:js/String/localeCompare), yang memperbolehkan untuk menyebutkan bahasa (yang biasanya diambil dari environment, urutan huruf bergantung dari bahasa) dan menyebutkan peraturan-peraturan tambahan seperti case sensitivity atau apakah `"a"` and `"á"` dianggap sama dan seterusnya.
+<<<<<<< HEAD
## Bagian internal dari unicode
```warn header="Pengetahuan lanjutan"
@@ -669,6 +787,17 @@ Jika Anda ingin belajar lebih lanjut tentang aturan normalisasi dan variasinya -
- Untuk mengubah case kecil/besar dari string, gunakan: `toLowerCase/toUpperCase`.
- Untuk mencari substring, gunakan: `indexOf`, atau `includes/startsWith/endsWith` untuk pengecekan sederhana.
- Untuk membandingkan string mengikuti bahasa, gunakan `localeCompare`, jika tidak mereka akan dibandingkan berdasarkan kode karakter.
+=======
+## Summary
+
+- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${…}`.
+- We can use special characters, such as a line break `\n`.
+- To get a character, use: `[]` or `at` method.
+- To get a substring, use: `slice` or `substring`.
+- To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`.
+- To look for a substring, use: `indexOf`, or `includes/startsWith/endsWith` for simple checks.
+- To compare strings according to the language, use: `localeCompare`, otherwise they are compared by character codes.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ada beberapa metode string lain yang berguna:
@@ -676,4 +805,10 @@ Ada beberapa metode string lain yang berguna:
- `str.repeat(n)` -- mengulang string sebanyak `n` kali.
- ...dan masih banyak lagi yang dapat ditemukan di dalam [manual](mdn:js/String).
+<<<<<<< HEAD
String juga memiliki method-method untuk mencari/mengganti dengan ekspresi reguler (regular expression). Tetapi itu adalah topik yang luas, jadi topik ini dibahas di bagiannya sendiri .
+=======
+Strings also have methods for doing search/replace with regular expressions. But that's big topic, so it's explained in a separate tutorial section .
+
+Also, as of now it's important to know that strings are based on Unicode encoding, and hence there're issues with comparisons. There's more about Unicode in the chapter .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
index f9d2db39a..cc97bde23 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
@@ -59,7 +59,11 @@ alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
Solusi tersebut memiliki waktu penyelesaian [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). Dalam kata lain, jika kita menambah ukuran *array* 2 kali lipat, algoritma akan bekerja 4 kali lipat lebih lama.
+<<<<<<< HEAD
Untuk *array* yang besar (1000, 10000 *item* atau lebih) algoritma yang demikian akan mengarah pada kelambanan yang parah.
+=======
+For big arrays (1000, 10000 or more items) such algorithms can lead to serious sluggishness.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
# Solusi cepat
@@ -91,4 +95,8 @@ alert( getMaxSubSum([-1, -2, -3]) ); // 0
Algoritma tersebut membutuhkan tepat 1 *array* yang lolos, jadi waktu penyelesaian adalah O(n).
+<<<<<<< HEAD
Kamu dapat menemukan informasi yang lebih rinci tentang algoritma di sini: [Masalah *subarray* maksimum](http://en.wikipedia.org/wiki/Maximum_subarray_problem). Jika masih kurang jelas bagaimana hal tersebut bekerja, maka mohon menelusuri algoritma pada contoh di atas, perhatikan bagaimana algoritmanya bekerja, itulah cara yang paling baik.
+=======
+You can find more detailed information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md
index e74f23a47..5429e1165 100644
--- a/1-js/05-data-types/04-array/2-create-array/task.md
+++ b/1-js/05-data-types/04-array/2-create-array/task.md
@@ -6,11 +6,19 @@ importance: 5
Mari coba 5 operasi *array*.
+<<<<<<< HEAD
1. Buat sebuah *array* `styles` dengan elemen "Jazz" dan "Blues" di dalamnya.
2. Tambahkan "Rock-n-Roll" pada akhir *array*.
3. Ganti nilai yang berada di tengah menjadi "Classics". Kodemu untuk menemukan nilai di tengah harus berhasil untuk *array* sepanjang apapun.
4. Hilangkan nilai pertama dari *array* lalu tampilkan *array*.
5. Dahulan *array* dengan `Rap` and `Reggae` di depannya.
+=======
+1. Create an array `styles` with items "Jazz" and "Blues".
+2. Append "Rock-n-Roll" to the end.
+3. Replace the value in the middle with "Classics". Your code for finding the middle value should work for any arrays with odd length.
+4. Strip off the first value of the array and show it.
+5. Prepend `Rap` and `Reggae` to the array.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
*Array* selama proses:
diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md
index dfe8704aa..eb1586af1 100644
--- a/1-js/05-data-types/04-array/3-call-array-this/task.md
+++ b/1-js/05-data-types/04-array/3-call-array-this/task.md
@@ -11,7 +11,7 @@ let arr = ["a", "b"];
arr.push(function() {
alert( this );
-})
+});
arr[2](); // ?
```
diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md
index 813c1bf88..ab32bf5e0 100644
--- a/1-js/05-data-types/04-array/article.md
+++ b/1-js/05-data-types/04-array/article.md
@@ -92,6 +92,38 @@ let fruits = [
Gaya "tanda koma yang membuntuti" membuat lebih mudah untuk memasukkan/menghilangkan item dari sebuah array, karena semua baris serupa.
````
+## Get last elements with "at"
+
+[recent browser="new"]
+
+Let's say we want the last element of the array.
+
+Some programming languages allow the use of negative indexes for the same purpose, like `fruits[-1]`.
+
+Although, in JavaScript it won't work. The result will be `undefined`, because the index in square brackets is treated literally.
+
+We can explicitly calculate the last element index and then access it: `fruits[fruits.length - 1]`.
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+alert( fruits[fruits.length-1] ); // Plum
+```
+
+A bit cumbersome, isn't it? We need to write the variable name twice.
+
+Luckily, there's a shorter syntax: `fruits.at(-1)`:
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+// same as fruits[fruits.length-1]
+alert( fruits.at(-1) ); // Plum
+```
+
+In other words, `arr.at(i)`:
+- is exactly the same as `arr[i]`, if `i >= 0`.
+- for negative values of `i`, it steps back from the end of the array.
## Metode *pop*/*push*, *shift*/*unshift*
@@ -121,9 +153,15 @@ Sebuah *stack* biasanya diilustrasikan sebagai sebuah *pack* kartu: kartu-kartu
Untuk *stack*, elemen terakhir yang di-*push* diterima lebih dulu, hal itu juga disebut sebagai prinsip LIFO (*Last-In-First-Out*) atau "terakhir masuk, pertama keluar". Sedangkan untuk *queue*, kita memiliki prinsip (*First-In-First-Out*) atau "pertama masuk, pertama keluar".
+<<<<<<< HEAD
*Array* dalam JavaScript dapat bekerja baik sebagai sebuah *queue* maupun *stack*. Keduanya membuat kamu bisa menambahkan/menghilangkan elemen baik dari/ke awal ataupun akhir.
Dalam *computer science* struktur data yang memungkinkan kita bisa melakukan hal-hal demikian disebut sebagai [*deque* (*double-ended queue*)](https://en.wikipedia.org/wiki/Double-ended_queue).
+=======
+Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements, both to/from the beginning or the end.
+
+In computer science, the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
**Metode yang berfungsi dengan bagian akhir dari _array_:**
@@ -138,6 +176,8 @@ Dalam *computer science* struktur data yang memungkinkan kita bisa melakukan hal
alert( fruits ); // Apple, Orange
```
+ Both `fruits.pop()` and `fruits.at(-1)` return the last element of the array, but `fruits.pop()` also modifies the array by removing it.
+
`push`
: Mendorong elemen ke bagian akhir *array*:
@@ -248,7 +288,11 @@ Mengapa bekerja dengan bagian akhir sebuah *array* ketimbang bagian depannya? Ma
fruits.shift(); // mengambil 1 elemen dari bagian awal
```
+<<<<<<< HEAD
Tidaklah cukup mengambil dan menghapus elemen dengan angka `0`. Elemen lainnya juga perlu diberi angka pula.
+=======
+It's not enough to take and remove the element with the index `0`. Other elements need to be renumbered as well.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Operasi `shift` harus menjalankan 3 hal:
@@ -366,11 +410,19 @@ Ada satu sintaks lagi untuk membuat sebuah *array*:
let arr = *!*new Array*/!*("Apple", "Pear", "etc");
```
+<<<<<<< HEAD
Sintaks tersebut jarang digunakan, karena tanda kurung siku `[]` lebih pendek. Juga terdapat sebuah fitur yang sukar di dalamnya.
+=======
+It's rarely used, because square brackets `[]` are shorter. Also, there's a tricky feature with it.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jika `new Array` dipanggil dengan sebuah argumen tunggal yang mana adalah sebuah angka, maka sintaks tersebut akan membuat sebuah *array* yang *tanpa elemen, namun dengan panjang sesuai yang diberikan*.
+<<<<<<< HEAD
Mari lihat bagaimana orang-orang bisa terjebak dengan hal ini:
+=======
+Let's see how one can shoot themselves in the foot:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let arr = new Array(2); // akankah membuat sebuah array berisi [2] ?
@@ -395,7 +447,11 @@ let matrix = [
[7, 8, 9]
];
+<<<<<<< HEAD
alert( matrix[1][1] ); // 5, elemen pusat
+=======
+alert( matrix[0][1] ); // 2, the second value of the first inner array
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## toString
@@ -442,7 +498,11 @@ Mari kita ingat aturannya:
- Jika salah satu argumen `==` adalah objek, dan argumen lainnya primitif, objek tersebut akan diubah menjadi primitif, seperti yang dijelaskan pada bab .
- ... Dengan pengecualian `null` dan` undefined` yang sama `==` satu sama lain dan tidak ada yang lain.
+<<<<<<< HEAD
Perbandingan ketat `===` bahkan lebih sederhana, karena tidak mengonversi jenis.
+=======
+The strict comparison `===` is even simpler, as it doesn't convert types.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi, jika kita membandingkan array dengan `==`, keduanya tidak akan pernah sama, kecuali jika kita membandingkan dua variabel yang mereferensikan array yang sama persis.
@@ -462,7 +522,11 @@ alert( 0 == [] ); // true
alert('0' == [] ); // false
```
+<<<<<<< HEAD
Di sini, dalam kedua kasus, kami membandingkan primitif dengan objek array. Jadi, array `[]` diubah menjadi primitif untuk tujuan perbandingan dan menjadi string kosong `` '' `.
+=======
+Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kemudian proses perbandingan berlanjut dengan primitif, seperti yang dijelaskan dalam bab :
@@ -481,6 +545,7 @@ Sederhana saja: jangan gunakan operator `==`. Sebaliknya, bandingkan item-by-ite
*Array* adalah sebuah objek berjenis khusus, cocok untuk menyimpan dan mengelola data yang tersusun.
+<<<<<<< HEAD
- Deklarasinya:
```js
@@ -492,11 +557,33 @@ Sederhana saja: jangan gunakan operator `==`. Sebaliknya, bandingkan item-by-ite
```
Panggilan `new Array(number)` membuat sebuah *array* dengan panjang indeks (*length*) yang diberikan, tetapi tanpa elemen.
+=======
+The declaration:
+
+```js
+// square brackets (usual)
+let arr = [item1, item2...];
+
+// new Array (exceptionally rare)
+let arr = new Array(item1, item2...);
+```
+
+The call to `new Array(number)` creates an array with the given length, but without elements.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Properti `length` adalah panjang *array* atau, lebih tepatnya, angka indeks terakhir plus satu. Hal tersebut secara otomatis diatur dengan metode *array*.
- Jika kita memendekkan `length` secara manuak, *array* tersebut akan terpotong.
+<<<<<<< HEAD
Kita bisa menggunakan sebuah *array* sebagai sebuah *deque* dengan operasi sebagai berikut:
+=======
+Getting the elements:
+
+- we can get element by its index, like `arr[0]`
+- also we can use `at(i)` method that allows negative indexes. For negative values of `i`, it steps back from the end of the array. If `i >= 0`, it works same as `arr[i]`.
+
+We can use an array as a deque with the following operations:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- `push(...items)` menambahkan `items` ke bagian akhir *array*.
- `pop()` menghilangkan elemen dari bagian akhir *array* dan mengembalikannya.
diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
index d939723d4..7257b05f4 100644
--- a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
+++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
@@ -4,7 +4,11 @@ nilai penting: 4
# Buatlah objek dengan kunci dari array
+<<<<<<< HEAD
Anggaplah kita menerima sebuah array dari user didalam form `{id:..., name:..., age... }`.
+=======
+Let's say we received an array of users in the form `{id:..., name:..., age:... }`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Buatlah sebuah fungsi `groupById(arr)` yang membuat sebuah objek, dengan `id` sebagai key/kunci, dan item array sebagai nilai
diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
index db32d9a11..241b74c6e 100644
--- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
+++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
@@ -4,13 +4,13 @@ describe("filterRangeInPlace", function() {
let arr = [5, 3, 8, 1];
- filterRangeInPlace(arr, 1, 4);
+ filterRangeInPlace(arr, 2, 5);
- assert.deepEqual(arr, [3, 1]);
+ assert.deepEqual(arr, [5, 3]);
});
it("doesn't return anything", function() {
assert.isUndefined(filterRangeInPlace([1,2,3], 1, 4));
});
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md
index bb1b59be7..e19f24663 100644
--- a/1-js/05-data-types/05-array-methods/article.md
+++ b/1-js/05-data-types/05-array-methods/article.md
@@ -1,6 +1,10 @@
# Metode *array*
+<<<<<<< HEAD
*Array* menyediakan begitu banyak metode. Untuk mempermudah, dalam bab ini metode-metode tersebut dibagi menjadi beberapa kelompok.
+=======
+Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Menambahkan/menghapus *item*
@@ -32,11 +36,19 @@ alert( arr.length ); // 3
Elemen tersebut telah dihapus, tetapi *array* itu masih memiliki 3 elemen, kita bisa melihat bahwa `arr.length == 3`.
+<<<<<<< HEAD
Hal itu alami, karena `delete obj.key` menghilangkan sebuah nilai berdasarkan `key`. Itulah yang dilakukannya. Tidak masalah bagi objek. Tapi untuk *array* kita biasanya ingin elemen yang tersisa untuk bergeser dan mengisi ruang yang dikosongkan tadi. Kita ingin memiliki sebuah *array* yang lebih pendek sekarang.
+=======
+That's natural, because `delete obj.key` removes a value by the `key`. It's all it does. Fine for objects. But for arrays we usually want the rest of the elements to shift and occupy the freed place. We expect to have a shorter array now.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi, metode khusus harus digunakan.
+<<<<<<< HEAD
Metode [arr.splice(start)](mdn:js/Array/splice) adalahs sebuah fungsi serbaguna untuk *array*. *Splice* bisa melakukan banyak hal: memasukkan, menghilangkan serta mengganti elemen.
+=======
+The [arr.splice](mdn:js/Array/splice) method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sintaksnya yakni:
@@ -64,7 +76,11 @@ alert( arr ); // ["I", "JavaScript"]
Mudah, kan? Mulai dari indeks `1` metode ini menghilangkan elemen di indeks `1`.
+<<<<<<< HEAD
Dalam contoh selanjutnya kita menghilangkan 3 element dan menggantinya dengan 2 elemen lain:
+=======
+In the next example, we remove 3 elements and replace them with the other two:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let arr = [*!*"I", "study", "JavaScript",*/!* "right", "now"];
@@ -86,7 +102,11 @@ let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- array yang berisi elemen-elemen yang dihapus
```
+<<<<<<< HEAD
Metode `splice` juga mampu memasukkan elemen tanpa menghilangkan elemen apapun yang ada sebelumnya. Untuk itu kita perlu mengatur `deleteCount` menjadi `0`:
+=======
+The `splice` method is also able to insert the elements without any removals. For that, we need to set `deleteCount` to `0`:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let arr = ["I", "study", "JavaScript"];
@@ -116,7 +136,11 @@ alert( arr ); // 1,2,3,4,5
### *slice*
+<<<<<<< HEAD
Metode [arr.slice](mdn:js/Array/slice) lebih sederhana daripada metode serupa sebelumnya yakni `arr.splice`.
+=======
+The method [arr.slice](mdn:js/Array/slice) is much simpler than the similar-looking `arr.splice`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sintaksnya adalah:
@@ -126,7 +150,11 @@ arr.slice([start], [end])
Metode ini mengembalikan sebuah sebuah *array* baru hasil salinan semua *item* yang ada dari indeks `start` hingga `end` (indeks `end` tidak termasuk). Baik `start` maupun `end` bisa saja negatif, dalam kasus tersebut posisi dari bagian akhir *array* sudah diasumsikan/diperkirakan.
+<<<<<<< HEAD
Mirip dengan metode *string* `str.slice`, namun membuat *subarray* bukan *substring*.
+=======
+It's similar to a string method `str.slice`, but instead of substrings, it makes subarrays.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contohnya:
@@ -208,7 +236,7 @@ Metode [arr.forEach](mdn:js/Array/forEach) membuat kita dapat menjalankan sebuah
Sintaksnya:
```js
arr.forEach(function(item, index, array) {
- // ... do something with item
+ // ... do something with an item
});
```
@@ -236,6 +264,7 @@ Kini mari membahas metode-metode yang bertugas mencari dalam *array*.
### *indexOf/lastIndexOf* dan *includes*
+<<<<<<< HEAD
Metode [arr.indexOf](mdn:js/Array/indexOf), [arr.lastIndexOf](mdn:js/Array/lastIndexOf) dan [arr.includes](mdn:js/Array/includes) memiliki sintaks yang sama dan pada dasarnya keduanya melakukan fungsi yang samahave the same syntax, namun untuk mengoperasikannya perlu ditujukan *item* bukan karakter:
- `arr.indexOf(item, from)` -- mencari `item` dimulai dari indeks `from`, dan mengembalikan indeks dimana *item* yang dicari itu ditemukan, jika tidak akan mengembalikan `-1`.
@@ -243,6 +272,16 @@ Metode [arr.indexOf](mdn:js/Array/indexOf), [arr.lastIndexOf](mdn:js/Array/lastI
- `arr.includes(item, from)` -- mencari `item` dimulai dari indeks `from`, mengembalkikan `true` jika yang dicari itu ditemukan.
Contohnya:
+=======
+The methods [arr.indexOf](mdn:js/Array/indexOf) and [arr.includes](mdn:js/Array/includes) have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters:
+
+- `arr.indexOf(item, from)` -- looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`.
+- `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found.
+
+Usually, these methods are used with only one argument: the `item` to search. By default, the search is from the beginning.
+
+For instance:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let arr = [1, 0, false];
@@ -254,6 +293,7 @@ alert( arr.indexOf(null) ); // -1
alert( arr.includes(1) ); // true
```
+<<<<<<< HEAD
Perlu diperhatikan bahwa metode tersebut menggunakan perbandingan `===`. Jadi, jika kita mencari `false`, metode ini akan tepat mencari `false` dan bukan nol.
Jika kita ingin memeriksa pencantuman, dan tidak ingin tahu indeks yang persis, maka direkomendasikan menggunakan `arr.includes`.
@@ -264,11 +304,41 @@ Juga, perbedaan kecil dari `includes` yakni metode ini menangani `NaN` dengan te
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (seharusnya 0, tetapi tanda persamaan === tidak berfungsi pada NaN)
alert( arr.includes(NaN) );// true (benar)
+=======
+Please note that `indexOf` uses the strict equality `===` for comparison. So, if we look for `false`, it finds exactly `false` and not the zero.
+
+If we want to check if `item` exists in the array and don't need the index, then `arr.includes` is preferred.
+
+The method [arr.lastIndexOf](mdn:js/Array/lastIndexOf) is the same as `indexOf`, but looks for from right to left.
+
+```js run
+let fruits = ['Apple', 'Orange', 'Apple']
+
+alert( fruits.indexOf('Apple') ); // 0 (first Apple)
+alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)
```
+````smart header="The `includes` method handles `NaN` correctly"
+A minor, but noteworthy feature of `includes` is that it correctly handles `NaN`, unlike `indexOf`:
+
+```js run
+const arr = [NaN];
+alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0)
+alert( arr.includes(NaN) );// true (correct)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
+```
+That's because `includes` was added to JavaScript much later and uses the more up-to-date comparison algorithm internally.
+````
+
+<<<<<<< HEAD
### *find* dan *findIndex*
Bayangkan kita memiliki sebuah *array* berisi objek. Bagaimana cata kita menemukan sebuah objek dengan kondisi tertentu?
+=======
+### find and findIndex/findLastIndex
+
+Imagine we have an array of objects. How do we find an object with a specific condition?
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Berikut ini ada metode [arr.find(fn)](mdn:js/Array/find) yang dapat mudah digunakan.
@@ -286,7 +356,11 @@ Fungsi tersebut dipanggil untuk elemen-elemen dalam *array*, satu sama lainnya:
- `index` adalah indeks elemen tersebut.
- `array` adalah *array* itu sendiri.
+<<<<<<< HEAD
Jika fungsi tersebut mengembalikan `true`, pencarian dihentikan, lalu `item` akan dikembalikan. Jika tidak ditemukan apa-apa, `undefined` yang dikembalikan.
+=======
+If it returns `true`, the search is stopped, the `item` is returned. If nothing is found, `undefined` is returned.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, kita memiliki sebuah *array* berisi elemen pengguna, tiap pengguna memiliki *field* `id` dan `name`. Mari cari pengguna dengan `id == 1`:
@@ -302,11 +376,38 @@ let user = users.find(item => item.id == 1);
alert(user.name); // John
```
+<<<<<<< HEAD
Pada kehidupan nayata *array* berisi objek adalah hal yang umum, jadi metode `find` sangatlah berguna.
+=======
+In real life, arrays of objects are a common thing, so the `find` method is very useful.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ingat bahwa contoh yang kami berikan untuk mencari (`find`) fungsi `item => item.id == 1` hanya dengan satu argumen. Ini adalah hal umum, argumen lainnya pada fungsi lainnya jarang digunakan.
+<<<<<<< HEAD
Metode [arr.findIndex](mdn:js/Array/findIndex) pada dasarnya sama, namun mengembalikan indeks dimana elemen tersebut ditemukan bukan elemen itu sendiri serta mengembalikan `-1` ketika tidak ditemukan apapun.
+=======
+The [arr.findIndex](mdn:js/Array/findIndex) method has the same syntax but returns the index where the element was found instead of the element itself. The value of `-1` is returned if nothing is found.
+
+The [arr.findLastIndex](mdn:js/Array/findLastIndex) method is like `findIndex`, but searches from right to left, similar to `lastIndexOf`.
+
+Here's an example:
+
+```js run
+let users = [
+ {id: 1, name: "John"},
+ {id: 2, name: "Pete"},
+ {id: 3, name: "Mary"},
+ {id: 4, name: "John"}
+];
+
+// Find the index of the first John
+alert(users.findIndex(user => user.name == 'John')); // 0
+
+// Find the index of the last John
+alert(users.findLastIndex(user => user.name == 'John')); // 3
+```
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
### *filter*
@@ -390,7 +491,12 @@ Secara harfiah, semua elemen dikonversi menjadi *string* untuk dibandingkan. Sed
Untuk menggunakan urutan penataan kita sendiri, kita perlu memberikan sebuah fungsi sebagai argumen pada `arr.sort()`.
+<<<<<<< HEAD
Fungsi tersebut harus membandingkan dua nilai yang berubah-ubah dan mengembalikan (hasilnya):
+=======
+The function should compare two arbitrary values and return:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
function compare(a, b) {
if (a > b) return 1; // if the first value is greater than the second
@@ -419,11 +525,19 @@ alert(arr); // *!*1, 2, 15*/!*
Kini metode tersebu berfungsi seperti yang diinginkan.
+<<<<<<< HEAD
Mari berhenti sejenak dan pikirkan apa yang terjadi. `arr` bisa jadi *array* berisi apapun, benar? *Array* itu bisa saja berisi angka atau *string* atau objek atau apapun. Kita memiliki sekumpulan *beberapa item*. Untuk mengurutkannya, kita perlu sebuah *fungsi pengurutan* yang tahu bagaimana cara untuk membandingkan elemen-elemen. Setelan awalnya adalah sebuah urutan *string*.
+=======
+Let's step aside and think about what's happening. The `arr` can be an array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Metode `arr.sort(fn)` mengimplementasikan sebuah algoritma pengurutan yang umum. Kita tidak perlu benar-benar tahu bagaimana algoritma itu bekerja (sebuah [cara cepat/*quicksort*](https://en.wikipedia.org/wiki/Quicksort) yang sudah teroptimasi sepanjang waktu). Algoritma itu akan menyusuri *array*, membandungkan elemen-elemennya menggunakan fungsi yang diberikan dan mengurutkan ulang elemen-elemen tersebut, yang perlu kita lakukan yakni memberikan `fn` yang mana akan melakukan operasi perbandingan.
+<<<<<<< HEAD
*Ngomong-omong*, jika kita pernah ingin tahu elemen mana saja yang dibandingkan -- cukup dengan cara memberi *alert*:
+=======
+By the way, if we ever want to know which elements are compared -- nothing prevents us from alerting them:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
@@ -480,7 +594,11 @@ Ini adalah situasi dari dunia nyata. Kita menulis sebuah aplikasi olahpesan, dan
Metode [str.split(delim)](mdn:js/String/split) melakukan tepat hal yang dijelaskan di atas. Metode ini memisahkan *string* ke dalam *array* dengan *delimiter* (pemisah) `delim`.
+<<<<<<< HEAD
Dalam contoh berikut ini, kita memisahkan elemen dengan tanda koma yang diikuti oleh spasi:
+=======
+In the example below, we split by a comma followed by a space:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let names = 'Bilbo, Gandalf, Nazgul';
@@ -547,9 +665,15 @@ Argument-argumennya yakni:
- `index` -- adalah posisi *item* tersebut.
- `array` -- adalah *array*-nya.
+<<<<<<< HEAD
Jika fungsi sudah diterapkan, masil dari panggilan fungsi sebelumnya dioper ke panggilan selanjutnya sebagai argumen pertama.
Memang terdengar rumit, tapi tidak seperti yang kamu pikirkan tentang argumen pertama sebagai "akumulator" yang menyimpan dan menggabungkan jasil dari semua eksekusi sebelumnya. Serta pada akhirnya, itu menjadi hasil dari `reduce`.
+=======
+As the function is applied, the result of the previous function call is passed to the next one as the first argument.
+
+So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end, it becomes the result of `reduce`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Cara termudah untuk memahami metode ini adalah dengan melihat contohnya.
@@ -615,10 +739,14 @@ arr.reduce((sum, current) => sum + current);
```
+<<<<<<< HEAD
Jadi sangat disarankan untuk selalu menspesifikasikan nilai awal.
Metode [arr.reduceRight](mdn:js/Array/reduceRight) melaksanakan hal yang sama, tapi beroperasi dari kanan ke kiri.
+=======
+The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same but goes from right to left.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Array.isArray
@@ -627,8 +755,13 @@ Metode [arr.reduceRight](mdn:js/Array/reduceRight) melaksanakan hal yang sama, t
Jadi `typeof` tidak membantu membedakan sebuah objek polos dari sebuah *array*:
```js run
+<<<<<<< HEAD
alert(typeof {}); // objek
alert(typeof []); // sama
+=======
+alert(typeof {}); // object
+alert(typeof []); // object (same)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
...Tetapi *array* serung diguakan hingga ada metode khusus untuk hal ini: [Array.isArray(value)](mdn:js/Array/isArray). Metode ini mengembalikan `true` jika `value` adalah sebuah *array*, dan `false` jika sebaliknya.
@@ -643,7 +776,11 @@ alert(Array.isArray([])); // true
Hamppir semua metode *array* yang memanggil fungsi -- seperti `find`, `filter`, `map`, dengan pengecualian `sort`, menerima paramater tambahan yakni `thisArg`.
+<<<<<<< HEAD
Parameter itu tidak dijelaskan pada bab sebelumnya, karena jarang digunakan. Tetapi demi kelengkapan kita harus menutupi metodenya.
+=======
+That parameter is not explained in the sections above, because it's rarely used. But for completeness, we have to cover it.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Berikut ini adalah sintkas lengkap dari metode-metode tersebut:
@@ -702,11 +839,19 @@ Sebuah panggilan ke `users.filter(army.canJoin, army)` bisa diganti dengan `user
- `slice(start, end)` -- membuat *array* baru, menyalin elemen dari posisi `start` hingga `end` (tidak inklusif) ke dalam *array* baru tersebut.
- `concat(...items)` --mengembalikan sebuah *array* baru: menyalin semua anggota *array* yang sekarang dan menambahkan `items` ke dalamnya. Jika `items` adalah sebuah *array*, maka elemennya yang akan diambil.
+<<<<<<< HEAD
- Untuk mencari di antara elemen-elemen:
- `indexOf/lastIndexOf(item, pos)` -- mencari `item` mulai dari posisi `pos`, mengembalikan indeksnya atau `-1` jika tidak ditemukan.
- `includes(value)` -- mengembalikan `true` jika *array* memiliki `value`, jika tidak akan mengembalikan `false`.
- `find/filter(func)` -- menyaring elemen dengan menggunakan fungsi, mengembalikan nilai awal/semua nilai yang membuat hasil *return*-nya menjadi `true`.
- `findIndex` seperti `find`, namun mengembalikan indeks bukan nilai.
+=======
+- To search among elements:
+ - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, and return the index or `-1` if not found.
+ - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`.
+ - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`.
+ - `findIndex` is like `find`, but returns the index instead of a value.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Untuk mengulang elemen:
- `forEach(func)` -- memanggil `func` untuk setiap elemen, tidak mengembalikan apapun.
@@ -718,8 +863,13 @@ Sebuah panggilan ke `users.filter(army.canJoin, army)` bisa diganti dengan `user
- `split/join` -- mengonversi sebuah *string* menjadi *array* dan sebaliknya.
- `reduce(func, initial)` -- menghitung sebuah nilai tunggal pada *array* dengan cara memanggil `func` untuk setiap elemen dan mengoper hasil tersebut di antara panggilan.
+<<<<<<< HEAD
- Sebagai tambahan:
- `Array.isArray(arr)` memeriksa apakah `arr` merupakan *array* atau bukan.
+=======
+- Additionally:
+ - `Array.isArray(value)` checks `value` for being an array, if so returns `true`, otherwise `false`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tolong diingat bahwa metode `sort`, `reverse` dan `splice` memodifikasi *array* itu sendiri.
@@ -731,7 +881,12 @@ Metode-metode ini adalah yang paling sering digunakan, mencakupi 99% kasus pengg
Metode ini berperilaku seperti operator `||` dan `&&`: jika `fn` mengembalikan nilai yang sebenarnya,` arr.some () `segera mengembalikan` true` dan berhenti melakukan iterasi pada item lainnya; jika `fn` mengembalikan nilai yang salah,` arr.every () `segera mengembalikan` false` dan juga menghentikan iterasi pada item lainnya.
+<<<<<<< HEAD
Kita bisa menggunakan `every` untuk membandingkan array:
+=======
+ We can use `every` to compare arrays:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
function arraysEqual(arr1, arr2) {
return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
@@ -748,7 +903,11 @@ Metode-metode ini adalah yang paling sering digunakan, mencakupi 99% kasus pengg
Untuk daftar lengkapnya, lihat [manual](mdn:js/Array).
+<<<<<<< HEAD
Sejak pandangan pertama mungkin terlihat ada begitu banyak metode, cukup sulit untuk diingat. Namun sebenarnya hal itu jauh lebih mudah.
+=======
+At first sight, it may seem that there are so many methods, quite difficult to remember. But actually, that's much easier.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Lihat *cheat sheet* hanya untuk sekedar tahu semua metode tersebut. Lalu selesaikan *task* bab ini sebagai latihan, jadi kamu memiliki pengalaman mengenai metode *array*.
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index c394ead3f..dab3d5615 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -28,10 +28,17 @@ let range = {
Untuk bisa membuat `range` bisa diiterasi (dan membuat `for..of` bekerja) kita harus menambahkan sebuah metode kedalam objeknya bernama `Symbol.iterator` (Simbol built-in spesian yang hanya digunakan untuk hal itu).
+<<<<<<< HEAD
1. Ketika `for.of` dimulai, itu akan memanggil metodenya sekali (atau error jika tidak ditemukan). Metodenya haruslah mengembalikan sebuah *iterator* -- sebuah objek dengan metode `next`.
2. Selanjutnya, `for..of` bekerja *hanya bila itu mengembalikan objek*.
3. Ketika `for..of` menginginkan nilai selanjutnya, itu akan memanggil `next()` didalam objeknya.
4. Hasil dari `next()` harus mempunyai form `{done: Boolean, value: any}`, dimana `done=true` berarti iterasinya telah selesai, sebaliknya `value` adalah nilai selanjutnya.
+=======
+1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
+2. Onward, `for..of` works *only with that returned object*.
+3. When `for..of` wants the next value, it calls `next()` on that object.
+4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the loop is finished, otherwise `value` is the next value.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ini adalah implementasi penuh untuk `range` dengan catatan:
@@ -44,11 +51,16 @@ let range = {
// 1. panggil for..of pertama kali untuk memanggil ini
range[Symbol.iterator] = function() {
+<<<<<<< HEAD
// ini akan mengembalikan objek iterator:
// 2. Selanjutnya, for..of hanya bekerja dengan iterator ini, menanyakan nilai selanjutnya
+=======
+ // ...it returns the iterator object:
+ // 2. Onward, for..of works only with the iterator object below, asking it for next values
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
return {
current: this.from,
- last: this.to,
+ last: this.to,
// 3. next() dipanggil untuk setiap iterasi oleh perulangan for..of
next() {
@@ -174,7 +186,11 @@ ketika kita menggunakan javascript untuk melakukan prakter didalam browser atau
Contoh, string adalah keduanya, bisa diiterasi (`for..of` dapat bekerja) dan seperti array(mempunyai indeks angka dan `length`(panjang)).
+<<<<<<< HEAD
Akan tetapi bisa diiterasi mungkin bukanlah array. Dan sebaliknya sebuah array mungkin tidak bisa diiterasi.
+=======
+But an iterable may not be array-like. And vice versa an array-like may not be iterable.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh, `range` di contoh diatas bisa diiterasi, tapi tidak seperti array, karena itu tidak memiliki properti indeks dan `length`.
@@ -218,8 +234,13 @@ alert(arr.pop()); // World (metode bekerja)
Hal yang serupa terjadi untuk sesuatu yang bisa diiterasi:
+<<<<<<< HEAD
```js
// asumsikan bahwa range diambil dari contoh diatas
+=======
+```js run
+// assuming that range is taken from the example above
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
let arr = Array.from(range);
alert(arr); // 1,2,3,4,5 (konversi array toString bekerja)
```
@@ -233,8 +254,13 @@ Argumen kedua yang opsional `mapFn` bisa saja sebuah fungsi yang akan digunakan
Contoh:
+<<<<<<< HEAD
```js
// asumsikan bahwa range diambil dari contoh diatas
+=======
+```js run
+// assuming that range is taken from the example above
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
// kuadratkan setiap angka
let arr = Array.from(range, num => num * num);
@@ -271,7 +297,11 @@ for (let char of str) {
alert(chars);
```
+<<<<<<< HEAD
...Tapi ini lebih pendek.
+=======
+...But it is shorter.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kita bahkan bisa membangun `slice` pengganti didalamnya:
diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md
index 9ec9951cf..0275e1b8b 100644
--- a/1-js/05-data-types/07-map-set/article.md
+++ b/1-js/05-data-types/07-map-set/article.md
@@ -10,10 +10,15 @@ Tapi itu tidak cukup dalam kehidupan nyata. Itu sebabnya `Map` dan` Set` juga ad
## Map
+<<<<<<< HEAD
[Map](mdn:js/Map) adalah kumpulan item data yang berkunci, seperti `Object`. Tetapi perbedaan utama adalah `Map` membolehkan kunci jenis apa pun.
+=======
+[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Metode dan properti:
+<<<<<<< HEAD
- `new Map()` -- menciptakan map.
- `map.set(key, value)` -- menyimpan nilai dengan kunci.
- `map.get(key)` -- mengembalikan nilai dengan kunci, `undefined` jika` key` tidak ada di map.
@@ -21,6 +26,15 @@ Metode dan properti:
- `map.delete(key)` -- menghapus nilai dengan kunci.
- `map.clear()` -- menghapus semua isi dari map.
- `map.size` -- mengembalikan jumlah elemen saat ini.
+=======
+- [`new Map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element (the key/value pair) by the key.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya:
@@ -100,14 +114,24 @@ map.set('1', 'str1')
```
````
+<<<<<<< HEAD
## Iterasi Atas Map
+=======
+## Iteration over Map
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Untuk looping atas `map`, ada 3 method:
+<<<<<<< HEAD
- `map.keys()` -- mengembalikan iterable untuk kunci,
- `map.values()` -- mengembalikan iterable untuk nilai,
- `map.entries()` -- mengembalikan iterable untuk entri `[key, value]`, ini digunakan dengan standar di `for..of`.
+=======
+- [`map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) -- returns an iterable for keys,
+- [`map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) -- returns an iterable for values,
+- [`map.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Misalnya:
@@ -162,7 +186,11 @@ let map = new Map([
alert( map.get('1') ); // str1
```
+<<<<<<< HEAD
Jika kita memiliki objek biasa, dan kita mau menciptakan sebuah `Map` darinya, kita bisa menggunakan method built-in [Object.entries(obj)](mdn:js/Object/entries) yang mengembalikan array daripada pasangan-pasangan kunci/nilai untuk satu objek yang berformat persis sama.
+=======
+If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) that returns an array of key/value pairs for an object exactly in that format.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi kita bisa menciptakan map dari objek seperti ini:
@@ -233,16 +261,29 @@ Itu sama, karena `Object.fromEntries` mengharapkan objek iterabel sebagai argume
## Set
+<<<<<<< HEAD
`Set` adalah tipe koleksi spesial - "set nilai-nilai" (tanpa kunci), dimana setiap nilai hanya dapat terjadi sekali.
+=======
+A [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) is a special type collection - "set of values" (without keys), where each value may occur only once.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Method utamanya adalah:
+<<<<<<< HEAD
- `new Set(iterable)` -- menciptakan set, dan jika objek `iterable` disediakan (biasanya array), menyalin nilai darinya ke set.
- `set.add(value)` -- menambahkan nilai, mengembalikan set itu sendiri.
- `set.delete(value)` -- menghapus nilai, mengembalikan `true` jika `value` ada pada saat panggilan berlangsung, jika tidak `false`.
- `set.has(value)` -- mengembalikan `true` jika nilai ada di set, jika tidak `false`.
- `set.clear()` -- menghapus semuanya dari set.
- `set.size` -- adalah hitungan elemen.
+=======
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value, returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Fitur utamanya adalah panggilan berulang `set.add(value)` dengan nilai yang sama tidak melakukan apa-apa. Itulah alasan mengapa setiap nilai hanya muncul dalam `Set` sekali.
@@ -272,7 +313,11 @@ for (let user of set) {
}
```
+<<<<<<< HEAD
Alternatif untuk `Set` dapat berupa array pengguna, dan kode untuk memeriksa duplikat pada setiap insersi menggunakan [arr.find](mdn:js/Array/find). Tetapi kinerjanya akan jauh lebih buruk, karena metode ini menjalani seluruh array memeriksa setiap elemen. `Set` jauh lebih baik dioptimalkan secara internal untuk pemeriksaan keunikan.
+=======
+The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Iteration atas Set
@@ -291,20 +336,35 @@ set.forEach((value, valueAgain, set) => {
Ingat keanehannya. Fungsi callback yang dilewatkan dalam `forEach` memiliki 3 argumen: satu `value`, kemudian *nilai yang sama* `valueAgain`, dan kemudian objek target. Memang, nilai yang sama muncul dalam argumen dua kali.
+<<<<<<< HEAD
Itu untuk kompatibilitas dengan `Map` di mana callback yang dilewati `forEach` memiliki tiga argumen. Terlihat agak aneh, memang. Tetapi dapat membantu mengganti `Map` dengan` Set` dalam kasus-kasus tertentu dengan mudah, dan sebaliknya.
+=======
+That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But this may help to replace `Map` with `Set` in certain cases with ease, and vice versa.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Metode yang sama yang dimiliki `Map` untuk iterator juga didukung:
+<<<<<<< HEAD
- `set.keys()` -- mengembalikan objek iterable untuk nilai,
- `set.values()` -- sama dengan `set.keys()`, untuk kompatibilitas dengan `Map`,
- `set.entries()` -- mengembalikan objek iterable untuk entri `[nilai, nilai]`, ada untuk kompatibilitas dengan `Map`.
+=======
+- [`set.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys) -- returns an iterable object for values,
+- [`set.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values) -- same as `set.keys()`, for compatibility with `Map`,
+- [`set.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries) -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Ringkasan
+<<<<<<< HEAD
`Map` -- adalah kumpulan nilai-nilai berkunci.
+=======
+[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- is a collection of keyed values.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Metode dan properti:
+<<<<<<< HEAD
- `new Map([iterable])` -- membuat map, dengan `iterable` opsional (mis. array) dari pasangan `[key, value]` untuk inisialisasi.
- `map.set(key, value)` -- menyimpan nilai dengan kunci.
- `map.get(key)` -- mengembalikan nilai dengan kunci, `undefined` jika `key` tidak ada di map.
@@ -312,21 +372,43 @@ Metode dan properti:
- `map.delete(key)` -- menghapus nilai dengan kunci.
- `map.clear()` -- menghapus semuanya dari peta.
- `map.size` -- mengembalikan jumlah elemen saat ini.
+=======
+- [`new Map([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key, returns the map itself.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Perbedaan dari `Object` biasa:
- Kunci apa saja, objek bisa dijadikan kunci.
- Metode-metode tambahan untuk kenyamanan, properti `size`.
+<<<<<<< HEAD
`Set` -- adalah kumpulan nilai-nilai unik.
+=======
+[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- is a collection of unique values.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Metode dan properti:
+<<<<<<< HEAD
- `new Set([iterable])` -- membuat set, dengan nilai opsional `iterable` (mis. array) untuk inisialisasi.
- `set.add(value)` -- menambahkan nilai (tidak melakukan apa-apa jika `value` ada), mengembalikan set itu sendiri.
- `set.delete(value)` -- menghapus nilai, mengembalikan `true` jika `value` ada pada saat panggilan berlangsung, jika tidak `false`.
- `set.has(value)` -- mengembalikan `true` jika nilai ada di set, jika tidak `false`.
- `set.clear()` -- menghapus semuanya dari set.
- `set.size` -- adalah hitungan elemen.
+=======
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, with optional `iterable` (e.g. array) of values for initialization.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value (does nothing if `value` exists), returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Iterasi atas `Map` dan` Set` selalu dalam urutan insersi, jadi kami tidak dapat mengatakan bahwa koleksi ini tidak berurut, tetapi kami tidak dapat menyusun ulang elemen atau secara langsung mendapatkan elemen dengan nomornya.
diff --git a/1-js/05-data-types/08-weakmap-weakset/article.md b/1-js/05-data-types/08-weakmap-weakset/article.md
index 7b5d963de..3374ab95a 100644
--- a/1-js/05-data-types/08-weakmap-weakset/article.md
+++ b/1-js/05-data-types/08-weakmap-weakset/article.md
@@ -1,8 +1,18 @@
+<<<<<<< HEAD
# WeakMap dan WeakSet
+=======
+
+# WeakMap and WeakSet
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Seperti yang kita tahu dari bab , Mesin Javascript menyimpan sebuah nilai didalam memori selama itu bisa terjangkau (dan secara potensial bisa digunakan).
+<<<<<<< HEAD
Contoh:
+=======
+For instance:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
let john = { name: "John" };
@@ -55,13 +65,21 @@ john = null; // tulis ulang referensinya
*/!*
```
+<<<<<<< HEAD
`WeakMap` secara dasar berbeda didalam aspek ini. Itu tidak akan mencegah pembuangan dari objek kunci.
+=======
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is fundamentally different in this aspect. It doesn't prevent garbage-collection of key objects.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Ayo kita lihat didalam contoh.
## WeakMap
+<<<<<<< HEAD
Perbedaan pertama dari `Map` adalah kunci `WeakMap` haruslah objek, bukan nilai primitif:
+=======
+The first difference between [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is that keys must be objects, not primitive values:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let weakMap = new WeakMap();
@@ -95,10 +113,10 @@ Bandingkan itu dengan `Map` biasa dicontoh diatas. Sekarang jika `john` hanya ad
`WeakMap` hanya mempunyai metode berikut:
-- `weakMap.get(key)`
-- `weakMap.set(key, value)`
-- `weakMap.delete(key)`
-- `weakMap.has(key)`
+- [`weakMap.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set)
+- [`weakMap.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get)
+- [`weakMap.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete)
+- [`weakMap.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has)
Kenapa terdapat batasan seperti itu? Itu hanyalah untuk alasan teknis. Jika sebuah objek kehilangan semua referensi lainnya (seperti `john` didalam kode diatas), lalu itu akan dibuang secara otomatis. Tapi secara teknis itu tidak benar-benar di spesifikasikan *ketika pembersihan terjadi*.
@@ -183,6 +201,7 @@ function process(obj) {
let result = /* kalkulasi hasil */ obj;
cache.set(obj, result);
+ return result;
}
return cache.get(obj);
@@ -222,6 +241,7 @@ function process(obj) {
let result = /* perhitungan hasil */ obj;
cache.set(obj, result);
+ return result;
}
return cache.get(obj);
@@ -243,11 +263,19 @@ obj = null;
## WeakSet
+<<<<<<< HEAD
`WeakSet` memiliki perilaku yang sama:
- Analoginya adalah untuk meng-`Set`, tapi mungkin kita hanya butuh menambahkan objek kedalam `WeakSet` (bukan primitif).
- Sebuah objek ada didalam set selama itu bisa dijangkau dari tempat lain.
- Seperti `Set`, itu mendukung `add`, `has` dan `delete`, tapi tidak `size`, `keys()` dan tidak ada iterasi
+=======
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) behaves similarly:
+
+- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
+- An object exists in the set while it is reachable from somewhere else.
+- Like `Set`, it supports [`add`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/add), [`has`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/has) and [`delete`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/delete), but not `size`, `keys()` and no iterations.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
menjadi "weak", itu juga menyediakan penyimpanan tambahan. Tapi tidak untuk data yang asal-asalan, tapi untuk "yes/no". Keanggotaan dari `WeakSet` mungkin berarti sesuatu tentang objeknya.
@@ -281,9 +309,15 @@ Hal yang paling bisa diingat adalah batasan dari `WeakMap` dan `WeakSet` adalah
## Ringkasan
+<<<<<<< HEAD
`WeakMap` adalah koleksi seperti-`Map` yang mengijinkan hanya objek sebagai kunci dan menghapus mereka bersama dengan nilai yang terkait sekalinya mereka menjadi tidak terjangkau.
`WeakSet` adalah koleksi seperti-`Set` yang hanya menyimpan objek dan menghapus mereka sekalinya mereka menjadi tidak bisa diakses.
+=======
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is `Map`-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means.
+
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Keduanya tidak mendukung metode dan properti yang mengacu pada seluruh kunci atau jumlah mereka. Hanya operasi individual yang diperbolehkan.
diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md
index 2ff3562ba..6fb782b3f 100644
--- a/1-js/05-data-types/09-keys-values-entries/article.md
+++ b/1-js/05-data-types/09-keys-values-entries/article.md
@@ -76,9 +76,15 @@ Objek kekurangan banyak method yang ada untuk arrays, contoh `map`, `filter` dan
Jika kita ingin mengapplikasikan method-method tersebut, kita bisa menggunakan `Object.entries` diikuti oleh `Object.fromEntries`:
+<<<<<<< HEAD
1. Gunakan `Object.entries(obj)` untuk mendapatkan array pasangan kunci/nilai dari `obj`.
2. Gunakan method array di array tersebut, contoh `map`.
3. Gunakan `Object.fromEntries(array)` di array hasil untuk mengubahnya kembali menjadi objek.
+=======
+1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
+2. Use array methods on that array, e.g. `map`, to transform these key/value pairs.
+3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, kita mempunyai objek dengan harga-harga, dan mau melipat duakan harga-harganya:
@@ -91,12 +97,22 @@ let prices = {
*!*
let doublePrices = Object.fromEntries(
+<<<<<<< HEAD
// ubah menjadi array, map, lalu fromEntries mengembalikan objeknya
Object.entries(prices).map(([key, value]) => [key, value * 2])
+=======
+ // convert prices to array, map each key/value pair into another pair
+ // and then fromEntries gives back the object
+ Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
);
*/!*
alert(doublePrices.meat); // 8
-```
+```
+<<<<<<< HEAD
Mungkin ini terlihat susah pertama kalinya, tetapi ini akan menjadi mudah untuk di mengerti setelah kamu menggunakannya beberapa kali. Kita bisa membuat perantaian hebat dengan cara ini.
+=======
+It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/05-data-types/10-destructuring-assignment/article.md b/1-js/05-data-types/10-destructuring-assignment/article.md
index 370831864..ac56dec6a 100644
--- a/1-js/05-data-types/10-destructuring-assignment/article.md
+++ b/1-js/05-data-types/10-destructuring-assignment/article.md
@@ -2,6 +2,7 @@
Dua stuktur data yang paling banyak digunakan di Javascript adalah `Object` dan `Array`
+<<<<<<< HEAD
Objek memungkinkan kita untuk membuat entitas tunggal yang menyimpan data item berdasarkan kunci, dan array memungkinkan kita untuk mengumpulkan data item menjadi koleksi yang terurut.
Tetapi ketika kita meneruskannya ke suatu fungsi, itu mungkin tidak perlu objek / array secara keseluruhan, melainkan potongan individual.
@@ -9,11 +10,25 @@ Tetapi ketika kita meneruskannya ke suatu fungsi, itu mungkin tidak perlu objek
*Destructuring assignment* adalah sebuah sintaks spesial yang memungkinkan kita untuk "membongkar" array atau objek menjadi variabel yang banyak, kadang-kadang itu memang lebih nyaman. Destrukturisasi juga berfungsi baik dengan fungsi-fungsi kompleks yang mempunyai banyak parameter, nilai default, dan sebagainya.
## Destrukturisasi Array
+=======
+- Objects allow us to create a single entity that stores data items by key.
+- Arrays allow us to gather data items into an ordered list.
+
+However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties.
+
+*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient.
+
+Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh bagaimana array di-destrukturisasi menjadi variabel:
```js
+<<<<<<< HEAD
// kita mempunyai array dengan nama, dan nama keluarga
+=======
+// we have an array with a name and surname
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
let arr = ["John", "Smith"]
*!*
@@ -37,10 +52,19 @@ alert(firstName); // John
alert(surname); // Smith
```
+<<<<<<< HEAD
````smart header="\"Destructuring\" bukan berarti \"destructive\"."
Ini disebut "destructuring assignment," karena "destructurizes" dengan menyalin item kedalam variabel. Tetapi array itu sendiri tidak dimodifikasi.
Ini hanya cara singkat untuk menulis:
+=======
+As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples to understand it better.
+
+````smart header="\"Destructuring\" does not mean \"destructive\"."
+It's called "destructuring assignment," because it "destructurizes" by copying items into variables. However, the array itself is not modified.
+
+It's just a shorter way to write:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// let [firstName, surname] = arr;
let firstName = arr[0];
@@ -60,7 +84,11 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic
alert( title ); // Consul
```
+<<<<<<< HEAD
Pada kode diatas, elemen kedua dari array dilewati, yang ketiga ditetapkan untuk `title`, dan sisa item array juga dilewati (karena tidak ada variabel untuknya).
+=======
+In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items are also skipped (as there are no variables for them).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
````smart header="Bekerja dengan iterabel apapun di sisi kanan"
@@ -71,11 +99,16 @@ Pada kode diatas, elemen kedua dari array dilewati, yang ketiga ditetapkan untuk
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);
```
-That works, because internally a destructuring assignment works by iterating over the right value. It's kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
+That works, because internally a destructuring assignment works by iterating over the right value. It's a kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
````
+<<<<<<< HEAD
````smart header="Menetapkan ke apa saja pada sisi kiri"
+=======
+````smart header="Assign to anything at the left-side"
+We can use any "assignables" on the left side.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kita bisa menggunakan "penetapan" apa saja pada sisi kiri.
@@ -90,11 +123,18 @@ alert(user.surname); // Smith
````
+<<<<<<< HEAD
````smart header="Pengulangan dengan .entries()"
Di bagian sebelumnya kita melihat metode [Object.entries(obj)](mdn:js/Object/entries).
Kita bisa menggunakan itu untuk destrukturisasi untuk melompati kunci-dan-nilai sebuah objek:
+=======
+````smart header="Looping with .entries()"
+In the previous chapter, we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
+
+We can use it with destructuring to loop over the keys-and-values of an object:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let user = {
@@ -102,7 +142,7 @@ let user = {
age: 30
};
-// loop over keys-and-values
+// loop over the keys-and-values
*!*
for (let [key, value] of Object.entries(user)) {
*/!*
@@ -163,14 +203,24 @@ If we'd like also to gather all that follows -- we can add one more parameter th
let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
*!*
+<<<<<<< HEAD
// Catatan bahwa tipe dari `rest` adalah Array.
+=======
+// rest is an array of items, starting from the 3rd one
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2
*/!*
```
+<<<<<<< HEAD
Nilai dari `rest` adalah array dari elemen array yang tersisa. Kita bisa menggunakan variabel lain apapun pada `rest`, hanya pastikan memiliki tiga titik sebelum itu dan pergi terakhir di penetapan destrukturisasi.
+=======
+The value of `rest` is the array of the remaining array elements.
+
+We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
@@ -179,7 +229,11 @@ let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Ro
### Nilai default
+<<<<<<< HEAD
Jika ada lebih sedikit nilai dalam array daripada variabel dalam penugasan, tidak akan ada kesalahan. Nilai absen dianggap undefined:
+=======
+If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
*!*
@@ -227,7 +281,11 @@ Sintaks dasarnya adalah:
let {var1, var2} = {var1:…, var2:…}
```
+<<<<<<< HEAD
Kita memiliki objek yang ada di sisi kanan, yang ingin kita pisah menjadi beberapa variabel. Sisi kiri berisi "pola" untuk properti yang sesuai. Dalam kasus sederhana, itu adalah daftar nama variabel di `{...}`.
+=======
+We should have an existing object on the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in `{...}`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contohnya:
@@ -247,7 +305,13 @@ alert(width); // 100
alert(height); // 200
```
+<<<<<<< HEAD
Properti `options.title`, `options.width` dan `options.height` ditugaskan ke variabel yang sesuai. Urutannya tidak masalah. Ini juga berfungsi:
+=======
+Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables.
+
+The order does not matter. This works too:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// mengganti urutan di let {...}
@@ -409,9 +473,15 @@ alert( title ); // Menu
## Destrukturisasi bersarang
+<<<<<<< HEAD
Jika suatu objek atau array berisi objek dan array bersarang lainnya, kita dapat menggunakan pola sisi kiri yang lebih kompleks untuk mengekstraksi bagian yang lebih dalam.
Dalam kode di bawah ini `options` memiliki objek lain di properti` size` dan sebuah array di properti `items`. Pola di sisi kiri penugasan memiliki struktur yang sama untuk mengekstrak nilai dari mereka:
+=======
+If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
+
+In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern on the left side of the assignment has the same structure to extract values from them:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let options = {
@@ -420,7 +490,7 @@ let options = {
height: 200
},
items: ["Cake", "Donut"],
- extra: true
+ extra: true
};
// tugas dekstukturisasi dibagi dalam beberapa baris untuk kejelasan
@@ -440,8 +510,12 @@ alert(item1); // Cake
alert(item2); // Donut
```
+<<<<<<< HEAD
Semua properti objek `options` kecuali` extra` yang tidak ada di bagian kiri, ditetapkan ke variabel yang sesuai:
+=======
+All properties of `options` object except `extra` which is absent in the left part, are assigned to corresponding variables:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6

@@ -451,9 +525,15 @@ Perhatikan bahwa tidak ada variabel untuk `size` dan` item`, karena kita mengamb
## Parameter fungsi cerdas
+<<<<<<< HEAD
Ada kalanya suatu fungsi memiliki banyak parameter, yang sebagian besar bersifat opsional. Itu terutama berlaku untuk antarmuka pengguna. Bayangkan sebuah fungsi yang menciptakan menu. Mungkin memiliki lebar, tinggi, judul, daftar item dan sebagainya.
Berikut cara yang buruk untuk menulis fungsi tersebut:
+=======
+There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, an item list and so on.
+
+Here's a bad way to write such a function:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
@@ -461,7 +541,11 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
}
```
+<<<<<<< HEAD
Dalam kehidupan nyata, masalahnya adalah bagaimana cara mengingat urutan argumen. Biasanya IDE mencoba membantu kita, terutama jika kodenya didokumentasikan dengan baik, tetapi masih ... Masalah lain adalah bagaimana memanggil fungsi ketika sebagian besar parameter ok secara default.
+=======
+In real-life, the problem is how to remember the order of arguments. Usually, IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Soperti ini?
@@ -526,7 +610,11 @@ function({
})
```
+<<<<<<< HEAD
Kemudian, untuk objek parameter, akan ada variabel `varName` untuk properti` incomingProperty`, dengan `defaultValue` secara default.
+=======
+Then, for an object of parameters, there will be a variable `varName` for the property `incomingProperty`, with `defaultValue` by default.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Harap perhatikan bahwa destrukturisasi seperti itu mengasumsikan bahwa `showMenu ()` memang memiliki argumen. Jika kita menginginkan semua nilai secara default, maka kita harus menentukan objek kosong:
@@ -553,7 +641,7 @@ Dalam kode di atas, objek argumen keseluruhan adalah `{}` secara default, jadi s
- Penugasan destrukturisasi memungkinkan untuk memetakan objek atau array secara instan ke banyak variabel.
- Sintaks lengkap objek:
```js
- let {prop : varName = default, ...rest} = object
+ let {prop : varName = defaultValue, ...rest} = object
```
Ini berarti properti `prop` harus masuk ke variabel` varName` dan, jika tidak ada properti seperti itu, maka nilai `default` harus digunakan.
@@ -563,9 +651,13 @@ Dalam kode di atas, objek argumen keseluruhan adalah `{}` secara default, jadi s
- Sintaks lengkap array:
```js
- let [item1 = default, item2, ...rest] = array
+ let [item1 = defaultValue, item2, ...rest] = array
```
+<<<<<<< HEAD
Item pertama masuk ke `item1`; yang kedua masuk ke `item2`, sisanya membuat array `rest`.
+=======
+ The first item goes to `item1`; the second goes into `item2`, and all the rest makes the array `rest`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Dimungkinkan untuk mengekstraksi data dari array / objek bersarang, untuk itu sisi kiri harus memiliki struktur yang sama dengan yang benar.
diff --git a/1-js/05-data-types/11-date/1-new-date/solution.md b/1-js/05-data-types/11-date/1-new-date/solution.md
index 41ea33cf4..e9700da0a 100644
--- a/1-js/05-data-types/11-date/1-new-date/solution.md
+++ b/1-js/05-data-types/11-date/1-new-date/solution.md
@@ -13,6 +13,6 @@ We could also create a date from a string, like this:
```js run
//new Date(datastring)
-let d2 = new Date("February 20, 2012 03:12:00");
+let d2 = new Date("2012-02-20T03:12");
alert( d2 );
```
diff --git a/1-js/05-data-types/11-date/article.md b/1-js/05-data-types/11-date/article.md
index b779b314a..f754bc630 100644
--- a/1-js/05-data-types/11-date/article.md
+++ b/1-js/05-data-types/11-date/article.md
@@ -57,10 +57,17 @@ Untuk membuat objek `Date` baru panggil `new Date()` dengan salah satu dari argu
`new Date(year, month, date, hours, minutes, seconds, ms)`
: Membuat waktu dengan komponen yang diberikan dari zona waktu lokal. Hanya dua argument pertama yang wajib.
+<<<<<<< HEAD
- `Tahun`nya harus mempunyai 4 angka: `2013` boleh, `98` tidak boleh.
- Perhitungan `Bulan`nya dimulai dari `0` (Jan), sampai `11` (Des).
- Parameter `date` sebenarnya adalah hari dari bulan, jika tidak ada maka akan diasumsikan `1`.
- Jika `jam/menit/detik/milidetik` tidak ada, mereka akan diasumsikan sama dengan `0`.
+=======
+ - The `year` should have 4 digits. For compatibility, 2 digits are also accepted and considered `19xx`, e.g. `98` is the same as `1998` here, but always using 4 digits is strongly encouraged.
+ - The `month` count starts with `0` (Jan), up to `11` (Dec).
+ - The `date` parameter is actually the day of month, if absent then `1` is assumed.
+ - If `hours/minutes/seconds/ms` is absent, they are assumed to be equal `0`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh:
@@ -378,7 +385,11 @@ for (let i = 0; i < 10; i++) {
```warn header="Berhati-hati saat melakukan microbenchmarking/pengujian kemampuan micro"
Mesin Javascript modern melakukan banyak optimasi. mereka mungkin merekayasa hasil dari "test buatan" dibandingkan dengan "pemakaian normal", terutama ketika kita mengukur kemampuan sesuatu yang sangat kecil, seperti bagaimana operator bekerja, atau fungsi bawaan. Jadi jika kamu sangat serius ingin mengerti tentang performansi, maka pelajarilah bagaiman mesin Javascript bekerja. dan maka kamu mungkin tidak butuh microbenchmarking sama sekali
+<<<<<<< HEAD
Kumpulan artikel yang bagus tentang V8 bisa ditemukan di .
+=======
+The great pack of articles about V8 can be found at .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Date.parse dari sebuah string
@@ -409,7 +420,7 @@ Kita bisa secara instan membuat sebuah objek `new Date` dari timestamp:
```js run
let date = new Date( Date.parse('2012-01-26T13:51:50.417-07:00') );
-alert(date);
+alert(date);
```
## Ringkasan
diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md
index 19bf86d3e..ebc287030 100644
--- a/1-js/05-data-types/12-json/article.md
+++ b/1-js/05-data-types/12-json/article.md
@@ -27,7 +27,11 @@ Untungnya, (kita) tak perlu untuk menulis kode untuk menangani semua hal ini. Tu
## JSON.stringify
+<<<<<<< HEAD
[JSON](http://en.wikipedia.org/wiki/JSON) (*JavaScript Object Notation*) adalah sebuah format umum yang merepresentasikan nilai-nilai dan objek. JSON dideskripsikan sebagaimana dalam standar [RFC 4627](http://tools.ietf.org/html/rfc4627). Awalnya JSON dibuat untuk JavaScript, tapi banyak bahasa pemrograman lain memiliki *library* untuk menangani JSON juga. Oleh karena itu, kini jadi mudah untuk menggunakan JSON untuk tujuan pertukaran data ketika klien menggunakan JavaScript dan server ditulis menggunakan bahasa pemrograman Ruby/PHP/Java/apapun itu.
+=======
+The [JSON](https://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a general format to represent values and objects. It is described as in [RFC 4627](https://tools.ietf.org/html/rfc4627) standard. Initially it was made for JavaScript, but many other languages have libraries to handle it as well. So it's easy to use JSON for data exchange when the client uses JavaScript and the server is written on Ruby/PHP/Java/Whatever.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
JavaScript menyediakan metode-metode seperti:
@@ -41,7 +45,7 @@ let student = {
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
- wife: null
+ spouse: null
};
*!*
@@ -58,7 +62,7 @@ alert(json);
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
- "wife": null
+ "spouse": null
}
*/
*/!*
@@ -402,7 +406,7 @@ Untuk men-*decode* sebuah *string* JSON, kita memerlukan sebuah metode lain bern
Sintaksnya:
```js
-let value = JSON.parse(str, [reviver]);
+let value = JSON.parse(str[, reviver]);
```
*str*
@@ -448,7 +452,11 @@ let json = `{
Selaain itu semua, JSON tidak mendukung komentar. Menambahkan sebuah komentar ke JSON akan membuat JSON tersebut tidak valid.
+<<<<<<< HEAD
Terdapat format lain yang dinamakan [JSON5](http://json5.org/), yang mengizinkan *key* tanpa tanda kutip, adanya komentar dan lain-lain. Tapi ini adalah *library* yang berdiri sendiri, tidak terdapat dalam spesifikasi bahasa pemrograman.
+=======
+There's another format named [JSON5](https://json5.org/), which allows unquoted keys, comments etc. But this is a standalone library, not in the specification of the language.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
JSON biasa memang seketat itu bukan karena para pengembangnya malas, tetapi agar implementasinya mudah, dapat diandalkan dan cepat saat proses *parsing* algoritma.
diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
index a5390dc0e..e9e4967cb 100644
--- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
@@ -37,4 +37,8 @@ Catatan. Biasanya, rumus adalah solusi tercepat. Itu hanya menggunakan 3 operasi
varian perulangan adalah yang kedua dalam hal waktu. Di varian rekusif dan perulangan kita menambahkan angka yang sama. Tapi rekursi melibatkan pemanggilan bercabang dan manajemen tumpukan eksekusi. Itu juga memakan sumberdaya, jadi itu lebih lambat.
+<<<<<<< HEAD
Catatan+. Beberapa mesin mendukung optimasi "tail call": jika sebuah pemanggilan rekursi adalah yang paling terakhir didalam fungsi (seperti dalam `sumTo` diatas), maka fungsi terluar tidak butuh untuk melanjutkan eksekusi, jadi mesinnya tidak akan mengingat konteks dari eksekusi. Itu akan menghilangkan beban didalam memori, jadi menghitung `sumTo(100000)` menjadi mungkin. Tapi jika mesin Javascript tidak mendukung optimasi tail call (kebanyakan tidak), disana akan terdapat error: "maximum stack size exceeded", karena disana biasanya terdapat batasan dalam total ukuran stack/penumpukan.
+=======
+P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function, with no other calculations performed, then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
index 2ec804d5f..0f4f94113 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
@@ -33,7 +33,11 @@ printReverseList(list);
# Menggunakan perulangan
+<<<<<<< HEAD
Varian perulangan juga sedikit lebih rumit daripada mengeluarkannya secara langsung.
+=======
+The loop variant is also a little bit more complicated than the direct output.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tidak ada cara untuk mendapatkan nilai terakhir didalam `list` kita. Kita juga tidak bisa "berjalan mundur".
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index 05b912bf1..e0f597834 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -61,7 +61,7 @@ Ketika `pow(x, n)` dipanggil, eksekusinya dibagi menjadi dua cabang:
if n==1 = x
/
pow(x, n) =
- \
+ \
else = x * pow(x, n - 1)
```
@@ -287,7 +287,11 @@ Interatif `pow` menggunakan konteks tunggal mengganti `i` dan `result` didalam p
**Rekursi apapun bisa ditulis ulang sebagai perulangan. Varian perulangan biasanya bisa dibuat lebih efektif.**
+<<<<<<< HEAD
...Tapi terkadang menulis ulang bukanlah hal yang sepele, terutama ketika fungsi menggunakan pemanggilan rekursif yang berbeda tergantung dari kondisi dan menyatukan hasil mereka atau cabangnya lebih rumit. Dan optimasinya mungkin tidak dibutuhkan dan benar-benar menghabiskan tenaga.
+=======
+...But sometimes the rewrite is non-trivial, especially when a function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Rekursi bisa memberikan kode yang lebih pendek, lebih mudah dimengerti dan didukung. Optimasi tidak dibutuhkan di setiap tempat, kebanyakan kita butuh kode yang bagus, itulah kenapa itu digunakan.
@@ -538,7 +542,11 @@ Istilah:
list = { value, next -> list }
```
+<<<<<<< HEAD
Pohon seperti pohon elemen HTML atau pohon departemen dari bab ini juga secara natural rekursif: cabang mereka dan setuap cabang mempunyai cabang lainnya.
+=======
+ Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they have branches and every branch can have other branches.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Fungsi rekursif bisa digunakan untuk menyusurinya seperti yang telah kita lihat didalam contoh `sumSalary`.
diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
index 09c8a7611..9b539946a 100644
--- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
+++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
@@ -23,7 +23,11 @@ function sum(a, b) {
alert( sum(1, 2, 3, 4, 5) );
```
+<<<<<<< HEAD
Disana tidak akan terdapat error karena argumen "berlebihan". Tapi tentu saja hasilnya hanya dua angka pertama yang dihitung.
+=======
+There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted, so the result in the code above is `3`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sisa parameternya bisa digunakan didalam fungsi dengan menggunakan tiga titik `...` diikuti nama dari array yang akan berisi mereka. Titik secara harfiah berarti "kumpulkan sisa parameter didalam array".
diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
index c180224b4..52950977b 100644
--- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
+++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
@@ -1,5 +1,11 @@
+importance: 5
+<<<<<<< HEAD
# Fungsi di dalam if
+=======
+---
+# Function in if
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Lihatlah kode di bawah ini. Apa hasil dari panggilan fungsi di baris terakhir?
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
index e3c335e03..802f28c4d 100644
--- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
@@ -23,7 +23,7 @@ describe("byField", function(){
{ name: "John", age: 20, surname: "Johnson"},
];
let ageSortedAnswer = users.sort(byField("age"));
- assert.deepEqual(ageSortedKey, ageSortedKey);
+ assert.deepEqual(ageSortedKey, ageSortedAnswer);
});
it("sorts users by surname", function(){
diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md
index c406df77e..4b61db81e 100644
--- a/1-js/06-advanced-functions/03-closure/article.md
+++ b/1-js/06-advanced-functions/03-closure/article.md
@@ -8,7 +8,11 @@ Tapi apa yang terjadi jika variabel luar berubah saat fungsinya dibuat? Akankan
Dan bagaimana jika sebuah fungsi diberikan sebagai paramter dan dipanggil dibagian kode lain, akankah itu mendapatkan akses ke variabel luar ditempat itu?
+<<<<<<< HEAD
Ayo kita peruas pengetahuan kita untuk mengerti skenario ini dan skenario yang lebih kompleks.
+=======
+And what if a function is passed along as an argument and called from another place of code, will it get access to outer variables at the new place?
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Kita akan bahas tentang variabel `let/const` di sini"
Di JavaScript, ada 3 cara mendeklarasi variabel: `let`, `const` (cara-cara modern), dan `var` (sisa masa lalu).
diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md
index 61a8bad58..204328fd8 100644
--- a/1-js/06-advanced-functions/04-var/article.md
+++ b/1-js/06-advanced-functions/04-var/article.md
@@ -1,9 +1,16 @@
# Si Tua "var"
+<<<<<<< HEAD
```smart header="Artikel ini untuk memahami script lama"
Informasi yang terdapat di artikel ini berguna untuk memahami script lama.
Hal itu bukanlah cara kita menulis kode baru.
+=======
+```smart header="This article is for understanding old scripts"
+The information in this article is useful for understanding old scripts.
+
+That's not how we write new code.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Di bab paling awal tentang [variabel](info:variables), kami menyebutkan tiga cara untuk deklarasi variabel:
@@ -55,7 +62,7 @@ alert(test); // Error: test tidak didefinisikan
Hal yang sama juga untuk loop: `var` tidak dapat berupa blok atau loop-lokal:
-```js
+```js run
for (var i = 0; i < 10; i++) {
var one = 1;
// ...
@@ -166,7 +173,7 @@ Lebih baik didemonstrasikan dengan sebuah contoh:
```js run
function sayHi() {
- alert(phrase);
+ alert(phrase);
*!*
var phrase = "Hello";
@@ -246,12 +253,21 @@ Ada beberapa cara lain selain tanda kurung untuk memberi tahu Javascript bahwa y
```js run
// Cara membuat IIFE
+<<<<<<< HEAD
(function() {
alert("kurung disekitar fungsi");
}*!*)*/!*();
(function() {
alert("kurung disekitar semuanya");
+=======
+*!*(*/!*function() {
+ alert("Parentheses around the function");
+}*!*)*/!*();
+
+*!*(*/!*function() {
+ alert("Parentheses around the whole thing");
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
}()*!*)*/!*;
*!*!*/!*function() {
diff --git a/1-js/06-advanced-functions/05-global-object/article.md b/1-js/06-advanced-functions/05-global-object/article.md
index a6c8afcce..026df1b2e 100644
--- a/1-js/06-advanced-functions/05-global-object/article.md
+++ b/1-js/06-advanced-functions/05-global-object/article.md
@@ -25,7 +25,11 @@ var gVar = 5;
alert(window.gVar); // 5 (menjadi properti objek global)
```
+<<<<<<< HEAD
Mohon jangan bergantung dengan itu! Perilaku ini ada untuk alasan kompatibilitas. Script modern menggunakan [JavaScript modules](info:modules) dimana hal-hal tersebut tidak terjadi.
+=======
+Function declarations have the same effect (statements with `function` keyword in the main code flow, not function expressions).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jika kita menggunakan `let`, hal tersebut tidak akan terjadi:
diff --git a/1-js/06-advanced-functions/06-function-object/article.md b/1-js/06-advanced-functions/06-function-object/article.md
index d41f83c4d..4956433e7 100644
--- a/1-js/06-advanced-functions/06-function-object/article.md
+++ b/1-js/06-advanced-functions/06-function-object/article.md
@@ -326,7 +326,11 @@ welcome(); // Hello, Guest (pemanggilan bercabang bekerja)
Sekarang hal itu bekerja karena nama `"func"` adalah fungsi-lokal. Fungsi itu tidak diambil dari luar (dan tidak terlihat dari luar). Spesifikasinya menjamin itu akan selalu mereferensi fungsi saat ini.
+<<<<<<< HEAD
Fungsi dari luar kode mempunyai variabel `sayHi` atau `welcome`nya sendiri. Dan `func` adalah sebuah "nama fungsi internal", bagaimana fungsi bisa memanggil dirinya sendiri secara internal.
+=======
+The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", the way for the function to can call itself reliably.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```smart header="Tidak ada hal semacam itu untuk deklarasi fungsi"
Fitur "nama internal" dideskripsikan disini hanya tersedia untuk ekspresi fungsi, bukan deklarasi fungsi. Untuk deklarasi fungsi, tidak terdapat sintaks untuk menambahkan sebuah nama "internal".
diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
index cc0650309..adc774da9 100644
--- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
+++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
@@ -27,7 +27,11 @@ Biasanya, adalah sebuah fungsi. Untuk beberapa alasan, sebuah string dari kode b
: Penundaannya sebelum berjalan, didalam milidetik (1000 milidetik = 1 detik), secara default 0.
`arg1`, `arg2`...
+<<<<<<< HEAD
: Argumen-argumen untuk fungsinya (tidak didukung didalam IE9-).
+=======
+: Arguments for the function
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Contoh, kode ini memanggil `sayHi()` setelah satu detik:
@@ -102,7 +106,11 @@ Seperti yang bisa kita lihat dari keluaran `alert`, didalam peramban identifier
Lainnya, tidak terdapat spesifikasi universal untuk metode-metode ini, jadi tidak ada masalah.
+<<<<<<< HEAD
Untuk peramban, timer dideskripsikan didalam [bagian timer](https://www.w3.org/TR/html5/webappapis.html#timers) dari standar HTML5.
+=======
+For browsers, timers are described in the [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) of HTML Living Standard.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## setInterval
@@ -232,7 +240,11 @@ setTimeout(function() {...}, 100);
Untuk `setInterval` fungsinya akan tetap didalam memori sampai `clearInterval` dipanggil.
+<<<<<<< HEAD
Tidak terdapat efek-samping pada hal itu. Sebuah fungsi mereferensi lingkungan leksikal luar, jadi, selama itu masih ada, variabel luar pun akan tetap ada. Hal itu mungkin akan memakan memori daripada fungsinya sendiri. Jadi ketika kita tidak butuh fungsi yang sudah dijadwalkan lagi, akan lebih baik untuk dibatalkan/diberhentikan, bahkan jika itu sebuah kode yang sangat pendek/kecil.
+=======
+There's a side effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
````
## setTimeout dengan penundaan nol
@@ -255,8 +267,13 @@ Pada baris pertama "akan memasukan pemanggilan kedalam urutan pemanggilan setela
Juga terdapat kasus yang berhubungan dengan peramban, kita akan membahasnya didalam bab .
+<<<<<<< HEAD
````smart header="Penundaan dengan nol faktanya tidaklah nol (didalam peramban)"
Didalam peramban, terdapat sebuah batasan seberapa seringnya timer bercabang bisa berjalan. [standar HTML5](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) mengatakan: "setelah lima timer bercabang, intervalnya dipaksa untuk berjalan setidaknya 4 milidetik.".
+=======
+````smart header="Zero delay is in fact not zero (in a browser)"
+In the browser, there's a limitation of how often nested timers can run. The [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.".
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Let's demonstrate what it means with the example below. The `setTimeout` call in it re-schedules itself with zero delay. Each call remembers the real time from the previous one in the `times` array. What do the real delays look like? Let's see:
Ayo kita prakterkan apa artinya itu dengan contoh dibawah. Pemanggilan `setTimeout` menjadwalkan ulang dengan penundaan 0. Setiap pemanggilan mengingat waktu yang asli dari pemanggilan sebelumnya didalam array `times`. Seperti apa penundaan sesungguhnya terlihat? Lihat dibawah:
@@ -295,9 +312,16 @@ Untuk Javascript dibagian server, batasan itu tidaklah ada, dan disana terdapat
Perhatikan bahwa seluruh metode penjadwalan tidak *menjamin* delay yang tepat.
+<<<<<<< HEAD
Contoh, didalam peramban timer mungkin lebih lambat untuk beberapa alasan:
- CPU-nya sedang melakukan banyak pekerjaan.
- Ada tab peramban yang sedang berjalan dalam mode background.
- Laptopnya sedang menggunakan mode batre.
+=======
+For example, the in-browser timer may slow down for a lot of reasons:
+- The CPU is overloaded.
+- The browser tab is in the background mode.
+- The laptop is on battery saving mode.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Semua itu mungkin menaikan resolusi timernya (delay minimalnya) menjadi 300ms atau bahkan 1000ms tergantung perambannya dan performasi pada OS-nya.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
index 6035fe6e3..d292a927d 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
@@ -8,9 +8,15 @@ Buatlah sebuah dekorator "penutup" `throttle(f, ms)` -- yang mengembalikan sebua
Ketika fungsinya dipanggil beberapa kali, fungsinya akan melakukan pemanggilan kepada `f` maksimal sekali per `ms` milidetik.
+<<<<<<< HEAD
Perbedaannya dengan dekorator debounce adalah keduanya benar-benar dekorator berbeda:
- `debounce` menjalankan fungsinya sekali setelah masa "tidak aktif". Bagus untuk memproses hasil akhir.
- `throttle` menjalankan fungsinya tidak lebih banyak dari waktu `ms` yang diberikan. Bagus untuk update tersusun yang tidak terlalu sering dipanggil.
+=======
+Compared to the debounce decorator, the behavior is completely different:
+- `debounce` runs the function once after the "cooldown" period. Good for processing the final result.
+- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Dengan kata lain, `throttle` seperti seorang sekertaris yang menerima panggilan telefon, tapi menggangu bos nya (memanggil fungsi `f` asli) tidak lebih sering dari sekali per `ms` milidetik.
diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
index 08962f264..33f5b8330 100644
--- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
+++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
@@ -1,5 +1,9 @@
+<<<<<<< HEAD
Errornya muncul karena `ask` mendapatkan fungsi `loginOk/loginFail` tanpa objeknya.
+=======
+The error occurs because `askPassword` gets functions `loginOk/loginFail` without the object.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
ketika `ask` memanggil, `loginOk/loginFail` mengasumsikan bahwa `this=undefined`.
diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md
index 43bfe08d9..39dba7ec6 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -187,8 +187,13 @@ let user = {
let say = user.say.bind(user);
+<<<<<<< HEAD
say("Hello"); // Hello, John (argumen "Hello" dikirim untuk digunakan)
say("Bye"); // Bye, John ("Bye" dikirim untuk digunakan)
+=======
+say("Hello"); // Hello, John! ("Hello" argument is passed to say)
+say("Bye"); // Bye, John! ("Bye" is passed to say)
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
````smart header="Metode yang bermanfaat: `bindAll`"
@@ -202,7 +207,12 @@ for (let key in user) {
}
```
+<<<<<<< HEAD
Librari Javascript juga menyediakan fungsi untuk memudahkan pengikatan/binding masal, contoh [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) didalam lodash.
+=======
+JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll) in lodash.
+````
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Partial functions/Fungsi sebagian
diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md
index 7b2f842fa..82669bfb7 100644
--- a/1-js/07-object-properties/01-property-descriptors/article.md
+++ b/1-js/07-object-properties/01-property-descriptors/article.md
@@ -19,7 +19,11 @@ Properti Objek, selain sebuah **`Nilai`**, memiliki tiga atribut spesial (yang d
Kita belum melihat mereka, karena biasanya mereka tidak muncul. Ketika kita membuat sebuah properti "dengan cara biasa", Semua dari tiga attribut diatas biasanya bernilai `benar`.namun, kita juga bisa mengubahnya kapan pun kita mau.
+<<<<<<< HEAD
Pertama, mari kita lihat bagaimana cara mendapatkan properti flag tersebut.
+=======
+The method [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Pada Method [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor) memperbolehkan kita untuk melakukan query terhadap informasi *komplit* dari sebuah properti.
@@ -56,7 +60,11 @@ alert( JSON.stringify(descriptor, null, 2 ) );
*/
```
+<<<<<<< HEAD
Untuk mengganti flag tersebut, kita dapat menggunakan [Object.defineProperty](mdn:js/Object/defineProperty).
+=======
+To change the flags, we can use [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sintaksnya adalah:
@@ -125,7 +133,11 @@ Sekarang tidak ada yang dapat mengubah nama dari user kita, kecuali mereka menet
```smart header="Errors appear only in strict mode"
+<<<<<<< HEAD
Pada mode non-strict, tidak ada eror yang terjadi ketika menulis pada properti non-writable dan sejenisnya. tapi operasi itu tetap tidak akan berhasil. Aksi pelanggaran flag hanya saja diabaikan pada mode non-strict.
+=======
+In non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Berikut contoh kasus yang sama, tapi properti itu dibuat dari awal:
@@ -196,7 +208,11 @@ alert(Object.keys(user)); // name
Flag non-configurable (`configurable:false`) terkadang sudah diatur sebelumnya untuk objek dan properti bawaan.
+<<<<<<< HEAD
Sebuah properti non-configurable tidak bisa di hapus.
+=======
+A non-configurable property can't be deleted, its attributes can't be modified.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sebagai contoh, `Math.PI` adalah non-writable, non-enumerable and non-configurable:
@@ -216,12 +232,13 @@ alert( JSON.stringify(descriptor, null, 2 ) );
Jadi, seorang programer tidak akan bisa mengganti nilai dari sebuah `Math.PI` atau juga menimpanya.
```js run
-Math.PI = 3; // Error
+Math.PI = 3; // Error, because it has writable: false
// menghapus Math.PI juga tidak akan bekerja
```
Membuat sebuah properti non-configurable adalah jalan satu arah. kita tidak bisa mengubahnya kembali dengan `defineProperty`.
+<<<<<<< HEAD
Tepatnya, non-configurable memberlakukan beberapa pembatasan pada `defineProperty`:
1. tidak bisa mengubah flag `configurable` .
2. tidak bisa mengubah flag `enumerable` .
@@ -229,6 +246,22 @@ Tepatnya, non-configurable memberlakukan beberapa pembatasan pada `definePropert
4. tidak bisa mengubah `get/set` untuk sebuah properti aksesor (tapi bisa menetapkannya jika kosong).
Disini kita membuat `user.name` menjadi sebuah konstant "yang selamanya tersegel":
+=======
+We also can't change `Math.PI` to be `writable` again:
+
+```js run
+// Error, because of configurable: false
+Object.defineProperty(Math, "PI", { writable: true });
+```
+
+There's absolutely nothing we can do with `Math.PI`.
+
+Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
+
+**Please note: `configurable: false` prevents changes of property flags and its deletion, while allowing to change its value.**
+
+Here `user.name` is non-configurable, but we can still change it (as it's writable):
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
let user = {
@@ -243,7 +276,7 @@ user.name = "Pete"; // works fine
delete user.name; // Error
```
-And here we make `user.name` a "forever sealed" constant:
+And here we make `user.name` a "forever sealed" constant, just like the built-in `Math.PI`:
```js run
let user = {
@@ -265,15 +298,26 @@ Object.defineProperty(user, "name", {writable: true}); // Error
*/!*
```
+<<<<<<< HEAD
```smart header="\"Non-configurable\" doesn't mean \"non-writable\""
Catatan pengecualian: sebuah nilai dari non-configurable, tapi writable properti masih bisa diubah.
Ide dari `configurable: false` adalah untuk mencegah perubahan properti flag dan penghapusannya, bukan perubahan dalam nilainya.
+=======
+```smart header="The only attribute change possible: writable true -> false"
+There's a minor exception about changing flags.
+
+We can change `writable: true` to `false` for a non-configurable property, thus preventing its value modification (to add another layer of protection). Not the other way around though.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
## Object.defineProperties
+<<<<<<< HEAD
Ada sebuah method [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) yang memperbolehkan untuk mendefinisikan banyak properti pada satu waktu.
+=======
+There's a method [Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) that allows to define many properties at once.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sintaksnya adalah:
@@ -299,7 +343,11 @@ Jadi, kita bisa mengatur banyak properti dalam satu waktu.
## Object.getOwnPropertyDescriptors
+<<<<<<< HEAD
Untuk mendapat semua properti deskriptor pada satu waktu, kita dapat menggunakan sebuah method [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors).
+=======
+To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors).
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Bersamaan dengan `Object.defineProperties` itu dapat digunakan menjadi cara "flags-aware" untuk mengkloning sebuah objek:
@@ -318,12 +366,17 @@ for (let key in user) {
Perbedaan lainnya adalah jika `for..in` mengabaikan properti simbolik, tapi `Object.getOwnPropertyDescriptors` mengembalikan *semua* properti deskriptor termasuk properti simboliknya.
+<<<<<<< HEAD
## menyegel sebuah objek secara global
+=======
+Another difference is that `for..in` ignores symbolic and non-enumerable properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic and non-enumerable ones.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Properti deskriptor bekerja pada level invidual propertinya.
Dan ada juga method yang memberi batasan akses terkait *keselurhan* objek:
+<<<<<<< HEAD
[Object.preventExtensions(obj)](mdn:js/Object/preventExtensions)
: Melarang penambahan pada properti baru dalam objek.
@@ -332,9 +385,20 @@ Dan ada juga method yang memberi batasan akses terkait *keselurhan* objek:
[Object.freeze(obj)](mdn:js/Object/freeze)
: Melarang penambahan/pengurangan/pengubahan pada properti. Menetapkan `configurable: false, writable: false` untuk semua properti yang ada.
+=======
+[Object.preventExtensions(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
+: Forbids the addition of new properties to the object.
+
+[Object.seal(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
+: Forbids adding/removing of properties. Sets `configurable: false` for all existing properties.
+
+[Object.freeze(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
+: Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Dan ada juga test untuk mereka:
+<<<<<<< HEAD
[Object.isExtensible(obj)](mdn:js/Object/isExtensible)
: Mengembalikan `false` jika menambahkan properti itu dilarang, selain itu `true`.
@@ -343,5 +407,15 @@ Dan ada juga test untuk mereka:
[Object.isFrozen(obj)](mdn:js/Object/isFrozen)
: Mengembalikan `true` jika menambahkan/mengurangi/mengubah properti itu dilarang, dan semua properti yang sekarang memiliki `configurable: false, writable: false`.
+=======
+[Object.isExtensible(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
+: Returns `false` if adding properties is forbidden, otherwise `true`.
+
+[Object.isSealed(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
+: Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`.
+
+[Object.isFrozen(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
+: Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Method diatas biasanya jarang digunakan pada prakteknya.
diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md
index d9adfa6e1..1ad9fbe45 100644
--- a/1-js/07-object-properties/02-property-accessors/article.md
+++ b/1-js/07-object-properties/02-property-accessors/article.md
@@ -5,7 +5,11 @@ Terdapat dua jenis properti objek.
Yang pertama adalah *properti data*. Kita telah mengetahui bagaimana cara kerja mereka. Semua properti yang kita gunakan sampai sekarang adalah properti data.
+<<<<<<< HEAD
Yang kedua adalah properti yang bisa dibilang cukup baru. Properti itu adalah *properti aksesor*. Mereka sebenarnya adalah fungsi untuk mendapatkan dan mengatur sebuah nilai, tapi mereka mirip seperti properti biasa pada kode eksternal.
+=======
+The second type of property is something new. It's an *accessor property*. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Getter dan setter
diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md
index 894b47cb2..967a74dfb 100644
--- a/1-js/08-prototypes/01-prototype-inheritance/article.md
+++ b/1-js/08-prototypes/01-prototype-inheritance/article.md
@@ -54,7 +54,11 @@ alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
```
+<<<<<<< HEAD
Pada baris `(*)` menyetel `animal` untuk menjadi prototype dari `rabbit`.
+=======
+Here the line `(*)` sets `animal` to be the prototype of `rabbit`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Lalu, ketika `alert` mencoba untuk membaca properti `rabbit.eats` `(**)`, ternyata `rabbit` tidak memiliki propertinya, maka Javascript mengikuti referensi `[[Prototype]]`nya dan menemukan `animal` (mencari dari bawah ke atas):
@@ -131,9 +135,14 @@ Akan tetapi terdapat dua batasan:
Dan juga tentu saja: hanya terdapat satu `[[Prototype]]`. Sebuah objek tidak bisa mewarisi dari dua objek.
+<<<<<<< HEAD
```smart header="`__proto__` adalah asal usul getter/setter untuk `[[Prototype]]`"
Biasanya kesalan *developer* pemula adalah tidak mengetahui perbedaan antara keduanya.
+=======
+```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
+It's a common mistake of novice developers not to know the difference between these two.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Perlu diingat bahwa `__proto__` *tidak sama* dengan properti internal `[[Prototype]]`. Itu hanyalah *getter/setter* untuk `[[Prototype]]`. Nanti kita akan melihat situasi dimana hal itu akan digunakan, untuk sekarang kita hanya perlu tahu, kita akan terus bangun pemahaman kita tentang Javascript.
@@ -287,7 +296,11 @@ for(let prop in rabbit) alert(prop); // jumps, lalu eats
*/!*
```
+<<<<<<< HEAD
Jika itu bukanlah hal yang kita inginkanm dan kita ingin untuk mengecualikan properti warisan, terdapat metode bawaan [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): yang mengembalikan `true` jika `obj` memiliki properti bernama `key` (bukan properti warisan).
+=======
+If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Jadi kita bisa memisahkan properti warisan (atau melakukan sesuatu dengan properti warisan itu):
diff --git a/1-js/08-prototypes/03-native-prototypes/article.md b/1-js/08-prototypes/03-native-prototypes/article.md
index c1f70ae89..0f7db592a 100644
--- a/1-js/08-prototypes/03-native-prototypes/article.md
+++ b/1-js/08-prototypes/03-native-prototypes/article.md
@@ -2,7 +2,11 @@
Properti `"prototype"` adalah properti yang banyak digunakan oleh Javascript itu sendiri. Semua konstruktor fungsi menggunakannya.
+<<<<<<< HEAD
Pertama kita akan melihat lebih lengkapnya dan bagaimana cara menggunakannya untuk menambah kemampuan dari objek-objek bawaan.
+=======
+First we'll look at the details, and then how to use it for adding new capabilities to built-in objects.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Object.prototype
diff --git a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
index 837d34e8e..4735b9ac7 100644
--- a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
+++ b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
@@ -28,4 +28,8 @@ alert(dictionary); // "apple,__proto__"
Ketika kita membuat sebuah properti menggunakan deskriptor, tandanya akan menjadi `false` secara bawaan. Jadi kode diatas, `dictionary.toString` tidak bisa dihitung.
+<<<<<<< HEAD
Lihat bab [](info:property-descriptors) untuk review.
+=======
+See the chapter [](info:property-descriptors) for review.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md
index a4ce2646c..9c5f1eb3d 100644
--- a/1-js/08-prototypes/04-prototype-methods/article.md
+++ b/1-js/08-prototypes/04-prototype-methods/article.md
@@ -3,15 +3,18 @@
In the first chapter of this section, we mentioned that there are modern methods to setup a prototype.
-The `__proto__` is considered outdated and somewhat deprecated (in browser-only part of the JavaScript standard).
+Setting or reading the prototype with `obj.__proto__` is considered outdated and somewhat deprecated (moved to the so-called "Annex B" of the JavaScript standard, meant for browsers only).
-The modern methods are:
+The modern methods to get/set a prototype are:
-- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
- [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj`.
- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto`.
-These should be used instead of `__proto__`.
+The only usage of `__proto__`, that's not frowned upon, is as a property when creating a new object: `{ __proto__: ... }`.
+
+Although, there's a special method for this too:
+
+- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
For instance:
@@ -22,7 +25,7 @@ let animal = {
// create a new object with animal as a prototype
*!*
-let rabbit = Object.create(animal);
+let rabbit = Object.create(animal); // same as {__proto__: animal}
*/!*
alert(rabbit.eats); // true
@@ -36,7 +39,9 @@ Object.setPrototypeOf(rabbit, {}); // change the prototype of rabbit to {}
*/!*
```
-`Object.create` has an optional second argument: property descriptors. We can provide additional properties to the new object there, like this:
+The `Object.create` method is a bit more powerful, as it has an optional second argument: property descriptors.
+
+We can provide additional properties to the new object there, like this:
```js run
let animal = {
@@ -57,26 +62,34 @@ The descriptors are in the same format as described in the chapter >>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
// menjalankan Class User hanya dengan fungsi
diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md
index 742a61356..cca448000 100644
--- a/1-js/09-classes/02-class-inheritance/article.md
+++ b/1-js/09-classes/02-class-inheritance/article.md
@@ -107,7 +107,11 @@ class Rabbit extends Animal {
}
```
+<<<<<<< HEAD
Biasanya kita tidak ingin sepenuhnya mengganti metode induk, melainkan untuk membangun di atasnya untuk mengubah atau memperluas fungsinya. Kita melakukan sesuatu dalam metode kita, tetapi memanggil metode induk sebelum/sesudahnya atau dalam proses.
+=======
+Usually, however, we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Kelas menyediakan kata kunci `"super"` untuk itu.
@@ -160,7 +164,12 @@ Sekarang `Rabbit` mempunyai metode `stop` yang memanggil induk `super.stop()` di
````smart header="_Arrow functions_ tidak mempunyai `super`"
Seperti yang disebutkan di bab , _arrow functions_ tidak memiliki `super`.
+<<<<<<< HEAD
Jika diakses, itu diambil dari fungsi luar. Misalnya:
+=======
+If accessed, it's taken from the outer function. For instance:
+
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
class Rabbit extends Animal {
stop() {
@@ -177,9 +186,13 @@ setTimeout(function() { super.stop() }, 1000);
```
`````
+<<<<<<< HEAD
## Mengganti konstruktor
Dengan konstruktor, ini menjadi sedikit rumit.
+=======
+## Overriding constructor
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Sampai sekarang, `Rabbit` tidak mempunyai `constructor` sendiri.
@@ -280,7 +293,11 @@ alert(rabbit.earLength); // 10
*/!*
```
+<<<<<<< HEAD
### Mengganti bidang kelas: catatan rumit
+=======
+### Overriding class fields: a tricky note
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```warn header="Advanced note"
Catatan ini mengasumsikan kamu memiliki pengalaman tertentu dengan kelas, mungkin dalam bahasa pemrograman lain.
@@ -315,13 +332,21 @@ new Rabbit(); // animal
*/!*
```
+<<<<<<< HEAD
Di sini, kelas `Rabbit` memperluas `Animal` dan mengganti bidang `nama` dengan nilainya sendiri.
+=======
+Here, class `Rabbit` extends `Animal` and overrides the `name` field with its own value.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Tidak ada konstruktor sendiri dalam `Rabbit`, jadi konstruktor `Animal` dipanggil.
Yang menarik adalah dalam kedua kasus: `new Animal()` dan `new Rabbit()`, `alert` di baris `(*)` menampilkan `animal`.
+<<<<<<< HEAD
**Dengan kata lain, konstruktor induk selalu menggunakan nilai bidangnya sendiri, bukan yang diganti.**
+=======
+**In other words, the parent constructor always uses its own field value, not the overridden one.**
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Apa yang aneh tentang itu?
@@ -358,24 +383,40 @@ Dan itulah yang secara natural kita harapkan. Ketika konstruktor induk dipanggil
...Tetapi untuk bidang kelas tidak demikian. Seperti yang dikatakan, konstruktor induk selalu menggunakan bidang induk.
+<<<<<<< HEAD
Mengapa ada bedanya?
Nah, alasannya ada di urutan bidang inisialisasi. Bidang kelas diinisialisasi:
+=======
+Why is there a difference?
+
+Well, the reason is the field initialization order. The class field is initialized:
+- Before constructor for the base class (that doesn't extend anything),
+- Immediately after `super()` for the derived class.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
- Sebelum konstruktor untuk kelas dasar (yang tidak memperluas apa pun),
- Langsung setelah `super()` untuk kelas turunan.
Dalam kasus kita, `Rabbit` adalah kelas turunannya. Tidak ada `constructor()` di dalamnya. Seperti yang dikatakan sebelumnya, itu sama seperti jika ada konstruktor kosong hanya dengan `super(...args)`.
+<<<<<<< HEAD
Jadi, `new Rabbit()` memanggil `super()`, sehingga mengeksekusi konstruktor induk, dan (sesuai aturan untuk kelas turunan) hanya setelah bidang kelasnya diinisialisasi. Pada saat eksekusi induk konstruktor, belum ada bidang kelas `Rabbit`, itulah mengapa bidang `Animal` digunakan.
+=======
+This subtle difference between fields and methods is specific to JavaScript.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Perbedaan halus antara bidang dan metode ini khusus untuk JavaScript
Untungnya, perilaku ini hanya muncul dengan sendirinya jika bidang yang diganti digunakan di konstruktor induk. Maka mungkin sulit untuk memahami apa yang sedang terjadi, jadi kita menjelaskannya di sini.
+<<<<<<< HEAD
Jika ini menjadi masalah, seseorang dapat memperbaikinya dengan menggunakan metode atau _getter_/_setter_ sebagai ganti bidang.
## _Super: internals, [[HomeObject]]_
+=======
+## Super: internals, [[HomeObject]]
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```warn header="Advanced information"
Jika Anda membaca tutorial untuk pertama kali - bagian ini mungkin dilewati.
diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
index 3a1179b20..6435be8c2 100644
--- a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
+++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
@@ -21,14 +21,22 @@ alert( rabbit.hasOwnProperty('name') ); // true
Tapi itu belum semuanya.
+<<<<<<< HEAD
Bahkan setelah perbaikan, masih ada perbedaan penting dalam `"class Rabbit extends Object"` versus `class Rabbit`.
+=======
+Even after the fix, there's still an important difference between `"class Rabbit extends Object"` and `class Rabbit`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Seperti yang kita tahu, sintaks "extends" menyiapkan dua prototipe:
1. Antara `"prototype"` dari fungsi konstruktor (untuk metode).
2. Antara konstruktor berfungsi sendiri (untuk metode statis).
+<<<<<<< HEAD
Dalam kasus kita, untuk `class Rabbit extends Object` itu berarti:
+=======
+In the case of `class Rabbit extends Object` it means:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class Rabbit extends Object {}
@@ -37,7 +45,11 @@ alert(Rabbit.prototype.__proto__ === Object.prototype); // (1) true
alert(Rabbit.__proto__ === Object); // (2) true
```
+<<<<<<< HEAD
Jadi `Rabbit` sekarang menyediakan akses ke metode statis `Object` melalui `Rabbit`, seperti ini:
+=======
+So `Rabbit` now provides access to the static methods of `Object` via `Rabbit`, like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class Rabbit extends Object {}
@@ -67,7 +79,11 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
Jadi `Rabbit` tidak menyediakan akses ke metode statis `Object` dalam hal itu.
+<<<<<<< HEAD
Ngomong-ngomong, `Function.prototype` mempunyai fungsi metode "generic", seperti `call`, `bind` dll. Mereka terakhir tersedia dalam kedua kasus, karena untuk konstruktor `Object` bawaan, `Object.__proto__ === Function.prototype`.
+=======
+By the way, `Function.prototype` also has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Berikut gambarnya:
diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md
index a0a6b50db..f3f019c41 100644
--- a/1-js/09-classes/03-static-properties-methods/article.md
+++ b/1-js/09-classes/03-static-properties-methods/article.md
@@ -2,7 +2,13 @@
Kita juga dapat menetapkan metode ke fungsi kelas itu sendiri, bukan ke `" prototipe "`-nya. Metode seperti itu disebut _static_.
+<<<<<<< HEAD
Di dalam kelas, mereka ditambahkan oleh kata kunci `static`, seperti ini:
+=======
+We can also assign a method to the class as a whole. Such methods are called *static*.
+
+In a class declaration, they are prepended by `static` keyword, like this:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class User {
@@ -30,9 +36,17 @@ User.staticMethod(); // true
Nilai `this` dalam panggilan `User.staticMethod()` adalah konstruktor kelas `User` itu sendiri (aturan "object before dot").
+<<<<<<< HEAD
Biasanya, metode statis digunakan untuk mengimplementasikan fungsi yang dimiliki kelas, tetapi tidak untuk objek tertentu darinya.
Misalnya, kita punya objek `Article` dan membutuhkan sebuah fungsi untuk membandingkan mereka. Solusi natural adalah menambahkan metode `Article.compare`, seperti ini:
+=======
+Usually, static methods are used to implement functions that belong to the class as a whole, but not to any particular object of it.
+
+For instance, we have `Article` objects and need a function to compare them.
+
+A natural solution would be to add `Article.compare` static method:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class Article {
@@ -62,9 +76,17 @@ articles.sort(Article.compare);
alert( articles[0].title ); // CSS
```
+<<<<<<< HEAD
Di sini `Article.compare` berdiri "di atas" _articles_, sebagai alat untuk membandingkannya. Ini bukan metode _article_, melainkan seluruh kelas.
Contoh lain adalah apa yang disebut metode "factory". Bayangkan, kita butuh beberapa cara untuk membuat _article_:
+=======
+Here `Article.compare` method stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
+
+Another example would be a so-called "factory" method.
+
+Let's say, we need multiple ways to create an article:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
1. Buat dengan parameter yang diberikan (`title`, `date` dsb).
2. Buat _article_ kosong dengan tanggal hari ini.
@@ -72,7 +94,11 @@ Contoh lain adalah apa yang disebut metode "factory". Bayangkan, kita butuh bebe
Cara pertama dapat diterapkan oleh konstruktor. Dan untuk yang kedua kita bisa membuat metode statis kelas.
+<<<<<<< HEAD
Seperti `Article.createTodays()` di sini:
+=======
+Such as `Article.createTodays()` here:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class Article {
@@ -99,12 +125,32 @@ Sekarang setiap kali kita perlu membuat _today's digest_, kita dapat memanggil `
Metode statis juga digunakan dalam kelas terkait basis data untuk mencari/menyimpan/menghapus entri dari basis data, seperti ini:
```js
+<<<<<<< HEAD
// dengan asumsi Article adalah kelas khusus untuk mengelola articles
// metode statis untuk menghapus article:
Article.remove({ id: 12345 });
```
## Properti Statis
+=======
+// assuming Article is a special class for managing articles
+// static method to remove the article by id:
+Article.remove({id: 12345});
+```
+
+````warn header="Static methods aren't available for individual objects"
+Static methods are callable on classes, not on individual objects.
+
+E.g. such code won't work:
+
+```js
+// ...
+article.createTodays(); /// Error: article.createTodays is not a function
+```
+````
+
+## Static properties
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
[recent browser=Chrome]
diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md
index 00c5748c8..b15f21ed0 100644
--- a/1-js/09-classes/04-private-protected-properties-methods/article.md
+++ b/1-js/09-classes/04-private-protected-properties-methods/article.md
@@ -112,8 +112,13 @@ class CoffeeMachine {
// membuat mesin kopi
let coffeeMachine = new CoffeeMachine(100);
+<<<<<<< HEAD
// tambahkan air
coffeeMachine.waterAmount = -10; // Error: Negative water
+=======
+// add water
+coffeeMachine.waterAmount = -10; // _waterAmount will become 0, not -10
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```
Sekarang aksesnya terkendali, jadi pengaturan air di bawah nol gagal.
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index 8bbd94b09..57af23879 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -93,7 +93,7 @@ Algoritma `obj instanceof Class` bekerja kurang lebih sebgai berikut:
alert(rabbit instanceof Animal); // true
*/!*
- // rabbit.__proto__ === Rabbit.prototype
+ // rabbit.__proto__ === Animal.prototype (no match)
*!*
// rabbit.__proto__.__proto__ === Animal.prototype (match!)
*/!*
diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md
index 081141339..f47e41f0b 100644
--- a/1-js/09-classes/07-mixins/article.md
+++ b/1-js/09-classes/07-mixins/article.md
@@ -103,7 +103,11 @@ Berikut diagramnya (lihat bagian kanan):
Itu karena metode `sayHi` dan `sayBye` awalnya dibuat di `sayHiMixin`. Jadi, meskipun disalin, properti internal `[[HomeObject]]` mereferensikan `sayHiMixin`, seperti yang ditunjukkan pada gambar di atas.
+<<<<<<< HEAD
Karena `super` mencari metode induk di `[[HomeObject]].[[Prototype]]`, itu berarti mencari `sayHiMixin.[[Prototype]]`, bukan `User.[[Prototype]]`.
+=======
+As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Peristiwa _Mixin_
diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md
index a90f95819..1dd9240ce 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -633,7 +633,11 @@ Sebagai contoh:
Peran dari global handler `window.onerror` biasanya bukan untuk memulihkan eksekusi dari kodingannya - itu biasanya tidak mungkin jika terjadi kesalahan pemrograman, namun tugasnya adalah untuk mengirim pesan eror ke pengembang.
+<<<<<<< HEAD
Ada juga layanan web yang menyediakan pencatatan eror untuk kasus seperti itu, seperti or .
+=======
+There are also web-services that provide error-logging for such cases, like or .
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
Mereka bekerja seperti ini:
diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md
index e598cd666..8b61fbc39 100644
--- a/1-js/10-error-handling/2-custom-errors/article.md
+++ b/1-js/10-error-handling/2-custom-errors/article.md
@@ -22,9 +22,15 @@ Secara internal, kita akan menggunakan `JSON.parse`. Jika menerima `json` yang s
Fungsi kita `readUser(json)` tidak hanya akan membaca JSON, tetapi juga memeriksa ("memvalidasi") data. Jika tidak ada bidang yang wajib diisi, atau formatnya salah, itu adalah kesalahan. Dan itu bukan `SyntaxError`, karena datanya benar secara sintaksis, tetapi jenis kesalahan lain. Kita akan menyebutnya `ValidationError` dan membuat kelas untuk itu. Kesalahan semacam itu juga harus membawa informasi tentang bidang yang melanggar.
+<<<<<<< HEAD
Kelas `ValidationError` kita harus mewarisi dari kelas `Error` bawaan.
Kelas itu sudah ada di dalamnya, tetapi berikut ini kode perkiraannya sehingga kita dapat memahami apa yang kita perluas:
+=======
+Our `ValidationError` class should inherit from the `Error` class.
+
+The `Error` class is built-in, but here's its approximate code so we can understand what we're extending:
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js
// "Kode semu" untuk kelas Kesalahan bawaan yang ditentukan oleh JavaScript itu sendiri
@@ -39,7 +45,7 @@ class Error {
Sekarang mari kita mewarisi `ValidationError` darinya dan mencobanya dalam tindakan:
-```js run untrusted
+```js run
*!*
class ValidationError extends Error {
*/!*
@@ -122,11 +128,19 @@ Kita juga bisa melihat `err.name`, seperti ini:
Versi `instanceof` jauh lebih baik, karena di masa mendatang kita akan memperluas `ValidationError`, membuat subtipe darinya, seperti `PropertyRequiredError`. Dan pemeriksaan `instanceof` akan terus berfungsi untuk kelas pewaris baru. Jadi itu bukti masa depan.
+<<<<<<< HEAD
Juga penting bahwa jika `catch` menemui kesalahan yang tidak diketahui, maka itu akan ditarik kembali di baris `(**)`. Blok `catch` hanya mengetahui cara menangani validasi dan kesalahan sintaksis, jenis lain (karena kesalahan ketik pada kode atau kesalahan lain yang tidak diketahui) akan gagal.
+=======
+Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (caused by a typo in the code or other unknown reasons) should fall through.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
## Warisan lebih lanjut
+<<<<<<< HEAD
Kelas `ValidationError` sangat umum. Banyak hal mungkin salah. Properti mungkin tidak ada atau mungkin dalam format yang salah (seperti nilai string untuk `age`). Mari kita buat kelas yang lebih konkret `PropertyRequiredError`, tepatnya untuk properti yang tidak ada. Ini akan membawa informasi tambahan tentang properti yang hilang.
+=======
+The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age` instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
+>>>>>>> 3d7abb9cc8fa553963025547717f06f126c449b6
```js run
class ValidationError extends Error {
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index 8daa4f08d..12b843dd8 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -28,7 +28,11 @@ function loadScript(src) {
}
```
+<<<<<<< HEAD
Fungsi tersebut menambahkan ke dokumen baru, dibuat secara dinamis, tag `
+