Skip to content

Sync with upstream @ 540d753e #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 700 commits into from
Closed
Changes from all commits
Commits
Show all changes
700 commits
Select commit Hold shift + click to select a range
86ed165
grammar suggestion
Sep 24, 2022
1b87b89
Omitting parentheses after `new`
web-dev-sam Sep 25, 2022
a965e49
typo
joaquinelio Sep 27, 2022
4c693a2
Update article.md
skromez Sep 27, 2022
1292386
typo
joaquinelio Sep 28, 2022
fe525d2
Change link to the spec
romanstetsyk Sep 28, 2022
f2ef231
Fix typo "stirng" to "string"
ann-kilzer Sep 29, 2022
8d89b7f
ECMA broken link
joaquinelio Sep 29, 2022
24dfb1f
Remove description of inconsistency between Chrome and Firefox
wdscxsj Sep 29, 2022
594bc55
https link
joaquinelio Sep 29, 2022
15ab2fd
Merge pull request #3209 from joaquinelio/patch-18
iliakan Sep 30, 2022
fde193a
Merge pull request #3208 from wdscxsj/patch-1
iliakan Sep 30, 2022
63bc08e
Merge pull request #3207 from joaquinelio/patch-17
iliakan Sep 30, 2022
4d42242
Merge pull request #3206 from ann-kilzer/patch-1
iliakan Sep 30, 2022
dc6e7d1
Merge pull request #3205 from romanstetsyk/master
iliakan Sep 30, 2022
e0621be
Merge pull request #3202 from joaquinelio/patch-15
iliakan Oct 1, 2022
4a9dc8e
Merge pull request #3204 from joaquinelio/patch-16
iliakan Oct 1, 2022
c8b4d34
move Unicode to a separate article
iliakan Oct 1, 2022
98d0c2c
Merge pull request #3201 from MindLaborDev/patch-1
iliakan Oct 1, 2022
b24e3fb
Merge pull request #3200 from digital-bw/patch-4
iliakan Oct 1, 2022
586cc54
Merge pull request #3199 from digital-bw/patch-3
iliakan Oct 1, 2022
2cb64ab
Merge pull request #3198 from skromez/master
iliakan Oct 1, 2022
2180da8
Merge pull request #3197 from digital-bw/patch-2
iliakan Oct 1, 2022
aedeed3
Merge pull request #3195 from digital-bw/patch-1
iliakan Oct 1, 2022
c27a7b4
closes #3185
iliakan Oct 1, 2022
c589176
closes #3183
iliakan Oct 1, 2022
666f356
closes #3190
iliakan Oct 1, 2022
c99d740
closes #3179
iliakan Oct 1, 2022
18b1314
closes #3096
iliakan Oct 2, 2022
cd86528
Fix typo
wdscxsj Oct 3, 2022
165a3f5
typo "optimzed
joaquinelio Oct 3, 2022
f0ce7e9
IE 9
joaquinelio Oct 3, 2022
f0fa52f
Fix typo
wdscxsj Oct 4, 2022
3a5d32e
Remove typo
aki-mizu Oct 5, 2022
4573d0b
Fix typos
TevaHenry Oct 5, 2022
dca45f7
Unicode art, grammar suggestions
joaquinelio Oct 5, 2022
dc7a157
Update article.md
joaquinelio Oct 5, 2022
87c0ca9
mdn link
joaquinelio Oct 6, 2022
af4843b
👾 smth
Rnbsov Oct 8, 2022
530dc9f
👾 smth
Rnbsov Oct 8, 2022
1d999c7
👾 smth
Rnbsov Oct 8, 2022
429caba
👾 smth
Rnbsov Oct 8, 2022
306a197
Update article.md
joaquinelio Oct 10, 2022
69bfbb0
Update article.md
joaquinelio Oct 10, 2022
b89b938
Update article.md
joaquinelio Oct 10, 2022
455c57a
Update article.md
joaquinelio Oct 10, 2022
6f34912
Update article.md
joaquinelio Oct 10, 2022
bf7d8bb
Merge pull request #3220 from joaquinelio/patch-19
iliakan Oct 10, 2022
7b0f9e5
Content-Length is now a CORS-safelisted response header
wdscxsj Oct 11, 2022
fe8ed87
Fix typo
wdscxsj Oct 12, 2022
75edb67
strict-origin-when-cross-origin is now the default referrerPolicy
wdscxsj Oct 12, 2022
0c5ac0e
typo at String concatenation with binary
adam4nj Oct 13, 2022
ca42edd
Remove a redundant argument
wdscxsj Oct 13, 2022
0487c35
Remove use of error.message in onerror()
wdscxsj Oct 14, 2022
c09efa8
http to https checked links
joaquinelio Oct 14, 2022
2ca8f83
closes #3242
iliakan Oct 18, 2022
245e59e
closes #3239
iliakan Oct 18, 2022
28803aa
Merge pull request #3238 from joaquinelio/pp
iliakan Oct 18, 2022
2f37897
minor fixes
iliakan Oct 18, 2022
f6cb5e9
Merge pull request #3237 from wdscxsj/patch-9
iliakan Oct 18, 2022
321b05e
Merge pull request #3223 from joaquinelio/patch-20
iliakan Oct 18, 2022
508ca01
closes #3229
iliakan Oct 18, 2022
5f91fda
closes #3230
iliakan Oct 18, 2022
aaf3b5b
Merge pull request #3231 from wdscxsj/patch-4
iliakan Oct 18, 2022
91e8edd
Merge pull request #3232 from wdscxsj/patch-5
iliakan Oct 18, 2022
36eb3da
Merge pull request #3233 from wdscxsj/patch-6
iliakan Oct 18, 2022
b0e2e04
Merge pull request #3234 from adam4nj/patch-1
iliakan Oct 18, 2022
a4050f2
Merge pull request #3235 from wdscxsj/patch-7
iliakan Oct 18, 2022
5dff42b
closes #3222
iliakan Oct 18, 2022
0c8e883
typo *udefined
joaquinelio Oct 20, 2022
4edd6b5
Proper Polish language inflection
f6p Oct 20, 2022
094aa10
Add .at( ) to strings summary
joaquinelio Oct 20, 2022
434e637
For the completeness of example.
Vic-Bonlight Oct 28, 2022
b3c7a7f
👾 add run button and remove typo
Rnbsov Oct 29, 2022
515dc44
👾 smth
Rnbsov Oct 29, 2022
78a9566
👾 smth
Rnbsov Oct 29, 2022
9e08049
👾 smth
Rnbsov Oct 29, 2022
1bda839
fix: typo getRangesAt to getRangeAt
leviding Oct 30, 2022
55b6c5e
Update article.md
nikolai-chernolutskii Oct 30, 2022
588117e
Update index.html
Alexandre887 Oct 30, 2022
4943f21
Update article.md
alagunoff Nov 1, 2022
8d185f7
Update article.md
Alexandre887 Nov 4, 2022
c70a3dc
Merge pull request #3218 from aki-mizu/patch-1
iliakan Nov 13, 2022
1fb0500
Merge pull request #3219 from TevaHenry/localstorage-sessionstorage
iliakan Nov 13, 2022
fe3d781
Merge pull request #3227 from Rnbsov/patch-75
iliakan Nov 13, 2022
1b078d0
Merge pull request #3245 from joaquinelio/patch-19
iliakan Nov 13, 2022
294a91e
Merge pull request #3246 from f6p/patch-1
iliakan Nov 13, 2022
083de40
Merge pull request #3247 from joaquinelio/patch-20
iliakan Nov 13, 2022
a4f1afd
Merge pull request #3248 from Victor-Nikliaiev/patch-1
iliakan Nov 13, 2022
fac9385
fixes #3249
iliakan Nov 13, 2022
ffbe0f5
Merge pull request #3251 from Rnbsov/patch-77
iliakan Nov 13, 2022
f47885b
minor fixes
iliakan Nov 13, 2022
7048f44
Merge pull request #3252 from leviding/patch-7
iliakan Nov 13, 2022
2c8f0fc
Merge pull request #3253 from nikolai-chernolutskii/patch-1
iliakan Nov 13, 2022
6fc7ba3
Merge pull request #3254 from Alexandre887/master
iliakan Nov 13, 2022
121141b
minor fixes
iliakan Nov 13, 2022
a665e29
Merge pull request #3255 from alagunoff/patch-1
iliakan Nov 13, 2022
8d9ecb7
Merge pull request #3258 from Alexandre887/patch-1
iliakan Nov 13, 2022
dafc925
the output is 0
joaquinelio Nov 14, 2022
c918da4
map.delete removes the pair key/value
joaquinelio Nov 14, 2022
9f1848c
Update article.md
joaquinelio Nov 14, 2022
d52f318
fix typo on Remainder %
cerealexperiments Nov 15, 2022
e1bec69
Merge pull request #3267 from cerealexperiments/patch-1
iliakan Nov 15, 2022
e912311
Merge pull request #3265 from joaquinelio/patch-20
iliakan Nov 15, 2022
cfc0195
Merge branch 'master' into patch-19
iliakan Nov 15, 2022
33c48a4
Merge pull request #3264 from joaquinelio/patch-19
iliakan Nov 15, 2022
477cb58
Merge pull request #3214 from joaquinelio/patch-17
iliakan Nov 15, 2022
746ad80
closes #3260
iliakan Nov 16, 2022
4e26c7e
Suggestion
bogdanbacosca Nov 26, 2022
657e389
minor code formatting
bogdanbacosca Nov 26, 2022
45a2d14
other code formatting bits
bogdanbacosca Nov 26, 2022
66ad8c1
Revert "minor code formatting"
bogdanbacosca Nov 26, 2022
67fe46f
Merge pull request #3279 from bogdanbacosca/if-else-bogdan
iliakan Nov 30, 2022
cfe2249
Bezier curves: update paused demo on point move
orelby Nov 30, 2022
1ce5644
Merge pull request #3287 from orelby/animation/bezier-curve/update-de…
iliakan Nov 30, 2022
8375316
fix typo, remove pleonasm
a-v-gor Dec 6, 2022
e75f655
small format change
joaquinelio Dec 7, 2022
4a8e8e1
Update article.md
Violet-Bora-Lee Dec 7, 2022
3f305f5
Merge pull request #3292 from a-v-gor/proofreading
iliakan Dec 11, 2022
9a26eb0
Merge pull request #3293 from joaquinelio/patch-19
iliakan Dec 11, 2022
ea7738b
Merge pull request #3295 from Violet-Bora-Lee/patch-4
iliakan Dec 11, 2022
b2e7dbf
grammar & legility (to check)
joaquinelio Dec 12, 2022
88d9b3f
removed -> remove; optimzed -> optimized ;
sagarpanchal Jan 18, 2023
ccd0a11
Fix "JavaScript specials" links
odsantos Jan 22, 2023
ae7afcb
update
bogdanbacosca Jan 24, 2023
03b8f2e
Merge pull request #3278 from bogdanbacosca/work
iliakan Jan 24, 2023
cd988dd
Fix a typo
MAHIN0093 Jan 24, 2023
bbf3a44
Update 1-js/05-data-types/04-array/article.md
MAHIN0093 Jan 24, 2023
f489288
Update button to fix horizontal scroll on mobile
marcusicaro Jan 25, 2023
4baa619
fix: add missing word 'to'
JeraldVin Jan 26, 2023
a4e9ba5
Merge pull request #3336 from JeraldVin/patch-1
iliakan Jan 26, 2023
d906956
Merge pull request #3334 from marcusicaro/patch-1
iliakan Jan 26, 2023
f9afaf3
Merge pull request #3330 from odsantos/fix-javascript-specials-links
iliakan Jan 26, 2023
5a3db89
Merge pull request #3332 from MAHIN0093/change
iliakan Jan 26, 2023
9e3fa13
Merge pull request #3302 from joaquinelio/patch-19
iliakan Jan 29, 2023
968fa09
added a word
Raviikumar001 Apr 4, 2023
ea5fbfa
added word fix
Raviikumar001 Apr 6, 2023
af71856
Merge pull request #3425 from Raviikumar001/Added-a-word
iliakan Apr 17, 2023
cd8dd53
#3345 Fixed Grammar
pradeep-ramola Apr 23, 2023
733ff69
Merge pull request #3435 from pradeep-ramola/master
iliakan Apr 29, 2023
e68750e
translated Russian word into English
MSHNK1 Jul 9, 2023
023c0ec
Fixing a minor grammatical typo in the document.
rahulrao0209 Jul 16, 2023
d694e89
Merge pull request #3492 from MSHNK1/fix-typos
iliakan Jul 17, 2023
285083f
minor fixes
iliakan Aug 7, 2023
8ab6b39
Add WeakRef and FinalizationRegistry article
WOLFRIEND Nov 4, 2023
5ab1ce2
Merge pull request #3609 from WOLFRIEND/master
iliakan Nov 15, 2023
b7ebc1b
Improve awkward sentence structure
smith558 Nov 24, 2023
75bad83
Improve grammar
smith558 Nov 24, 2023
74a8a19
Fix formatting char
smith558 Nov 27, 2023
d51037a
Fix grammar and add an example
nakhodkin Dec 27, 2023
c66bace
Fix grammar and typos
nakhodkin Dec 31, 2023
bbac8a5
Fix grammar and JavaScript syntax
nakhodkin Jan 2, 2024
1b9a28b
Update article.md
JaFro96 Jan 4, 2024
4ec440f
Update article.md
JaFro96 Jan 4, 2024
d83bfb2
refactor: Updated RFC spec Safe Methods URL in Cookies chapter
alexandermirzoyan Jan 12, 2024
9ec34c6
Replace assignment with equals in Truncate the text task
CJDumbleton Jan 17, 2024
2e0d5fb
Add missing word
qadzek Jan 20, 2024
52e184c
Add missing CSS unit
qadzek Jan 20, 2024
0530c92
fix square brackets
mikayel00 Jan 24, 2024
9270fe5
Merge pull request #3639 from JaFro96/master
smith558 Jan 24, 2024
f0f1006
fix: json
mikayel00 Jan 24, 2024
c98ec82
Merge pull request #3647 from CJDumbleton/CJDumbleton-patch-1
smith558 Jan 24, 2024
9c07c5b
Merge pull request #3649 from qadzek/patch-1
smith558 Jan 24, 2024
1a6edd7
Merge pull request #3656 from mikayel00/fix-brackets
smith558 Jan 26, 2024
9d157d8
Merge pull request #3617 from smith558/patch-3
smith558 Jan 27, 2024
b6c604a
Merge branch 'master' into patch-5
smith558 Jan 27, 2024
4286703
Merge pull request #3644 from alexandermirzoyan/patch-2
smith558 Jan 27, 2024
26ac4c8
Merge pull request #3212 from wdscxsj/patch-2
smith558 Jan 27, 2024
f24e463
Merge pull request #3213 from joaquinelio/patch-15
smith558 Jan 27, 2024
774d0c1
Merge pull request #3326 from sagarpanchal/patch-2
smith558 Jan 27, 2024
aacfc93
Fixed grammar error in regex-groups article.md
eedrxs Jan 27, 2024
e2ac312
Merge pull request #3659 from eedrxs/patch-1
smith558 Jan 27, 2024
ee62307
Update article.md
nepikn Feb 2, 2024
4a20875
Update article.md
smith558 Feb 11, 2024
5ce4b3a
Merge pull request #3664 from nepikn/patch-2
smith558 Feb 11, 2024
daca277
Fix grammar
smith558 Feb 11, 2024
3e92613
Improve options description
smith558 Feb 11, 2024
b6e7472
Update samesite content
smith558 Feb 13, 2024
d134cab
Remove "surely"
smith558 Feb 13, 2024
19e62af
Update article.md
smith558 Feb 13, 2024
a7d351f
change IndexedDb to IndexedDB (#3660)
0xtpsl Feb 13, 2024
ab1db04
Fix grammar and typos (#3628)
nakhodkin Feb 14, 2024
d461a93
Merge pull request #3217 from wdscxsj/patch-3
smith558 Feb 14, 2024
00bdf88
Update LICENSE.md
iliakan Mar 8, 2024
25c9bdf
Update LICENSE.md
iliakan Mar 8, 2024
c13e707
Update LICENSE.md
iliakan Mar 8, 2024
e15f535
Update LICENSE.md
iliakan Mar 8, 2024
2f91d87
Update LICENSE.md
iliakan Mar 8, 2024
ea05aa9
Updated result visualization
Filin3 Mar 31, 2024
04b73bf
Merge pull request #3681 from Filin3/patch-1
smith558 May 5, 2024
acf339c
Merge pull request #3632 from nakhodkin/patch-2
smith558 May 5, 2024
541b7f9
Merge pull request #3636 from nakhodkin/patch-5
smith558 May 5, 2024
0b9bc2f
Merge pull request #3634 from nakhodkin/patch-4
smith558 May 5, 2024
85da6f1
Update article.md
ellie-heidari May 10, 2024
475899e
Update article.md
smith558 May 17, 2024
7e524ba
Add link
smith558 May 17, 2024
42851f4
Update task.md
pvepamb1 May 18, 2024
2092da7
Merge pull request #3694 from pvepamb1/patch-1
smith558 May 18, 2024
f684d39
change example element of multidimensional array
sneeed Jun 8, 2024
c151e11
minor fixes
iliakan Jun 13, 2024
3fd3f98
- `run`
Alexandre887 Jun 23, 2024
d1ffe5d
docs: remove eval polyfill.io
kricsleo Jul 5, 2024
262f91a
Merge pull request #3712 from kricsleo/patch-1
smith558 Jul 8, 2024
815fafa
Merge pull request #3692 from ellie-heidari/patch-1
smith558 Jul 8, 2024
d6e0376
Remove BigInt IE incompatibility part (#3709)
FloffyGarlic Jul 9, 2024
5a0df77
Update article.md
shallow-beach Jul 10, 2024
62827d8
Merge pull request #3715 from shallow-beach/master
smith558 Jul 10, 2024
4104eba
Merge pull request #3704 from Alexandre887/patch-10
smith558 Jul 10, 2024
ca72abb
Merge pull request #3700 from sneeed/patch-2
smith558 Jul 10, 2024
b258d7d
Merge pull request #3495 from rahulrao0209/patch-1
smith558 Jul 10, 2024
6f08958
minor fix to function name written in explanation
tonybishnoi Oct 9, 2024
eedc262
Grammatical fix
nikoandpiko Oct 22, 2024
34a80e7
Merge pull request #3768 from tonybishnoi/patch-1
smith558 Oct 24, 2024
67833c9
Update article.md
zakingslayerv22 Dec 11, 2024
b36823a
better wording
pj-szdm Dec 18, 2024
dc14378
Update article.md
mhi1627 Jan 22, 2025
8b2a2f2
Improve readability
AdityaGirdhar Jan 30, 2025
a2b97b5
Merge pull request #3810 from AdityaGirdhar/patch-1
smith558 Feb 4, 2025
793ad4b
Merge branch 'master' into patch-1
smith558 Feb 4, 2025
e466826
Merge pull request #3772 from nikoandpiko/patch-1
smith558 Feb 4, 2025
a087279
Merge pull request #3804 from mhi1627/patch-1
smith558 Feb 8, 2025
26daef2
Merge pull request #3794 from zakingslayerv22/patch-1
smith558 Feb 8, 2025
6236eb8
Merge pull request #3797 from pj-szdm/patch-1
smith558 Feb 8, 2025
011dd4f
Update article.md
Gleb-Pastushenko Feb 10, 2025
1dce5b7
Merge pull request #3815 from Gleb-Pastushenko/patch-6
smith558 Feb 10, 2025
4b3474b
Fixed missing closing parenthesis in 2-ui/4-forms-control/1-form-elem…
vincent-clipet Mar 10, 2025
3d7abb9
Merge pull request #3822 from vincent-clipet/fix/missing_parenthesis
smith558 Mar 10, 2025
3de63df
promise.all task
iliakan Mar 24, 2025
ef31066
minor fixes
iliakan Mar 24, 2025
de4247b
minor fixes
iliakan Mar 24, 2025
0af25bc
minor fixes
iliakan Mar 24, 2025
d932e52
minor fixes
iliakan Mar 24, 2025
f0d8abb
minor fixes
iliakan Mar 24, 2025
f775835
minor fixes
iliakan Mar 24, 2025
0760c90
minor fixes
iliakan Mar 24, 2025
5dea441
minor fixes
iliakan Mar 24, 2025
035c526
minor fixes
iliakan Mar 24, 2025
4c4598b
Fix for #3826 - Removed errorception.com from the respective md file.
Paramesh-T-S Mar 29, 2025
cde189d
Update Safari settings screenshots
dangerman Apr 2, 2025
78c6c44
Update Safari devtools instructions
dangerman Apr 2, 2025
e88c212
Update Function object, NFE article
rahulrao0209 Apr 6, 2025
a711a1f
Merge pull request #3830 from Paramesh-T-S/Issue_fix_Outdate_-link_in…
iliakan Apr 8, 2025
efaa9aa
sentry.io added as per suggestion - https://github.com/javascript-tut…
Paramesh-T-S Apr 8, 2025
6cc5077
Merge pull request #3835 from Paramesh-T-S/Issue_fix_Outdate_-link_in…
iliakan Apr 9, 2025
81cfee9
Update article.md
rahulrao0209 Apr 13, 2025
e2d8ebe
Merge pull request #3836 from rahulrao0209/patch-3
smith558 Apr 13, 2025
6bbdd0c
Merge pull request #3834 from rahulrao0209/patch-2
smith558 Apr 13, 2025
d3c395c
Merge pull request #3832 from dangerman/update-safari-devtools-screen…
smith558 Apr 13, 2025
540d753
Replace with up to date screenshots
smith558 Apr 13, 2025
f3145fa
merging all conflicts
iliakan May 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: iliakan
47 changes: 47 additions & 0 deletions 1-js/01-getting-started/1-intro/article.md
Original file line number Diff line number Diff line change
@@ -34,16 +34,26 @@ Skirtingi varikliai turi skirtingus slapyvardžius. Pavyzdžiui:
Varikliai yra sudėtingi, bet pagrindai yra paprasti.
<<<<<<< HEAD
1. Variklis (vidinis, jei jis yra naršyklėje) skaito skriptą.
2. Konvertuoja (dar kitaip - kompiliuoja) skriptą į mašininį kodą.
3. Įvykdomas mašininis kodas.
=======
1. The engine (embedded if it's a browser) reads ("parses") the script.
2. Then it converts ("compiles") the script to machine code.
3. And then the machine code runs, pretty fast.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Varikliai optimizuoja kodą kiekviename žingsnyje. Jie netgi stebi sukompiliuotą skriptą, kuomet jis vykdomas, bei analizuoja duomenis, kurie jame naudojami, ir pagal tai taiko papildomas optimizacijas. Po viso šio procesio, skriptai yra vykdomi gan greitai.
```

## Ką gali JavaScript padaryti naršyklėje?

<<<<<<< HEAD
Modernus JavaScript yra “saugi” programavimo kalba. Ji neleidžia programuotojui pasiekti atminties arba CPU, nes iš pat pradžių ji buvo sukurta naršyklėms, kurioms to nereikia.
=======
Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or the CPU, because it was initially created for browsers which do not require it.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
JavaScript galimybės stipriai priklauso nuo aplinkos, kurioje ji vykdomas. Pavyzdžiui, [Node.js](https://wikipedia.org/wiki/Node.js) palaiko funkcijas, kurios leidžia Javascript skaityti/rašyti failus, vykdyti kompiuterių tinklų užklausas ir pan.

@@ -59,7 +69,11 @@ Pavyzdžiui, JavaScript naršyklėje gali:

## Ko NEGALI padaryti JavaScript naršyklėje?

<<<<<<< HEAD
JavaScript galimybės naryklėje yra ribojamos dėl vartotojų saugumo. Tikslas - neleisti tinklalapiams pasiekti privačius duomenis arba žaloti vartotojo duomenis.
=======
JavaScript's abilities in the browser are limited to protect the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Ribojimų pavyzdžiai:
- JavaScript tinklalapyje negali skaityti/rašyti failus esančius kietajame diske, juos kopijuoti arba vykdyti programas. JavaScript neturi tiesioginės prieigos prie operacinės sistemos funkcijų.
@@ -71,12 +85,26 @@ Ribojimų pavyzdžiai:

Tai vadinama “Same Origin Policy”. Norint tai apeiti, *abu tinklalapiai* turi susitarti dėl keitimosi duomenimis ir juose turi būti specialus JavaScript kodas, kuris tai tvarko. Apie tai kalbėsime vienoje iš pamokų.

<<<<<<< HEAD
Šis ribojimas yra, vėlgi, dėl vartotojų saugmo. Tinklapis `http://anysite.com`, kurį vartotojas atidarė, neturėtų pasiekti kitos naršyklės kortelės su URL `http://gmail.com` ir vogti informaciją.
- JavaScript gali lengvai komunikuoti internetu su serveriu, iš kurio atėjo tinklalapis. Bet tinklalapio galimybės gauti duomenis iš kitų tinklapių/duomenų yra kiek sudėtingesnės. Nors ir įmanoma, tai reikalauja išreikštinio susitarimo (per HTTP antraštes) iš nuotolinio serverio pusės. Vėlgi, dėl saugumo priežasčių.

![](limitations.svg)

Šių ribojimų nėra, jeigu JavaScript vykdomas ne naršyklėje, bet, pavyzdžiui, serveryje. Šiuolaikinės naršyklės taip pat turi papildinius ir plėtinius (ang. *plugins/extensions*), kurie gali prašyti vartotojų leidimo.
=======
There are ways to interact with the camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency).
- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other page if they come from different sites (from a different domain, protocol or port).

This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and must contain special JavaScript code that handles it. We'll cover that in the tutorial.

This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com`, for example, and steal information from there.
- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation.

![](limitations.svg)

Such limitations do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugins/extensions which may ask for extended permissions.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Kuo ypatinga JavaScript?

@@ -90,20 +118,29 @@ JavaScript yra vienintelė naršyklės technologija, kuri turi šiuos tris dalyk

Štai kuo ypatinga JavaScript. Tai yra viena labiausiai išplitusių technologijų, kalbant apie naršyklės sąsajos (ang. *interface*) kūrimą.

<<<<<<< HEAD
Tačiau su JavaScript galima rašyti serverines, mobilias programas (ang. *applications*) ir pan.
=======
That said, JavaScript can be used to create servers, mobile applications, etc.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Kalbos “virš” JavaScript

JavaScript sintaksė, be abejo, tinka ne visiem ir ne visada. Skirtingi žmonės nori skirtingų savybių.

Nieko nuostabaus, nes kiekvienas projektas yra skirtingas ir gali turėti labai skirtingų reikalavimų.

<<<<<<< HEAD
Dėl šių priežasčių atsirado daug kalbų, kurios yra konvertuojamos (ang. *transpiling*) į JavaScript ir tik tada vykdomos naršyklėje.
=======
So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Modernūs įrankiai atlieka konvertaciją labai greitai, tad programuotojai gali programuoti šiomis kalbomis nesigilindami į patį konvertavimo procesą.

Tokių kalbų pavyzdžiai:

<<<<<<< HEAD
- [CoffeeScript](http://coffeescript.org/) yra “syntactic sugar” JavaScript. Trumpesnė sintaksė, su kuria galima rašyti aiškesnį ir konkretesnį kodą. Tai dažniausiai patinka Ruby programuotojams.
- [TypeScript](http://www.typescriptlang.org/) pagrindinis tikslas yra įvesti statinį tipizavimą. Tai palengvina sudėtingų sistemų programavimą. Sukurtas Microsoft.
- [Flow](http://flow.org/) taip pat turi statinį tipizavimą, bet kiek kitokiu būdu. Sukurtas Facebook.
@@ -112,6 +149,16 @@ Tokių kalbų pavyzdžiai:
- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) yra moderni, glausta ir saugi programavimo kalba, kuri gali būti skirta naršyklei arba Node

Yra ir daugiau pavyzdžių. Tačiau, netgi jeigu mes naudojame kažkurią iš transpiliuojamų kalbų, suprasti JavaScript yra ne mažiau svarbu.
=======
- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node.

There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Santrauka

23 changes: 23 additions & 0 deletions 1-js/01-getting-started/2-manuals-specifications/article.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@

# Vadovai ir specifikacija

<<<<<<< HEAD
Ši knyga yra *pamokų formato*. Jos tikslas - padėti palaipsniui išmokti kalbą. Tačiau kuomet išmoksti pagrindus, prireikia kitų resursų.
=======
This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Specifikacija

[The ECMA-262 specification](https://www.ecma-international.org/publications/standards/Ecma-262.htm) turi pačią nuodugniausią, detalią ir formalią informaciją apie JavaScript. Iš esmės, ši specifikacija apibrėžia pačią kalbą.

Tačiau iš šios specifikacijos mokytis iš pat pradžių yra gana sunku, nes informacija labai formali. Jeigu reikia pačios tiksliausios informacijos apie kalbą, specifikacija yra puikus šaltinis. Tačiau vargu, ar to prireiks kiekvieną dieną.

<<<<<<< HEAD
Kasmet yra išleidžiama nauja specifikacijos versija. Tarp šitų išleidimų, galima rasti juodraštį (ang. *draft*) čia <https://tc39.es/ecma262/>.
=======
A new specification version is released every year. Between these releases, the latest specification draft is at <https://tc39.es/ecma262/>.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Galite perskaityti apie naujausias savybes, įskaitant ir tas, kurios yra “beveik standartas” (dar vadinamas “stage 3”) galima rasti <https://github.com/tc39/proposals>.

@@ -20,10 +28,16 @@ Taip pat, jeigu norite programuoti naršyklei, tam yra kita specifikacija, kuri

Vadovą galima rasti <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference>.

<<<<<<< HEAD

Tačiau, dažniausiai geriausia tiesiog ieškoti informacijos internete. Verta tiesiog naudoti “MDN [terminas]” užklausoje, pavyzdžiui <https://google.com/search?q=MDN+parseInt> tam, kad rastumėte informacijos apie `parseInt` funkciją.

## Suderinamumo lentelės
=======
You can find it at <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference>.

Although, it's often best to use an internet search instead. Just use "MDN [term]" in the query, e.g. <https://google.com/search?q=MDN+parseInt> to search for the `parseInt` function.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
JavaScript yra nuolatos tobulinama kalba, todėl naujos savybės atsiranda reguliariai.

@@ -32,6 +46,15 @@ Pamatyti, ar šias savybes palaiko konkrečios naršyklės ar kiti varikliai, ga
- <http://caniuse.com> - kiekvienos savybės suderinamumo lentelės. T.y. kad pamatyti kurie varikliai palaiko modernias kriptografijos funkcijas: <http://caniuse.com/#feat=cryptography>.
- <https://kangax.github.io/compat-table> - lentelė su kalbos savybe ir varikliais, kurie palaiko/nepalaiko šias savybes.

<<<<<<< HEAD
Visi šie šaltiniai yra naudingi realiame pasaulyje, nes jie turi svarbios informacijos apie kalbą, suderinamumą ir pan.

Prisimink juos tiems atvejams, kai reikės detalios informacijos apie konkrečią savybę.
=======
- <https://caniuse.com> - per-feature tables of support, e.g. to see which engines support modern cryptography functions: <https://caniuse.com/#feat=cryptography>.
- <https://kangax.github.io/compat-table> - a table with language features and engines that support those or don't support.

All these resources are useful in real-life development, as they contain valuable information about language details, their support, etc.

Please remember them (or this page) for the cases when you need in-depth information about a particular feature.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
24 changes: 24 additions & 0 deletions 1-js/01-getting-started/3-code-editors/article.md
Original file line number Diff line number Diff line change
@@ -14,7 +14,12 @@ Jeigu dar neišsirinkote IDE, pamąstykite apie šiuos:
- [Visual Studio Code](https://code.visualstudio.com/) (daugiaplatformis, nemokamas).
- [WebStorm](http://www.jetbrains.com/webstorm/) (daugiaplatformis, mokamas).

<<<<<<< HEAD
Windows taip pat yra “Visual Studio”, tačiau nereiktų jo maišyt su “Visual Studio Code”. “Visual Studio” yra mokamas ir tik Windows skirtas redaktorius, kuris puikiai derinasi su .NET platforma. Jis taip pat tinka ir JavaScript. yra ir nemokama versija [Visual Studio Community](https://www.visualstudio.com/vs/community/).
=======
- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Dauguma IDE yra mokami, tačiau turi bandomąjį periodą. Jų kaina dažniausiai pakenčiama, atsižvelgiant į programuotojų atlyginimus, tad tiesiog išsirink tokį, kuris atrodo patogiausiai.

@@ -30,14 +35,33 @@ Praktikoj, lengvasvoriai redaktoriai turi daug papildymų (ang. *plugins*), įsk

Šie pasirinkimai verti dėmesio:

<<<<<<< HEAD
- [Sublime Text](http://www.sublimetext.com) (daugiaplatformis, laikinai nemokamas).
- [Notepad++](https://notepad-plus-plus.org/) (Windows, nemokamas).
- [Vim](http://www.vim.org/) ir [Emacs](https://www.gnu.org/software/emacs/) yra labai puikūs, jeigu moki jais naudotis.

## Nesiginčykime
=======
There are many options, for instance:

- [Sublime Text](https://www.sublimetext.com/) (cross-platform, shareware).
- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
- [Vim](https://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Redaktoriai, kurie buvo paminėti šioje pamokoje yra tie, kuriuos aš ir mano draugai, kuriuos laikau kietais programuotojais, naudojame ilgą laiką ir kurie tenkina mūsų poreikius.

Mūsų dideliame pasaulyje yra kitų puikių redaktorių. Tiesiog pasirink tokį, kuris tau labiausiai patinka.

<<<<<<< HEAD
Redaktoriaus pasirinkimas, kaip ir bet kokio kito įrankio, yra individualus ir priklauso nuo projektų bei kitų, dažnai subjektyvių kriterijų.
=======
There are other great editors in our big world. Please choose the one you like the most.

The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences.

The author's personal opinion:

- I'd use [Visual Studio Code](https://code.visualstudio.com/) if I develop mostly frontend.
- Otherwise, if it's mostly another language/platform and partially frontend, then consider other editors, such as XCode (Mac), Visual Studio (Windows) or Jetbrains family (Webstorm, PHPStorm, RubyMine etc, depending on the language).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
6 changes: 5 additions & 1 deletion 1-js/01-getting-started/4-devtools/article.md
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ Programuotojų įrankiai standartiškai atidarys konsolės langą.

Turėtų atrodyt panašiai į tai:

![chrome](chrome.png)
![chrome](chrome.webp)

Konkretus vaizdas priklauso nuo Chrome versijos, kurią naudojate. Kartais atsiranda pakeitimų, bet visgi vaizdas turėtų būti panašus.

@@ -49,7 +49,11 @@ Jų išvaizda gana panaši. Kai išmoksti vieną (gali pradėti nuo Chrome), gal

Safari (Mac naršyklė, neveikia Windows/Linux) yra šiek tiek unikali. Iš pradžių mums reikia įjungti “Programuotojo Meniu” (ang. *“developer menu”*).

<<<<<<< HEAD
Atidarykite Nuostatas (ang. “*preferences*”) ir eikite į "Pažangi" (ang. “advanced”). Apačioj bus langelis (ang. *“checkbox”*):
=======
Open Settings and go to the "Advanced" pane. There's a checkbox at the bottom:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
![safari](safari.png)

Binary file removed 1-js/01-getting-started/4-devtools/chrome.png
Binary file not shown.
Binary file added 1-js/01-getting-started/4-devtools/chrome.webp
Binary file not shown.
Binary file added 1-js/01-getting-started/4-devtools/chrome@2.webp
Binary file not shown.
Binary file removed 1-js/01-getting-started/4-devtools/chrome@2x.png
Binary file not shown.
Binary file modified 1-js/01-getting-started/4-devtools/safari.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified 1-js/01-getting-started/4-devtools/safari@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion 1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
Original file line number Diff line number Diff line change
@@ -12,13 +12,24 @@ const birthday = '18.04.1982';
const age = someCode(birthday);
```

<<<<<<< HEAD
Mes turime konstantą `birthday` data ir amžius `age` yra paskaičiuojame pagal `birthday` tam tikro kodo pagalba (jis čia nepateiktas dėl glaustumo ir dėl to, kad tai nėra svarbu užduočiai).
=======
Here we have a constant `birthday` for the date, and also the `age` constant.

The `age` is calculated from `birthday` using `someCode()`, which means a function call that we didn't explain yet (we will soon!), but the details don't matter here, the point is that `age` is calculated somehow based on the `birthday`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Ar būtų gerai naudoti didžiąsias raides `birthday`? O kaip dėl `age`? O galbūt netgi abiems?

```js
<<<<<<< HEAD
const BIRTHDAY = '18.04.1982'; // perrašyti didžiosiomis raidėmis?

const AGE = someCode(BIRTHDAY); // perrašyti didžiosiomis raidėmis?
```
=======
const BIRTHDAY = '18.04.1982'; // make birthday uppercase?

const AGE = someCode(BIRTHDAY); // make age uppercase?
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
76 changes: 76 additions & 0 deletions 1-js/02-first-steps/04-variables/article.md
Original file line number Diff line number Diff line change
@@ -63,7 +63,12 @@ let age = 25;
let message = 'Labas';
```

<<<<<<< HEAD
Kai kurie žmonės apibrėžia kelis kintamuosius tokiu kelių eilių stiliumi:
=======
Some people also define multiple variables in this multiline style:

>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js no-beautify
let user = 'John',
age = 25,
@@ -88,22 +93,37 @@ Senesniuose skriptuose galite rasti kitą raktažodį: `var` vietoje `let`:
*!*var*/!* message = 'Labas';
```

<<<<<<< HEAD
Raktažodis `var` yra *beveik* tas pats kaip `let`. Jis taip pat deklaruoja kintamąjį, bet šiek tiek kitokiu, “senoviniu” būdu.

Yra subtilūs skirtumai tarp `let` ir `var`, bet kol kas jie mums nėra svarbūs. Mes apie juos kalbėsime detaliau skyriuje <info:var>.
=======
The `var` keyword is *almost* the same as `let`. It also declares a variable but in a slightly different, "old-school" way.

There are subtle differences between `let` and `var`, but they do not matter to us yet. We'll cover them in detail in the chapter <info:var>.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## Realaus gyvenimo analogija
Tam kad būtų lengviau suprasti “kintamojo” sąvoką, įsivaizduokime jį kaip “dėžę” skirtą sudėti duomenims, ant kurios priklijuotas unikaliai pavadintas lipdukas.
<<<<<<< HEAD
Pavyzdžiui kintamąjį `message` galime įsivaizduoti kaip dėžę su etikete `"message"`, kurios viduje yra patalpinta vertė `"Labas!"`:
=======
For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
![](variable.svg)
Mes galime į dėžę įdėti bet kokią vertę.
<<<<<<< HEAD
Mes taip pat galime ją pakeisti kiek norime kartų:
=======
We can also change it as many times as we want:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let message;
@@ -149,12 +169,21 @@ let message = "That"; // SyntaxError: 'message' has already been declared
Taigi, kintamąjį turėtume deklaruoti vieną kartą, o tada į jį atsiremti be `let`.
````

<<<<<<< HEAD
```smart header="Funkcinės kalbos"
Yra įdomu pastebėti, kad egzistuoja [funkcinės](https://en.wikipedia.org/wiki/Functional_programming) programavimo kalbos, tokios kaip [Scala](http://www.scala-lang.org/) arba [Erlang](http://www.erlang.org/), kurios draudžia keisti kintamųjų vertes.
=======
```smart header="Functional languages"
It's interesting to note that there exist so-called [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming languages, such as [Haskell](https://en.wikipedia.org/wiki/Haskell), that forbid changing variable values.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Tokiose kalbose, kai vertė yra patalpinama “į dėžę”, ji ten ir pasilieka amžiams. Jeigu norime patalpinti kažką kito, kalba mus priverčia sukurti naują dėžę (deklaruoti naują kintamąjį). Mes nebegalime dar kartą panaudoti senojo.
<<<<<<< HEAD
Nors tai atrodo keistai iš pirmo žvilgsnio, tačiau šios kalbos yra gana gabios rimtame programų kūrime. Dar daugiau, yra tam tikrų sričių kaip lygiagretusis skaičiavimas (ang. *“parallel computations”*) kur toks apribojimas suteikia tam tikros naudos. Studijuoti tokią kalbą (net jeigu neplanuojate jos greitu laiku naudoti) yra rekomenduotina, kad praplėstumėte savo mąstymą.
=======
Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```

## Kintamųjų įvardinimas [#variable-naming]
@@ -192,19 +221,32 @@ let 1a; // negali prasidėti skaičiumi
let my-name; // brūkšniai '-' pavadinime neleidžiami
```

<<<<<<< HEAD
```smart header="Svarbu didžiosios ar mažosios raidės"
Kintamieji su pavadinimais `obuolys` ir `obuoLYS` yra du skirtingi kintamieji.
```

````smart header="Nelotyniškos raidės leidžiamos, bet nerekomenduojamos"
Galima naudoti bet kokią kalbą, įskaitant kirilicos raides ar net hieroglifus:
=======
```smart header="Case matters"
Variables named `apple` and `APPLE` are two different variables.
```
````smart header="Non-Latin letters are allowed, but not recommended"
It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
let имя = '...';
let 我 = '...';
```
<<<<<<< HEAD
Techniškai jokios klaidos tame nėra ir tokie pavadinimai yra leistini, tačiau tarptautinė tradicija yra naudoti angliškus kintamųjų pavadinimus. Net jeigu rašome trumpą skriptą, jo gyvenimas gali būti labai ilgas. Kada nors žmonėms iš kitų šalių gali tekti jį perskaityti.
=======
Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it sometime.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````

````warn header="Rezervuoti pavadinimai"
@@ -259,12 +301,20 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // klaida, negalima priskirti konstantos iš naujo!
```
<<<<<<< HEAD
Kai programuotojas yra užtikrintas, kad kintamasis niekada nesikeis, gali deklaruoti jį su `const`, kad garantuotų ir aiškiai praneštų šį faktą ir kitiems.
=======
When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and communicate that fact to everyone.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### Konstantos didžiosiomis raidėmis
<<<<<<< HEAD
Plačiai paplitusi praktika naudoti konstantas kaip kodinius pavadinimus sunkiai įsimenamoms vertėms, kurios yra jau žinomos prieš atlikimą.
=======
There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Tokios konstantos pavadinamos naudojant didžiąsias raides ir pabrėžimo ženklą.
@@ -289,35 +339,61 @@ Nauda:
Kada turėtume naudoti didžiąsias raides konstantoms ir kada turėtume jas pavadinti normaliu būdu? Išsiaiškinkime.
<<<<<<< HEAD
Būti “konstanta” tereiškia, kad to kintamojo vertė niekada nesikeičia. Bet yra tokių konstantų, kurių vertė yra žinoma prieš kodo atlikimą (kaip pavyzdžiui šešioliktainė raudonos spalvos vertė) ir taip pat yra konstantos, kurios yra *išmatuojamos* (ang. *“calculated”*) veikimo metu kol vykdomas kodas, bet nesikeičia po jų pradinio paskyrimo.
Pavyzdžiui:
=======
Being a "constant" just means that a variable's value never changes. But some constants are known before execution (like a hexadecimal value for red) and some constants are *calculated* in run-time, during the execution, but do not change after their initial assignment.
For instance:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
const pageLoadTime = /* kiek laiko užtruko paleisti puslapį */;
```
<<<<<<< HEAD
Vertė `pageLoadTime` nebuvo žinoma prieš paleidžiant puslapį, tad pavadinimas užrašytas įprastiniu būdu, bet tai vis dar konstanta, nes ji nesikeičia po paskyrimo.
Kitais žodžiais, didžiosiomis raidėmis pavadintos konstantos yra naudojamos kaip kodiniai žodžiai išanksto sukoduotoms (ang. *“hard-coded”*) vertėms.
=======
The value of `pageLoadTime` is not known before the page load, so it's named normally. But it's still a constant because it doesn't change after the assignment.
In other words, capital-named constants are only used as aliases for "hard-coded" values.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Teisingai įvardykite dalykus
Kalbant apie kintamuosius yra dar vienas labai svarbus punktas.
Kintamojo pavadinimas turi turėti švarią, aiškią reikšmę, apibūdinančią duomenis, kuriuos jis saugo.
<<<<<<< HEAD
Kintamųjų įvardinimas yra viena iš svarbiausių ir sudėtingiausių sugebėjimų programuojant. Žvilgtelėjus į kintamųjų pavadinimus galima nustatyti kurį kodą parašė naujokas, o kurį jau patyręs programuotojas.
Tikrame projekte, daugiausiai laiko yra skiriama modifikuoti ir išplėsti jau esamą kodą negu rašant kažką visiškai naujo nuo pat pradžių. Kai grįžtame prie kodo po to kai kurį laiką darėme kažką kito, daug lengviau kai randi informaciją su aiškiomis etiketėmis. Arba kitaip tariant, kai kintamieji turi gerus pavadinimus.
=======
Variable naming is one of the most important and complex skills in programming. A glance at variable names can reveal which code was written by a beginner versus an experienced developer.
In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Prašau, skirkite laiko sugalvodami kintamajam tinkamą pavadinimą prieš jį deklaruodami. Toks įprotis jums tikrai vėliau atsipirks.
Kelios sektinos taisyklės:
<<<<<<< HEAD
- Naudokite žmogui lengvai perskaitomus pavadinimus, kaip `userName` arba `shoppingCart`.
- Laikykitės atokiau nuo sutrumpinimų arba trumpų pavadinimų kaip `a`, `b`, `c`, nebent tikrai žinote ką darote.
- Pavadinimus kurkite kaip galima labiau apibūdinančius, bet glaustus. Pavyzdžiui blogi pavadinimai yra tokie kaip `data` ir `value`. Tokie pavadinimai nieko nesako. Tinka tik tokiu atveju jeigu kodo turinys yaptingai aiškiai parodo, į kuriuos “data” arba “value” kintamasis nurodo.
- Susitarkite dėl terminų su komanda ir savo mintyse. Jeigu lankytojas puslapyje yra vadinamas “user” tai ir susiję kintamieji turi būti pavadinti `currentUser` arba `newUser` vietoje `currentVisitor` arba `newManInTown`.
=======
- Use human-readable names like `userName` or `shoppingCart`.
- Stay away from abbreviations or short names like `a`, `b`, and `c`, unless you know what you're doing.
- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing.
- Agree on terms within your team and in your mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Skamba paprastai? Iš tikrųjų taip ir yra, bet praktikoje sukurti apibūdinančius ir tuo pačiu glaustus kintamųjų pavadinimus nėra lengva. Pabandykite.
37 changes: 37 additions & 0 deletions 1-js/02-first-steps/05-types/article.md
Original file line number Diff line number Diff line change
@@ -68,9 +68,26 @@ Daugiau apie darbą su skaičiais bus skyriuje <info:number>.

## BigInt [#bigint-type]

<<<<<<< HEAD
JavaScript tipo “number” sudėtyje negali būti skaičių, didesnių už <code>(2<sup>53</sup>-1)</code> (t. y. `9007199254740991`), arba mažesnių nei <code>-(2<sup>53</sup>-1)</code> neigiamiems skaičiams. Šį techninį apribojimą lemia jų vidinė išvaizda.

Tačiau kartais mums reikia tikrai milžiniškų skaičių, pavyzdžiui, kriptografijoje arba naudojant laiko žymą (“timestamp”) su mikrosekundėmis.
=======
In JavaScript, the "number" type cannot safely represent integer values larger than <code>(2<sup>53</sup>-1)</code> (that's `9007199254740991`), or less than <code>-(2<sup>53</sup>-1)</code> for negatives.
To be really precise, the "number" type can store larger integers (up to <code>1.7976931348623157 * 10<sup>308</sup></code>), but outside of the safe integer range <code>±(2<sup>53</sup>-1)</code> there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored.

For example, these two numbers (right above the safe range) are the same:

```js
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992
```

So to say, all odd integers greater than <code>(2<sup>53</sup>-1)</code> can't be stored at all in the "number" type.
For most purposes <code>±(2<sup>53</sup>-1)</code> range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Neseniai į kalbą buvo pridėtas `BigInt` tipas, kuriuo galima išreikšti bet kokio ilgio sveikuosius skaičius.
@@ -83,12 +100,15 @@ const bigInt = 1234567890123456789012345678901234567890n;
Kadangi `BigInt` skaičiai reikalingi retai, čia jų neaprašysime, bet skirsime jiems atskirą skyrių <info:bigint>. Jį skaitykite, kai prireiks tokių didelių skaičių.
<<<<<<< HEAD
```smart header="Suderinamumo problemos"
Šiuo metu `BigInt` yra palaikomas Firefox/Chrome/Edge/Safari, bet ne IE.
```
Jūs galite patikrinti [*MDN* BigInt suderinamumo lentelė](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) norėdami sužinoti, kurios naršyklės versijos yra palaikomos.
=======
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## String
Eilutė (ang. *“String”*) JavaScript turi būti apsupta kabutėmis.
@@ -212,7 +232,11 @@ Tipas `symbol` yra naudojamas unikaliems objektų identifikatoriams sukurti. Tur
## Operatorius typeof [#type-typeof]
<<<<<<< HEAD
Operatorius `typeof` grąžina argumento tipą. Jis naudingas kai mes norime išskirtinai apdoroti skirtingų tipų vertes arba norime greitai patikrinti tipą.
=======
The `typeof` operator returns the type of the operand. It's useful when we want to process values of different types differently or just want to do a quick check.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

Iškvietimas `typeof x` grąžina eilutę su tipo pavadinimu:

@@ -262,6 +286,7 @@ Kai kurie žmonės mėgsta `typeof(x)`, nors `typeof x` sintaksė yra daug dažn

JavaScript turi 8 pagrindinius duomenų tipus.

<<<<<<< HEAD
- `number` skirtas bet kokio tipo skaičiams: sveikiems ir slankiojančio kablelio skaičiams.
- `bigint` skirtas bet kokio ilgio sveikiesiems skaičiams.
- `string` skirtas eilutėms. Eilutė gali turėti vieną ar daugiau ženklų, nėra atskiro vieno-ženklo tipo.
@@ -270,6 +295,18 @@ JavaScript turi 8 pagrindinius duomenų tipus.
- `undefined` nepriskirtoms vertėms -- atskiras tipas turintis vieną vertę `undefined`.
- `object` skirtas sudėtingesnėms duomenų struktūroms.
- `symbol` skirtas unikaliems identifikatoriams.
=======
- Seven primitive data types:
- `number` for numbers of any kind: integer or floating-point, integers are limited by <code>±(2<sup>53</sup>-1)</code>.
- `bigint` for integer numbers of arbitrary length.
- `string` for strings. A string may have zero or more characters, there's no separate single-character type.
- `boolean` for `true`/`false`.
- `null` for unknown values -- a standalone type that has a single value `null`.
- `undefined` for unassigned values -- a standalone type that has a single value `undefined`.
- `symbol` for unique identifiers.
- And one non-primitive data type:
- `object` for more complex data structures.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Operatorius `typeof` leidžia matyti, kuris tipas yra saugomas kintamajame.
18 changes: 18 additions & 0 deletions 1-js/02-first-steps/07-type-conversions/article.md
Original file line number Diff line number Diff line change
@@ -6,8 +6,13 @@ Pavyzdžiui `alert` automatiškai paverčia bet kokią jiems duotą vertę į ei

Yra tokių konkrečių atvejų kai mums reikia vertę pakeisti į atitinkamą tipą.

<<<<<<< HEAD
```smart header="Dar nekalbant apie objektus"
Šiame skyriuje kol kas dar nekalbėsime apie objektus. Dabar kalbėsime tik apie primityvus.
=======
```smart header="Not talking about objects yet"
In this chapter, we won't cover objects. For now, we'll just be talking about primitives.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Vėliau, kai susipažinsime su objektais, skyriuje <info:object-toprimitive> pamatysime, kaip objektai tinka.
```
@@ -34,7 +39,11 @@ Eilutės konversijos dažniausiai yra labai akivaizdžios. `false` tampa `"false

## Skaičių konversijos

<<<<<<< HEAD
Skaičių konversijos įvyksta automatiškai matematinėse funkcijose ir formulėse.
=======
Numeric conversion in mathematical functions and expressions happens automatically.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Pavyzdžiui, kai dalyba `/` taikoma ne skaičiams:

@@ -69,8 +78,13 @@ Skaičių konversijos taisyklės:
|-------|-------------|
|`undefined`|`NaN`|
|`null`|`0`|
<<<<<<< HEAD
|<code>true&nbsp;ir&nbsp;false</code> | `1` ir `0` |
| `string` | Tarpai pradžioje ir pabaigoje panaikinami. Jeigu likusi eilutė yra tuščia, rezultatas yra `0`. Kitu atveju, skaičius "perskaitomas" iš eilutės. Klaida grąžina `NaN`. |
=======
|<code>true&nbsp;and&nbsp;false</code> | `1` and `0` |
| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Pavyzdžiai:

@@ -130,7 +144,11 @@ Konversija laikosi taisyklių:
|`undefined`|`NaN`|
|`null`|`0`|
|<code>true&nbsp;/&nbsp;false</code> | `1 / 0` |
<<<<<<< HEAD
| `string` | Eilutė skaitoma taip kaip yra, tarpai iš abiejų pusių ignoruojami. Tuščia eilutė tampa `0`. Klaida grąžina `NaN`. |
=======
| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. |
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**`Loginės Konversijos`** -- Nutinka loginėse operacijose. Gali būti atliekama su `Boolean(value)`.
Original file line number Diff line number Diff line change
@@ -16,10 +16,20 @@ undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```

<<<<<<< HEAD
1. Sudėtis su eilute `"" + 1` paverčia `1` į eilutę: `"" + 1 = "1"`, o tada mes turime `"1" + 0`, taikoma ta pati taisyklė.
2. Atimtis `-` (kaip ir didžioji dalis matematinių operacijų) veikia tik su skaičiais, tad tuščią eilutę `""` paverčia į `0`.
3. Sudėtis su eilute prijungia skaičių `5` prie eilutės.
4. Atimtis visada paverčia į numerius, tad `" -9 "` tampa numeriu `-9` (ignoruoja tarpus aplink).
5. `null` tampa `0` po skaičių konversijos.
6. `undefined` tampa `NaN` po skaičių konversijos.
7. Tarpų ženklai yra nukerpami nuo eilutės pradžios ir pabaigos kai eilutė paverčiama į skaičių. Čia visa eilutė susideda iš tarpo ženklų kaip `\t`, `\n` ir “įprastinių” tarpų esančių tarp jų. Tad panašiai kaip ir tuščia eilutė, ji tampa `0`.
=======
1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
3. The addition with a string appends the number `5` to the string.
4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it).
5. `null` becomes `0` after the numeric conversion.
6. `undefined` becomes `NaN` after the numeric conversion.
7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
38 changes: 37 additions & 1 deletion 1-js/02-first-steps/08-operators/article.md
Original file line number Diff line number Diff line change
@@ -50,8 +50,14 @@ Rezultatas `a % b` yra dalybos iš `a` ir `b` [likutis](https://en.wikipedia.org
Pavyzdžiui:

```js run
<<<<<<< HEAD
alert( 5 % 2 ); // 1, likutis, gautas padalijus 5 iš 2
alert( 8 % 3 ); // 2, likutis, gautas padalijus 8 iš 3
=======
alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```

### Kėlimas laipsniu **
@@ -68,7 +74,11 @@ alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
```

<<<<<<< HEAD
Kaip ir matematikoje, kėlimo laipsniu operatorius tinka ir ne sveikiesiems skaičiams.
=======
Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

Pavyzdžiui, norėdami gauti skaičiaus kvadratinę šaknį, turime ji pakelti iki ½ laipsnio:

@@ -80,7 +90,11 @@ alert( 8 ** (1/3) ); // 2 (kubinė šaknis iš a yra lygiavertė a pekėlimui ik

## Eilučių sudėtis naudojant binarinį +

<<<<<<< HEAD
Apžvelkime ypatingas JavaScript operatorių savybes, kurios išeina už mokyklinės aritmetikos ribų.
=======
Let's meet the features of JavaScript operators that are beyond school arithmetics.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Dažniausiai operatorius pliusas `+` sumuoja skaičius.
@@ -194,18 +208,32 @@ JavaScript turi daug operatorių. Kiekvienas operatorius turi atitinkamą pirmen
| Pirmenybė | Pavadinimas | Ženklas |
|------------|------|------|
| ... | ... | ... |
<<<<<<< HEAD
| 15 | unarinis pliusas | `+` |
| 15 | unarinis minusas | `-` |
| 14 | kėlimas laipsniu | `**` |
| 13 | daugyba | `*` |
| 13 | dalyba | `/` |
| 12 | sudėtis | `+` |
| 12 | atimtis | `-` |
=======
| 14 | unary plus | `+` |
| 14 | unary negation | `-` |
| 13 | exponentiation | `**` |
| 12 | multiplication | `*` |
| 12 | division | `/` |
| 11 | addition | `+` |
| 11 | subtraction | `-` |
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
| ... | ... | ... |
| 2 | priskyrimas | `=` |
| ... | ... | ... |
<<<<<<< HEAD
Kaip matome, “unarinio pliuso” prioritetas yra `15`, t. y. aukštesnis už “sudėties” (binarinio pliuso) prioritetą `12`. Todėl išraiškoje `"+apples + +oranges"` unarinis pliusas veikia pirmiau už sudėtinį pliusą.
=======
As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

## Priskyrimas

@@ -303,9 +331,13 @@ Tokie operatoriai turi tokią pačią pirmenybę kaip ir įprasti priskyrimai, t
```js run
let n = 2;
n *= 3 + 5;
n *= 3 + 5; // right part evaluated first, same as n *= 8
<<<<<<< HEAD
alert( n ); // 16 (pirmiausiai bus vykdoma dešinioji pusė, išraiška yra identiška n *= 8)
=======
alert( n ); // 16
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```

## Padidėjimas/sumažėjimas
@@ -437,7 +469,11 @@ Operatorių sąrašas:
- RIGHT SHIFT ( `>>` )
- ZERO-FILL RIGHT SHIFT ( `>>>` )
<<<<<<< HEAD
Šie operatoriai naudojami labai retai, kai reikia atlikti veiksmus su skaičiais pačiu žemiausiu (bitų) lygiu. Šių operatorių artimiausiu metu mums neprireiks, nes interneto svetainių kūrimui jie mažai reikalingi, tačiau kai kuriose specialiose srityse, pavyzdžiui, kriptografijoje, jie yra naudingi. MDN galite perskaityti [skyrių apie juos](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise), kai to tikrai prireiks.
=======
These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

## Kablelis

11 changes: 11 additions & 0 deletions 1-js/02-first-steps/10-ifelse/article.md
Original file line number Diff line number Diff line change
@@ -68,7 +68,11 @@ if (cond) {

## Išlyga "else"

<<<<<<< HEAD
Į `if` teiginį gali būti įterptas neprivalomas “else” blokas. Jis vykdomas, kai sąlyga yra “falsy”.
=======
The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Pavyzdžiui:
```js run
@@ -180,10 +184,17 @@ alert( message );

Iš praždių gali būti sunku suprasti kas vyksta. Bet geriau įsižiūrėjus matome, kad tai tik įprastinė testų seka:

<<<<<<< HEAD
1. Pirmas klaustukas patikrina ar `age < 3`.
2. Jeigu true -- grąžina `'Labas, kūdikėli!'`. Kitu atveju, pereina prie išraiškos po dvitaškio '":"' ir tikrina `age < 18`.
3. Jeigu šitas yra true -- grąžina `'Labas!'`. Kitu atveju, pereina prie išraiškos po dvitaškio '":"' ir tikrina `age < 100`.
4. Jeigu tai true -- grąžina `'Sveiki!'`. Kitu atveju, pereina prie išraiškos po paskutinio dvitaškio '":"', grąžina `'Koks neįprastas amžius!'`.
=======
1. The first question mark checks whether `age < 3`.
2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`.
3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`.
4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Štai kaip tai atrodytų, jeigu naudotume `if..else`:

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Atsakymas: `null`, nes tai yra pirmoji falsy vertė sąraše.

```js run
alert( 1 && null && 2 );
alert(1 && null && 2);
```

40 changes: 40 additions & 0 deletions 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,11 @@

Nulinio susiliejimo operatorius užrašomas dviem klausiamaisiais ženklais `??`.

<<<<<<< HEAD
Kadangi jis apdoroja `null` ir `undefined` vienodai, šiame straipsnyje įvesime specialų terminą. Trumpai sakysime, kad vertė yra “apibrėžta”, jei ji nėra lygi nei `null`, nei `undefined`.
=======
As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Rezultatas `a ?? b` yra:
- jei `a` yra apibrėžta, tada `a`,
@@ -22,29 +26,49 @@ result = (a !== null && a !== undefined) ? a : b;

Dabar turėtų būti visiškai aišku, ką daro `??`. Pažiūrėkime, kur jis padeda.

<<<<<<< HEAD
Paprastai operatorius `??` reikalingas norint nustatyti numatytoją vertę potencialiai neapibrėžtam kintamajam.

Pavyzdžiui, čia mes atvaizduojame `user`, jei jo vertė nėra `null/undefined`, priešingu atveju - `Anonimas`:
=======
The common use case for `??` is to provide a default value.

For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let user;

<<<<<<< HEAD
alert(user ?? "Anonimas"); // Anonimas (user yra neapibrėžtas)
=======
alert(user ?? "Anonymous"); // Anonymous (user is undefined)
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
O štai pavyzdys, kai `user` priskirta vertė:
```js run
let user = "Jonas";

<<<<<<< HEAD
alert(user ?? "Anonimas"); // Jonas (user yra apibrėžtas)
=======
alert(user ?? "Anonymous"); // John (user is not null/undefined)
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
Mes taip pat galime naudoti `??` seką, norėdami iš sąrašo išrinkti pirmąją vertę, kuri nėra `null/undefined`.
<<<<<<< HEAD
Tarkime, kad turime naudotojo duomenis kintamuosiuose `firstName`, `lastName` arba `nickName`. Visi jie gali būti neapibrėžti, jei naudotojas nusprendė neįvesti vertės.
Mes norėtume, kad naudotojo vardas būtų atvaizduojamas naudojant vieną iš šių kintamųjų arba rodomas "Anonimas", jei visi jie neapibrėžti.
=======
Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values.
We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Panaudokime operatorių `??`:
@@ -76,7 +100,11 @@ alert(firstName || lastName || nickName || "Anonimas"); // Supercoder
*/!*
```
<<<<<<< HEAD
Istoriškai ARBA `||` operatorius buvo pirmasis. Jis egzistuoja nuo pat JavaScript atsiradimo pradžios, todėl programišiai jau seniai jį naudojo tokiems tikslams.
=======
Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Kita vertus, nulinio susiliejimo operatorius `??` į JavaScript buvo pridėtas visai neseniai, o priežastis buvo ta, kad žmonės nebuvo patenkinti `||`.
@@ -106,11 +134,19 @@ Praktikoje nulinis aukštis dažnai yra tinkama vertė, kurios nereikėtų keist
## Pirmenybė
<<<<<<< HEAD
Operatoriaus `??` pirmenybė yra tokia pati kaip ir `||`. Abu jie [MDN lentelėje](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) yra lygūs `3`.
=======
The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Tai reiškia, kad, kaip ir `||`, nulinio susiliejimo operatorius `??` vertinamas prieš `=` ir `?`, bet po daugumos kitų operacijų, tokių kaip `+`, `*`.
<<<<<<< HEAD
Taigi, jei norime pasirinkti vertę su `??` išraiškoje su kitais operatoriais, pridėkite skliaustelius:
=======
So we may need to add parentheses in expressions like this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let height = null;
@@ -128,7 +164,11 @@ Priešingu atveju, jei praleisime skliaustelius, kadangi `*` turi didesnę pirme
// be skliaustelių
let area = height ?? 100 * width ?? 50;

<<<<<<< HEAD
// ...veikia taip pat, kaip ir čia (tikriausiai ne tai, ko norime):
=======
// ...works this way (not what we want):
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
let area = height ?? (100 * width) ?? 50;
```
47 changes: 45 additions & 2 deletions 1-js/02-first-steps/13-while-for/article.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,24 @@ Pavyzdžiui, įvairių prekių išbraukimas viena paskui kitą iš sąrašo, arb

*Ciklai* (ang. “*Loops*”) yra būdas pakartoti daug kartų tą patį kodą.

<<<<<<< HEAD
## Ciklas “while”
=======
```smart header="The for..of and for..in loops"
A small announcement for advanced readers.
This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
If you came to this article searching for other types of loops, here are the pointers:
- See [for..in](info:object#forin) to loop over object properties.
- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
Otherwise, please read on.
```

## The "while" loop
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Ciklas `while` turi sekančią sintaksę:

@@ -162,11 +179,14 @@ for (i = 0; i < 3; i++) { // naudojamas jau egzituojantis kintamasis
alert(i); // 3, matomas, nes buvo deklaruotas už ciklo ribų
```
````

<<<<<<< HEAD

### Dalių praleidimas
=======
### Skipping parts
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Bet kuri `for` dalis gali būti praleista.

@@ -268,7 +288,11 @@ for (let i = 0; i < 10; i++) {

Iš techninės perspektyvos tai yra visiškai identiškas kodas aukščiau esančiam pavyzdžiui. Žinoma, mes galime tiesiog apgobti `if` rinkinį vietoje to, kad naudotume `continue`.

<<<<<<< HEAD
Bet to pašalinis efektas yra papildomas matrioškinis lygis (šaukimas `alert` viduje riestinių skliaustų). O jeigu kodas `if` viduje yra ilgesnis nei kelios eilės, tai apsunkina skaitomumą.
=======
But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
````warn header="Jokių `break/continue` dešinėje '?' pusėje"
@@ -286,7 +310,6 @@ if (i > 5) {
...ir perrašytume jį naudodami klaustuką:
```js no-beautify
(i > 5) ? alert(i) : *!*continue*/!*; // continue nėra leidžiamas
```
@@ -320,7 +343,12 @@ Mums reikia tokio būdo, kuris sustabdytų procesą, jeigu lankytojas atšaukia

Įprastinis `break` sekantis po `input` sustabdytų tik vidinį ciklą. To neužtenka -- į pagalba ateina žymos!

<<<<<<< HEAD
*Žyma* -- tai yra toks identifikatorius su dvitaškiu prieš ciklą:
=======
A *label* is an identifier with a colon before a loop:

>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
žymosPavadinimas: for (...) {
...
@@ -342,7 +370,12 @@ Teiginys `break <žymosPavadinimas>` cikle žemiau nutraukia procesą iki žymos
// daryti kažką su verte...
}
}
<<<<<<< HEAD
alert('Baigta!');
=======

alert('Done!');
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```

Kodas viršuje `break išorinis` suranda viršuje žymą su pavadinimu `išorinis` ir nutraukia tą ciklą.
@@ -361,14 +394,24 @@ Direktyvą `continue` taip pat galima naudoti su žyma. Šiuo atveju valdymas bu
````warn header="Žymos neleidžia \"peršokti\" bet kur"
Žymos negali leisti peršokti į bet kurią arbitrišką kodo vietą.
<<<<<<< HEAD
Pavyzdžiui tai nėra įmanoma:
=======
For example, it is impossible to do this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
break žyma; // neperšoka į žymą žemiau (neveikia)
žyma: for (...)
```
<<<<<<< HEAD
Direktyva `break` turi būti kodo bloko viduje. Techniškai tinka bet koks pažymėtas kodo blokas, pavyzdžiui:
=======
A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
label: {
// ...
4 changes: 4 additions & 0 deletions 1-js/02-first-steps/14-switch/article.md
Original file line number Diff line number Diff line change
@@ -139,7 +139,11 @@ switch (a) {
Dabar abu `3` ir `5` parodo tą pačią žinutę.
<<<<<<< HEAD
Gebėjimas “sugrupuoti” bylas yra šalutinis efektas to kaip `switch/case` veikia be `break`. Čia `case 3` vykdymas prasideda nuo eilės su `(*)` ir eina per bylą `case 5`, nes nėra `break`.
=======
The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Tipas yra svarbu
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
<<<<<<< HEAD
Abi funkcijos veikia vienodai, skirtumų nėra.
=======
No difference!

In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
74 changes: 73 additions & 1 deletion 1-js/02-first-steps/15-function-basics/article.md
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ Pirmiausia įrašomas raktažodis `funkcija`, po jo nurodomas funkcijos pavadini

```js
function name(parameter1, parameter2, ... parameterN) {
...body...
// body
}
```

@@ -178,7 +178,23 @@ alert( from ); // Ana
Jei parametras nenurodytas, jo vertė tampa `undefined`.
<<<<<<< HEAD
Pavyzdžiui, aukščiau pateiktą funkciją `showMessage(from, text)` galima iškviesti su vienu argumentu:
=======
- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term).
- An argument is the value that is passed to the function when it is called (it's a call time term).
We declare functions listing their parameters, then call them passing arguments.
In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
## Default values
If a function is called, but an argument is not provided, then the corresponding value becomes `undefined`.
For instance, the aforementioned function `showMessage(from, text)` can be called with a single argument:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
showMessage("Ana");
@@ -196,7 +212,17 @@ function showMessage(from, *!*text = "tekstas nepridėtas"*/!*) {
showMessage("Ana"); // Ana: tekstas nepridėtas
```
<<<<<<< HEAD
Dabar, jei `text` parametras nenurodytas, jo vertė bus `"tekstas nepridėtas"`.
=======
Now if the `text` parameter is not passed, it will get the value `"no text given"`.
The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this:
```js
showMessage("Ann", undefined); // Ann: no text given
```
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Šiuo atveju `"tekstas nepridėtas"` yra eilutė, tačiau vietoj jos gali būti sudėtingesnė išraiška, kuri apskaičiuojama ir priskiriama, kai nėra parametro. Pavyzdžiui:
@@ -213,9 +239,47 @@ JavaScript kalba numatytieji parametrai apskaičiuojami kiekvieną kartą, kai f
Aukščiau pateiktame pavyzdyje `anotherFunction()` bus iškviečiama kiekvieną kartą, kai `showMessage()` bus iškviesta be `text` parametro.
```
<<<<<<< HEAD
### Alternatyvūs numatytieji parametrai
Kartais tikslinga parametrams priskirti numatytąsias vertes ne funkcijos deklaravimo metu, o vėliau.
=======
````smart header="Default parameters in old JavaScript code"
Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them.
Nowadays, we can come across them in old scripts.
For example, an explicit check for `undefined`:
```js
function showMessage(from, text) {
*!*
if (text === undefined) {
text = 'no text given';
}
*/!*

alert( from + ": " + text );
}
```
...Or using the `||` operator:
```js
function showMessage(from, text) {
// If the value of text is falsy, assign the default value
// this assumes that text == "" is the same as no text at all
text = text || 'no text given';
...
}
```
````
### Alternative default parameters
Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Mes galime patikrinti, ar parametras perduotas funkcijos vykdymo metu, palyginę jį su `undefined`:
@@ -411,7 +475,11 @@ Du nepriklausomi veiksmai paprastai reiškia dvi funkcijas, net jei jos turi bū
```smart header="Ypač trumpi funkcijų pavadinimai"
Labai dažnai naudojami funkcijų pavadinimai kartais būna itin trumpi.

<<<<<<< HEAD
Pavyzdžiui, [jQuery](http://jquery.com) framework'e yra funkcija, pavadinta `$`. [Lodash](http://lodash.com/) bibliotekoje pagrindinę funkciją žymi vardas `_`.
=======
For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

Tai yra išimtys. Apskritai funkcijų pavadinimai turėtų būti vidutiniškai trumpi ir apibūdinti funkcijų veiksmus.
```
@@ -479,7 +547,11 @@ function name(kableliais, atskirti, parametrai) {
Kad kodas būtų švaresnis ir aiškesnis, rekomenduojama naudoti lokalinius kintamuosius ir funkcijų parametrus, o ne išorinius kintamuosius.
<<<<<<< HEAD
Funkcija, kuri gauna parametrus, dirba su jais ir grąžina rezultatą, yra daug aiškesnė nei funkcija, kuri iškviečiama be parametrų, bet keičia išorinius kintamuosius, o tai gali turėti šalutinį poveikį.
=======
It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Funkcijos pavadinimo pasirinkimas:
40 changes: 39 additions & 1 deletion 1-js/02-first-steps/16-function-expressions/article.md
Original file line number Diff line number Diff line change
@@ -82,14 +82,20 @@ let sayHi = function() { // (1) sukurti
alert( "Labas" );
};

let func = sayHi;
let func = sayHi; //(2)
// ...
```

Viskas veiktų taip pat.

<<<<<<< HEAD
````smart header="Kodėl pabaigoje dedamas kabliataškis?"
Jums gali kilti klausimas, kodėl Function Expression pabaigoje turi kabliataškį `;`, o Function Declaration -- ne:
=======
````smart header="Why is there a semicolon at the end?"
You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
function sayHi() {
@@ -143,13 +149,21 @@ function showCancel() {
ask("Ar sutinkate?", showOk, showCancel);
```

<<<<<<< HEAD
Praktikoje tokios funkcijos yra gana naudingos. Pagrindinis skirtumas tarp “realaus” `ask` ir aukščiau pateikto pavyzdžio yra tas, kad realios funkcijos naudoja sudėtingesnius sąveikos su naudotoju būdus nei paprastas `confirm`. Naršyklėje tokios funkcijos paprastai atvaizduoja gražiai atrodantį klausimo langą. Bet tai jau kita istorija.
=======
In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**Funkcijos `ask` argumentai vadinamos *callback-funkcijomis* arba *callback'ais*.**

Idėja yra ta, kad mes perduodame funkciją ir tikimės, kad prireikus vėliau ji bus “iškviesta atgal” (ang. *“call back”* -- grįžtamasis iškvietimas).

<<<<<<< HEAD
Norėdami užrašyti tą pačią funkciją daug trumpiau, galime naudoti `Function Expression`:
=======
We can use Function Expressions to write an equivalent, shorter function:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run no-beautify
function ask(question, yes, no) {
@@ -186,15 +200,23 @@ Apžvelkime pagrindinius Function Expression ir Function Declaration skirtumus.

Pirma, sintaksė: kaip juos atskirti kode.

<<<<<<< HEAD
- *Function Declaration:* funkcija, deklaruojama kaip atskiras teiginys pagrindiniame kodo sraute.
=======
- *Function Declaration:* a function, declared as a separate statement, in the main code flow:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
// Function Declaration
function sum(a, b) {
return a + b;
}
```
<<<<<<< HEAD
- *Function Expression:* funkcija, sukurta išraiškos viduje arba kitoje sintaksės konstrukcijoje. Šiuo atveju funkcija sukuriama dešinėje “priskyrimo išraiškos” `=` pusėje:
=======
- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
// Function Expression
@@ -291,18 +313,29 @@ if (age < 18) {
welcome(); // \ (bus vykdoma)
*/!*
// |
<<<<<<< HEAD
function welcome() { // |
alert("Labas!"); // | Function Declaration yra prieinamas
} // | visame kodo bloke, kuriame jis deklaruotas.
=======
function welcome() { // |
alert("Hello!"); // | Function Declaration is available
} // | everywhere in the block where it's declared
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
// |
*!*
welcome(); // / (bus vykdoma)
*/!*

} else {

<<<<<<< HEAD
function welcome() {
alert("Laba diena!");
=======
function welcome() {
alert("Greetings!");
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
}
}

@@ -359,8 +392,13 @@ welcome(); // dabar viskas gerai
```
<<<<<<< HEAD
```smart header="Kada rinktis Function Declaration, o kada - Function Expression?"
Paprastai, kai reikia deklaruoti funkciją, pirmiausia reikia atkreipti dėmesį į Function Declaration sintaksę. Ši sintaksė suteikia daugiau laisvės organizuojant kodą, nes tokias funkcijas galime iškviesti prieš jas deklaruodami.
=======
```smart header="When to choose Function Declaration versus Function Expression?"
As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Function Declaration taip pat geriau skaitomumo požiūriu, nes kode lengviau rasti `function f(...) {...}` nei `let f = function(...) {...};`. Function Declaration labiau “traukia akį”.
22 changes: 22 additions & 0 deletions 1-js/02-first-steps/17-arrow-functions-basics/article.md
Original file line number Diff line number Diff line change
@@ -48,7 +48,11 @@ Kaip jūs matote, `(a, b) => a + b` reiškia funkciją, kuri priima du argumentu
alert( double(3) ); // 6
```

<<<<<<< HEAD
- Jeigu argumentų nėra, skliaustai bus tušti (tačiau jie turėtų būti):
=======
- If there are no arguments, parentheses are empty, but they must be present:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

```js run
let sayHi = () => alert("Labas!");
@@ -64,8 +68,13 @@ Pavyzdžiui, norėdami dinamiškai sukurti funkciją:
let age = prompt("Koks jūsų amžius?", 18);
let welcome = (age < 18) ?
<<<<<<< HEAD
() => alert('Labas!') :
() => alert("Laba diena!");
=======
() => alert('Hello!') :
() => alert("Greetings!");
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
welcome();
```
@@ -76,9 +85,15 @@ Jie labai patogūs atliekant paprastus vienos eilutės veiksmus, kai tiesiog tin

## Kelių eilučių rodyklių funkcijos

<<<<<<< HEAD
Aukščiau pateiktuose pavyzdžiuose buvo paimti argumentai iš `=>` kairės pusės ir su jais įvertinta dešiniosios pusės išraiška.

Kartais mums reikia šiek tiek sudėtingesnių dalykų, pavyzdžiui, kelių išraiškų ar teiginių. Tai taip pat įmanoma, tačiau jas turėtume uždaryti figūriniais skliaustais. Tada juose reikia naudoti įprastą `return`.
=======
The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them.
Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Štai taip:
@@ -105,7 +120,14 @@ O dabar mes jau galime naudoti rodyklių funkcijas vienos eilutės veiksmams ir

## Santrauka

<<<<<<< HEAD
Rodyklių funkcijos yra patogios, kai reikia parašyti vieną eilutę. Jos būna dviejų rūšių:

1. Be figūrinių skliaustų: `(...args) => expression` -- dešinioji išraiškos pusė: funkcija ją apskaičiuoja ir grąžina rezultatą. Skliaustelius galima praleisti, jei yra tik vienas argumentas: `n => n * 2`.
2. Su figūriniais skliaustais: `(...args) => { body }` -- figūriniai skliaustai leidžia įrašyti kelis teiginius funkcijos viduje, tačiau mums reikia aiškaus `return`, kad ką nors grąžintume.
=======
Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors:

1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`.
2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
24 changes: 24 additions & 0 deletions 1-js/02-first-steps/18-javascript-specials/article.md
Original file line number Diff line number Diff line change
@@ -55,7 +55,11 @@ Kad būtų įjungtos visos šiuolaikinės JavaScript ypatybės, skriptus turėtu

Ši direktyva turi būti skripto viršuje arba funkcijos kūno pradžioje.

<<<<<<< HEAD
Be `"use strict"` viskas veikia, tačiau kai kurios funkcijos veikia senamadiškai, “suderinamumo” būdu. Apskritai mums labiau tiktų šiuolaikinis elgesys.
=======
Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Kai kurios šiuolaikinės kalbos savybės (pvz., klasės, kurias nagrinėsime ateityje) įgalina griežtąjį režimą netiesiogiai.

@@ -103,6 +107,7 @@ Išsamiau: <info:variables> ir <info:types>.

Kaip darbo aplinką naudojame naršyklę, todėl pagrindinės vartotojo sąsajos funkcijos bus:

<<<<<<< HEAD
[`prompt(question, [default])`](mdn:api/Window/prompt)
: Užduoti klausimą `question` ir grąžinti lankytojo įvestus duomenis arba `null`, jei lankytojas paspaudė “atšaukti”.

@@ -111,6 +116,16 @@ Kaip darbo aplinką naudojame naršyklę, todėl pagrindinės vartotojo sąsajos

[`alert(message)`](mdn:api/Window/alert)
: Išvesti pranešimą `message`.
=======
[`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt)
: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel".

[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`.

[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert)
: Output a `message`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Visos šios funkcijos yra *modalinės*, jos sustabdo kodo vykdymą ir neleidžia lankytojui sąveikauti su puslapiu, kol jis neatsakys.

@@ -143,8 +158,13 @@ Aritmetikos
Priskyrimo operatoriai
: Yra paprastas priskyrimas: `a = b` ir kombinuotas, pavyzdžiui, `a *= 2`.

<<<<<<< HEAD
Bitų operacijos
: Bitų operatoriai su 32 bitų sveikaisiais skaičiais dirba žemiausiu, bitų lygiu. Daugiau apie jų galite perskaityti [MDN](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise).
=======
Bitwise
: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) when they are needed.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Sąlyginiai operatoriai
: Vienintelis operatorius, turintis tris parametrus: `cond ? resultA : resultB`. Jeigu `cond` yra truthy, grąžina `resultA`, priešingu atveju `resultB`.
@@ -256,7 +276,11 @@ Mes apžvelgėme tris būdus, kaip galima sukurti funkciją JavaScript:
3. Rodyklės funkcijos (ang. *“arrow functions”*):

```js
<<<<<<< HEAD
// išraiška dešinėje pusėje
=======
// expression on the right side
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
let sum = (a, b) => a + b;
// kelių eilučių kodas figūriniuose skliaustuose { ... }, čia reikalingas return:
21 changes: 10 additions & 11 deletions 1-js/03-code-quality/01-debugging-chrome/article.md
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ If we press `key:Esc`, then a console opens below. We can type commands there an

After a statement is executed, its result is shown below.

For example, here `1+2` results in `3`, and `hello("debugger")` returns nothing, so the result is `undefined`:
For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`:

![](chrome-sources-console.svg)

@@ -71,12 +71,12 @@ We can always find a list of breakpoints in the right panel. That's useful when
- ...And so on.

```smart header="Conditional breakpoints"
*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression is truthy.
*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy.
That's handy when we need to stop only for a certain variable value or for certain function parameters.
```

## Debugger command
## The command "debugger"

We can also pause the code by using the `debugger` command in it, like this:

@@ -92,8 +92,7 @@ function hello(name) {
}
```

That's very convenient when we are in a code editor and don't want to switch to the browser and look up the script in developer tools to set the breakpoint.

Such command works only when the development tools are open, otherwise the browser ignores it.

## Pause and look around

@@ -107,7 +106,7 @@ Please open the informational dropdowns to the right (labeled with arrows). They

1. **`Watch` -- shows current values for any expressions.**

You can click the plus `+` and input an expression. The debugger will show its value at any moment, automatically recalculating it in the process of execution.
You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution.

2. **`Call Stack` -- shows the nested calls chain.**

@@ -143,11 +142,11 @@ There are buttons for it at the top of the right panel. Let's engage them.
Clicking this again and again will step through all script statements one by one.

<span class="devtools" style="background-position:-62px -192px"></span> -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`.
: Similar to the previous "Step" command, but behaves differently if the next statement is a function call. That is: not a built-in, like `alert`, but a function of our own.
: Similar to the previous "Step" command, but behaves differently if the next statement is a function call (not a built-in, like `alert`, but a function of our own).

The "Step" command goes into it and pauses the execution at its first line, while "Step over" executes the nested function call invisibly, skipping the function internals.
If we compare them, the "Step" command goes into a nested function call and pauses the execution at its first line, while "Step over" executes the nested function call invisibly to us, skipping the function internals.

The execution is then paused immediately after that function.
The execution is then paused immediately after that function call.

That's good if we're not interested to see what happens inside the function call.

@@ -163,7 +162,7 @@ There are buttons for it at the top of the right panel. Let's engage them.
: That button does not move the execution. Just a mass on/off for breakpoints.

<span class="devtools" style="background-position:-90px -146px"></span> -- enable/disable automatic pause in case of an error.
: When enabled, and the developer tools is open, a script error automatically pauses the execution. Then we can analyze variables to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment.
: When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment.

```smart header="Continue to here"
Right click on a line of code opens the context menu with a great option called "Continue to here".
@@ -195,7 +194,7 @@ As we can see, there are three main ways to pause a script:
2. The `debugger` statements.
3. An error (if dev tools are open and the button <span class="devtools" style="background-position:-90px -146px"></span> is "on").

When paused, we can debug - examine variables and trace the code to see where the execution goes wrong.
When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.

There are many more options in developer tools than covered here. The full manual is at <https://developers.google.com/web/tools/chrome-devtools>.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion 1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion 1-js/03-code-quality/02-coding-style/code-style.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion 1-js/03-code-quality/03-comments/article.md
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ Such comments allow us to understand the purpose of the function and use it the

By the way, many editors like [WebStorm](https://www.jetbrains.com/webstorm/) can understand them as well and use them to provide autocomplete and some automatic code-checking.

Also, there are tools like [JSDoc 3](https://github.com/jsdoc3/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at <http://usejsdoc.org/>.
Also, there are tools like [JSDoc 3](https://github.com/jsdoc/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at <https://jsdoc.app>.

Why is the task solved this way?
: What's written is important. But what's *not* written may be even more important to understand what's going on. Why is the task solved exactly this way? The code gives no answer.
16 changes: 8 additions & 8 deletions 1-js/03-code-quality/05-testing-mocha/article.md
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ describe("pow", function() {
A spec has three main building blocks that you can see above:

`describe("title", function() { ... })`
: What functionality we're describing. In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.
: What functionality we're describing? In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.

`it("use case description", function() { ... })`
: In the title of `it` we *in a human-readable way* describe the particular use case, and the second argument is a function that tests it.
@@ -69,7 +69,7 @@ The flow of development usually looks like this:

1. An initial spec is written, with tests for the most basic functionality.
2. An initial implementation is created.
3. To check whether it works, we run the testing framework [Mocha](http://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
3. To check whether it works, we run the testing framework [Mocha](https://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
4. Now we have a working initial implementation with tests.
5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail.
6. Go to 3, update the implementation till tests give no errors.
@@ -79,15 +79,15 @@ So, the development is *iterative*. We write the spec, implement it, make sure t

Let's see this development flow in our practical case.

The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use few JavaScript libraries to run the tests, just to see that they are working (they will all fail).
The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use a few JavaScript libraries to run the tests, just to see that they are working (they will all fail).

## The spec in action

Here in the tutorial we'll be using the following JavaScript libraries for tests:

- [Mocha](http://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
- [Chai](http://chaijs.com) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
- [Sinon](http://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.
- [Mocha](https://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
- [Chai](https://www.chaijs.com/) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
- [Sinon](https://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.

These libraries are suitable for both in-browser and server-side testing. Here we'll consider the browser variant.

@@ -338,14 +338,14 @@ The newly added tests fail, because our implementation does not support them. Th
```smart header="Other assertions"
Please note the assertion `assert.isNaN`: it checks for `NaN`.
There are other assertions in [Chai](http://chaijs.com) as well, for instance:
There are other assertions in [Chai](https://www.chaijs.com/) as well, for instance:
- `assert.equal(value1, value2)` -- checks the equality `value1 == value2`.
- `assert.strictEqual(value1, value2)` -- checks the strict equality `value1 === value2`.
- `assert.notEqual`, `assert.notStrictEqual` -- inverse checks to the ones above.
- `assert.isTrue(value)` -- checks that `value === true`
- `assert.isFalse(value)` -- checks that `value === false`
- ...the full list is in the [docs](http://chaijs.com/api/assert/)
- ...the full list is in the [docs](https://www.chaijs.com/api/assert/)
```
So we should add a couple of lines to `pow`:
23 changes: 10 additions & 13 deletions 1-js/03-code-quality/06-polyfills/article.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

# Polyfills and transpilers

The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at <https://tc39.github.io/ecma262/> and then progress to the [specification](http://www.ecma-international.org/publications/standards/Ecma-262.htm).
The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at <https://tc39.github.io/ecma262/> and then progress to the [specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/).

Teams behind JavaScript engines have their own ideas about what to implement first. They may decide to implement proposals that are in draft and postpone things that are already in the spec, because they are less interesting or just harder to do.

So it's quite common for an engine to implement only the part of the standard.
So it's quite common for an engine to implement only part of the standard.

A good page to see the current state of support for language features is <https://kangax.github.io/compat-table/es6/> (it's big, we have a lot to study yet).
A good page to see the current state of support for language features is <https://compat-table.github.io/compat-table/es6/> (it's big, we have a lot to study yet).

As programmers, we'd like to use most recent features. The more good stuff - the better!

@@ -40,9 +40,9 @@ Now the rewritten code is suitable for older JavaScript engines.
Usually, a developer runs the transpiler on their own computer, and then deploys the transpiled code to the server.
Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there.
Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there.
Modern project build systems, such as [webpack](http://webpack.github.io/), provide means to run transpiler automatically on every code change, so it's very easy to integrate into development process.
Modern project build systems, such as [webpack](https://webpack.js.org/), provide a means to run a transpiler automatically on every code change, so it's very easy to integrate into the development process.
## Polyfills
@@ -69,23 +69,20 @@ if (!Math.trunc) { // if no such function
}
```
JavaScript is a highly dynamic language, scripts may add/modify any functions, even including built-in ones.
Two interesting libraries of polyfills are:
- [core js](https://github.com/zloirock/core-js) that supports a lot, allows to include only needed features.
- [polyfill.io](http://polyfill.io) service that provides a script with polyfills, depending on the features and user's browser.
JavaScript is a highly dynamic language. Scripts may add/modify any function, even built-in ones.
One interesting polyfill library is [core-js](https://github.com/zloirock/core-js), which supports a wide range of features and allows you to include only the ones you need.
## Summary
In this chapter we'd like to motivate you to study modern and even "bleeding-edge" language features, even if they aren't yet well-supported by JavaScript engines.
Just don't forget to use transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). And they'll ensure that the code works.
Just don't forget to use a transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). They'll ensure that the code works.
For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](http://webpack.github.io/) with [babel-loader](https://github.com/babel/babel-loader) plugin.
For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](https://webpack.js.org/) with the [babel-loader](https://github.com/babel/babel-loader) plugin.
Good resources that show the current state of support for various features:
- <https://kangax.github.io/compat-table/es6/> - for pure JavaScript.
- <https://compat-table.github.io/compat-table/es6/> - for pure JavaScript.
- <https://caniuse.com/> - for browser-related functions.
P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though.
21 changes: 11 additions & 10 deletions 1-js/04-object-basics/01-object/article.md
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ The resulting `user` object can be imagined as a cabinet with two signed files l

![user object](object-user.svg)

We can add, remove and read files from it any time.
We can add, remove and read files from it at any time.

Property values are accessible using the dot notation:

@@ -62,7 +62,7 @@ user.isAdmin = true;

![user object 2](object-user-isadmin.svg)

To remove a property, we can use `delete` operator:
To remove a property, we can use the `delete` operator:

```js
delete user.age;
@@ -201,13 +201,13 @@ let bag = {
};
```

Square brackets are much more powerful than the dot notation. They allow any property names and variables. But they are also more cumbersome to write.
Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write.

So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets.

## Property value shorthand

In real code we often use existing variables as values for property names.
In real code, we often use existing variables as values for property names.

For instance:

@@ -252,7 +252,7 @@ let user = {

## Property names limitations

As we already know, a variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
As we already know, a variable cannot have a name equal to one of the language-reserved words like "for", "let", "return" etc.

But for an object property, there's no such restriction:

@@ -325,7 +325,7 @@ alert( "blabla" in user ); // false, user.blabla doesn't exist

Please note that on the left side of `in` there must be a *property name*. That's usually a quoted string.

If we omit quotes, that means a variable, it should contain the actual name to be tested. For instance:
If we omit quotes, that means a variable should contain the actual name to be tested. For instance:

```js run
let user = { age: 30 };
@@ -355,7 +355,7 @@ In the code above, the property `obj.test` technically exists. So the `in` opera
Situations like this happen very rarely, because `undefined` should not be explicitly assigned. We mostly use `null` for "unknown" or "empty" values. So the `in` operator is an exotic guest in the code.
## The "for..in" loop
## The "for..in" loop [#forin]
To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for(;;)` construct that we studied before.
@@ -412,7 +412,7 @@ for (let code in codes) {
*/!*
```
The object may be used to suggest a list of options to the user. If we're making a site mainly for German audience then we probably want `49` to be the first.
The object may be used to suggest a list of options to the user. If we're making a site mainly for a German audience then we probably want `49` to be the first.
But if we run the code, we see a totally different picture:
@@ -424,9 +424,10 @@ The phone codes go in the ascending sorted order, because they are integers. So
````smart header="Integer properties? What's that?"
The "integer property" term here means a string that can be converted to-and-from an integer without a change.
So, "49" is an integer property name, because when it's transformed to an integer number and back, it's still the same. But "+49" and "1.2" are not:
So, `"49"` is an integer property name, because when it's transformed to an integer number and back, it's still the same. But `"+49"` and `"1.2"` are not:
```js run
// Number(...) explicitly converts to a number
// Math.trunc is a built-in function that removes the decimal part
alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property
alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" ⇒ not integer property
@@ -481,7 +482,7 @@ They store properties (key-value pairs), where:
To access a property, we can use:
- The dot notation: `obj.property`.
- Square brackets notation `obj["property"]`. Square brackets allow to take the key from a variable, like `obj[varWithKey]`.
- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`.
Additional operators:
- To delete a property: `delete obj.prop`.
131 changes: 96 additions & 35 deletions 1-js/04-object-basics/02-object-copy/article.md
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ And here's how it's actually stored in memory:

The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it.

We may think of an object variable, such as `user`, as like a sheet of paper with the address of the object on it.
We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it.

When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object.

@@ -100,15 +100,37 @@ alert( a == b ); // false
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake.
````smart header="Const objects can be modified"
An important side effect of storing objects as references is that an object declared as `const` *can* be modified.

For instance:

```js run
const user = {
name: "John"
};
*!*
user.name = "Pete"; // (*)
*/!*
alert(user.name); // Pete
```

It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change.

In other words, the `const user` gives an error only if we try to set `user=...` as a whole.

That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter <info:property-descriptors>.
````

## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]

So, copying an object variable creates one more reference to the same object.

But what if we need to duplicate an object? Create an independent copy, a clone?
That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. But there is rarely a need -- copying by reference is good most of the time.
But what if we need to duplicate an object?

But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level.
We can create a new object and replicate the structure of the existing one, by iterating over its properties and copying them on the primitive level.

Like this:

@@ -133,21 +155,22 @@ clone.name = "Pete"; // changed the data in it
alert( user.name ); // still John in the original object
```

Also we can use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) for that.
We can also use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).

The syntax is:

```js
Object.assign(dest, [src1, src2, src3...])
Object.assign(dest, ...sources)
```

- The first argument `dest` is a target object.
- Further arguments `src1, ..., srcN` (can be as many as needed) are source objects.
- It copies the properties of all source objects `src1, ..., srcN` into the target `dest`. In other words, properties of all arguments starting from the second are copied into the first object.
- The call returns `dest`.
- Further arguments is a list of source objects.

For instance, we can use it to merge several objects into one:
```js
It copies the properties of all source objects into the target `dest`, and then returns it as the result.

For example, we have `user` object, let's add a couple of permissions to it:
```js run
let user = { name: "John" };
let permissions1 = { canView: true };
@@ -159,6 +182,9 @@ Object.assign(user, permissions1, permissions2);
*/!*
// now user = { name: "John", canView: true, canEdit: true }
alert(user.name); // John
alert(user.canView); // true
alert(user.canEdit); // true
```
If the copied property name already exists, it gets overwritten:
@@ -171,9 +197,9 @@ Object.assign(user, { name: "Pete" });
alert(user.name); // now user = { name: "Pete" }
```
We also can use `Object.assign` to replace `for..in` loop for simple cloning:
We also can use `Object.assign` to perform a simple object cloning:
```js
```js run
let user = {
name: "John",
age: 30
@@ -182,15 +208,18 @@ let user = {
*!*
let clone = Object.assign({}, user);
*/!*
alert(clone.name); // John
alert(clone.age); // 30
```
It copies all properties of `user` into the empty object and returns it.
Here it copies all properties of `user` into the empty object and returns it.
There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial.
## Nested cloning
Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them?
Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects.
Like this:
```js run
@@ -205,9 +234,7 @@ let user = {
alert( user.sizes.height ); // 182
```
Now it's not enough to copy `clone.sizes = user.sizes`, because the `user.sizes` is an object, it will be copied by reference. So `clone` and `user` will share the same sizes:
Like this:
Now it's not enough to copy `clone.sizes = user.sizes`, because `user.sizes` is an object, and will be copied by reference, so `clone` and `user` will share the same sizes:

```js run
let user = {
@@ -223,42 +250,76 @@ let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true, same object
// user and clone share sizes
user.sizes.width++; // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one
user.sizes.width = 60; // change a property from one place
alert(clone.sizes.width); // 60, get the result from the other one
```

To fix that, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
To fix that and make `user` and `clone` truly separate objects, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning.

We can use recursion to implement it. Or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).

````smart header="Const objects can be modified"
An important side effect of storing objects as references is that an object declared as `const` *can* be modified.
### structuredClone

For instance:
The call `structuredClone(object)` clones the `object` with all nested properties.

Here's how we can use it in our example:
```js run
const user = {
name: "John"
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
*!*
user.name = "Pete"; // (*)
let clone = structuredClone(user);
*/!*
alert(user.name); // Pete
alert( user.sizes === clone.sizes ); // false, different objects
// user and clone are totally unrelated now
user.sizes.width = 60; // change a property from one place
alert(clone.sizes.width); // 50, not related
```
It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change.
The `structuredClone` method can clone most data types, such as objects, arrays, primitive values.
In other words, the `const user` gives an error only if we try to set `user=...` as a whole.
It also supports circular references, when an object property references the object itself (directly or via a chain or references).
That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter <info:property-descriptors>.
````
For instance:
```js run
let user = {};
// let's create a circular reference:
// user.me references the user itself
user.me = user;

let clone = structuredClone(user);
alert(clone.me === clone); // true
```
As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well.
Although, there are cases when `structuredClone` fails.
For instance, when an object has a function property:
```js run
// error
structuredClone({
f: function() {}
});
```
Function properties aren't supported.
To handle such complex cases we may need to use a combination of cloning methods, write custom code or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
## Summary
Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself.
All operations via copied references (like adding/removing properties) are performed on the same single object.
To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
20 changes: 10 additions & 10 deletions 1-js/04-object-basics/03-garbage-collection/article.md
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ Now if we do the same:
user = null;
```

...Then the object is still reachable via `admin` global variable, so it's in memory. If we overwrite `admin` too, then it can be removed.
...Then the object is still reachable via `admin` global variable, so it must stay in memory. If we overwrite `admin` too, then it can be removed.

## Interlinked objects

@@ -169,11 +169,11 @@ The first step marks the roots:

![](garbage-collection-2.svg)

Then their references are marked:
Then we follow their references and mark referenced objects:

![](garbage-collection-3.svg)

...And their references, while possible:
...And continue to follow further references, while possible:

![](garbage-collection-4.svg)

@@ -183,12 +183,12 @@ Now the objects that could not be visited in the process are considered unreacha

We can also imagine the process as spilling a huge bucket of paint from the roots, that flows through all references and marks all reachable objects. The unmarked ones are then removed.

That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not affect the execution.
That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not introduce any delays into the code execution.

Some of the optimizations:

- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". Many objects appear, do their job and die fast, they can be cleaned up aggressively. Those that survive for long enough, become "old" and are examined less often.
- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine tries to split the garbage collection into pieces. Then the pieces are executed one by one, separately. That requires some extra bookkeeping between them to track changes, but we have many tiny delays instead of a big one.
- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". In typical code, many objects have a short life span: they appear, do their job and die fast, so it makes sense to track new objects and clear the memory from them if that's the case. Those that survive for long enough, become "old" and are examined less often.
- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine splits the whole set of existing objects into multiple parts. And then clear these parts one after another. There are many small garbage collections instead of a total one. That requires some extra bookkeeping between them to track changes, but we get many tiny delays instead of a big one.
- **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution.

There exist other optimizations and flavours of garbage collection algorithms. As much as I'd like to describe them here, I have to hold off, because different engines implement different tweaks and techniques. And, what's even more important, things change as engines develop, so studying deeper "in advance", without a real need is probably not worth that. Unless, of course, it is a matter of pure interest, then there will be some links for you below.
@@ -199,14 +199,14 @@ The main things to know:

- Garbage collection is performed automatically. We cannot force or prevent it.
- Objects are retained in memory while they are reachable.
- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole.
- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above.

Modern engines implement advanced algorithms of garbage collection.

A general book "The Garbage Collection Handbook: The Art of Automatic Memory Management" (R. Jones et al) covers some of them.

If you are familiar with low-level programming, the more detailed information about V8 garbage collector is in the article [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
If you are familiar with low-level programming, more detailed information about V8's garbage collector is in the article [A tour of V8: Garbage Collection](https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).

[V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
The [V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn more about garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](https://mrale.ph) who worked as one of the V8 engineers. I'm saying: "V8", because it is best covered by articles on the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.

In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.
In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.
3 changes: 1 addition & 2 deletions 1-js/04-object-basics/04-object-methods/7-calculator/task.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ importance: 5

Create an object `calculator` with three methods:

- `read()` prompts for two values and saves them as object properties.
- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
- `sum()` returns the sum of saved values.
- `mul()` multiplies saved values and returns the result.

@@ -21,4 +21,3 @@ alert( calculator.mul() );
```

[demo]

8 changes: 4 additions & 4 deletions 1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ importance: 2

# Chaining

There's a `ladder` object that allows to go up and down:
There's a `ladder` object that allows you to go up and down:

```js
let ladder = {
@@ -21,7 +21,7 @@ let ladder = {
};
```

Now, if we need to make several calls in sequence, can do it like this:
Now, if we need to make several calls in sequence, we can do it like this:

```js
ladder.up();
@@ -32,10 +32,10 @@ ladder.down();
ladder.showStep(); // 0
```

Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this:
Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this:

```js
ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```

Such approach is widely used across JavaScript libraries.
Such an approach is widely used across JavaScript libraries.
4 changes: 2 additions & 2 deletions 1-js/04-object-basics/04-object-methods/article.md
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ let user = {
// first, declare
function sayHi() {
alert("Hello!");
};
}

// then add as a method
user.sayHi = sayHi;
@@ -90,7 +90,7 @@ user = {

As demonstrated, we can omit `"function"` and just write `sayHi()`.

To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases the shorter syntax is preferred.
To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred.

## "this" in methods

Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ Is it possible to create functions `A` and `B` so that `new A() == new B()`?
function A() { ... }
function B() { ... }

let a = new A;
let b = new B;
let a = new A();
let b = new B();

alert( a == b ); // true
```
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ importance: 5

Create a constructor function `Calculator` that creates objects with 3 methods:

- `read()` asks for two values using `prompt` and remembers them in object properties.
- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
- `sum()` returns the sum of these properties.
- `mul()` returns the multiplication product of these properties.

2 changes: 1 addition & 1 deletion 1-js/04-object-basics/06-constructor-new/article.md
Original file line number Diff line number Diff line change
@@ -171,7 +171,7 @@ alert( new SmallUser().name ); // John
Usually constructors don't have a `return` statement. Here we mention the special behavior with returning objects mainly for the sake of completeness.

````smart header="Omitting parentheses"
By the way, we can omit parentheses after `new`, if it has no arguments:
By the way, we can omit parentheses after `new`:
```js
let user = new User; // <-- no parentheses
47 changes: 30 additions & 17 deletions 1-js/04-object-basics/07-optional-chaining/article.md
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ In many practical cases we'd prefer to get `undefined` instead of an error here
let html = document.querySelector('.elem').innerHTML; // error if it's null
```

Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.

How can we do this?

@@ -44,11 +44,19 @@ let user = {};
alert(user.address ? user.address.street : undefined);
```

It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. For more deeply nested properties, that becomes a problem as more repetitions are required.
It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code.

E.g. let's try getting `user.address.street.name`.
Here's how the same would look for `document.querySelector`:

We need to check both `user.address` and `user.address.street`:
```js run
let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
```

We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good.

For more deeply nested properties, it becomes even uglier, as more repetitions are required.

E.g. let's get `user.address.street.name` in a similar fashion.

```js
let user = {}; // user has no address
@@ -58,7 +66,7 @@ alert(user.address ? user.address.street ? user.address.street.name : null : nul

That's just awful, one may even have problems understanding such code.

Don't even care to, as there's a better way to write it, using the `&&` operator:
There's a little better way to write it, using the `&&` operator:

```js run
let user = {}; // user has no address
@@ -92,6 +100,12 @@ alert( user?.address?.street ); // undefined (no error)
The code is short and clean, there's no duplication at all.
Here's an example with `document.querySelector`:
```js run
let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element
```
Reading the address with `user?.address` works even if `user` object doesn't exist:
```js run
@@ -108,9 +122,9 @@ E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/un
```warn header="Don't overuse the optional chaining"
We should use `?.` only where it's ok that something doesn't exist.

For example, if according to our coding logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.

So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug.
```
````warn header="The variable before `?.` must be declared"
@@ -127,15 +141,15 @@ The variable must be declared (e.g. `let/const/var user` or as a function parame

As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.

So, if there are any further function calls or side effects, they don't occur.
So, if there are any further function calls or operations to the right of `?.`, they won't be made.

For instance:

```js run
let user = null;
let x = 0;

user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++

alert(x); // 0, value not incremented
```
@@ -162,13 +176,13 @@ userAdmin.admin?.(); // I am admin
*/!*

*!*
userGuest.admin?.(); // nothing (no such method)
userGuest.admin?.(); // nothing happens (no such method)
*/!*
```
Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the user object exists, so it's safe read from it.
Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it.
Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
@@ -179,7 +193,7 @@ let user1 = {
firstName: "John"
};

let user2 = null;
let user2 = null;

alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
@@ -192,17 +206,16 @@ delete user?.name; // delete user.name if user exists
```
````warn header="We can use `?.` for safe reading and deleting, but not writing"
The optional chaining `?.` has no use at the left side of an assignment.
The optional chaining `?.` has no use on the left side of an assignment.
For example:
```js run
let user = null;

user?.name = "John"; // Error, doesn't work
// because it evaluates to undefined = "John"
// because it evaluates to: undefined = "John"
```
It's just not that smart.
````
## Summary
@@ -217,4 +230,4 @@ As we can see, all of them are straightforward and simple to use. The `?.` check
A chain of `?.` allows to safely access nested properties.
Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
Loading