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: doc/fi/function/closures.md
+17-37Lines changed: 17 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,8 @@
1
-
## Closures and References
1
+
## Sulkeumat ja viitteet
2
2
3
-
One of JavaScript's most powerful features is the availability of *closures*,
4
-
this means that scopes **always** keep access to the outer scope they were
5
-
defined in. Since the only scoping that JavaScript has is
6
-
[function scope](#function.scopes), all functions, by default, act as closures.
3
+
*Sulkeumat* ovat eräs JavaScriptin voimakkaimmista ominaisuuksista. Näkyvyysalueilla on siis **aina** pääsy ulompaan näkyvyysalueeseensa. Koska JavaScriptissä ainut tapa määritellä näkyvyyttä pohjautuu [funktionäkyvyyteen](#function.scopes), kaikki funktiot käyttäytyvät oletuksena sulkeumina.
7
4
8
-
### Emulating private variables
5
+
### Paikallisten muuttujien emulointi
9
6
10
7
function Counter(start) {
11
8
var count = start;
@@ -24,51 +21,38 @@ defined in. Since the only scoping that JavaScript has is
24
21
foo.increment();
25
22
foo.get(); // 5
26
23
27
-
Here, `Counter` returns **two** closures. The function `increment` as well as
28
-
the function `get`. Both of these functions keep a **reference** to the scope of
29
-
`Counter` and, therefore, always keep access to the `count` variable that was
30
-
defined in that very scope.
24
+
Tässä tapauksessa `Counter` palauttaa **kaksi** sulkeumaa. Funktion `increment` lisäksi palautetaan myös funktio `get`. Kumpikin funktio **viittaa**`Counter`-näkyvyysalueeseen ja pääsee siten käsiksi `count`-muuttujan arvoon.
31
25
32
-
### Why Private Variables Work
26
+
### Miksi paikalliset muuttujat toimivat
33
27
34
-
Since it is not possible to reference or assign scopes in JavaScript, there is
35
-
**no** way of accessing the variable `count` from the outside. The only way to
36
-
interact with it is via the two closures.
28
+
JavaScriptissä ei voida viitata näkyvyysalueisiin. Tästä seuraa **ettei**`count`-muuttujan arvoon voida päästä käsiksi funktion ulkopuolelta. Ainoastaan nämä kaksi sulkeumaa mahdollistavat sen.
37
29
38
30
var foo = new Counter(4);
39
31
foo.hack = function() {
40
32
count = 1337;
41
33
};
42
34
43
-
The above code will **not** change the variable `count` in the scope of `Counter`,
44
-
since `foo.hack` was not defined in **that** scope. It will instead create - or
45
-
override - the *global* variable `count`.
35
+
Yllä oleva koodi **ei** muuta muuttujan `count` arvoa `Counter`-näkyvyysalueessa. Tämä johtuu siitä, että `foo.hack`-ominaisuutta ei ole määritelty **kyseisessä** näkyvyysalueessa. Sen sijaan se luo - tai ylikirjoittaa - *globaalin* muuttujan `count`.
46
36
47
-
### Closures Inside Loops
37
+
### Sulkeumat luupeissa
48
38
49
-
One often made mistake is to use closures inside of loops, as if they were
50
-
copying the value of the loops index variable.
39
+
Usein sulkeumia käytetään väärin luuppien sisällä indeksimuuttujien arvon kopiointiin.
51
40
52
41
for(var i = 0; i < 10; i++) {
53
42
setTimeout(function() {
54
43
console.log(i);
55
44
}, 1000);
56
45
}
57
46
58
-
The above will **not** output the numbers `0` through `9`, but will simply print
59
-
the number `10` ten times.
47
+
Yllä oleva koodi **ei** tulosta numeroita `nollasta``yhdeksään`. Sen sijaan se tulostaa numeron `10` kymmenen kertaa.
60
48
61
-
The *anonymous* function keeps a **reference** to `i` and at the time
62
-
`console.log` gets called, the `for loop` has already finished and the value of
63
-
`i` as been set to `10`.
49
+
*Nimetön* funktio saa **viitteen**`i`-muuttujaan `console.log`-kutsuhetkellä. Tällöin luuppi on jo suoritettu ja `i`:n arvoksi on asetettu `10`.
64
50
65
-
In order to get the desired behavior, it is necessary to create a **copy** of
66
-
the value of `i`.
51
+
Päästäksemme haluttuun lopputulokseen on tarpeen luoda **kopio**`i`:n arvosta.
67
52
68
-
### Avoiding the Reference Problem
53
+
### Viiteongelman välttäminen
69
54
70
-
In order to copy the value of the loop's index variable, it is best to use an
71
-
[anonymous wrapper](#function.scopes).
55
+
Voimme välttää ongelman käyttämällä [nimetöntä käärettä](#function.scopes).
72
56
73
57
for(var i = 0; i < 10; i++) {
74
58
(function(e) {
@@ -78,15 +62,11 @@ In order to copy the value of the loop's index variable, it is best to use an
78
62
})(i);
79
63
}
80
64
81
-
The anonymous outer function gets called immediately with `i` as its first
82
-
argument and will receive a copy of the **value** of `i` as its parameter `e`.
65
+
Nimetöntä ulkofunktiota kutsutaan heti käyttäen `i`:tä se ensimmäisenä argumenttina. Tällöin se saa kopion `i`:n**arvosta** parametrina `e`.
83
66
84
-
The anonymous function that gets passed to `setTimeout` now has a reference to
85
-
`e`, whose value does **not** get changed by the loop.
67
+
Nimetön funktio, jolle annetaan `setTimeout` sisältää nyt viitteen `e`:hen, jonka arvoa luuppi **ei** muuta.
86
68
87
-
There is another possible way of achieving this; that is to return a function
88
-
from the anonymous wrapper, that will then have the same behavior as the code
89
-
above.
69
+
Samaan lopputulokseen voidaan päästä myös palauttamalla funktio nimettömästä kääreestä. Tällöin se käyttäytyy samoin kuten yllä.
Constructors in JavaScript are yet again different from many other languages. Any
4
-
function call that is preceded by the `new` keyword acts as a constructor.
3
+
JavaScriptin konstruktorit eroavat monista muista kielistä selvästi. Jokainen funktiokutsu, joka sisältää avainsanan `new` toimii konstruktorina.
5
4
6
-
Inside the constructor - the called function - the value of `this` refers to a
7
-
newly created `Object`. The [`prototype`](#object.prototype) of this **new**
8
-
object is set to the `prototype` of the function object that was invoked as the
9
-
constructor.
5
+
Konstruktorin - kutsutun funktion - `this`-muuttujan arvo viittaa luotuun `Object`-olioon. Tämän **uuden** olion [`prototyyppi`](#object.prototype) asetetaan osoittamaan konstruktorin kutsuman funktio-olion prototyyppiin.
10
6
11
-
If the function that was called has no explicit `return` statement, then it
12
-
implicitly returns the value of `this` - the new object.
7
+
Mikäli kutsuttu funktio ei sisällä selvää `return`-lausetta, tällöin se palauttaa `this`-muuttujan arvon eli uuden olion.
13
8
14
9
function Foo() {
15
10
this.bla = 1;
@@ -21,16 +16,14 @@ implicitly returns the value of `this` - the new object.
21
16
22
17
var test = new Foo();
23
18
24
-
The above calls `Foo` as constructor and sets the `prototype` of the newly
25
-
created object to `Foo.prototype`.
19
+
Yllä `Foo`:ta kutsutaan konstruktorina. Juuri luodun olion `prototyyppi` asetetaan osoittamaan ominaisuuteen `Foo.prototype`.
26
20
27
-
In case of an explicit `return` statement the function returns the value
28
-
specified that statement, **but only** if the return value is an `Object`.
21
+
Selvän `return`-lausekkeen tapauksessa funktio palauttaa ainoastaan määritellyn lausekkeen arvon. Tämä pätee tosin **vain jos** palautettava arvo on tyypiltään `Object`.
29
22
30
23
function Bar() {
31
24
return 2;
32
25
}
33
-
new Bar(); // a new object
26
+
new Bar(); // uusi olio
34
27
35
28
function Test() {
36
29
this.value = 2;
@@ -39,23 +32,20 @@ specified that statement, **but only** if the return value is an `Object`.
39
32
foo: 1
40
33
};
41
34
}
42
-
new Test(); // the returned object
35
+
new Test(); // palautettu olio
43
36
44
-
When the `new` keyword is omitted, the function will **not**return a new object.
37
+
Mikäli `new`-avainsanaa ei käytetä, funktio **ei**palauta uutta oliota.
45
38
46
39
function Foo() {
47
-
this.bla = 1; // gets set on the global object
40
+
this.bla = 1; // asetetaan globaalisti
48
41
}
49
42
Foo(); // undefined
50
43
51
-
While the above example might still appear to work in some cases, due to the
52
-
workings of [`this`](#function.this) in JavaScript, it will use the
53
-
*global object* as the value of `this`.
44
+
Vaikka yllä oleva esimerkki saattaa näyttää toimivan joissain tapauksissa, viittaa [`this`](#function.this) globaalin olion `this`-ominaisuuteen.
54
45
55
-
### Factories
46
+
### Tehtaat
56
47
57
-
In order to be able to omit the `new` keyword, the constructor function has to
58
-
explicitly return a value.
48
+
Mikäli `new`-avainsanan käyttöä halutaan välttää, voidaan konstruktori pakottaa palauttamaan arvo.
59
49
60
50
function Bar() {
61
51
var value = 1;
@@ -72,25 +62,17 @@ explicitly return a value.
72
62
new Bar();
73
63
Bar();
74
64
75
-
Both calls to `Bar` return the exact same thing, a newly create object which
76
-
has a property called `method` on it, that is a
77
-
[Closure](#function.closures).
65
+
Tässä tapauksessa molemmat `Bar`-funktion kutsut käyttäytyvät samoin. Kumpikin kutsu palauttaa olion, joka sisältää `method`-ominaisuuden. Kyseinen ominaisuus on [sulkeuma](#function.closures).
78
66
79
-
It is also to note that the call `new Bar()` does **not** affect the prototype
80
-
of the returned object. While the prototype will be set on the newly created
81
-
object, `Bar` never returns that new object.
67
+
On myös tärkeää huomata, että kutsu `new Bar()`**ei** vaikuta palautetun olion prototyyppiin. Vaikka luodun olion prototyyppi onkin asetettu, `Bar` ei palauta ikinä kyseistä prototyyppioliota.
82
68
83
-
In the above example, there is no functional difference between using and
84
-
not using the `new` keyword.
69
+
Yllä olevassa esimerkissä `new`-avainsanan käytöllä tai käyttämällä jättämisellä ei ole toiminnan kannalta mitään merkitystä.
85
70
71
+
### Tehtaiden käyttö uusien olioiden luomiseen
86
72
87
-
### Creating New Objects via Factories
73
+
Usein suositellaan `new`-avainsanan käytön **välttämistä**. Tämä johtuu siitä, että sen käyttämättä jättäminen voi johtaa bugeihin.
88
74
89
-
An often made recommendation is to **not** use `new` since forgetting its use
90
-
may lead to bugs.
91
-
92
-
In order to create new object, one should rather use a factory and construct a
93
-
new object inside of that factory.
75
+
Sen sijaan suositellaan käytettävän tehdasta, jonka sisällä varsinainen olio konstruoidaan.
94
76
95
77
function Foo() {
96
78
var obj = {};
@@ -107,22 +89,13 @@ new object inside of that factory.
107
89
return obj;
108
90
}
109
91
110
-
While the above is robust against a missing `new` keyword and certainly makes
111
-
the use of [private variables](#function.closures) easier, it comes with some
112
-
downsides.
92
+
Vaikka yllä oleva esimerkki välttää `new`-avainsanan käyttöä ja tekee [paikallisten muuttujien](#function.closures) käytön helpommaksi, sisältää se joitain huonoja puolia.
113
93
114
-
1. It uses more memory since the created objects do **not** share the methods
115
-
on a prototype.
116
-
2. In order to inherit the factory needs to copy all the methods from another
117
-
object or put that object on the prototype of the new object.
118
-
3. Dropping the prototype chain just because of a left out `new` keyword
119
-
somehow goes against the spirit of the language.
94
+
1. Se käyttää enemmän muistia. Tämä johtuu siitä, että luodut oliot **eivät** jaa prototyypin metodeja.
95
+
2. Perinnän tapauksessa tehtaan tulee kopioida toisen olion kaikki metodit tai vaihtoehtoisesti asettaa kyseinen olio toisen prototyypiksi.
96
+
3. Prototyyppiketjun käsitteen unohtaminen on vain välttääksemme `new`-avainsanan käyttöä on vastoin kielen filosofista perustaa.
120
97
121
-
### In Conclusion
98
+
### Yhteenveto
122
99
123
-
While omitting the `new` keyword might lead to bugs, it is certainly **not** a
124
-
reason to drop the use of prototypes altogether. In the end it comes down to
125
-
which solution is better suited for the needs of the application, it is
126
-
especially important to choose a specific style of object creation **and stick**
127
-
with it.
100
+
Vaikka `new`-avainsanan käyttö voi johtaa bugeihin, prototyyppien käyttöä **ei** kannata unohtaa kokonaan. Loppujen lopuksi kyse on siitä, kumpi tapa sopii sovelluksen tarpeisiin paremmin. On erityisen tärkeää valita jokin tietty tapa ja **pitäytyä** sen käytössä.
Functions in JavaScript are first class objects. That means they can be
4
-
passed around like any other value. One common use of this feature is to pass
5
-
an *anonymous function* as a callback to another, possibly asynchronous function.
3
+
JavaScriptissä funktiot ovat ensimmäisen luokan olioita. Tämä tarkoittaa sitä, että niitä voidaan välittää kuten muitakin arvoja. Usein tätä käytetään takaisinkutsuissa käyttämällä *nimettömiä, mahdollisesti asynkronisia funktioita*.
6
4
7
-
### The `function` Declaration
5
+
### `function`-määre
8
6
9
7
function foo() {}
10
8
11
-
The above function gets [hoisted](#function.scopes) before the execution of the
12
-
program starts; thus, it is available *everywhere* in the scope it was *defined*
13
-
in, even if called before the actual definition in the source.
9
+
Yllä oleva funktio [hilataan](#function.scopes) ennen ohjelman suorituksen alkua. Se näkyy *kaikkialle* näkyvyysalueessaan, jossa se on *määritelty*. Tämä on totta jopa silloin, jos sitä kutsutaan ennen määrittelyään.
14
10
15
-
foo(); // Works because foo was created before this code runs
11
+
foo(); // Toimii, koska foo on luotu ennen kuin koodi suoritetaan
16
12
function foo() {}
17
13
18
-
### The `function` Expression
14
+
### `function`-lauseke
19
15
20
16
var foo = function() {};
21
17
22
-
This example assigns the unnamed and *anonymous* function to the variable `foo`.
18
+
Tämä esimerkki asettaa nimeämättömän ja *nimettömän* funktion muuttujan `foo` arvoksi.
23
19
24
20
foo; // 'undefined'
25
-
foo(); // this raises a TypeError
21
+
foo(); // tämä palauttaa TypeError-virheen
26
22
var foo = function() {};
27
23
28
-
Due to the fact that `var` is a declaration, that hoists the variable name `foo`
29
-
before the actual execution of the code starts, `foo` is already defined when
30
-
the script gets executed.
24
+
`var` on määre. Tästä johtuen se hilaa muuttujanimen `foo` ennen kuin itse koodia ryhdytään suorittamaan.
31
25
32
-
But since assignments only happen at runtime, the value of `foo` will default
33
-
to [undefined](#core.undefined) before the corresponding code is executed.
26
+
Sijoituslauseet suoritetaan *vasta* kun niihin saavutaan. Tästä johtuen `foo` saa arvokseen [undefined](#core.undefined) ennen kuin varsinaista sijoitusta päästään suorittamaan.
34
27
35
-
### Named Function Expression
28
+
### Nimetty funktiolauseke
36
29
37
-
Another special case is the assignment of named functions.
30
+
Nimettyjen funktioiden sijoitus tarjoaa toisen erikoistapauksen.
38
31
39
32
var foo = function bar() {
40
-
bar(); // Works
33
+
bar(); // Toimii
41
34
}
42
35
bar(); // ReferenceError
43
36
44
-
Here `bar` is not available in the outer scope, since the function only gets
45
-
assigned to `foo`; however, inside of `bar` it is available. This is due to
46
-
how [name resolution](#function.scopes) in JavaScript works, the name of the
47
-
function is *always* made available in the local scope of the function itself.
37
+
Tässä tapauksessa `bar` ei ole saatavilla ulommalla näkyvyysalueessa. Tämä johtuu siitä, että se on sidottu `foo`:n sisälle. Tämä johtuu siitä, kuinka näkyvyysalueet ja niihin kuuluvat jäsenet [tulkitaan](#function.scopes). Funktion nimi on *aina* saatavilla sen paikallisessa näkyvyysalueessa itsessään.
0 commit comments