Skip to content

Commit fc365e5

Browse files
authored
Merge pull request #188 from yoga1234/master
Translation
2 parents d4e6885 + f85ae32 commit fc365e5

File tree

1 file changed

+81
-81
lines changed
  • 1-js/08-prototypes/01-prototype-inheritance

1 file changed

+81
-81
lines changed

1-js/08-prototypes/01-prototype-inheritance/article.md

Lines changed: 81 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
# Prototypal inheritance
1+
# Pewarisan *Prototype* (*Prototypal Inheritance*)
22

3-
In programming, we often want to take something and extend it.
3+
Dalam *programming*, terkadang kita ingin mengambil sesuatu lalu dikembangkan lagi.
44

5-
For instance, we have a `user` object with its properties and methods, and want to make `admin` and `guest` as slightly modified variants of it. We'd like to reuse what we have in `user`, not copy/reimplement its methods, just build a new object on top of it.
5+
Contoh, kita memiliki objek `user` lengkap dengan properti dan metodenya, dan kita ingin membuat `admin` dan `guest` sebagai varian yang sedikit diubah dari objek `user`. Kita ingin menggunakan apa yang dimiliki oleh `user`, bukan menyalin ataupun meimplementasikan ulang metode-metodenya, akan tetapi menciptakan objek baru diatasnya.
66

7-
*Prototypal inheritance* is a language feature that helps in that.
7+
*Pewarisan Prototype* adalah fitur yang bisa membantu untuk melakukan hal itu.
88

99
## [[Prototype]]
1010

11-
In JavaScript, objects have a special hidden property `[[Prototype]]` (as named in the specification), that is either `null` or references another object. That object is called "a prototype":
11+
Didalam Javascript, objek memiliki properti tersembunyi yang spesial `[[Prototype]]` (seperti yang dinamakan didalam spesifikasinya), yang mana dapat mereferensi pada `null` atau mereferensi pada objek lainnya. Objek itu disebut dengan *prototype*:
1212

1313
![prototype](object-prototype-empty.svg)
1414

15-
When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it.
15+
Ketika kita membaca properti dari sebuah objek dan ternyata propertinya tidak ada, maka Javascript akan secara otomatis mengambilnya dari *prototype*nya. Dialam pemrograman, hal ini disebut dengan "Pewarisan *prototype*" atau *Prototypal Inheritance*. Dan tidak lama lagi kita akan belajar banyak contoh-contoh pewarisan, sama seperti banyak bahasa yang menggunakannya.
1616

17-
The property `[[Prototype]]` is internal and hidden, but there are many ways to set it.
17+
Properti yang dimiliki `[[Prototype]]` bersifat internal dan tersembunyi, tapi ada banyak cara untuk melihat properti tersebut.
1818

19-
One of them is to use the special name `__proto__`, like this:
19+
Salah satunya adalah menggunakan nama spesial `__proto__`, seperti:
2020

2121
```js run
2222
let animal = {
@@ -31,9 +31,9 @@ rabbit.__proto__ = animal; // sets rabbit.[[Prototype]] = animal
3131
*/!*
3232
```
3333

34-
Now if we read a property from `rabbit`, and it's missing, JavaScript will automatically take it from `animal`.
34+
Sekarang jika kita ingin membaca properti dari `rabbit`, dan ternyada tidak ada, Javascript akan mengambilnya dari `animal`.
3535

36-
For instance:
36+
Contoh:
3737

3838
```js
3939
let animal = {
@@ -47,24 +47,24 @@ let rabbit = {
4747
rabbit.__proto__ = animal; // (*)
4848
*/!*
4949

50-
// we can find both properties in rabbit now:
50+
// sekarang kita bisa menggunakan kedua propertinya didalam *rabbit*:
5151
*!*
5252
alert( rabbit.eats ); // true (**)
5353
*/!*
5454
alert( rabbit.jumps ); // true
5555
```
5656

57-
Here the line `(*)` sets `animal` to be a prototype of `rabbit`.
57+
Pada baris `(*)` menyetel `animal` untuk menjadi prototype dari `rabbit`.
5858

59-
Then, when `alert` tries to read property `rabbit.eats` `(**)`, it's not in `rabbit`, so JavaScript follows the `[[Prototype]]` reference and finds it in `animal` (look from the bottom up):
59+
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):
6060

6161
![](proto-animal-rabbit.svg)
6262

63-
Here we can say that "`animal` is the prototype of `rabbit`" or "`rabbit` prototypically inherits from `animal`".
63+
Disini kita bisa berkata bahwa "`animal` adalah prototype dari `rabbit`" atau "`rabbit` secara prototype mewarisi dari `animal`".
6464

65-
So if `animal` has a lot of useful properties and methods, then they become automatically available in `rabbit`. Such properties are called "inherited".
65+
Jadi jika `animal` memiliki banyak properti dan metode yang berguna, maka properti dan metode tersebut secara otomatis akan tersedia didalam `rabbit`. Properti tersebut dinamakan "pewarisan".
6666

67-
If we have a method in `animal`, it can be called on `rabbit`:
67+
Jika kita memiliki metode didalam `animal`, maka metode tersebut dapat dipanggil didalam `rabbit`:
6868

6969
```js run
7070
let animal = {
@@ -81,17 +81,17 @@ let rabbit = {
8181
__proto__: animal
8282
};
8383

84-
// walk is taken from the prototype
84+
// walk diambil dari prototype
8585
*!*
8686
rabbit.walk(); // Animal walk
8787
*/!*
8888
```
8989

90-
The method is automatically taken from the prototype, like this:
90+
Metodenya secara otomatis diambil dari *prototype*nya, seperti:
9191

9292
![](proto-animal-rabbit-walk.svg)
9393

94-
The prototype chain can be longer:
94+
Rantai *prototype* bisa lebih panjang:
9595

9696
```js run
9797
let animal = {
@@ -115,48 +115,48 @@ let longEar = {
115115
*/!*
116116
};
117117

118-
// walk is taken from the prototype chain
118+
// walk diambil dari rantai prototype
119119
longEar.walk(); // Animal walk
120-
alert(longEar.jumps); // true (from rabbit)
120+
alert(longEar.jumps); // true (dari rabbit)
121121
```
122122

123123
![](proto-animal-rabbit-chain.svg)
124124

125-
Now if we read something from `longEar`, and it's missing, JavaScript will look for it in `rabbit`, and then in `animal`.
125+
Sekarang jika kita membaca sesuatu dari `longEar`, dan ternyata tidak ada, Javascript akan mencarinya didalam `rabbit`, dan lalu didalam `animal`.
126126

127-
There are only two limitations:
127+
Akan tetapi terdapat dua batasan:
128128

129-
1. The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__` in a circle.
130-
2. The value of `__proto__` can be either an object or `null`. Other types are ignored.
129+
1. Referensinya tidak bisa berputar (seperti lingkaran atau perulangan tak terhingga). Javascript akan mengembalikan error jika kita mencoba untuk membuat `__proto__` berputar.
130+
2. Nilai dari `__proto__` bisa antara sebuah objek atau `null`. Tipe lainnya akan diabaikan.
131131

132-
Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
132+
Dan juga tentu saja: hanya terdapat satu `[[Prototype]]`. Sebuah objek tidak bisa mewarisi dari dua objek.
133133

134134

135-
```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
136-
It's a common mistake of novice developers not to know the difference between these two.
135+
```smart header="`__proto__` adalah asal usul getter/setter untuk `[[Prototype]]`"
136+
Biasanya kesalan *developer* pemula adalah tidak mengetahui perbedaan antara keduanya.
137137

138-
Please note that `__proto__` is *not the same* as the internal `[[Prototype]]` property. It's a getter/setter for `[[Prototype]]`. Later we'll see situations where it matters, for now let's just keep it in mind, as we build our understanding of JavaScript language.
138+
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.
139139

140-
The `__proto__` property is a bit outdated. It exists for historical reasons, modern JavaScript suggests that we should use `Object.getPrototypeOf/Object.setPrototypeOf` functions instead that get/set the prototype. We'll also cover these functions later.
140+
Properti `__proto__` sedikit ketinggalan jaman. Properti tersebut ada karena alasan lama, pada Javascript terbaru merekomendasikan kita untuk menggunakan fungsi `Object.getPrototypeOf/Object.setPrototypeOf` daripada *prototype* get/set. Kita akan belajar tentang fungsi ini nanti.
141141

142-
By the specification, `__proto__` must only be supported by browsers. In fact though, all environments including server-side support `__proto__`, so we're quite safe using it.
142+
Dari spesifikasinya, `__proto__` telah didukung oleh banyak *browser*. Faktanya, seluruh lingkungan termasuk dibagian *server* juga mendukung `__proto__`, jadi kita aman untuk menggunakannya.
143143

144-
As the `__proto__` notation is a bit more intuitively obvious, we use it in the examples.
144+
Karena notasi `__proto__` sedikit lebih jelas, kita akan menggunakannya didalam contoh.
145145
```
146146
147-
## Writing doesn't use prototype
147+
## Menulis tanpa menggunakan *prototype*
148148
149-
The prototype is only used for reading properties.
149+
*Prototype* hanya digunakan untuk membaca properti.
150150
151-
Write/delete operations work directly with the object.
151+
Operasi menulis / menghapus bekerja secara langsung dengan objeknya.
152152
153-
In the example below, we assign its own `walk` method to `rabbit`:
153+
Didalam contoh dibawah, kita memasukan metode `walk` kedalam `rabbit`:
154154
155155
```js run
156156
let animal = {
157157
eats: true,
158158
walk() {
159-
/* this method won't be used by rabbit */
159+
/* metode ini tidak akan digunakan oleh rabbit */
160160
}
161161
};
162162
@@ -173,13 +173,13 @@ rabbit.walk = function() {
173173
rabbit.walk(); // Rabbit! Bounce-bounce!
174174
```
175175

176-
From now on, `rabbit.walk()` call finds the method immediately in the object and executes it, without using the prototype:
176+
Mulai sekarang, pemanggilan `rabbit.walk()` akan menemukan metodenya secara langsung didalam objek dan langsung dieksekusi tanpa menggunakan *prototype*:
177177

178178
![](proto-animal-rabbit-walk-2.svg)
179179

180-
Accessor properties are an exception, as assignment is handled by a setter function. So writing to such a property is actually the same as calling a function.
180+
Properti pengakses adalah pengecualian, sebagaimana memasukan nilai dipegang oleh fungsi *setter*. Jadi menulis properti seperti itu sebenarnya sama dengan memanggil sebuah fungsi.
181181

182-
For that reason `admin.fullName` works correctly in the code below:
182+
Untuk alasan itu `admin.fullName` akan bekerja dengan benar pada contoh dibawah:
183183

184184
```js run
185185
let user = {
@@ -202,33 +202,33 @@ let admin = {
202202

203203
alert(admin.fullName); // John Smith (*)
204204

205-
// setter triggers!
205+
// memicu setter!
206206
admin.fullName = "Alice Cooper"; // (**)
207207

208-
alert(admin.fullName); // Alice Cooper, state of admin modified
209-
alert(user.fullName); // John Smith, state of user protected
208+
alert(admin.fullName); // Alice Cooper, state dari admin diubah
209+
alert(user.fullName); // John Smith, state dari user dilindungi / *protected*
210210
```
211211

212-
Here in the line `(*)` the property `admin.fullName` has a getter in the prototype `user`, so it is called. And in the line `(**)` the property has a setter in the prototype, so it is called.
212+
Disini pada baris `(*)` properti `admin.fullName` memiliki *getter* didalam prototype `user`, jadi itu akan dipanggil. Pada baris `(**)` properti memiliki *setter* didalam *prototype*, jadi itu dipanggil.
213213

214-
## The value of "this"
214+
## Nilai dari "this"
215215

216-
An interesting question may arise in the example above: what's the value of `this` inside `set fullName(value)`? Where are the properties `this.name` and `this.surname` written: into `user` or `admin`?
216+
Sebuah pertanyaan menarik mungkin muncul didalam contoh diatas: apa nilai dari `this` didalam `set fullName(value)`? Dimanakah properti dari `this.name` dan `this.surname` ditulis: kedalam `user` atau `admin`?
217217

218-
The answer is simple: `this` is not affected by prototypes at all.
218+
Jawabannya sederhana: `this` sama sekali tidak terkena efek oleh *prototype*.
219219

220-
**No matter where the method is found: in an object or its prototype. In a method call, `this` is always the object before the dot.**
220+
**Tidak peduli dimana metodenya ditemukan: didalam objek atau didalam *prototype*nya. Dalam pemanggilan metode, `this` adalah objeknya sebelum titik.**
221221

222-
So, the setter call `admin.fullName=` uses `admin` as `this`, not `user`.
222+
Jadi, pemanggilan *setter* `admin.fullName=` menggunakan `admin` sebagai `this` dan bukan `user`.
223223

224-
That is actually a super-important thing, because we may have a big object with many methods, and have objects that inherit from it. And when the inheriting objects run the inherited methods, they will modify only their own states, not the state of the big object.
224+
Itu sebenarnya adalah sebuah hal yang sangat penting, karena kita mungkin memiliki objek yang besar dengan banyak metode, dan memiliki objek yang mewarisinya. Dan ketika pewarisan objek berjalan metode yang diwariskan, mereka hanya akan memodifikasi bagian / *state* mereka sendiri, bukan bagian dari objek besarnya.
225225

226-
For instance, here `animal` represents a "method storage", and `rabbit` makes use of it.
226+
Contoh, disini `animal` merepresentasikan sebuah "method storage (penyimpanan metode)", dan `rabbit` menggunakannya.
227227

228-
The call `rabbit.sleep()` sets `this.isSleeping` on the `rabbit` object:
228+
Pemanggilan `rabbit.sleep()` menyetel `this.isSleeping` didalam objek `rabbit`:
229229

230230
```js run
231-
// animal has methods
231+
// animal memiliki metode
232232
let animal = {
233233
walk() {
234234
if (!this.isSleeping) {
@@ -245,26 +245,26 @@ let rabbit = {
245245
__proto__: animal
246246
};
247247

248-
// modifies rabbit.isSleeping
248+
// memodifikasi rabbit.isSleeping
249249
rabbit.sleep();
250250

251251
alert(rabbit.isSleeping); // true
252-
alert(animal.isSleeping); // undefined (no such property in the prototype)
252+
alert(animal.isSleeping); // undefined (no such property in the prototype / tidak ada property seperti itu didalam prototype)
253253
```
254254

255-
The resulting picture:
255+
Hasilnya:
256256

257257
![](proto-animal-rabbit-walk-3.svg)
258258

259-
If we had other objects, like `bird`, `snake`, etc., inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.
259+
Jika kita memiliki objek lainnya, seperti `bird`, `snake`, dll., Mewarisi dari `animal`, mereka juga akan memiliki kases kepada metode dari `animal`. Tapi `this` didalam setiap pemanggilan metode adalah objeknya itu sendiri, mengevaluasi pada saat pemanggilan (sebelum titik), bukan `animal`. Jadi ketika kita menulis data kedalam `this`, itu akan tersimpan kedalam objeknya.
260260

261-
As a result, methods are shared, but the object state is not.
261+
Sebagai hasilnya, metodenya dibagi bersama, tapi *state* dari objeknya tidak.
262262

263-
## for..in loop
263+
## Perulangan for..in
264264

265-
The `for..in` loop iterates over inherited properties too.
265+
Perulangan `for..in` mengiterasi properti yang diwariskan juga.
266266

267-
For instance:
267+
Contoh:
268268

269269
```js run
270270
let animal = {
@@ -277,19 +277,19 @@ let rabbit = {
277277
};
278278

279279
*!*
280-
// Object.keys only returns own keys
280+
// Object.keys hanya mengembalikan kunci / keys miliknya sendiri
281281
alert(Object.keys(rabbit)); // jumps
282282
*/!*
283283

284284
*!*
285-
// for..in loops over both own and inherited keys
286-
for(let prop in rabbit) alert(prop); // jumps, then eats
285+
// perulangan for..in mengiterasi kunci milik sendiri dan kunci yang diwariskan
286+
for(let prop in rabbit) alert(prop); // jumps, lalu eats
287287
*/!*
288288
```
289289

290-
If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
290+
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).
291291

292-
So we can filter out inherited properties (or do something else with them):
292+
Jadi kita bisa memisahkan properti warisan (atau melakukan sesuatu dengan properti warisan itu):
293293

294294
```js run
295295
let animal = {
@@ -312,28 +312,28 @@ for(let prop in rabbit) {
312312
}
313313
```
314314

315-
Here we have the following inheritance chain: `rabbit` inherits from `animal`, that inherits from `Object.prototype` (because `animal` is a literal object `{...}`, so it's by default), and then `null` above it:
315+
Disini kita memiliki rantai pewarisan: `rabbit` mewarisi dari `animal`, pewarisan itu dari `Object.prototype` (karena `animal` adalah objek literal `{...}`, jadi itu terjadi secara otomatis), dan lalu `null` diatasnya:
316316

317317
![](rabbit-animal-object.svg)
318318

319-
Note, there's one funny thing. Where is the method `rabbit.hasOwnProperty` coming from? We did not define it. Looking at the chain we can see that the method is provided by `Object.prototype.hasOwnProperty`. In other words, it's inherited.
319+
Catat bahwa ada satu hal lucu. darimanakah `rabbit.hasOwnProperty` datang? Kita tidak membuatnya. Lihat rantainya dan kita bisa melihat metodenya disediakan oleh `Object.prototype.hasOwnProperty`. Dengan kata lain, itu diwariskan.
320320

321-
...But why does `hasOwnProperty` not appear in the `for..in` loop like `eats` and `jumps` do, if `for..in` lists inherited properties?
321+
...Tapi kenapa `hasOwnProperty` tidak muncul didalam perulangan `for..in` seperti `eats` dan `jumps`, jika `for..in` adalah properti yang diwariskan?
322322

323-
The answer is simple: it's not enumerable. Just like all other properties of `Object.prototype`, it has `enumerable:false` flag. And `for..in` only lists enumerable properties. That's why it and the rest of the `Object.prototype` properties are not listed.
323+
Jawabanya sederhana: properti tersebut tidak dapat terhitung(*enumerable*). Sama seperti properti lainnya dari `Object.prototype`, yang mana memiliki tanda `enumerable:false`. Dan `for..in` hanya akan menampilkan properti yang dapat dihitung (*enumerable*). Itulah kenapa properti `Object.prototype`tidak terlihat.
324324

325-
```smart header="Almost all other key/value-getting methods ignore inherited properties"
326-
Almost all other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties.
325+
```smart header="Hampir semua metode key/value mengabaikan properti warisan"
326+
Hampir semua metode key/value, seperti `Object.keys`, `Object.values` dan lainnya mengabaikan properti warisan.
327327
328-
They only operate on the object itself. Properties from the prototype are *not* taken into account.
328+
Mereka hanya akan beroperasi pada objeknya sendiri. Properti dari *prototype* *tidak* akan dihitung.
329329
```
330330

331-
## Summary
331+
## Ringkasan
332332

333-
- In JavaScript, all objects have a hidden `[[Prototype]]` property that's either another object or `null`.
334-
- We can use `obj.__proto__` to access it (a historical getter/setter, there are other ways, to be covered soon).
335-
- The object referenced by `[[Prototype]]` is called a "prototype".
336-
- If we want to read a property of `obj` or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype.
337-
- Write/delete operations act directly on the object, they don't use the prototype (assuming it's a data property, not a setter).
338-
- If we call `obj.method()`, and the `method` is taken from the prototype, `this` still references `obj`. So methods always work with the current object even if they are inherited.
339-
- The `for..in` loop iterates over both its own and its inherited properties. All other key/value-getting methods only operate on the object itself.
333+
- Dalam Javascript, seluruh objek memiliki `[[Prototype]]` tersembunyi yang mana bisa objek atau `null`.
334+
- Kita bisa menggunakan `obj.__proto__` untuk mengaksesnya (selain getter/setter, terdapat cara lain, yang mana akan dibahas nanti).
335+
- Objek yang diferensi oleh `[[Prototype]]` dipanggil dengan sebuah "prototype".
336+
- Jika kita ingin membaca sebuah properti dari `obj` atau memanggil metode, dan ternyata tidak ada maka Javascript akan mencoba mencari didalam *prototype*nya
337+
- Operasi menulis/menghapus langsung bekerja didalam objeknya, mereka tidak menggunakan *prototype* (asumsikan propertinya adalah data, bukan sebuah *setter*).
338+
- Jika kita memanggil `obj.method()`, dan `method`nya diambil dari prototype, `this` akan mereferensi `obj`. Jadi metode selalu bekerja dengan objek yang sedang digunakannya bahkan jika objeknya adalah hasil pewarisan.
339+
- Perulangan `for..in` mengiterasi properti asli dan properti warisan. Semua metode key/value hanya akan bekerja pada objeknya sendiri.

0 commit comments

Comments
 (0)