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
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/10-bind/article.md
+48-46Lines changed: 48 additions & 46 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,15 +5,15 @@ libs:
5
5
6
6
# Function binding
7
7
8
-
When passing object methods as callbacks, for instance to `setTimeout`, there's a known problem: "losing`this`".
8
+
Ketika mengirimkan metode objek sebagai callback, seperti `setTimeout`, terdapat sebuah masalah: "kehilangan`this`".
9
9
10
-
In this chapter we'll see the ways to fix it.
10
+
Didalam chapter ini kita akan belajar cara memperbaikinya.
11
11
12
-
## Losing "this"
12
+
## Kehilangan "this"
13
13
14
-
We've already seen examples of losing `this`. Once a method is passed somewhere separately from the object -- `this`is lost.
14
+
Kita sudah melihat beberapa contoh saat kehilangan `this`. Sekalinya sebuah metode dikirim kebagian kode lain dengan terpisah dari objeknya -- `this`akan menghilang dari metodenya.
15
15
16
-
Here's how it may happen with`setTimeout`:
16
+
Ini adalah bagaimana hal itu terjadi dengan`setTimeout`:
As we can see, the output shows not "John" as`this.firstName`, but`undefined`!
31
+
Seperti yang bisa kita lihat, keluarannya tidak menampilkan "John" sebagai`this.firstName`, tapi menampilkan`undefined`!
32
32
33
-
That's because`setTimeout`got the function `user.sayHi`, separately from the object. The last line can be rewritten as:
33
+
Itu karena`setTimeout`mendapatkan fungsi `user.sayHi`, terpisah dari objeknya. Baris terakhir bisa ditulis ulang sebagai:
34
34
35
35
```js
36
36
let f =user.sayHi;
37
-
setTimeout(f, 1000); //lost user context
37
+
setTimeout(f, 1000); //kehilangan konteks dari user
38
38
```
39
39
40
-
The method `setTimeout`in-browser is a little special: it sets `this=window`for the function call (for Node.js, `this`becomes the timer object, but doesn't really matter here). So for`this.firstName`it tries to get `window.firstName`, which does not exist. In other similar cases, usually `this`just becomes`undefined`.
40
+
Metode `setTimeout`didalam peramban sedikit spesial: metode tersebut menyetel `this=window`untuk pemanggilan fungsi (untuk Node.js, `this`menjadi objek timer, tapi tidak terlalu penting disini). Jadi untuk`this.firstName`metodenya jadi mendapatkan `window.firstName`, yang mana tidak ada. Dalam kasus serupa lainnya `this`akan menjadi`undefined`.
41
41
42
-
The task is quite typical -- we want to pass an object method somewhere else (here -- to the scheduler) where it will be called. How to make sure that it will be called in the right context?
42
+
Tugasnya cukup tipikal -- kita ingin mengirim metode objek ke bagian kode lainnya (disini -- kepada penjadwal/setTimeout) dimana metodenya akan dipanggil. Bagaimana cara untuk memeriksa konteksnya dipanggil dengan benar?
43
43
44
-
## Solution 1: a wrapper
44
+
## Solusi 1: pembungkus
45
45
46
-
The simplest solution is to use a wrapping function:
46
+
Solusi sederhananya adalah untuk menggunakan fungsi pembungkus:
47
47
48
48
```js run
49
49
let user = {
@@ -60,17 +60,17 @@ setTimeout(function() {
60
60
*/!*
61
61
```
62
62
63
-
Now it works, because it receives `user`from the outer lexical environment, and then calls the method normally.
63
+
Kode diatas bekerja, karena `user`didapatkan dari lingkungan leksikal terluar, dan lalu memanggil metodenya secara normal.
Looks fine, but a slight vulnerability appears in our code structure.
71
+
Terlihat bagus, tapi sedikit memiliki kerentanan yang akan muncul pada struktur kodenya.
72
72
73
-
What if before`setTimeout`triggers (there's one second delay!) `user`changes value? Then, suddenly, it will call the wrong object!
73
+
Bagaimana jika sebelum`setTimeout`berjalan (terdapat penundaan selama satu detik!) nilai `user`untuk berubah? Maka, tiba-tiba,fungsinya akan memanggil objek yang salah.
74
74
75
75
76
76
```js run
@@ -83,32 +83,32 @@ let user = {
83
83
84
84
setTimeout(() =>user.sayHi(), 1000);
85
85
86
-
// ...the value of user changes within 1 second
86
+
// ...nilai dari user berubah sebelum 1 detik!
87
87
user = {
88
88
sayHi() { alert("Another user in setTimeout!"); }
89
89
};
90
90
91
-
//Another user in setTimeout!
91
+
//setTimeout menggunakan user yang berbeda!
92
92
```
93
93
94
-
The next solution guarantees that such thing won't happen.
94
+
Solusi selanjutnya akan menjamin hal seperti diatas tidak akan terjadi.
95
95
96
-
## Solution 2: bind
96
+
## Solusi 2: bind
97
97
98
-
Functions provide a built-in method[bind](mdn:js/Function/bind)that allows to fix`this`.
98
+
Fungsi menyediakan sebuah metode bawaan[bind](mdn:js/Function/bind)yang mengijinkan untuk membernarkan`this`.
99
99
100
-
The basic syntax is:
100
+
Sintaks dasarnya adalah:
101
101
102
102
```js
103
-
//more complex syntax will come a little later
103
+
//contoh sintaks yang lebih kompleks akan kita segera lihat
104
104
let boundFunc =func.bind(context);
105
105
```
106
106
107
-
The result of `func.bind(context)`is a special function-like "exotic object", that is callable as function and transparently passes the call to `func`setting`this=context`.
107
+
hasil dari `func.bind(contenxt)`adalah sesuatu yang terlihat seperti fungsi spesial atau bisa disebut dengan "objek eksotik", yang dapat dipanggil sebagai fungsi dan dapat melanjutkan pemanggilan kepada `func`sambil menyetel`this=context`.
108
108
109
-
In other words, calling`boundFunc`is like`func`with fixed`this`.
109
+
Dengan kata lain, memanggil`boundFunc`sama seperti`func`dengan nilai`this` yang tetap.
110
110
111
-
For instance, here`funcUser`passes a call to`func`with`this=user`:
111
+
Contoh, disini`funcUser`mengirimkan sebuah panggilan kepada`func`dengan`this=user`:
112
112
113
113
```js run
114
114
let user = {
@@ -125,9 +125,9 @@ funcUser(); // John
125
125
*/!*
126
126
```
127
127
128
-
Here`func.bind(user)`as a "bound variant" of `func`, with fixed`this=user`.
128
+
Disini`func.bin(user)`sebagai sebuah varian dari `func`, dengan nilai tetap`this=user`.
129
129
130
-
All arguments are passed to the original `func`"as is", for instance:
130
+
Seluruh argumen dikirim kepada `func`asli "sebagaimana adanya", contoh:
131
131
132
132
```js run
133
133
let user = {
@@ -142,11 +142,11 @@ function func(phrase) {
142
142
let funcUser =func.bind(user);
143
143
144
144
*!*
145
-
funcUser("Hello"); // Hello, John (argument "Hello" is passed, and this=user)
145
+
funcUser("Hello"); // Hello, John (argumen "Hello" dikirim, dan this=user)
146
146
*/!*
147
147
```
148
148
149
-
Now let's try with an object method:
149
+
Sekarang kita coba dengan menggunakan metode objek:
150
150
151
151
152
152
```js run
@@ -161,21 +161,21 @@ let user = {
161
161
let sayHi =user.sayHi.bind(user); // (*)
162
162
*/!*
163
163
164
-
//can run it without an object
164
+
//bisa dijalankan tanpa objek
165
165
sayHi(); // Hello, John!
166
166
167
167
setTimeout(sayHi, 1000); // Hello, John!
168
168
169
-
//even if the value of user changes within 1 second
170
-
// sayHi uses the pre-bound value which is reference to the old user object
169
+
//bahkan jika nilai dari user berubah sebelum 1 detik
170
+
// sayHi menggunakan nilai yang telah diikat, yang mana telah mereferensi kepada objek yang lama
171
171
user = {
172
172
sayHi() { alert("Another user in setTimeout!"); }
173
173
};
174
174
```
175
175
176
-
In the line `(*)`we take the method `user.sayHi`and bind it to `user`. The `sayHi`is a "bound" function, that can be called alone or passed to `setTimeout` -- doesn't matter, the context will be right.
176
+
Didalam baris `(*)`kita menggunakan metode `user.sayHi`dan mengikatkannta kepada `user`. `sayHi`adalah sebuah fungsi "terikat", yang bisa dipanggil sendiri atau dikirimkan kepada `setTimeout` -- itu tidaklah penting, yang penting adalah konteksnya tepat.
177
177
178
-
Here we can see that arguments are passed "as is", only `this`is fixed by`bind`:
178
+
Disini kita bisa melihat argumen yang dikirimkan "seperti adanya", hanya saja `this`nilainya menjadi tetap oleh`bind`:
179
179
180
180
```js run
181
181
let user = {
@@ -187,12 +187,12 @@ let user = {
187
187
188
188
let say =user.say.bind(user);
189
189
190
-
say("Hello"); // Hello, John ("Hello" argument is passed to say)
191
-
say("Bye"); // Bye, John ("Bye" is passed to say)
190
+
say("Hello"); // Hello, John (argumen "Hello" dikirim untuk digunakan)
191
+
say("Bye"); // Bye, John ("Bye" dikirim untuk digunakan)
192
192
```
193
193
194
-
````smart header="Convenience method: `bindAll`"
195
-
If an object has many methods and we plan to actively pass it around, then we could bind them all in a loop:
194
+
````smart header="Metode yang bermanfaat: `bindAll`"
195
+
Jika sebuah objek mempunyai beberapa metode dan kita berencana untuk mengirimkannya kebagian kode lain secara terus-menerus, kita bisa mengikatkannya didalam sebuah perulangan:
196
196
197
197
```js
198
198
for (let key in user) {
@@ -202,32 +202,33 @@ for (let key in user) {
202
202
}
203
203
```
204
204
205
-
JavaScript libraries also provide functions for convenient mass binding , e.g.[_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll)in lodash.
205
+
Librari Javascript juga menyediakan fungsi untuk memudahkan pengikatan/binding masal, contoh[_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll)didalam lodash.
206
206
````
207
207
208
-
## Partial functions
208
+
## Partial functions/Fungsi sebagian
209
209
210
-
Until now we have only been talking about binding `this`. Let's take it a step further.
210
+
Sampai sekarang kita hanya berbicara tentang binding/pengikatan `this`. Ayo kita lihat lebih dalam.
211
211
212
-
We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy.
212
+
Kita bisa mengikat bukan hanya `this`, tapi juga argumen. Yang mana sangat jarang digunakan, tapi terkadang cukup mudah digunakan.
213
213
214
-
The full syntax of `bind`:
214
+
Sintaks penuh dari `bind`:
215
215
216
216
```js
217
217
let bound = func.bind(context, [arg1], [arg2], ...);
218
218
```
219
219
220
-
It allows to bind context as `this` and starting arguments of the function.
220
+
Yang mana mengijinkan kita untuk mengikat konteks sebagai `this` dan memulai argumen dari sebuah fungsi.
221
221
222
222
For instance, we have a multiplication function `mul(a, b)`:
223
+
Contoh, kita mempunyai sebuah fungsi perkalian `mul(a, b)`:
223
224
224
225
```js
225
226
function mul(a, b) {
226
227
return a * b;
227
228
}
228
229
```
229
230
230
-
Let's use `bind` to create a function `double` on its base:
231
+
Kita gunakan `bind` untuk membuat sebuah fungsi `double` didalamnya:
The call to `mul.bind(null, 2)` creates a new function `double` that passes calls to `mul`, fixing `null` as the context and `2` as the first argument. Further arguments are passed "as is".
248
+
Pemanggilan terhadap `mul.bind(null, 2)` membuat sebuah fungsi baru `double` yang mengirimkan pemanggilan terhadap `mul, memperbaiki `null` sebagai konteks dan `2` sebagai argumen pertamanya. Ar
247
249
248
250
That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one.
0 commit comments