You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In programming, we often want to take something and extend it.
3
+
Dalam *programming*, terkadang kita ingin mengambil sesuatu lalu dikembangkan lagi.
4
4
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.
6
6
7
-
*Prototypal inheritance* is a language feature that helps in that.
7
+
*Pewarisan Prototype* adalah fitur yang bisa membantu untuk melakukan hal itu.
8
8
9
9
## [[Prototype]]
10
10
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*:
12
12
13
13

14
14
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.
16
16
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.
18
18
19
-
One of them is to use the special name `__proto__`, like this:
19
+
Salah satunya adalah menggunakan nama spesial `__proto__`, seperti:
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`.
35
35
36
-
For instance:
36
+
Contoh:
37
37
38
38
```js
39
39
let animal = {
@@ -47,24 +47,24 @@ let rabbit = {
47
47
rabbit.__proto__= animal; // (*)
48
48
*/!*
49
49
50
-
//we can find both properties in rabbit now:
50
+
//sekarang kita bisa menggunakan kedua propertinya didalam *rabbit*:
51
51
*!*
52
52
alert( rabbit.eats ); // true (**)
53
53
*/!*
54
54
alert( rabbit.jumps ); // true
55
55
```
56
56
57
-
Here the line `(*)`sets`animal`to be a prototype of`rabbit`.
57
+
Pada baris `(*)`menyetel`animal`untuk menjadi prototype dari`rabbit`.
58
58
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):
60
60
61
61

62
62
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`".
64
64
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".
66
66
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`:
68
68
69
69
```js run
70
70
let animal = {
@@ -81,17 +81,17 @@ let rabbit = {
81
81
__proto__: animal
82
82
};
83
83
84
-
// walk is taken from the prototype
84
+
// walk diambil dari prototype
85
85
*!*
86
86
rabbit.walk(); // Animal walk
87
87
*/!*
88
88
```
89
89
90
-
The method is automatically taken from the prototype, like this:
90
+
Metodenya secara otomatis diambil dari *prototype*nya, seperti:
91
91
92
92

93
93
94
-
The prototype chain can be longer:
94
+
Rantai *prototype* bisa lebih panjang:
95
95
96
96
```js run
97
97
let animal = {
@@ -115,48 +115,48 @@ let longEar = {
115
115
*/!*
116
116
};
117
117
118
-
// walk is taken from the prototype chain
118
+
// walk diambil dari rantai prototype
119
119
longEar.walk(); // Animal walk
120
-
alert(longEar.jumps); // true (from rabbit)
120
+
alert(longEar.jumps); // true (dari rabbit)
121
121
```
122
122
123
123

124
124
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`.
126
126
127
-
There are only two limitations:
127
+
Akan tetapi terdapat dua batasan:
128
128
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.
131
131
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.
133
133
134
134
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.
137
137
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.
139
139
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.
141
141
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.
143
143
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.
145
145
```
146
146
147
-
## Writing doesn't use prototype
147
+
## Menulis tanpa menggunakan *prototype*
148
148
149
-
The prototype is only used for reading properties.
149
+
*Prototype* hanya digunakan untuk membaca properti.
150
150
151
-
Write/delete operations work directly with the object.
151
+
Operasi menulis / menghapus bekerja secara langsung dengan objeknya.
152
152
153
-
In the example below, we assign its own `walk` method to `rabbit`:
153
+
Didalam contoh dibawah, kita memasukan metode `walk` kedalam `rabbit`:
154
154
155
155
```js run
156
156
let animal = {
157
157
eats: true,
158
158
walk() {
159
-
/* this method won't be used by rabbit */
159
+
/* metode ini tidak akan digunakan oleh rabbit */
160
160
}
161
161
};
162
162
@@ -173,13 +173,13 @@ rabbit.walk = function() {
173
173
rabbit.walk(); // Rabbit! Bounce-bounce!
174
174
```
175
175
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*:
177
177
178
178

179
179
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.
181
181
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:
183
183
184
184
```js run
185
185
let user = {
@@ -202,33 +202,33 @@ let admin = {
202
202
203
203
alert(admin.fullName); // John Smith (*)
204
204
205
-
//setter triggers!
205
+
//memicu setter!
206
206
admin.fullName="Alice Cooper"; // (**)
207
207
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*
210
210
```
211
211
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.
213
213
214
-
## The value of "this"
214
+
## Nilai dari "this"
215
215
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`?
217
217
218
-
The answer is simple: `this`is not affected by prototypes at all.
218
+
Jawabannya sederhana: `this`sama sekali tidak terkena efek oleh *prototype*.
219
219
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.**
221
221
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`.
223
223
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.
225
225
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.
227
227
228
-
The call `rabbit.sleep()`sets`this.isSleeping`on the`rabbit` object:
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)
253
253
```
254
254
255
-
The resulting picture:
255
+
Hasilnya:
256
256
257
257

258
258
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.
260
260
261
-
As a result, methods are shared, but the object state is not.
261
+
Sebagai hasilnya, metodenya dibagi bersama, tapi *state* dari objeknya tidak.
262
262
263
-
## for..in loop
263
+
## Perulangan for..in
264
264
265
-
The`for..in`loop iterates over inherited properties too.
265
+
Perulangan`for..in`mengiterasi properti yang diwariskan juga.
266
266
267
-
For instance:
267
+
Contoh:
268
268
269
269
```js run
270
270
let animal = {
@@ -277,19 +277,19 @@ let rabbit = {
277
277
};
278
278
279
279
*!*
280
-
// Object.keys only returns own keys
280
+
// Object.keys hanya mengembalikan kunci / keys miliknya sendiri
281
281
alert(Object.keys(rabbit)); // jumps
282
282
*/!*
283
283
284
284
*!*
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
287
287
*/!*
288
288
```
289
289
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).
291
291
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):
293
293
294
294
```js run
295
295
let animal = {
@@ -312,28 +312,28 @@ for(let prop in rabbit) {
312
312
}
313
313
```
314
314
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:
316
316
317
317

318
318
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.
320
320
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?
322
322
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.
324
324
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.
327
327
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.
329
329
```
330
330
331
-
## Summary
331
+
## Ringkasan
332
332
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