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 ca9e80601..3a1179b20 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 @@ -1,14 +1,14 @@ -First, let's see why the latter code doesn't work. +Pertama, mari kita lihat mengapa kode terakhir tidak berfungsi. -The reason becomes obvious if we try to run it. An inheriting class constructor must call `super()`. Otherwise `"this"` won't be "defined". +Alasannya menjadi jelas jika kita mencoba menjalankannya. Konstruktor kelas yang mewarisi harus memanggil `super()`. Jika tidak, `"this"` tidak akan "defined". -So here's the fix: +Jadi, inilah perbaikannya: ```js run class Rabbit extends Object { constructor(name) { *!* - super(); // need to call the parent constructor when inheriting + super(); // perlu memanggil konstruktor induk saat mewarisi */!* this.name = name; } @@ -19,63 +19,63 @@ let rabbit = new Rabbit("Rab"); alert( rabbit.hasOwnProperty('name') ); // true ``` -But that's not all yet. +Tapi itu belum semuanya. -Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`. +Bahkan setelah perbaikan, masih ada perbedaan penting dalam `"class Rabbit extends Object"` versus `class Rabbit`. -As we know, the "extends" syntax sets up two prototypes: +Seperti yang kita tahu, sintaks "extends" menyiapkan dua prototipe: -1. Between `"prototype"` of the constructor functions (for methods). -2. Between the constructor functions themselves (for static methods). +1. Antara `"prototype"` dari fungsi konstruktor (untuk metode). +2. Antara konstruktor berfungsi sendiri (untuk metode statis). -In our case, for `class Rabbit extends Object` it means: +Dalam kasus kita, untuk `class Rabbit extends Object` itu berarti: ```js run class Rabbit extends Object {} -alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true -alert( Rabbit.__proto__ === Object ); // (2) true +alert(Rabbit.prototype.__proto__ === Object.prototype); // (1) true +alert(Rabbit.__proto__ === Object); // (2) true ``` -So `Rabbit` now provides access to static methods of `Object` via `Rabbit`, like this: +Jadi `Rabbit` sekarang menyediakan akses ke metode statis `Object` melalui `Rabbit`, seperti ini: ```js run class Rabbit extends Object {} *!* -// normally we call Object.getOwnPropertyNames +// biasanya kita sebut Object.getOwnPropertyNames alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b */!* ``` -But if we don't have `extends Object`, then `Rabbit.__proto__` is not set to `Object`. +Tetapi jika kita tidak punya `extends Object`, lalu `Rabbit.__proto__` tidak diatur ke `Object`. -Here's the demo: +Berikut demo nya: ```js run class Rabbit {} alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true alert( Rabbit.__proto__ === Object ); // (2) false (!) -alert( Rabbit.__proto__ === Function.prototype ); // as any function by default +alert( Rabbit.__proto__ === Function.prototype ); // sebagai fungsi apa pun secara default *!* -// error, no such function in Rabbit +// error, tidak ada fungsi seperti itu di Rabbit alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error */!* ``` -So `Rabbit` doesn't provide access to static methods of `Object` in that case. +Jadi `Rabbit` tidak menyediakan akses ke metode statis `Object` dalam hal itu. -By the way, `Function.prototype` 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`. +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`. -Here's the picture: +Berikut gambarnya: ![](rabbit-extends-object.svg) -So, to put it short, there are two differences: +Jadi, sederhananya, ada dua perbedaan: -| class Rabbit | class Rabbit extends Object | -|--------------|------------------------------| -| -- | needs to call `super()` in constructor | -| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` | +| class Rabbit | class Rabbit extends Object | +| ----------------------------------------- | -------------------------------------- | +| -- | needs to call `super()` in constructor | +| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` | diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md index 1d0f98a74..def0e77cf 100644 --- a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md @@ -2,11 +2,11 @@ importance: 3 --- -# Class extends Object? +# _Class extends Object?_ -As we know, all objects normally inherit from `Object.prototype` and get access to "generic" object methods like `hasOwnProperty` etc. +Seperti yang kita ketahui, semua objek biasanya diwarisi dari `Object.prototype` dan mendapatkan akses ke metode objek "generic" seperti `hasOwnProperty` dll. -For instance: +Misalnya: ```js run class Rabbit { @@ -18,16 +18,16 @@ class Rabbit { let rabbit = new Rabbit("Rab"); *!* -// hasOwnProperty method is from Object.prototype +// metode hasOwnProperty dari Object.prototype alert( rabbit.hasOwnProperty('name') ); // true */!* ``` -But if we spell it out explicitly like `"class Rabbit extends Object"`, then the result would be different from a simple `"class Rabbit"`? +Tapi jika kita mengejanya secara eksplisit seperti `"class Rabbit extends Object"`, maka hasilnya akan berbeda dari `"class Rabbit"`? -What's the difference? +Apa perbedaannya? -Here's an example of such code (it doesn't work -- why? fix it?): +Berikut contoh kodenya (tidak berhasil -- mengapa? memperbaikinya?): ```js class Rabbit extends Object { @@ -36,7 +36,7 @@ class Rabbit extends Object { } } -let rabbit = new Rabbit("Rab"); +let rabbit = new Rabbit('Rab'); -alert( rabbit.hasOwnProperty('name') ); // Error +alert(rabbit.hasOwnProperty('name')); // Error ``` 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 ab08f2ded..61b7d56fc 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -1,9 +1,8 @@ +# Properti dan metode statis -# Static properties and methods +Kita juga dapat menetapkan metode ke fungsi kelas itu sendiri, bukan ke `" prototipe "`-nya. Metode seperti itu disebut _static_. -We can also assign a method to the class function itself, not to its `"prototype"`. Such methods are called *static*. - -In a class, they are prepended by `static` keyword, like this: +Di dalam kelas, mereka ditambahkan oleh kata kunci `static`, seperti ini: ```js run class User { @@ -17,23 +16,23 @@ class User { User.staticMethod(); // true ``` -That actually does the same as assigning it as a property directly: +Itu sebenarnya sama dengan menetapkannya sebagai properti secara langsung: ```js run -class User { } +class User {} -User.staticMethod = function() { +User.staticMethod = function () { alert(this === User); }; User.staticMethod(); // true ``` -The value of `this` in `User.staticMethod()` call is the class constructor `User` itself (the "object before dot" rule). +Nilai `this` dalam panggilan `User.staticMethod()` adalah konstruktor kelas `User` itu sendiri (aturan "object before dot"). -Usually, static methods are used to implement functions that belong to the class, but not to any particular object of it. +Biasanya, metode statis digunakan untuk mengimplementasikan fungsi yang dimiliki kelas, tetapi tidak untuk objek tertentu darinya. -For instance, we have `Article` objects and need a function to compare them. A natural solution would be to add `Article.compare` method, like this: +Misalnya, kita punya objek `Article` dan membutuhkan sebuah fungsi untuk membandingkan mereka. Solusi natural adalah menambahkan metode `Article.compare`, seperti ini: ```js run class Article { @@ -49,7 +48,7 @@ class Article { */!* } -// usage +// penggunaan let articles = [ new Article("HTML", new Date(2019, 1, 1)), new Article("CSS", new Date(2019, 0, 1)), @@ -63,17 +62,17 @@ articles.sort(Article.compare); alert( articles[0].title ); // CSS ``` -Here `Article.compare` stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class. +Di sini `Article.compare` berdiri "di atas" _articles_, sebagai alat untuk membandingkannya. Ini bukan metode _article_, melainkan seluruh kelas. -Another example would be a so-called "factory" method. Imagine, we need few ways to create an article: +Contoh lain adalah apa yang disebut metode "factory". Bayangkan, kita butuh beberapa cara untuk membuat _article_: -1. Create by given parameters (`title`, `date` etc). -2. Create an empty article with today's date. -3. ...or else somehow. +1. Buat dengan parameter yang diberikan (`title`, `date` dsb). +2. Buat _article_ kosong dengan tanggal hari ini. +3. ...atau yang lainnya. -The first way can be implemented by the constructor. And for the second one we can make a static method of the class. +Cara pertama dapat diterapkan oleh konstruktor. Dan untuk yang kedua kita bisa membuat metode statis kelas. -Like `Article.createTodays()` here: +Seperti `Article.createTodays()` di sini: ```js run class Article { @@ -84,7 +83,7 @@ class Article { *!* static createTodays() { - // remember, this = Article + // ingat, this = Article return new this("Today's digest", new Date()); } */!* @@ -95,41 +94,41 @@ let article = Article.createTodays(); alert( article.title ); // Today's digest ``` -Now every time we need to create a today's digest, we can call `Article.createTodays()`. Once again, that's not a method of an article, but a method of the whole class. +Sekarang setiap kali kita perlu membuat _today's digest_, kita dapat memanggil `Article.createTodays()`. Sekali lagi, itu bukan metode _article_, tapi metode seluruh kelas. -Static methods are also used in database-related classes to search/save/remove entries from the database, like this: +Metode statis juga digunakan dalam kelas terkait basis data untuk mencari/menyimpan/menghapus entri dari basis data, seperti ini: ```js -// assuming Article is a special class for managing articles -// static method to remove the article: -Article.remove({id: 12345}); +// dengan asumsi Article adalah kelas khusus untuk mengelola articles +// metode statis untuk menghapus article: +Article.remove({ id: 12345 }); ``` -## Static properties +## Properti Statis [recent browser=Chrome] -Static properties are also possible, they look like regular class properties, but prepended by `static`: +Properti statis juga dimungkinkan, mereka terlihat seperti properti kelas biasa, tetapi diawali dengan `static`: ```js run class Article { - static publisher = "Ilya Kantor"; + static publisher = 'Ilya Kantor'; } -alert( Article.publisher ); // Ilya Kantor +alert(Article.publisher); // Ilya Kantor ``` -That is the same as a direct assignment to `Article`: +Itu sama dengan penugasan langsung ke `Article`: ```js -Article.publisher = "Ilya Kantor"; +Article.publisher = 'Ilya Kantor'; ``` -## Inheritance of static properties and methods +## Pewarisan properti dan metode statis -Static properties and methods are inherited. +Properti dan metode statis diwarisi. -For instance, `Animal.compare` and `Animal.planet` in the code below are inherited and accessible as `Rabbit.compare` and `Rabbit.planet`: +Misalnya, `Animal.compare` dan `Animal.planet` dalam kode di bawah ini diwariskan dan dapat diakses sebagai `Rabbit.compare` dan `Rabbit.planet`: ```js run class Animal { @@ -153,7 +152,7 @@ class Animal { } -// Inherit from Animal +// Mewarisi dari Animal class Rabbit extends Animal { hide() { alert(`${this.name} hides!`); @@ -174,43 +173,43 @@ rabbits[0].run(); // Black Rabbit runs with speed 5. alert(Rabbit.planet); // Earth ``` -Now when we call `Rabbit.compare`, the inherited `Animal.compare` will be called. +Sekarang kita dapat memanggil `Rabbit.compare`, yang diwariskan `Animal.compare` akan dipanggil. -How does it work? Again, using prototypes. As you might have already guessed, `extends` gives `Rabbit` the `[[Prototype]]` reference to `Animal`. +Bagaimana cara kerjanya? Sekali lagi, menggunakan prototipe. Seperti yang mungkin sudah kamu duga, `extends` memberi `Rabbit` sebagai `[[Prototype]]` mengacu kepada `Animal`. ![](animal-rabbit-static.svg) -So, `Rabbit extends Animal` creates two `[[Prototype]]` references: +Jadi, `Rabbit extends Animal` membuat dua acuan `[[Prototype]]`: -1. `Rabbit` function prototypally inherits from `Animal` function. -2. `Rabbit.prototype` prototypally inherits from `Animal.prototype`. +1. `Rabbit` fungsi _prototypally_ mewarisi dari fungsi `Animal`. +2. `Rabbit.prototype` _prototypally_ mewarisi dari `Animal.prototype`. -As a result, inheritance works both for regular and static methods. +Hasilnya, pewarisan berfungsi baik untuk metode reguler dan statis. -Here, let's check that by code: +Di sini, mari kita periksa dengan kode: ```js run class Animal {} class Rabbit extends Animal {} -// for statics +// untuk statis alert(Rabbit.__proto__ === Animal); // true -// for regular methods +// untuk metode reguler alert(Rabbit.prototype.__proto__ === Animal.prototype); // true ``` -## Summary +## Ringkasan -Static methods are used for the functionality that belongs to the class "as a whole". It doesn't relate to a concrete class instance. +Metode statis digunakan untuk fungsionalitas yang termasuk dalam kelas "secara keseluruhan". Ini tidak terkait dengan instance kelas konkret. -For example, a method for comparison `Article.compare(article1, article2)` or a factory method `Article.createTodays()`. +Sebagai contoh, metode perbandingan `Article.compare(article1, article2)` atau metode _factory_ `Article.createTodays()`. -They are labeled by the word `static` in class declaration. +Mereka diberi label dengan kata `static` dalam deklarasi kelas. -Static properties are used when we'd like to store class-level data, also not bound to an instance. +Properti statis digunakan ketika kita ingin menyimpan data tingkat kelas, juga tidak terikat pada sebuah _instance_. -The syntax is: +Sintaksnya adalah: ```js class MyClass { @@ -222,13 +221,13 @@ class MyClass { } ``` -Technically, static declaration is the same as assigning to the class itself: +Secara teknis, deklarasi statis sama dengan menetapkan ke kelas itu sendiri: ```js MyClass.property = ... MyClass.method = ... ``` -Static properties and methods are inherited. +Properti dan metode statis diwarisi. -For `class B extends A` the prototype of the class `B` itself points to `A`: `B.[[Prototype]] = A`. So if a field is not found in `B`, the search continues in `A`. +Untuk `class B extends A` prototipe dari kelas `B` itu sendiri menunjuk ke `A`: `B.[[Prototype]] = A`. Jadi jika bidang tidak ditemukan di `B`, pencarian dilanjutkan di `A`.