Skip to content

Commit a30c23b

Browse files
committed
Merge branch 'master' of https://github.com/bebraw/JavaScript-Garden into fn-translation
2 parents afd901c + 4914f06 commit a30c23b

27 files changed

+1532
-1
lines changed

doc/fi/array/constructor.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## `Array`-konstruktori
2+
3+
`Array`-oletuskonstruktorin käytös ei ole lainkaan yksiselitteistä. Tämän vuoksi suositellaankin, että konstruktorin sijasta käytetään literaalinotaatiota `[]`.
4+
5+
[1, 2, 3]; // Tulos: [1, 2, 3]
6+
new Array(1, 2, 3); // Tulos: [1, 2, 3]
7+
8+
[3]; // Tulos: [3]
9+
new Array(3); // Tulos: []
10+
new Array('3') // Tulos: ['3']
11+
12+
Mikäli `Array`-konstruktorille annetaan vain yksi argumentti ja se on tyypiltään `Number`, konstruktori palauttaa uuden *harvan* taulukon, jonka `length`-attribuutti on asetettu annetun numeron mukaisesti. On tärkeää huomata, että **ainoastaan** `length` asetetaan tällä tavoin, todellisia taulukon indeksejä ei alusteta.
13+
14+
var arr = new Array(3);
15+
arr[1]; // undefined
16+
1 in arr; // false, indeksiä ei ole alustettu
17+
18+
Tämä on käytännöllistä vain harvoin, kuten merkkijonon toiston tapauksessa. Tällöin voidaan välttää `for-luupin` käyttämistä.
19+
20+
new Array(count + 1).join(stringToRepeat);
21+
22+
### Yhteenveto
23+
24+
`Array`-konstruktorin käyttöä tulee käyttää niin paljon kuin suinkin mahdollista. Sen sijaan on suositeltavaa käyttää literaalinotaatiota. Literaalit ovat lyhyempiä ja niiden syntaksi on selkeämpi. Tämän lisäksi ne tekevät koodista luettavampaa.
25+

doc/fi/array/general.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Taulukon iterointi ja attribuutit
2+
3+
Vaikka taulukot ovatkin JavaScript-olioita, niiden tapauksessa ei välttämättä kannata käyttää [`for in loop`](#object.forinloop)-luuppia. Pikemminkin tätä tapaa tulee **välttää**.
4+
5+
> **Huomio:** JavaScript-taulukot **eivät ole** *assosiatiivisia*. JavaScriptissa ainoastaan [oliot](#object.general) ovat avain-arvo-mappauksia. On huomattavaa, että toisin kuin assosiatiiviset taulukot, oliot **eivät** säilytä järjestystään.
6+
7+
`for in`-luuppi iteroi kaikki prototyyppiketjun sisältämät ominaisuudet. Tämän vuoksi tulee käyttää erityistä [`hasOwnProperty`](#object.hasownproperty)-metodia, jonka avulla voidaan taata, että käsitellään oikeita ominaisuuksia. Tästä johtuen iteroint on jo lähtökohtaisesti jopa **kaksikymmentä** kertaa hitaampaa kuin normaalin `for`-luupin tapauksessa.
8+
9+
### Iterointi
10+
11+
Taulukkojen tapauksessa paras suorituskyky voidaan saavuttaa käyttämällä klassista `for`-luuppia.
12+
13+
var list = [1, 2, 3, 4, 5, ...... 100000000];
14+
for(var i = 0, l = list.length; i < l; i++) {
15+
console.log(list[i]);
16+
}
17+
18+
Edelliseen esimerkkiin liittyy yksi mutta. Listan pituus on tallennettu välimuistiin erikseen käyttämällä `l = list.length`-lauseketta.
19+
20+
Vaikka `length`-ominaisuus määritelläänkin taulukossa itsessään, arvon hakeminen sisältää ylimääräisen operaation. Uudehkot JavaScript-ympäristöt **saattavat** optimoida tämän tapauksen. Tästä ei kuitenkaan ole mitään takeita.
21+
22+
Todellisuudessa välimuistin käytön pois jättäminen voi hidastaa luuppia jopa puolella.
23+
24+
### `length`-ominaisuus
25+
26+
`length`-ominaisuuden *getteri* palauttaa yksinkertaisesti taulukon sisältämien alkioiden määrän. Sen *setteriä* voidaan käyttää taulukon **typistämiseen**.
27+
28+
var foo = [1, 2, 3, 4, 5, 6];
29+
foo.length = 3;
30+
foo; // [1, 2, 3]
31+
32+
foo.length = 6;
33+
foo; // [1, 2, 3]
34+
35+
Pituuden pienemmäksi asettaminen typistää taulukkoa. Sen kasvattaminen ei kuitenkaan vaikuta mitenkään.
36+
37+
### Yhteenveto
38+
39+
Parhaan suorituskyvyn kannalta on parhainta käyttää tavallista `for`-luuppia ja tallentaa `length`-ominaisuus välimuistiin. `for in`-luupin käyttö taulukon tapauksessa on merkki huonosti kirjoitetusta koodista, joka on altis bugeille ja heikolle suorituskyvylle.
40+

doc/fi/core/eval.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Miksi `eval`-funktiota tulee välttää
2+
3+
`eval` suorittaa JavaScript-koodia sisältävän merkkijonon paikallisessa näkyvyysalueessa.
4+
5+
var foo = 1;
6+
function test() {
7+
var foo = 2;
8+
eval('foo = 3');
9+
return foo;
10+
}
11+
test(); // 3
12+
foo; // 1
13+
14+
`eval` suoritetaan paikallisessa näkyvyysalueessa ainoastaan kun sitä kutsutaan **suorasti** *ja* kutsutun funktion nimi on todellisuudessa `eval`.
15+
16+
var foo = 1;
17+
function test() {
18+
var foo = 2;
19+
var bar = eval;
20+
bar('foo = 3');
21+
return foo;
22+
}
23+
test(); // 2
24+
foo; // 3
25+
26+
`eval`-funktion käyttöä tulee välttää **ehdottomasti**. 99.9% sen "käyttötapauksista" voidaan toteuttaa **ilman** sitä.
27+
28+
### Piilotettu `eval`
29+
30+
[Aikakatkaisufunktiot](#other.timeouts) `setTimeout` and `setInterval` voivat kumpikin ottaa merkkijonon ensimmäisenä argumenttinaan. Kyseinen merkkijono suoritetaan **aina** globaalissa näkyvyysalueessa, koska tuolloin `eval`-funktiota kutsutaan epäsuorasti.
31+
32+
### Turvallisuusongelmat
33+
34+
`eval` on myös turvallisuusongelma. Se suorittaa **minkä tahansa** sille annetun koodin. Tämän vuoksi sitä ei tule **ikinä** käyttää tuntemattomasta tai epäluotttavasta lähteestä tulevien merkkijonojen kanssa.
35+
36+
### Yhteenveto
37+
38+
`eval`-funktiota ei pitäisi käyttää koskaan. Mikä tahansa sitä käyttävä koodi on kyseenalaista sekä suorituskyvyn että turvallisuuden suhteen. Mikäli jokin tarvitsee `eval`-funktiota toimiakseen, tulee sen suunnittelutapa kyseenalaistaa. Tässä tapauksessa on parempi suunnitella toisin ja välttää `eval`-funktion käyttöä.
39+

doc/fi/core/semicolon.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
## Automaattiset puolipisteet
2+
3+
Vaikka JavaScript käyttääkin C:n tapaista syntaksia, se **ei** pakota käyttämään puolipisteitä. Niiden käyttöä voidaan halutessa välttää.
4+
5+
Tästä huolimatta JavaScript ei kuitenkaan ole puolipisteetön kieli. Se tarvitsee niitä ymmärtääkseen lähdekoodia. Tämän vuoksi JavaScript-parseri lisää niitä tarpeen mukaan **automaattisesti**.
6+
7+
var foo = function() {
8+
} // parsimisvirhe, lisätään puolipiste
9+
test()
10+
11+
Lisäys tapahtuu ja parseri yrittää uudelleen.
12+
13+
var foo = function() {
14+
}; // ei virhettä, parsiminen jatkuu
15+
test()
16+
17+
Automaattista puolipisteiden lisäämistä pidetään eräänä JavaScriptin **suurimmista** suunnitteluvirheistä. Tämä johtuu siitä, että se voi muuttaa tapaa, jolla koodi käyttäytyy.
18+
19+
### Kuinka se toimii
20+
21+
Alla oleva koodi ei sisällä puolipisteitä. Täten niiden lisääminen jää parserin tehtäväksi.
22+
23+
(function(window, undefined) {
24+
function test(options) {
25+
log('testing!')
26+
27+
(options.list || []).forEach(function(i) {
28+
29+
})
30+
31+
options.value.test(
32+
'long string to pass here',
33+
'and another long string to pass'
34+
)
35+
36+
return
37+
{
38+
foo: function() {}
39+
}
40+
}
41+
window.test = test
42+
43+
})(window)
44+
45+
(function(window) {
46+
window.someLibrary = {}
47+
48+
})(window)
49+
50+
Alla parserin arvaus.
51+
52+
(function(window, undefined) {
53+
function test(options) {
54+
55+
// Not inserted, lines got merged
56+
log('testing!')(options.list || []).forEach(function(i) {
57+
58+
}); // <- lisätty
59+
60+
options.value.test(
61+
'long string to pass here',
62+
'and another long string to pass'
63+
); // <- lisätty
64+
65+
return; // <- lisätty, rikkoo return-lauseen
66+
{ // kohdellaan lohkona
67+
68+
// nimike ja yhden lausekkeen lause
69+
foo: function() {}
70+
}; // <- lisätty
71+
}
72+
window.test = test; // <- lisätty
73+
74+
// Rivit yhdistettiin jälleen
75+
})(window)(function(window) {
76+
window.someLibrary = {}; // <- lisätty
77+
78+
})(window); //<- lisätty
79+
80+
> **Huomio:** JavaScript-parseri ei käsittele return-lauseita ja rivivaihtoja "kunnolla". Vaikka tämä ei välttämättä olekaan parserin vika, voi siitä seurata epämiellyttäviä sivuvaikutuksia.
81+
82+
Yllä olevassa tapauksessa parseri muutti huomattavasti koodin käytöstä. Joissain tapauksissa se tekee kokonaan **väärän asian**.
83+
84+
### Johtavat sulkeet
85+
86+
Parseri **ei** lisää puolipistettä johtavien sulkeiden tapauksessa.
87+
88+
log('testing!')
89+
(options.list || []).forEach(function(i) {})
90+
91+
Koodi muuttuu seuraavaksi.
92+
93+
log('testing!')(options.list || []).forEach(function(i) {})
94+
95+
On **hyvin** mahdollista, että `log` **ei** palauta funktiota. Tästä johtuen yllä oleva palauttanee `TypeError`-virheen, joka toteaa että `undefined ei ole funktio`.
96+
97+
### Yhteenveto
98+
99+
On suositeltavaa ettei puolipisteitä jätetä pois **milloinkaan**. Tämän lisäksi sulut kannattaa pitää niitä vastaavien lausekkeiden kanssa samalla rivillään. `if` ja `else`-lauseiden tapauksessa sulkuja kannattaa käyttää aina. Sen lisäksi että edellä mainitut suositukset tekevät koodista johdonmukaisempaa, estävät ne myös JavaScript-parseria muuttamasta sen käytöstapaa.
100+

doc/fi/core/undefined.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
## `undefined` ja `null`
2+
3+
JavaScript sisältää kaksi erillistä arvoa `ei millekään`. Näistä hyödyllisempti on `undefined`.
4+
5+
### `undefined` ja sen arvo
6+
7+
`undefined` on tyyppi, jolla on vain yksi arvo: `undefined`.
8+
9+
Kieli määrittelee myös globaalin muuttujan, jonka arvo on `undefined`. Myös tätä arvoa kutsutaan nimellä `undefined`. Tämä muuttuja **ei** kuitenkaan ole vakio eikä kielen avainsana. Tämä tarkoittaa siis sitä, että sen *arvo* voidaan ylikirjoittaa.
10+
11+
> **ES5 Huomio:** ECMAScript 5:ssä `undefined`-tyyppiä ei voida *kirjoittaa* **enää** tiukassa moodissa. Sen nimi voidaan kuitenkin jättää katveeseen määrittelemällä esimerkiksi funktio, jonka nimi on `undefined`.
12+
13+
Seuraavat tapaukset palauttavat `undefined`-arvon:
14+
15+
- Globaalin (muokkaamattoman) muuttujan `undefined` arvon haku.
16+
- Puuttuvista `return`-lauseista seuraavat epäsuorat palautusarvot.
17+
- `return`-lauseet, jotka eivät palauta selvästi mitään.
18+
- Olemattomien ominaisuuksien haut.
19+
- Funktioparametrit, joiden arvoa ei ole asetettu.
20+
- Mikä tahansa, joka on asetettu arvoon `undefined`.
21+
22+
### Arvon `undefined` muutosten hallinta
23+
24+
Koska globaali muuttuja `undefined` sisältää ainoastaan todellisen `undefined`-tyypin arvon kopion, **ei** sen asettamienn uudelleen muuta *tyypin* `undefined` arvoa.
25+
26+
Kuitenkin, jotta `undefined`-tyypin arvoa voidaan verrata, tulee sen arvo voida hakea jotenkin ensin.
27+
28+
Tätä varten käytetään yleisesti seuraavaa tekniikkaa. Ajatuksena on antaa itse arvo käyttäen [nimetöntä käärettä](#function.scopes).
29+
30+
var undefined = 123;
31+
(function(something, foo, undefined) {
32+
// paikallisen näkyvyysalueen undefined
33+
// voi viitata jälleen todelliseen arvoon
34+
35+
})('Hello World', 42);
36+
37+
Samaan lopputuloksen voidaan päästä myös käyttämällä esittelyä kääreen sisällä.
38+
39+
var undefined = 123;
40+
(function(something, foo) {
41+
var undefined;
42+
...
43+
44+
})('Hello World', 42);
45+
46+
Tässä tapauksessa ainut ero on se, että pakattu versio vie 4 tavua enemmän tilaa 'var'-lauseen vuoksi.
47+
48+
### `null` ja sen käyttötapaukset
49+
50+
Vaikka `undefined`-arvoa käytetäänkin usein perinteisen *null*-arvon sijasta, todellinen `null` (sekä literaali että tyyppi) on enemmän tai vähemmän vain tietotyyppi.
51+
52+
Sitä käytetään joissain JavaScriptin sisäisissä toiminnoissa, kuten prototyyppiketjun pään toteamisessa (`Foo.prototype = null`). Useimmissa tapauksissa se voidaan korvata `undefined`-arvoa käyttäen.
53+
54+

doc/fi/function/arguments.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
## `arguments`-olio
2+
3+
Jokainen JavaScriptin näkyvyysalue pääsee käsiksi erikoismuuttujaan nimeltään `arguments`. Tämä muuttuja sisältää listan kaikista funktiolle annetuista argumenteista.
4+
5+
> **Huomio:** Mikäli `arguments` on jo määritelty funktion sisällä joko näkyvyysalueen, `var`-lauseen tai parametrin kautta, `arguments`-oliota ei luoda.
6+
7+
`arguments`-olio **ei** ole `Array`. Sen semantiikka, erityisesti `length`-ominaisuus, muistuttaa taulukkoa. Tästä huolimatta se ei peri `Array.prototype`:stä ja on itse asiassa `Object`.
8+
9+
Tästä johtuen `arguments`-olioon **ei** voida soveltaa normaaleja taulukkometodeja, kuten `push`, `pop` tai `slice`. Vaikka iterointi onnistuukin `for`-luuppeja käyttäen, tulee se muuttaa aidoksi `Array`-olioksi ennen kuin siihen voidaan soveltaa näitä metodeja.
10+
11+
### Array-olioksi muuttaminen
12+
13+
Alla oleva koodi palauttaa uuden `Array`-olion, joka sisältää `arguments`-olion kaikki jäsenet.
14+
15+
Array.prototype.slice.call(arguments);
16+
17+
Tämä muutos on luonteeltaan **hidas** eikä sitä suositella käytettävän suorituskykyä vaativissa osissa koodia.
18+
19+
### Argumenttien antaminen
20+
21+
Funktiosta toiselle voidaan antaa argumentteja seuraavasti.
22+
23+
function foo() {
24+
bar.apply(null, arguments);
25+
}
26+
function bar(a, b, c) {
27+
// tee jotain
28+
}
29+
30+
Toinen keino on käyttää sekä `call`- että `apply`-funktioita yhdessä ja luoda nopeita, sitomattomia kääreitä.
31+
32+
function Foo() {}
33+
34+
Foo.prototype.method = function(a, b, c) {
35+
console.log(this, a, b, c);
36+
};
37+
38+
// Luo "metodin" sitomaton versio
39+
// Se ottaa seuraavat parametrit: this, arg1, arg2...argN
40+
Foo.method = function() {
41+
42+
// Tulos: Foo.prototype.method.call(this, arg1, arg2... argN)
43+
Function.call.apply(Foo.prototype.method, arguments);
44+
};
45+
46+
47+
### Muodolliset parametrit ja argumenttien indeksit
48+
49+
`arguments`-olio luo sekä *getter*- että *setter*-funktiot sekä sen ominaisuuksille että myös funktion muodollisille parametreille.
50+
51+
Tästä seuraa, että muodollisen parametrin arvon muuttaminen muuttaa myös `arguments`-olion vastaavan ominaisuuden arvoa ja toisin päin.
52+
53+
function foo(a, b, c) {
54+
arguments[0] = 2;
55+
a; // 2
56+
57+
b = 4;
58+
arguments[1]; // 4
59+
60+
var d = c;
61+
d = 9;
62+
c; // 3
63+
}
64+
foo(1, 2, 3);
65+
66+
### Suorituskykyyn liittyviä myyttejä ja totuuksia
67+
68+
`arguments`-olio luodaan aina paitsi jos se on jo julistettu nimenä funktiossa tai sen muodollisena parametrina. Tämä siitä huolimatta käytetäänkö sitä vai ei.
69+
70+
Sekä *getter*- ja *setter*-funktiot luodaan **aina**. Tästä seuraa, että niiden käytöllä ei ole juurikaan merkitystä suorituskyvyn kannalta.
71+
72+
> **ES5 Huomio:** Näitä *getter*- ja *setter*-funktioita ei luoda tiukassa moodissa.
73+
74+
On kuitenkin eräs tapaus, jossa suorituskyky kärsii. Tämä liittyy `arguments.callee`-ominaisuuden käyttöön.
75+
76+
function foo() {
77+
arguments.callee; // tee jotain tällä funktio-oliolla
78+
arguments.callee.caller; // ja kutsuvalla funktio-oliolla
79+
}
80+
81+
function bigLoop() {
82+
for(var i = 0; i < 100000; i++) {
83+
foo(); // normaalisti tämä olisi inline-optimoitu
84+
}
85+
}
86+
87+
Yllä olevassa koodissa `foo`-kutsua ei voida [käsitellä avoimesti][1], koska sen tulee tietää sekä itsestään että kutsujasta. Sen lisäksi, että se haittaa suorituskykyä, rikkoo se myös kapseloinnin. Tässä tapauksessa funktio voi olla riippuvainen tietystä kutsuympäristöstä.
88+
89+
On **erittäin suositeltavaa** ettei `arguments.callee`-ominaisuutta tai sen ominaisuuksia käytetä **ikinä**.
90+
91+
> **ES5 Huomio:** Tiukassa moodissa `arguments.callee` palauttaa `TypeError`-virheen, koska se käyttö on vanhennettu.
92+
93+
[1]: http://en.wikipedia.org/wiki/Inlining
94+

0 commit comments

Comments
 (0)