Skip to content

Sync with upstream @ 540d753e #381

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 1,672 commits into from
Closed
Changes from all commits
Commits
Show all changes
1672 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
361f6a5
merging all conflicts
iliakan Jun 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -21,3 +21,4 @@ sftp-config.json
Thumbs.db


/svgs
64 changes: 63 additions & 1 deletion 1-js/01-getting-started/1-intro/article.md

Large diffs are not rendered by default.

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

# ম্যানুয়াল ও স্পেসিফিকেশন

<<<<<<< HEAD
এই বইটি একটি _টিউটরিয়াল।_ এর উদ্দেশ্য হল আপনাকে আস্তে আস্তে ভাষাটি শিখতে সাহায্য করা। কিন্তু আপনি ব্যাসিকগুলো একবার মোটামুটি শিখে গেলে অন্য আরো সোর্সের প্রয়োজন পড়বে।
=======
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
## স্পেসিফিকেশন

[ECMA-262 স্পেসিফিকেশনে](https://www.ecma-international.org/publications/standards/Ecma-262.htm) জাভাস্ক্রিপ্টের সবচেয়ে গভীর, বিস্তারিত ও আনুষ্ঠানিক তথ্য আছে। এটাই ভাষাটিকে সংজ্ঞায়িত করে।

কিন্তু এত বেশি আনুষ্ঠানিক হওয়ার কারণে প্রথমদিকে এটি বুঝতে বেশ অসুবিধা হয়। তাই আপনার যদি ভাষার বিস্তারিত ব্যাপারগুলোতে সবচেয়ে বিশ্বস্ত সোর্সের প্রয়োজন হয়, তাহলে এই স্পেসিফিকেশনটি দেখতে হবে। কিন্তু এটি দৈনন্দিন ব্যবহারের জন্য নয়।

<<<<<<< HEAD
প্রতি বছর একটি করে নতুন স্পেসিফিকেশন ভার্সন রিলিজ হয়। মধ্যবর্তী রিলিজসমূহ, সর্বশেষ স্পেসিফিকেশনের খসড়া এখানে পাওয়া যাবে: <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
"প্রায় স্ট্যান্ডার্ড" (তথাকথিত "স্টেজ-৩") ফিচারগুলোসহ একেবারে নতুন ও প্রান্তীয় ফিচারগুলোর ব্যাপারে পড়তে এখানকার প্রস্তাবগুলো দেখুন: <https://github.com/tc39/proposals>

<<<<<<< HEAD
আর আপনি যদি ব্রাউজারের জন্য ডেভেলাপ করেন তাহলে এ বিষয়ে বিস্তারিত ভাবে এই বইয়ের [দ্বিতীয় অংশে](info:browser-environment) আলোচনা করা হয়েছে।
=======
Also, if you're developing for the browser, then there are other specifications covered in the [second part](info:browser-environment) of the tutorial.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## ম্যানুয়াল

<<<<<<< HEAD
- **MDN (Mozilla) JavaScript Reference** হচ্ছে উদাহরণ ও অন্যান্য তথ্যসহ একটি ম্যানুয়াল। ভাষার নির্দিষ্ট কোন ফাংশন, মেথড ইত্যাদির ব্যাপারে বিস্তারিত তথ্যের জন্য এটি খুবই ভাল।

পাওয়া যাবে এখানে: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference>.
@@ -27,16 +40,30 @@
* **MSDN** – জাভাস্ক্রিপ্টসহ অনেক তথ্যসমৃদ্ধ মাইক্রোসফ্টের ম্যানুয়াল (ওরা অনেকসময় বলে JScript)। যদি নির্দিষ্টভাবে ইন্টারনেট এক্সপ্লোরারের ব্যাপারে কিছু লাগে তাহলে ঐখানে যাওয়াই ভাল: <http://msdn.microsoft.com/>.

আর "RegExp MSDN" অথবা "RegExp MSDN jscript" আকারেও ইন্টারনেট সার্চ করতে পারেন।
=======
- **MDN (Mozilla) JavaScript Reference** is the main manual with examples and other information. It's great to get in-depth information about individual language functions, methods etc.

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
## কম্প্যাটিবিলিটি টেবিল

জাভাস্ক্রিপ্ট একটি উন্নয়ণশীল ভাষা, নতুন নতুন ফিচার নিয়মিত যোগ করা হয়।

ব্রাউজার ভিত্তিক বা অন্যান্য ইন্জিনগুলোতে এগুলোর সাপোর্ট দেখুন:

<<<<<<< HEAD
- <http://caniuse.com> - ফিচারভিত্তিক সাপোর্টের টেবিল। যেমন- কোন ইন্জিনগুলো অধুনিক ক্রিপ্টোগ্রাফি ফাংশনগুলো সাপোর্ট করে দেখতে: <http://caniuse.com/#feat=cryptography>.
- <https://kangax.github.io/compat-table> - ভাষার ফিচারসমূহ ও কোন ইন্জিনগুলো সেগুলো সাপোর্ট করে বা করে না তার উপর একটি টেবিল।

এই সবগুলো রিসোর্সই সত্যিকারের ডেভেলাপমেন্টে কাজে লাগে। যেহেতু এগুলো ভাষার বিস্তারিত, সেগুলোর সাপোর্ট ইত্যাদি ব্যাপারে মূল্যবান তথ্য ধারণ করে।
=======
- <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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
দয়া করে এগুলো মনে রাখবেন (অথবা এই পেজটি)। যখন কোন একটি নির্দিষ্ট ফিচারের ব্যাপারে বিস্তারিত তথ্য লাগবে তখন এগুলো কাজে আসবে।
24 changes: 23 additions & 1 deletion 1-js/01-getting-started/3-code-editors/article.md
Original file line number Diff line number Diff line change
@@ -12,8 +12,13 @@

আপনি যদি এখনো কোন IDE নির্বাচন না করে থাকেন, তবে নিচের যেকোন একটি ব্যবহার করে দেখতে পারেনঃ

<<<<<<< HEAD
- [Visual Studio Code](https://code.visualstudio.com/) (এটি ক্রস প্ল্যাটফর্ম ও সম্পূর্ণ ফ্রি)
- [WebStorm](http://www.jetbrains.com/webstorm/) (এটিও ক্রস প্ল্যাটফর্ম তবে পেইড)
=======
- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
উইন্ডোজ ব্যবহার কারীদের জন্য "Visual Studio" নামের আরও একটি IDE রয়েছে, তবে "Visual Studio Code" র সাথে কনফিউজ হওয়ার দরকার নাই। এটি সম্পূর্ণ আলাদা একটি IDE, যদিও দুইটাই মাইক্রোসফট এর ডেভেলপ করা। "Visual Studio" একটি পেইড ও উইন্ডোজ ফ্রেন্ডলি এডিটর, এটি সবচেয়ে ভালো কাজ করে ডট নেট প্ল্যাটফর্মে। এটি জাভাস্ক্রিপ্ট এর জন্যও ভালো কাজ করে। একটি ফ্রি কমিউনিটি ভার্শনও আছে [Visual Studio Community](https://www.visualstudio.com/vs/community/) নামে।

@@ -29,18 +34,35 @@

কাজের ক্ষেত্রে, লাইটওয়েট এডিটর সমূহের জন্য অনেক অনেক প্লাগিনস রয়েছে - ডিরেক্টরি লেভেল সিনট্যাক্স এনালাইজার থেকে শুরু করে অটোকমপ্লিট সহ নানান কাজ খুব সহজেই করা যায় এসব প্লাগিনস ব্যবহার করে। সুতরাং একটি লাইটওয়েট এডিটর ও IDE এর মধ্যে তেমন বিশাল কোন সীমারেখা নাই।

<<<<<<< HEAD
নিচের লিংক গুলো আপনার মনোযোগ আকর্ষণ করবেঃ

- [Atom](https://atom.io/) (এটি ক্রস প্ল্যাটফর্ম ও সম্পূর্ণ ফ্রি)।
- [Visual Studio Code](https://code.visualstudio.com/) (এটি ক্রস প্ল্যাটফর্ম ও সম্পূর্ণ ফ্রি)।
- [Sublime Text](http://www.sublimetext.com) (এটি ক্রস প্ল্যাটফর্ম ও কিছু ক্ষেত্রে ফ্রি)।
- [Notepad++](https://notepad-plus-plus.org/) (উইন্ডোজ, ফ্রি)।
- [Vim](http://www.vim.org/) এবং [Emacs](https://www.gnu.org/software/emacs/) ও অসাধারণ এডিটর, যদি আপনি এদের সঠিক ব্যবহার করতে জানেন।
=======
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
## চলুন ঝগড়া বাদ দিয়ে কিছু কথা বলিঃ

উপরে উল্লেখিত এডিটর সমূহ আমি অথবা আমার বন্ধু যাদের আমি ভালো ডেভেলপার মনে করি, তারা অনেক দিন যাবৎ বেশ স্বাচ্ছন্দ্যে ব্যবহার করছে।

আমাদের এই বৃহৎ পৃথিবীতে আরও অনেক ভালো ভালো এডিটর আছে। আপনি আপনার পছন্দ অনুযায়ী যেকোন একটা ব্যবহার করতে পারেন।

একটি এডিটর বাছাই করা অনেক সময় আপনার প্রোজেক্ট, পূর্ব-অভিজ্ঞতা, কাজের স্বাচ্ছন্দ্য এসবের উপর নির্ভর করে।
<<<<<<< HEAD
একটি এডিটর বাছাই করা অনেক সময় আপনার প্রোজেক্ট, পূর্ব-অভিজ্ঞতা, কাজের স্বাচ্ছন্দ্য এসবের উপর নির্ভর করে।
=======
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 @@

দেখতে অনেকটা এমন হবে:

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

দেখতে ঠিক কেমন হবে সেটা আপনার ক্রোম ভার্সনের উপর নির্ভর করবে। এটা প্রায়ই বদলায়। তবে কিছুটা এমনই হওয়ার কথা।

@@ -49,7 +49,11 @@

সাফারি (ম্যাকের ব্রাউজার, উইন্ডোজ/লিনাক্সে সাপোর্ট করে না) এখানে একটু অন্যরকম। প্রথমে আমাদের "Develop menu" সক্রিয় করতে হবে।

<<<<<<< HEAD
Preferences খুলে "Advanced" প্যানে যান. নিচের দিকে একটি চেকবক্স আছে:
=======
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.
8 changes: 8 additions & 0 deletions 1-js/02-first-steps/01-hello-world/article.md
Original file line number Diff line number Diff line change
@@ -9,7 +9,11 @@

## "script" ট্যাগ

<<<<<<< HEAD
জাভাস্ক্রিপ্ট এর কার্যক্রম গুলো এইচটিএমএল ডকুমেন্টের যেকোনো অংশে রাখা যেতে পারে `<script>` ট্যাগের সাহায্য নিয়ে।
=======
JavaScript programs can be inserted almost anywhere into an HTML document using the `<script>` tag.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
উদাহরণস্বরূপ:

@@ -73,7 +77,11 @@
<script src="/path/to/script.js"></script>
```

<<<<<<< HEAD
এখানে, `/path/to/script.js` এই পথটি হয় সাইট এর মূল থেকে স্ক্রিপ্টের জন্য একটি সঠিক পথ। বর্তমান পৃষ্ঠা থেকে যে কেউ আপেক্ষিক পথ সরবরাহ করতে পারে. উদাহরণস্বরূপ, `src="script.js"` এই `"script.js"` ফাইল দিয়ে বর্তমান ফোল্ডার থেকে বুঝায়।
=======
Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
আমরা পুরো URL টিও দিতে পারি। উদাহরণস্বরূপ:

37 changes: 35 additions & 2 deletions 1-js/02-first-steps/02-structure/article.md
Original file line number Diff line number Diff line change
@@ -46,7 +46,11 @@ alert(3 +
+ 2);
```

<<<<<<< HEAD
উপরের কোডের আউটপুট `6` কারণ জাভাস্ক্রিপ্ট এখানে সেমিকোলন ব্যবহার করবে না। এটি খুবই স্পষ্ট বোঝা যাচ্ছে, যেহেতু লাইন `"+"` দিয়ে শেষ হয়েছে, সেহেতু এটি একটি "অসম্পূর্ণ এক্সপ্রেশন", সুতরাং সেমিকোলনের প্রয়োজন নেই। এবং এই ক্ষেত্রে কোডটি যেভাবে কাজ করা উচিত সেভাবেই কাজ করছে।
=======
The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so a semicolon there would be incorrect. And in this case, that works as intended.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**কিন্তু কিছু পরিস্থিতিতে যেখানে সেমিকোলন অবশ্যই প্রয়োজন, জাভাস্ক্রিপ্ট তা বুঝে নিতে ব্যর্থ হয়।**

@@ -56,19 +60,31 @@ alert(3 +
আপনি যদি এধরণের এররের একটি উদাহরণ দেখতে আগ্রহী হন, তাহলে এই কোডটি দেখুনঃ
```js run
[1, 2].forEach(alert)
alert("Hello");
[1, 2].forEach(alert);
```
<<<<<<< HEAD
`[]` এবং `forEach` এর মানে কি তা এখনই চিন্তা করার দরকার নেই। আমরা পরবর্তীতে তাদের নিয়ে জানব। আপাতত, শুধু মনে রাখুন এই কোডের আউটপুটঃ প্রথমে `1` এবং এরপর `2`।
এবার, কোডের শুরুতে একটি `alert` বসাই এবং সেমিকোলন ছাড়াই লাইনটি শেষ করিঃ
```js run no-beautify
alert("একটি এরর তৈরি হবে")
=======
No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them later. For now, just remember the result of running the code: it shows `Hello`, then `1`, then `2`.
[1, 2].forEach(alert)
Now let's remove the semicolon after the `alert`:
```js run no-beautify
alert("Hello")
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
[1, 2].forEach(alert);
```
<<<<<<< HEAD
এখন যদি আমরা কোডটি রান করি, শুধুমাত্র শুরুর `alert` টি দেখায় এবং এরপর আমরা একটি এরর পাই!
কিন্তু আমরা যদি `alert` এর পর একটি সেমিকোলন দেই, তাহলে সব ঠিকঠাক কাজ করেঃ
@@ -90,6 +106,23 @@ alert("একটি এরর তৈরি হবে")[1, 2].forEach(alert)
```
কিন্তু এখানে একটি নয়, দুটো আলাদা স্টেটমেন্ট হবে। এভাবে একটি লাইনে যোগ করে ফেলাটা পুরোপুরি ভুল, তাই এররটি তৈরি হয়েছে। এমনটা আরও অনেক পরিস্থিতিতে হতে পারে।
=======
The difference compared to the code above is only one character: the semicolon at the end of the first line is gone.
If we run this code, only the first `Hello` shows (and there's an error, you may need to open the console to see it). There are no numbers any more.
That's because JavaScript does not assume a semicolon before square brackets `[...]`. So, the code in the last example is treated as a single statement.
Here's how the engine sees it:
```js run no-beautify
alert("Hello")[1, 2].forEach(alert);
```
Looks weird, right? Such merging in this case is just wrong. We need to put a semicolon after `alert` for the code to work correctly.
This can happen in other situations also.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````

আমরা স্টেটমেন্টের শেষে সেমিকোলন দিতে পরামর্শ দেই, এমনকি যদি স্টেটমেন্টগুলো আলাদা লাইনেও হয়ে থাকে। এই রুলটি কমিউনিটিতে ব্যাপকভাবে গ্রহণ করা হয়েছে। আরও একবার এভাবে বলা যায় -- অধিকাংশ সময় সেমিকোলন ঊহ্য রাখা **সম্ভব**। কিন্তু এটি ব্যবহার করা নিরাপদ -- বিশেষ করে শিক্ষানবিশ/অনভিজ্ঞদের জন্য।
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ That's simple:
let ourPlanetName = "Earth";
```

Note, we could use a shorter name `planet`, but it might be not obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong.
Note, we could use a shorter name `planet`, but it might not be obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong.

## The name of the current visitor

9 changes: 5 additions & 4 deletions 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,14 @@ const birthday = '18.04.1982';
const age = someCode(birthday);
```

Here we have a constant `birthday` date and the `age` is calculated from `birthday` with the help of some code (it is not provided for shortness, and because details don't matter here).
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`.

Would it be right to use upper case for `birthday`? For `age`? Or even for both?

```js
const BIRTHDAY = '18.04.1982'; // make uppercase?
const BIRTHDAY = '18.04.1982'; // make birthday uppercase?

const AGE = someCode(BIRTHDAY); // make uppercase?
const AGE = someCode(BIRTHDAY); // make age uppercase?
```

40 changes: 21 additions & 19 deletions 1-js/02-first-steps/04-variables/article.md
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ Now, we can put some data into it by using the assignment operator `=`:
let message;

*!*
message = 'Hello'; // store the string
message = 'Hello'; // store the string 'Hello' in the variable named message
*/!*
```

@@ -64,6 +64,7 @@ let message = 'Hello';
```

Some people also define multiple variables in this multiline style:

```js no-beautify
let user = 'John',
age = 25,
@@ -87,22 +88,23 @@ In older scripts, you may also find another keyword: `var` instead of `let`:
*!*var*/!* message = 'Hello';
```

The `var` keyword is *almost* the same as `let`. It also declares a variable, but in a slightly different, "old-school" way.
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 for us yet. We'll cover them in detail in the chapter <info:var>.
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>.
````
## A real-life analogy
We can easily grasp the concept of a "variable" if we imagine it as a "box" for data, with a uniquely-named sticker on it.
For instance, the variable `message` can be imagined as a box labeled `"message"` with the value `"Hello!"` in it:
For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
![](variable.svg)
We can put any value in the box.
We can also change it as many times as we want:
```js run
let message;
@@ -149,11 +151,11 @@ So, we should declare a variable once and then refer to it without `let`.
````

```smart header="Functional languages"
It's interesting to note that there exist [functional](https://en.wikipedia.org/wiki/Functional_programming) programming languages, like [Scala](http://www.scala-lang.org/) or [Erlang](http://www.erlang.org/) that forbid changing variable values.
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.
In such languages, once the value is stored "in the box", it's there forever. If we need to store something else, the language forces us to create a new box (declare a new variable). We can't reuse the old one.
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. Studying such a language (even if you're not planning to use it soon) is recommended to broaden the mind.
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.
```

## Variable naming [#variable-naming]
@@ -192,18 +194,18 @@ let my-name; // hyphens '-' aren't allowed in the name
```

```smart header="Case matters"
Variables named `apple` and `AppLE` are two different variables.
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 or even hieroglyphs, like this:
It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this:
```js
let имя = '...';
let 我 = '...';
```
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 some time.
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.
````

````warn header="Reserved names"
@@ -258,12 +260,11 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // error, can't reassign the constant!
```
When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and clearly communicate that fact to everyone.
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.
### Uppercase constants
There is a widespread practice to use constants as aliases for difficult-to-remember values that are known prior to execution.
There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
Such constants are named using capital letters and underscores.
@@ -288,35 +289,36 @@ Benefits:
When should we use capitals for a constant and when should we name it normally? Let's make that clear.
Being a "constant" just means that a variable's value never changes. But there are constants that are known prior to execution (like a hexadecimal value for red) and there are constants that are *calculated* in run-time, during the execution, but do not change after their initial assignment.
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:
```js
const pageLoadTime = /* time taken by a webpage to load */;
```
The value of `pageLoadTime` is not known prior to the page load, so it's named normally. But it's still a constant because it doesn't change after assignment.
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.
In other words, capital-named constants are only used as aliases for "hard-coded" values.
## Name things right
Talking about variables, there's one more extremely important thing.
A variable name should have a clean, obvious meaning, describing the data that it stores.
Variable naming is one of the most important and complex skills in programming. A quick glance at variable names can reveal which code was written by a beginner versus an experienced developer.
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-labeled. Or, in other words, when the variables have good names.
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.
Please spend time thinking about the right name for a variable before declaring it. Doing so will repay you handsomely.
Some good-to-follow rules are:
- Use human-readable names like `userName` or `shoppingCart`.
- Stay away from abbreviations or short names like `a`, `b`, `c`, unless you really know what you're doing.
- 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 own mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`.
- 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`.
Sounds simple? Indeed it is, but creating descriptive and concise variable names in practice is not. Go for it.
75 changes: 43 additions & 32 deletions 1-js/02-first-steps/05-types/article.md
Original file line number Diff line number Diff line change
@@ -46,13 +46,15 @@ Besides regular numbers, there are so-called "special numeric values" which also
alert( "not a number" / 2 ); // NaN, such division is erroneous
```

`NaN` is sticky. Any further operation on `NaN` returns `NaN`:
`NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`:

```js run
alert( "not a number" / 2 + 5 ); // NaN
alert( NaN + 1 ); // NaN
alert( 3 * NaN ); // NaN
alert( "not a number" / 2 - 1 ); // NaN
```

So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result.
So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result (there's only one exception to that: `NaN ** 0` is `1`).

```smart header="Mathematical operations are safe"
Doing maths is "safe" in JavaScript. We can do anything: divide by zero, treat non-numeric strings as numbers, etc.
@@ -64,11 +66,22 @@ Special numeric values formally belong to the "number" type. Of course they are

We'll see more about working with numbers in the chapter <info:number>.
## BigInt
## BigInt [#bigint-type]
In JavaScript, the "number" type cannot 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. It's a technical limitation caused by their internal representation.
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.

For most purposes that's quite enough, but sometimes we need really big numbers, e.g. for cryptography or microsecond-precision timestamps.
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.

`BigInt` type was recently added to the language to represent integers of arbitrary length.

@@ -81,13 +94,6 @@ const bigInt = 1234567890123456789012345678901234567890n;

As `BigInt` numbers are rarely needed, we don't cover them here, but devoted them a separate chapter <info:bigint>. Read it when you need such big numbers.

```smart header="Compatibility issues"
Right now, `BigInt` is supported in Firefox/Chrome/Edge/Safari, but not in IE.
```

You can check [*MDN* BigInt compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) to know which versions of a browser are supported.

## String
A string in JavaScript must be surrounded by quotes.
@@ -211,16 +217,9 @@ The `symbol` type is used to create unique identifiers for objects. We have to m

## The typeof operator [#type-typeof]

The `typeof` operator returns the type of the argument. It's useful when we want to process values of different types differently or just want to do a quick check.

It supports two forms of syntax:

1. As an operator: `typeof x`.
2. As a function: `typeof(x)`.
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.

In other words, it works with parentheses or without them. The result is the same.

The call to `typeof x` returns a string with the type name:
A call to `typeof x` returns a string with the type name:

```js
typeof undefined // "undefined"
@@ -251,25 +250,37 @@ typeof alert // "function" (3)
The last three lines may need additional explanation:

1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter <info:number>. Here, it serves just as an example of an object.
2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof` behavior, coming from the early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own.
2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof`, coming from very early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own. The behavior of `typeof` is wrong here.
3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That also comes from the early days of JavaScript. Technically, such behavior isn't correct, but can be convenient in practice.

```smart header="The `typeof(x)` syntax"
You may also come across another syntax: `typeof(x)`. It's the same as `typeof x`.

To put it clear: `typeof` is an operator, not a function. The parentheses here aren't a part of `typeof`. It's the kind of parentheses used for mathematical grouping.

Usually, such parentheses contain a mathematical expression, such as `(2 + 2)`, but here they contain only one argument `(x)`. Syntactically, they allow to avoid a space between the `typeof` operator and its argument, and some people like it.

Some people prefer `typeof(x)`, although the `typeof x` syntax is much more common.
```
## Summary
There are 8 basic data types in JavaScript.
- `number` for numbers of any kind: integer or floating-point, integers are limited by <code>±(2<sup>53</sup>-1)</code>.
- `bigint` is 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`.
- `object` for more complex data structures.
- `symbol` for unique identifiers.
- 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.
The `typeof` operator allows us to see which type is stored in a variable.
- Two forms: `typeof x` or `typeof(x)`.
- Usually used as `typeof x`, but `typeof(x)` is also possible.
- Returns a string with the name of the type, like `"string"`.
- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
24 changes: 23 additions & 1 deletion 1-js/02-first-steps/07-type-conversions/article.md
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
এই অধ্যায়ে, আমরা অবজেক্ট নয় বরং, প্রিমিটিভ বিষয়গূলো জানবো। পরবর্তিতে, অবজেক্টের ধারণা পেলে, আমরা অবজেক্ট রূপান্তর নিয়ে আলোচনা করবো। <info:object-toprimitive>.
=======
```smart header="Not talking about objects yet"
In this chapter, we won't cover objects. For now we'll just be talking about primitives.
In this chapter, we won't cover objects. For now, we'll just be talking about primitives.
Later, after we learn about objects, in the chapter <info:object-toprimitive> we'll see how objects fit in.
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d:1-js/02-first-steps/07-type-conversions/article.md
@@ -39,7 +39,11 @@ alert(typeof value); // স্ট্রিং

## সংখ্যা রূপান্তর

<<<<<<< HEAD
গানিতিক ফাংশন এবং এক্সপ্রেশনের ক্ষেত্রে সংখ্যায় রুপান্তর নিজে থেকেই হয়ে থাকে।
=======
Numeric conversion in mathematical functions and expressions happens automatically.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
যেমন, ভাগের `/` সময় দুটি স্ট্রিং:

@@ -70,12 +74,21 @@ alert(age); // NaN, রূপান্তর হয়নি

সংখ্যা রুপান্তরের নিয়ম:

<<<<<<< HEAD
| ভ্যালু | পরিবর্তিত রুপ... |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `undefined` | `NaN` |
| `null` | `0` |
| <code>true&nbsp;&nbsp;false</code> | `1``0` |
| `string` | স্ট্রিংয়ের শুরু ও শেষের স্পেস থেকে তা মুছে ফেলা হয়। বাকিটা ফাঁকা স্ট্রিং হলে, তা `0` হবে। নাহয় নাম্বারগুলি স্ট্রিং থেকে নেয়া হয়। এরর হলে `NaN` আসে। |
=======
| Value | Becomes... |
|-------|-------------|
|`undefined`|`NaN`|
|`null`|`0`|
|<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
Examples:

@@ -130,12 +143,21 @@ alert( Boolean(" ") ); // স্পেস, এটাও true (স্ট্রি
রূপান্তর নীতি:
<<<<<<< HEAD
| ভ্যালু | বদলে যায়... |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `undefined` | `NaN` |
| `null` | `0` |
| <code>true&nbsp;/&nbsp;false</code> | `1 / 0` |
| `string` | স্ট্রিংয়ে যা তাই আসে, স্ট্রিংয়ের শুরু ও শেষের স্পেস থেকে তা মুছে ফেলা হয়। বাকিটা ফাঁকা স্ট্রিং হলে, তা `0` হবে। নাহয় নাম্বারগুলি স্ট্রিং থেকে নেয়া হয়। এরর হলে `NaN` আসে। |
=======
| Value | Becomes... |
|-------|-------------|
|`undefined`|`NaN`|
|`null`|`0`|
|<code>true&nbsp;/&nbsp;false</code> | `1 / 0` |
| `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
**`বুলিয়ানে রূপান্তর`** -- লজিকাল অপারেশনে হয়। আবার `Boolean(value)` দিয়েও করা যায।
Original file line number Diff line number Diff line change
@@ -9,18 +9,27 @@ true + false = 1
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
" -9 " + 5 = " -9 5" // (3)
" -9 " - 5 = -14 // (4)
null + 1 = 1 // (5)
undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```

<<<<<<< HEAD
1. কোন স্ট্রিংয়ের সাথে যোগের ক্ষেত্রে `"" + 1` তে `1` রূপান্তর হয়ে `"" + 1 = "1"` হয়। তাই এখানে পায় `"1" + 0`, এক্ষেত্রেও একই নিয়ম প্রযোজ্য।
2. বিয়োগ `-` (প্রায় অন্যসব অপারেটরের মতই) শুধুমাত্র সংখ্যা নিয়ে কাজ করে, এটি ফাঁকা স্ট্রিংকে শূন্য তে রূপান্তর করে নেয় `""` থেকে `0` হবে।
3. স্ট্রিং সংযুক্তকরণ নীতি অনুসারে `5` স্ট্রিংয়ে রূপান্তর হবে।
4. বিয়োগের সময় স্ট্রিং সবসময় সংখ্যায় রূপান্তর হয়, তাই এক্ষেত্রে `" -9 "` সংখ্যা `-9` তে পরিবর্তন হয় (এখানে স্পেসগুলিকে উপেক্ষা করে)।
5. `null` হবে `0` সংখ্যায় রুপান্তরের পর।
6. `undefined` হয়ে যায় `NaN` সংখ্যায় রূপান্তর করা হলে।
7. স্পেসসমূহ বাদ দেয়া হয় সংখ্যায় রুপান্তর করলে, এখানে পুরো স্ট্রিংটাই বিভিন্ন স্পেসে তৈরি, যেমনঃ `\t`, `\n` এবং তাদের মাঝের "রেগুলার" স্পেসসমূহ। সুতরাং এটি ফাঁকা স্ট্রিংয়ের মতই, যা শুন্যতে (`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
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ true + false
"$" + 4 + 5
"4" - 2
"4px" - 2
7 / 0
" -9 " + 5
" -9 " - 5
null + 1
69 changes: 68 additions & 1 deletion 1-js/02-first-steps/08-operators/article.md
Original file line number Diff line number Diff line change
@@ -50,23 +50,46 @@
যেমন:

```js run
<<<<<<< HEAD
alert( 5 % 2 ); // ১, ৫ কে ২ দিয়ে ভাগ করার পর ভাগশেষ
alert( 8 % 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
```

### সূচক **

<<<<<<< HEAD
সূচক অপারেটর `a ** b`, `a` কে `b` বার নিজেকে নিজে গুণ করে।
=======
The exponentiation operator `a ** b` raises `a` to the power of `b`.

In school maths, we write that as a<sup>b</sup>.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

যেমন:

```js run
<<<<<<< HEAD
alert( 2 ** 2 ); // ৪ (দুইকে দুইবার গুণ)
alert( 2 ** 3 ); // ৮ (২ * ২ * ২, ৩ বার)
alert( 2 ** 4 ); // ১৬ (২ * ২ * ২ * ২, ৪ বার)
```

গণিতে সূচক নন-ইন্টিজার বা অপূর্ণ সংখ্যার জন্যও প্রযোজ্য। যেমন, বর্গমূল হচ্ছে `১/২` দিয়ে ঘাত করা:
=======
alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
```
Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
For example, a square root is an exponentiation by ½:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
alert( 4 ** (1/2) ); // ২ (কোনো সংখ্যার সূচক ১/২ আর সংখ্যাটির বর্গমূল একই)
@@ -76,7 +99,11 @@ alert( 8 ** (1/3) ); // ২ (কোনো সংখ্যার সূচক ১
## বাইনারি + দিয়ে স্ট্রিং জোড়া দেয়া
<<<<<<< HEAD
এবার আমরা জাভাস্ক্রিপ্ট অপারেটরের কিছু বিশেষত্ব দেখি যেগুলো স্কুলের পাটিগণিতের বাইরে।
=======
Let's meet the features of JavaScript operators that are beyond school arithmetics.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
সাধারণত, প্লাস অপারেটর `+` সংখ্যা যোগ করে।
@@ -104,7 +131,16 @@ alert( 2 + '1' ); // "21"
alert(2 + 2 + '1' ); // "41", "221" না
```
<<<<<<< HEAD
এখানে অপারেটরগুলো একটির পর আরেকটি কাজ করেছে। প্রথম `+` দুইটি সংখ্যাকে যোগ করেছে, তাই এটা `4` রিটার্ন করে, তারপর পরের `+` এর সাথে স্ট্রিং `1` যোগ করে, তাই `4 + '1' = 41`
=======
Here, operators work one after another. The first `+` sums two numbers, so it returns `4`, then the next `+` adds the string `1` to it, so it's like `4 + '1' = '41'`.
```js run
alert('1' + 2 + 2); // "122" and not "14"
```
Here, the first operand is a string, the compiler treats the other two operands as strings too. The `2` gets concatenated to `'1'`, so it's like `'1' + 2 = "12"` and `"12" + 2 = "122"`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
বাইনারি `+` ই একমাত্র অপারেটর যেটি স্ট্রিং সাপোর্ট করে। অন্যন্য অপারেটর শুধু সংখ্যা নিয়ে কাজ করে আর সবসময় এর অপারেন্ডগুলোকে সংখ্যায় রূপান্তর করে নেয়।
@@ -185,6 +221,7 @@ alert( +apples + +oranges ); // ৫
| প্রিসিডেন্স | নাম | চিহ্ন |
|------------|------|------|
| ... | ... | ... |
<<<<<<< HEAD
| ১৭ | ইউনারি প্লাস | `+` |
| ১৭ | ইউনারি নেগেশন | `-` |
| ১৬ | সূচক | `**` |
@@ -197,10 +234,28 @@ alert( +apples + +oranges ); // ৫
| ... | ... | ... |
আমরা দেখতে পাচ্ছি, "ইউনারি প্লাসের" প্রায়োরিটি `১৭` যা যোগের (বাইনারি প্লাস) `১৩` এর চেয়ে বেশি। এজন্য `"+apples + +oranges"` এক্সপ্রেশনে ইউনারি প্লাস বাইনারি প্লাসের আগে কাজ করেছিলো।
=======
| 14 | unary plus | `+` |
| 14 | unary negation | `-` |
| 13 | exponentiation | `**` |
| 12 | multiplication | `*` |
| 12 | division | `/` |
| 11 | addition | `+` |
| 11 | subtraction | `-` |
| ... | ... | ... |
| 2 | assignment | `=` |
| ... | ... | ... |
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
## অ্যাসাইনমেন্ট
<<<<<<< HEAD
খেয়াল রাখবেন অ্যাসাইনমেন্টও `=` একটি অপারেটর। এটা প্রিসিডেন্স টেবিলের প্রায় নিচের দিকে খুব কম প্রায়োরিটি `` নিয়ে অবস্থান করছে।
=======
Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
এজন্য যখন আমরা `x = 2 * 2 + 1` এভাবে ভ্যারিয়েবল অ্যাসাইন করি তখন ক্যালকুলেশন আগে করা হয় আর তারপর `=` এর কাজ হয় যা হলো `x` এ ফলাফলটা জমা রাখা।
@@ -214,7 +269,11 @@ alert( x ); // ৫
`=` যে একট অপারেটর, কোনো জাদুকরি ল্যাঙ্গুয়েজ কনস্ট্রাকট না, তার একটা মজার প্রমাণ আছে।
<<<<<<< HEAD
জাভাস্ক্রিপ্টের বেশিরভাগ অপারেটরই একটি ভ্যালু রিটার্ন করে। আমরা `+` আর `-` এর ক্ষেত্রে তো বুঝতেই পারছি, কিন্তু এটা `=` এর জন্যও প্রযোজ্য।
=======
All operators in JavaScript return a value. That's obvious for `+` and `-`, but also true for `=`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`x = value` এক্সপ্রেশন কল `value` কে `x` এ লিখে *এবং তারপর সেটা রিটার্ন করে*।
@@ -294,9 +353,13 @@ alert( n ); // 14
```js run
let n = 2;

n *= 3 + 5;
n *= 3 + 5; // right part evaluated first, same as n *= 8

<<<<<<< HEAD
alert( n ); // 16 (ডান অংশ আগে ইভ্যালুয়েট হয়, n *= 8 এর অনুরূপ)
=======
alert( n ); // 16
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## ইনক্রিমেন্ট/ডিক্রিমেন্ট
@@ -428,7 +491,11 @@ counter++;
- RIGHT SHIFT ( `>>` )
- ZERO-FILL RIGHT SHIFT ( `>>>` )
<<<<<<< HEAD
এই অপারেটরগুলো খুব কম ক্ষেত্রে যখন আমাদের সংখ্যা নিয়ে খুব নিচের (বিটওয়াইজ) লেভেলে কাজ করতে হয় তখনই শুধু ব্যবহার হয়। আমাদের এই অপারেটরগুলো এরপর আর দরকার হচ্ছে না, যেহেতু ওয়েব ডেভেলপমেন্টে এদের খুব কম কাজই আছে, কিন্তু বিশেষ কিছু ক্ষেত্র, যেমন ক্রিপ্টোগ্রাফিতে এদের দরকার হবে। আপনি MDN এর [বিটওয়াইজ অপারেটর](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise) অধ্যায়টি পড়তে পারেন যখন দরকার পড়বে।
=======
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
## কমা
2 changes: 1 addition & 1 deletion 1-js/02-first-steps/09-comparison/article.md
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ In JavaScript they are written like this:
- Greater/less than: <code>a &gt; b</code>, <code>a &lt; b</code>.
- Greater/less than or equals: <code>a &gt;= b</code>, <code>a &lt;= b</code>.
- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
- Not equals. In maths the notation is <code>&ne;</code>, but in JavaScript it's written as <code>a != b</code>.
- Not equals: In maths the notation is <code>&ne;</code>, but in JavaScript it's written as <code>a != b</code>.

In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.

2 changes: 1 addition & 1 deletion 1-js/02-first-steps/10-ifelse/2-check-standard/task.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ importance: 2

Using the `if..else` construct, write the code which asks: 'What is the "official" name of JavaScript?'

If the visitor enters "ECMAScript", then output "Right!", otherwise -- output: "Didn't know? ECMAScript!"
If the visitor enters "ECMAScript", then output "Right!", otherwise -- output: "You don't know? ECMAScript!"

![](ifelse_task2.svg)

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

## The "else" clause

The `if` statement may contain an optional "else" block. It executes when the condition is false.
The `if` statement may contain an optional `else` block. It executes when the condition is falsy.

For example:
```js run
@@ -181,9 +181,9 @@ alert( message );
It may be difficult at first to grasp what's going on. But after a closer look, we can see that it's just an ordinary sequence of tests:

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!'`.
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!'`.

Here's how this looks using `if..else`:

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
উত্তর: `null`, কারণ এটি তালিকা থেকে প্রথম মিথ্যা মান

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

8 changes: 6 additions & 2 deletions 1-js/02-first-steps/11-logical-operators/article.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Logical operators

<<<<<<< HEAD
জাভাস্ক্রিপ্টে তিনটি লজিক্যাল অপারেটর রয়েছে: `||` (OR), `&&` (AND), `!` (NOT).
=======
There are four logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT), `??` (Nullish Coalescing). Here we cover the first three, the `??` operator is in the next article.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
যদিও তাদের "লজিক্যাল" বলা হয়, সেগুলি কেবল বুলিয়ান নয়, যে কোনও ধরণের মানগুলিতে প্রয়োগ করা যেতে পারে। তাদের ফলাফলও যে কোনও ধরণের হতে পারে।

@@ -64,7 +68,7 @@ if (hour < 10 || hour > 18 || isWeekend) {
}
```

## OR "||" finds the first truthy value
## OR "||" finds the first truthy value [#or-finds-the-first-truthy-value]

উপরে বর্ণিত যুক্তি কিছুটা ক্লাসিকাল। এখন, জাভাস্ক্রিপ্টের "অতিরিক্ত" বৈশিষ্ট্যগুলি নিয়ে আসি।

@@ -144,7 +148,7 @@ alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument.

That importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.

<<<<<<< HEAD
alert(x); // undefined, because (x = 1) not evaluated
64 changes: 62 additions & 2 deletions 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

[recent browser="new"]

<<<<<<< HEAD
এই নিবন্ধে আমরা কোন একটা এক্সপ্রেশান কে তখনি "সংজ্ঞায়িত" বলবো যখন সেটা `নাল` অথবা `অসঙ্গায়িত` কোনটাই হবে না ।

নাল-ঈশ কোয়েলেসিং অপারেটর কে দুইটি প্রশ্নবোধক চিহ্ন দ্বারা এভাবে লেখা হয় `??`
@@ -12,6 +13,17 @@
- যখন `a` সংজ্ঞায়িত না, তখন `b`

অন্যকথায় বলতে গেলে, যদি প্রথম আর্গুমেন্ট `নাল/অসঙ্গায়িত` না হয় তাহলে `??` এটা প্রথম আর্গুমেন্ট রিটার্ন করবে । তানাহলে , দ্বিতীয়টা রিটার্ন করবে।
=======
The nullish coalescing operator is written as two question marks `??`.

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`.

The result of `a ?? b` is:
- if `a` is defined, then `a`,
- if `a` isn't defined, then `b`.

In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
নাল-ঈশ কোয়েলেসিং অপারেটরটা নতুন কিছু নয়। এটা শুধুমাত্র একটা সুন্দর সিনট্যাক্স যেটা দুইটা মানের মধ্যে প্রথম সংজ্ঞায়িত মানটা বের করে দেয়।

@@ -21,29 +33,47 @@
result = a !== null && a !== undefined ? a : b;
```

<<<<<<< HEAD
সম্ভাব্য অসঙ্গায়িত ভ্যরিয়াবল এর ডিফল্ট মান সরবরাহ করা, `??` এটার সাধারণ ব্যাবহারের ক্ষেত্র ।

উদাহরণ হিসেবে বলা যায়, যদি `user` defined না হয় তাহলে আমরা `Anonymous`দেখাবো।
=======
Now it should be absolutely clear what `??` does. Let's see where it helps.

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;

alert(user ?? "Anonymous"); // Anonymous
alert(user ?? "Anonymous"); // Anonymous (user is undefined)
```
<<<<<<< HEAD
অবশ্য, যদি `user``নাল/অসঙ্গায়িত` ছাড়া অন্য কোন মান থাকে তাহলে আমরা `user` কেই দেখবো:
=======
Here's the example with `user` assigned to a name:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let user = "John";

alert(user ?? "Anonymous"); // John
alert(user ?? "Anonymous"); // John (user is not null/undefined)
```
একটা তালিকা থেকে প্রথম মান, যেটা `নাল/অসঙ্গায়িত` হবে না সেটাও আমরা `??` এর পর্যায়াক্রম ব্যবহার করে বের করতে পারি ।
<<<<<<< HEAD
মনে করি আমাদের কাছে একজন ব্যবহারকারী এর তথ্য আছে `firstName`, `lastName` অথবা `nickName` ভ্যারিয়েবল এ। সব গুলোর মানই অসঙ্গায়িত হতে পারি যদি ব্যবহারকারী কোন তথ্য না দেয়।
আমরা চাই যেকোনো একটি ভ্যারিয়েবল নিয়ে ব্যবহারকারীর নাম দেখাতে, অথবা "Anonymous" দেখাতে যদি সব ভ্যারিয়েবল অসঙ্গায়িত হয় ।
=======
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
এটা করার জন্যে `??` অপারেটর টা ব্যবহার করা যাক:
@@ -75,7 +105,11 @@ alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
*/!*
```
<<<<<<< HEAD
অর `||` অপারেটর জাভাস্ক্রিপ্ট এর শুরু থেকেই ছিল, তাই ডেভোলপাররা এটিই ব্যবহার করে আসছে অনেক লম্বা সময় ধরে ।
=======
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
অপরপক্ষে কোয়েলেসিং অপারেটর `??` সাম্প্রতিক সময়ে কেবল মাত্রই যুক্ত হল জাভাস্ক্রিপ্ট এ এবং এর কারণ হলে `||` এটা দ্বারা মানুষজন খুশি ছিল না।
@@ -97,18 +131,35 @@ alert(height || 100); // 100
alert(height ?? 100); // 0
```
<<<<<<< HEAD
- `height || 100` এটি দেখে যে `height` ফলছি ভ্যালু কিনা এবং ফলছি ভ্যালু হিসেবেই পায় ।
- তাই উত্তর হল দ্বিতীয় আর্গুমেন্ট, `100`
- `height ?? 100` এটি দেখে যে `height` `নাল/অসঙ্গায়িত` কিনা এবং দেখে যে এটি এমন না ।
- তাই উত্তর হিসেবে `height` এর মান দেখায়, যেটা হল `0`
যদি শূন্য উচ্চতা একটি বৈধ মান হয়ে যেটি কিনা ডিফল্ট মান দ্বারা পরিবর্তিত হবে না সেক্ষেত্রে `??` এই অপারেটর টা যথার্থ কাজ করছে ।
=======
- The `height || 100` checks `height` for being a falsy value, and it's `0`, falsy indeed.
- so the result of `||` is the second argument, `100`.
- The `height ?? 100` checks `height` for being `null/undefined`, and it's not,
- so the result is `height` "as is", that is `0`.
In practice, the zero height is often a valid value, that shouldn't be replaced with the default. So `??` does just the right thing.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## প্রাধান্য
<<<<<<< HEAD
`??` অপারেটর এর প্রাধান্য কিছুটা কম। [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) এ `` নাম্বার। । তাই `??` অপারেটর, `=` এবং `?` এর আগে মুল্যায়িত হবে, কিন্তু অন্যান্য বেশীর ভাগ অপারেশন, যেমন `+`, `*`, এর পরে মুল্যায়িত হবে।
তাই আমরা যদি `??` এই এক্সপ্রেশন এর মাধ্যমে কোন ভ্যালু নির্বাচন করতে চাই তাহলে বন্ধনীর ব্যবহার বিবেচনা করা উচিত:
=======
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).
That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`.
So we may need to add parentheses in expressions like this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let height = null;
@@ -126,8 +177,13 @@ alert(area); // ৫০০০
// বন্ধনী ব্যতীত
let area = height ?? 100 * width ?? 50;

<<<<<<< HEAD
// ...এটির মতই কাজ করে (যা খুব সম্ভবত আমরা চাই না):
let area = height ?? 100 * width ?? 50;
=======
// ...works this way (not what we want):
let area = height ?? (100 * width) ?? 50;
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
### && or || এর সাথে ?? ব্যবহার
@@ -140,7 +196,11 @@ let area = height ?? 100 * width ?? 50;
let x = 1 && 2 ?? 3; // সিনট্যাক্স ইরর
```
<<<<<<< HEAD
এটির সীমাবদ্ধতা অবশ্যই তর্কসাপেক্ষ কিন্তু যখন মানুষজন `||` এর পরিবর্তে `??` ব্যবহার করা শুরু করল তখন প্রোগ্রামিং ভুল দুর করার জন্যে এটি ল্যাঙ্গুয়েজ স্পেছিফিকেশন এ যুক্ত করা হয়।
=======
The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from `||` to `??`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ভুল এড়ানোর জন্যে পরিষ্কারভাবে বর্ণিত বন্ধনী ব্যবহার করুন:
41 changes: 33 additions & 8 deletions 1-js/02-first-steps/13-while-for/article.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,19 @@ For example, outputting goods from a list one after another or just running the

*Loops* are a way to repeat the same code multiple times.

```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

The `while` loop has the following syntax:
@@ -106,7 +119,7 @@ Let's examine the `for` statement part-by-part:

| part | | |
|-------|----------|----------------------------------------------------------------------------|
| begin | `i = 0` | Executes once upon entering the loop. |
| begin | `let i = 0` | Executes once upon entering the loop. |
| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. |
| body | `alert(i)`| Runs again and again while the condition is truthy. |
| step| `i++` | Executes after the body on each iteration. |
@@ -162,10 +175,8 @@ for (i = 0; i < 3; i++) { // use an existing variable
alert(i); // 3, visible, because declared outside of the loop
```
````


### Skipping parts

Any part of `for` can be skipped.
@@ -268,7 +279,7 @@ for (let i = 0; i < 10; i++) {

From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.

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.
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.
````
````warn header="No `break/continue` to the right side of '?'"
@@ -286,7 +297,6 @@ if (i > 5) {
...and rewrite it using a question mark:
```js no-beautify
(i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here
```
@@ -318,9 +328,10 @@ alert('Done!');

We need a way to stop the process if the user cancels the input.

The ordinary `break` after `input` would only break the inner loop. That's not sufficient--labels, come to the rescue!
The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue!

A *label* is an identifier with a colon before a loop:

```js
labelName: for (...) {
...
@@ -342,6 +353,7 @@ The `break <labelName>` statement in the loop below breaks out to the label:
// do something with the value...
}
}

alert('Done!');
```

@@ -362,13 +374,26 @@ The `continue` directive can also be used with a label. In this case, code execu
Labels do not allow us to jump into an arbitrary place in the code.
For example, it is impossible to do this:
```js
break label; // doesn't jumps to the label below
break label; // jump to the label below (doesn't work)
label: for (...)
```
A call to `break/continue` is only possible from inside a loop and the label must be somewhere above the directive.
A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
```js
label: {
// ...
break label; // works
// ...
}
```
...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
A `continue` is only possible from inside a loop.
````

## Summary
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/14-switch/article.md
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ switch (a) {
break;
*/!*
case 5:
alert( 'Too large' );
alert( 'Too big' );
break;
default:
alert( "I don't know such values" );
@@ -139,7 +139,7 @@ switch (a) {
Now both `3` and `5` show the same message.
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`.
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`.
## Type matters
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
পার্থক্য নেই.
<<<<<<< HEAD
পার্থক্য নেই.
=======
No difference!

In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
Original file line number Diff line number Diff line change
@@ -14,4 +14,8 @@ function checkAge(age) {
}
```

<<<<<<< HEAD
নোটঃ `age > 18` দুপাশে প্রথম ব্রাকেট প্রয়োজনীয় না। শুধুই বুঝার সুবিধার্থে দেওয়া।
=======
Note that the parentheses around `age > 18` are not required here. They exist for better readability.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
124 changes: 113 additions & 11 deletions 1-js/02-first-steps/15-function-basics/article.md
Original file line number Diff line number Diff line change
@@ -20,11 +20,15 @@ function showMessage() {
}
```

<<<<<<< HEAD
ফাংশন বানাতে প্রথমের `function` কীওয়ার্ডটা লিখে বুঝিয়ে দিতে হবে জাভাস্ক্রিপ্ট ইঞ্জিনকে যা এখন আমরা যা লিখতে যাচ্ছি তা একসাথে একটা কাজ সমাধান করতে যাচ্ছে। এরপরে _ফাংশনের নাম_ লিখে ফাংশনকে যে কোনো জায়গা থেকে ডাকার ব্যবস্থা করতে হবে। এরপর দুই প্রথম ব্রাকেটের মাঝে কিছু জিনিস দিতে হবে প্রয়োজন অনুসারে, যেটাকে বলে _প্যারামিটার_ (প্যারামিটার যে দিতেই হবে তার বাধ্যবাধকতা নেই। যেমন উপরের উদাহরণে দেওয়া হয় নাই। যদি প্যারামিটার লাগে তাহলে কমা দিয়ে আলাদা করে হয় প্যারামিটারগুলো। একটা ফাংশনে একাধিক প্যারামিটার থাকতে পারে।) সবশেষে দুই সেকেন্ড ব্রাকেটের মাঝে কোড লিখতে হয়, যা কিনা কোনো নির্দিষ্ট কাজ করতে সাহায্য করবে। এই অংশকে বলা হয় _ফাংশন বডি_।
=======
The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above, we'll see examples later) and finally the code of the function, also named "the function body", between curly braces.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
function name(parameters) {
...body...
function name(parameter1, parameter2, ... parameterN) {
// body
}
```

@@ -137,26 +141,31 @@ alert( userName ); // *!*Rahim*/!*, অপরিবর্তনীয়, ফাং

## প্যারামিটার

<<<<<<< HEAD
আমরা প্রয়োজনীয় ডাটা প্যারামিটার এর মাধ্যমে কোনো ফাংশনে ব্যবহার করতে পারি। (এদেরকে _ফাংশন আর্গুমেন্টস_ ও বলা হয়)।
=======
We can pass arbitrary data to functions using parameters.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
নিচের উদাহরণে দুইটা প্যারামিটার আছে। একটা `from` এবং অন্যটা `text`

```js run
<<<<<<< HEAD
function showMessage(*!*from, text*/!*) { // আর্গুমেন্টসঃ from, text
=======
function showMessage(*!*from, text*/!*) { // parameters: from, text
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
alert(from + ': ' + text);
}

*!*
showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
showMessage('Ann', "What's up?"); // Ann: What's up? (**)
*/!*
*!*showMessage('Ann', 'Hello!');*/!* // Ann: Hello! (*)
*!*showMessage('Ann', "What's up?");*/!* // Ann: What's up? (**)
```
যখন ফাংশন লাইন `(*)` এবং `(**)` কল করে, ভ্যালুগুলো `from` এবং `text` এ এসাইন হয়। পরবর্তিতে প্রয়োজনানুসারে ফাংশন তাদেরকে ব্যবহার করে।
আরেকটা উদাহরণ দেখা যাকঃ ভ্যারিয়েবল `from` ফাংশনে ডিক্লিয়ার করলাম। নোটঃ ফাংশন `from` কে পরিবর্তন করে, কিন্তু এই পরিবর্তন বাইরে কোথাও দেখা যাবে না। কারণ, ফাংশন সবসময় ভ্যাল্যুর একটা কপি নিজের কাছে রেখে দিবে।
```js run
function showMessage(from, text) {
@@ -175,23 +184,47 @@ showMessage(from, "Hello"); // *Ann*: Hello
alert( from ); // Ann
```
<<<<<<< HEAD
## ডিফল্ট ভ্যালু
যদি কোনো প্যারামিটার এর মান দেওয়া না থাকে, তাহলে সেটার ভ্যালু `undefined` ধরে নেওয়া হয়।
=======
When a value is passed as a function parameter, it's also called an *argument*.

In other words, to put these terms straight:

- 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`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

তাই একাধিক প্যারামিটারের ক্ষেত্রে `showMessage(from, text)` একটা আর্গুমেন্ট দিলেও প্রোগ্রাম চলবে। যেমনঃ

```js
showMessage("Ann");
```

<<<<<<< HEAD
<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
এইখানে কোনো ভুল নেই। এমন ফাংশন কল `"Ann: undefined"` রিটার্ন করবে। এখানে `text` প্যারামিটারের মান বলে দেওয়া হয় নাই। তাই `text === undefined` ধরে নিবে প্রোগ্রাম।
=======
That's not an error. Such a call would output `"*Ann*: undefined"`. There's no `text`, so it's assumed that `text === undefined`.
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d:1-js/02-first-steps/15-function-basics/article.md

যদি কোনো মান সেট না হলে ডিফল্টভাবে একটা মান ধরে নিয়ে প্রোগ্রাম চালাতে চাই, তাহলে প্যারামিটারেই মানটা এসাইন করে দিতে পারবো। যেমনঃ
=======
That's not an error. Such a call would output `"*Ann*: undefined"`. As the value for `text` isn't passed, it becomes `undefined`.

We can specify the so-called "default" (to use if omitted) value for a parameter in the function declaration, using `=`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

```js run
function showMessage(from, *!*text = "no text given"*/!*) {
@@ -201,7 +234,17 @@ function showMessage(from, *!*text = "no text given"*/!*) {
showMessage("Ann"); // Ann: no text given
```
<<<<<<< HEAD
এখানে যদি `text` প্যারামিটারের মান ইউজার না দেয়, তাহলে ডিফল্টভাবে `"no text given"` সেট হয়ে থাকবে।
=======
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
এখানে `"no text given"` একটা স্ট্রিং। কিন্তু আমরা চাইলে এখানে যে কোনো কিছু ব্যবহার করতে পারি। এমনকি জটিল লজিক্যাল অপারেশনও। যদি প্যারামিটার মিসিং থাকে তাহলে বাই ডিফল্ট সেই অপারেশন কাজ করবে। যেমনঃ
@@ -215,6 +258,7 @@ function showMessage(from, text = anotherFunction()) {
```smart header="Evaluation of default parameters"
জাভাস্ক্রিপ্টে কোনো প্যারামিটারের বিপরীতে কোনো মান সেট করে না দিলে প্যারামিটারে ডিফল্টভাবে এসাইন করা মান কল হবে যতবার পুরো ফাংশন কল করা হবে।

<<<<<<< HEAD
উপরের উদাহরণ টেনে বলা যায়, `anotherFunction()` ততবার কল হবে যতবার `showMessage()` কল করা হবে `text` প্যারামিটারের মান দেওয়া ছাড়াই।
```
@@ -228,13 +272,57 @@ function showMessage(from, text = anotherFunction()) {
Sometimes it makes sense to set default values for parameters not in the function declaration, but at a later stage, during its execution.
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d:1-js/02-first-steps/15-function-basics/article.md
=======
In the example above, `anotherFunction()` isn't called at all, if the `text` parameter is provided.
To check for an omitted parameter, we can compare it with `undefined`:
On the other hand, it's independently called every time when `text` is missing.
```

````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
We can check if the parameter is passed during the function execution, by comparing it with `undefined`:
```js run
function showMessage(text) {
// ...
*!*
if (text === undefined) {
if (text === undefined) { // if the parameter is missing
text = 'empty message';
}
*/!*
@@ -248,24 +336,28 @@ showMessage(); // empty message
...Or we could use the `||` operator:
```js
<<<<<<< HEAD
<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
function showMessage(from, text) {
// যদি `text` এর মান না দেওয়া হয় তাহলে "default" ভ্যালু সেট করে নিবে
text = text || 'no text given';
=======
// if text parameter is omitted or "" is passed, set it to 'empty'
=======
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
function showMessage(text) {
// if text is undefined or otherwise falsy, set it to 'empty'
text = text || 'empty';
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d:1-js/02-first-steps/15-function-basics/article.md
...
}
```
Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when falsy values, such as `0`, are considered regular:
Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when most falsy values, such as `0`, should be considered "normal":

```js run
// if there's no "count" parameter, show "unknown"
function showCount(count) {
// if count is undefined or null, show "unknown"
alert(count ?? "unknown");
}
@@ -426,9 +518,15 @@ checkPermission(..) // পারমিশন চেক করে, true/false র
```smart header="Ultrashort function names"
যে ফাংশনগুলো *খুব বেশি* কল করা হয়, তাকে মাঝে মাঝে স্পেশাল কিছু সূচনা নাম দেওয়া হয়ে থাকে।

<<<<<<< HEAD
যেমন, [jQuery](http://jquery.com) ফ্রেমওয়ার্ক `$` দিয়ে শুরু করে তাদের ফাংশন নাম। আবার [Lodash](http://lodash.com/) লাইব্রেরি `_` দিয়ে শুরু করে।

এগুলো এক্সেপশন। বেশিরভাগ সময় ফাংশন নাম অর্থপূর্ন ও বিস্তারিত হওয়া উচিৎ।
=======
For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.

These are exceptions. Generally function names should be concise and descriptive.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```

## ফাংশন == কমেন্টস
@@ -494,7 +592,11 @@ function name(parameters, delimited, by, comma) {
কোডকে অর্থপূর্ন ও গোছালো রাখতে লোকাল ভ্যারিয়েবল ইউজ করা উচিৎ, গ্লোবাল ভ্যারিয়েবল ইউজ না করে।
<<<<<<< HEAD
বাইরের ভ্যারিয়েবল মডিফাই করে ও কোনো প্যারামিটার না রেখে ফাংশন ইউজ করার চেয়ে প্যারামিটারসহ ফাংশন নিয়ে কাজ করা অনেক বেশি অর্থপূর্ন ও সহজ।
=======
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
ফাংশন নামকরণঃ
46 changes: 29 additions & 17 deletions 1-js/02-first-steps/16-function-expressions/article.md
Original file line number Diff line number Diff line change
@@ -12,17 +12,29 @@ function sayHi() {

There is another syntax for creating a function that is called a *Function Expression*.

It looks like this:
It allows us to create a new function in the middle of any expression.

For example:

```js
let sayHi = function() {
alert( "Hello" );
};
```

Here, the function is created and assigned to the variable explicitly, like any other value. No matter how the function is defined, it's just a value stored in the variable `sayHi`.
Here we can see a variable `sayHi` getting a value, the new function, created as `function() { alert("Hello"); }`.

As the function creation happens in the context of the assignment expression (to the right side of `=`), this is a *Function Expression*.

Please note, there's no name after the `function` keyword. Omitting a name is allowed for Function Expressions.

Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable `sayHi`".

In more advanced situations, that we'll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous.

The meaning of these code samples is the same: "create a function and put it into the variable `sayHi`".
## Function is a value

Let's reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the `sayHi` variable.

We can even print out that value using `alert`:

@@ -63,22 +75,22 @@ Here's what happens above in detail:
2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself.
3. Now the function can be called as both `sayHi()` and `func()`.

Note that we could also have used a Function Expression to declare `sayHi`, in the first line:
We could also have used a Function Expression to declare `sayHi`, in the first line:

```js
let sayHi = function() {
let sayHi = function() { // (1) create
alert( "Hello" );
};

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

Everything would work the same.


````smart header="Why is there a semicolon at the end?"
You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not:
You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not:
```js
function sayHi() {
@@ -90,9 +102,9 @@ let sayHi = function() {
}*!*;*/!*
```
The answer is simple:
- There's no need for `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` etc.
- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block, but rather an assignment. The semicolon `;` is recommended at the end of statements, no matter what the value is. So the semicolon here is not related to the Function Expression itself, it just terminates the statement.
The answer is simple: a Function Expression is created here as `function(…) {…}` inside the assignment statement: `let sayHi = …;`. The semicolon `;` is recommended at the end of the statement, it's not a part of the function syntax.
The semicolon would be there for a simpler assignment, such as `let sayHi = 5;`, and it's also there for a function assignment.
````

## Callback functions
@@ -132,13 +144,13 @@ function showCancel() {
ask("Do you agree?", showOk, showCancel);
```

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 function usually draws a nice-looking question window. But that's another story.
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.

**The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.**

The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer.

We can use Function Expressions to write the same function much shorter:
We can use Function Expressions to write an equivalent, shorter function:

```js run no-beautify
function ask(question, yes, no) {
@@ -174,15 +186,15 @@ Let's formulate the key differences between Function Declarations and Expression

First, the syntax: how to differentiate between them in the code.

- *Function Declaration:* a function, declared as a separate statement, in the main code flow.
- *Function Declaration:* a function, declared as a separate statement, in the main code flow:

```js
// Function Declaration
function sum(a, b) {
return a + b;
}
```
- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`:
- *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" `=`:

```js
// Function Expression
@@ -279,7 +291,7 @@ if (age < 18) {
welcome(); // \ (runs)
*/!*
// |
function welcome() { // |
function welcome() { // |
alert("Hello!"); // | Function Declaration is available
} // | everywhere in the block where it's declared
// |
@@ -289,7 +301,7 @@ if (age < 18) {

} else {

function welcome() {
function welcome() {
alert("Greetings!");
}
}
@@ -348,7 +360,7 @@ welcome(); // ok now


```smart header="When to choose Function Declaration versus Function Expression?"
As a rule of thumb, when we need to declare a function, the first 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.
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.
That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching".
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

```js run
function ask(question, yes, no) {
if (confirm(question)) yes()
if (confirm(question)) yes();
else no();
}

Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

```js run
function ask(question, yes, no) {
if (confirm(question)) yes()
if (confirm(question)) yes();
else no();
}

38 changes: 36 additions & 2 deletions 1-js/02-first-steps/17-arrow-functions-basics/article.md
Original file line number Diff line number Diff line change
@@ -6,15 +6,19 @@
একে "এ্যারো ফাংশন" বলা হয় কারণ এটা দেখতে অনেকটা এই রকমঃ

```js
let func = (arg1, arg2, ...argN) => expression
let func = (arg1, arg2, ..., argN) => expression;
```

<<<<<<< HEAD
এখানে `func` নামে একটা ফাংশন তৈরি করা হয়েছে যা `arg1..argN` আর্গুমেন্ট হিসেবে নিচ্ছে, তারপর ডানপাশের `expression` টি সম্পাদন করে তার যে রেজাল্ট হয় সেটা রিটার্ন করছে।
=======
This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
অন্যথায় বলতে গেলে, এটা নিম্নোক্ত কোডটির সংক্ষিপ্ত রূপ।

```js
let func = function(arg1, arg2, ...argN) {
let func = function(arg1, arg2, ..., argN) {
return expression;
};
```
@@ -34,7 +38,11 @@ let sum = function(a, b) {
alert( sum(1, 2) ); // 3
```

<<<<<<< HEAD
এখানে আপনি যেমনটি দেখতে পাচ্ছেন, `(a, b) => a + b` ফাংশনটি দুইটা আর্গুমেন্ট নিচ্ছে যথাক্রমে `a``b` এবং সম্পাদনের সময় এটি `a + b` এক্সপ্রেশনটির মান নির্ণয় করছে এবং তার রেজাল্টটি রিটার্ন করছে।
=======
As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- যদি আমাদের কেবল একটি মাত্র আর্গুমেন্ট থাকে তাহলে প্যারামিটারগুলোর দুই পাশে যে প্যারেন্থেসিস বা প্রথম বন্ধনী থাকে সেটি না দিলেও চলে, যেটা কোডটাকে আরও সংক্ষিপ্ত করে নিয়ে আসে।

@@ -49,7 +57,11 @@ alert( sum(1, 2) ); // 3
alert( double(3) ); // 6
```

<<<<<<< HEAD
- যদি ফাংশনের কোন আর্গুমেন্ট না থাকে তাহলে প্যারেন্থেসিস বা প্রথম বন্ধনীদ্বয় খালি থাকবে (কিন্তু তারা উপস্থিত থাকবে)
=======
- If there are no arguments, parentheses are empty, but they must be present:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

```js run
let sayHi = () => alert("হ্যালো!");
@@ -65,8 +77,13 @@ alert( sum(1, 2) ); // 3
let age = prompt("আপনার বয়স কত?", 18);
let welcome = (age < 18) ?
<<<<<<< HEAD
() => alert('হ্যালো') :
() => alert("অভিবাদন!");
=======
() => alert('Hello!') :
() => alert("Greetings!");
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
welcome();
```
@@ -77,17 +94,27 @@ welcome();

## অনেক লাইনের এ্যারো ফাংশন

<<<<<<< HEAD
উপড়ের উদাহরণগুলোতে (`=>`) এই চিহ্নের বাম পাশে আর্গুমেন্ট সমূহ নিয়েছে এবং তাদের সাহায্যে ডান পাশের এক্সপ্রেশনটির মান নির্ধারন করেছে।

কিন্তু কখনো সখনো আমাদের এর থেকে কিছুটা বেশি জটিল কাজ করতে হয়, যেমন একের অধিক এক্সপ্রেশন অথবা স্টেটমেন্ট সম্পাদন করা। এটাও সম্ভব, কিন্তু তার জন্য তাদের কার্লি ব্র্যাসেস বা দ্বিতীয় বন্ধনীর ভিতরে লিখতে হবে। তারপর সেখানে একটা সাধারন `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
অনেকটা এইরকমঃ
```js run
let sum = (a, b) => { // এই কার্লি ব্র্যাসটা শুরু করে একটা বহুলাইন ফাংশনের।
let result = a + b;
*!*
<<<<<<< HEAD
return result; // যদি আমরা কার্লি ব্র্যাসেস ব্যবহার করি, তাহলে আমাদের আলাদাকরে একটা "return" ব্যবহার করা লাগবে।
=======
return result; // if we use curly braces, then we need an explicit "return"
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
*/!*
};
@@ -107,7 +134,14 @@ alert( sum(1, 2) ); // 3
## Summary
## মূলকথা
<<<<<<< HEAD
এ্যারো ফাংশন এক লাইনের কাজের জন্য খুব সুবিধাজনক। এটা দুই প্রকার হতে পারেঃ
1. কোন কার্লি ব্র্যাসেস ছাড়াঃ `(...args) => expression` -- ডান পাশের অংশটা একটা এক্সপ্রেশন এবং ফাংশনটি এই এক্সপ্রেশনের মান নির্ণয় করে এবং সেটা রিটার্ন করে।
2. কার্লি ব্র্যাসেস সহঃ `(...args) => { body }` -- বন্ধনীসমূহ ফাংশনের ভিতরে একের অধিক স্ট্যাটমেন্ট লিখতে দিচ্ছে, কিন্তু আমাদের কোন কিছু রিটার্ন করার জন্য আলাদা করে `return` ব্যবহার করতে হবে।
=======
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
14 changes: 7 additions & 7 deletions 1-js/02-first-steps/18-javascript-specials/article.md
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ To fully enable all features of modern JavaScript, we should start scripts with

The directive must be at the top of a script or at the beginning of a function body.

Without `"use strict"`, everything still works, but some features behave in the old-fashion, "compatible" way. We'd generally prefer the modern behavior.
Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.

Some modern features of the language (like classes that we'll study in the future) enable strict mode implicitly.

@@ -103,13 +103,13 @@ More in: <info:variables> and <info:types>.

We're using a browser as a working environment, so basic UI functions will be:

[`prompt(question, [default])`](mdn:api/Window/prompt)
[`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)`](mdn:api/Window/confirm)
[`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)`](mdn:api/Window/alert)
[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert)
: Output a `message`.

All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until they answer.
@@ -144,7 +144,7 @@ Assignments
: There is a simple assignment: `a = b` and combined ones like `a *= 2`.

Bitwise
: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise) when they are needed.
: 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.

Conditional
: The only operator with three parameters: `cond ? resultA : resultB`. If `cond` is truthy, returns `resultA`, otherwise `resultB`.
@@ -256,7 +256,7 @@ We covered three ways to create a function in JavaScript:
3. Arrow functions:
```js
// expression at the right side
// expression on the right side
let sum = (a, b) => a + b;
// or multi-line syntax with { ... }, need return here:
@@ -273,7 +273,7 @@ We covered three ways to create a function in JavaScript:
```
- Functions may have local variables: those declared inside its body. Such variables are only visible inside the function.
- Functions may have local variables: those declared inside its body or its parameter list. Such variables are only visible inside the function.
- Parameters can have default values: `function sum(a = 1, b = 2) {...}`.
- Functions always return something. If there's no `return` statement, then the result is `undefined`.
42 changes: 42 additions & 0 deletions 1-js/03-code-quality/01-debugging-chrome/article.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<<<<<<< HEAD
# ক্রোমে ডিবাগিং
=======
# Debugging in the browser
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
আরো জটিল জটিল কোড লিখার আগে ডিভাগিং সম্পর্কে জানা যাক -

@@ -38,7 +42,11 @@

একটি স্টেটমেন্ট এক্সিকিউট করার পর তার রেজাল্ট নিচেই দেখতে পাবো ।

<<<<<<< HEAD
উদাহরণ হিসেবে এখানে `1+2` এর রেজাল্ট `3` এবং `hello("debugger")` কিছুই রিটার্ন করে না , সেক্ষেত্রে রেজাল্ট হবে `undefined` :
=======
For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
![](chrome-sources-console.svg)

@@ -64,12 +72,20 @@
- ...ইত্যাদি ।

```smart header="Conditional breakpoints"
<<<<<<< HEAD
লাইন নাম্বারে *Right click* করে *conditional* ব্রেক পয়েন্ট তৈরি করা যায় । এটা তখনি ট্রিগ্রার করে যখন এক্সপ্রেশনটি সত্য হয় ।
=======
*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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
এটা আসলেই কার্যকর যখন আমাদের একটি নির্দিষ্ট ভেরিয়বল ভেলুতে থামা দরকার অথবা নির্দিষ্ট ফাংসন প্যারামিটারে ।
```

<<<<<<< HEAD
## ডিভাগার কমান্ড
=======
## The command "debugger"
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
আমরা নিচের মত `debugger` কমান্ড ব্যবহার করেও কোড পজ করতে পারি ঃ

@@ -85,9 +101,13 @@ function hello(name) {
}
```

<<<<<<< HEAD
এটি খুবই সুবিধাজনক যখন আমরা একটি কোড এডিটরে থাকি এবং ব্রেকপয়েন্ট সেট করতে ব্রাউজারের ডেভলপার টুলে যাওয়া লাগে না ।

## পজ করুন এবং চারদিকে লক্ষ্য করুন
=======
Such command works only when the development tools are open, otherwise the browser ignores it.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
আমাদের উদাহরণে পেজ লোডের সময় `hello()` কল করা হয়েছে, তো সবচাইতে সহজ উপায় ডিবাগারটি একটিভ করার জন্য (ব্রেকপয়েন্ট সেট করার পর) পেজটি রিলোড করতে হবে । কিবোর্ড থেকে `key:F5` (Windows, Linux) or `key:Cmd+R` (Mac) প্রেস করুন ।

@@ -99,7 +119,11 @@ function hello(name) {

1. **`Watch` -- যেকোনো এক্সপ্রেশনের জন্য বর্তমান মান দেখায় ।**

<<<<<<< HEAD
আপনি চাইলে প্লাসে `+` ক্লিক করে একটি এক্সপ্রেশন ইনপুট দিতে পারেন । ডিবাগার যেকোনো মুহূর্তে এটির মান দেখাবে এবং অটোম্যাটিক্যালি এক্সিকিশন প্রসেস গুলো পুনরায় ক্যালকুলেট হবে ।
=======
You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
2. **`Call Stack` -- নেস্টেড কল গুলো দেখায়.**

@@ -133,11 +157,20 @@ function hello(name) {

এক্সিকিউশনটি আবার শুরু হয়েছে এবং অন্য একটি ব্রেকপয়েন্টে `say()` যেয়ে থেমেছে । এখন কল স্ট্যাকে লক্ষ্য করুন এখানে আরেকটি কল বৃদ্ধি পেয়েছে । এখন আমরা `say()` এর মধ্যে ।

<<<<<<< HEAD
<span class="devtools" style="background-position:-200px -190px"></span> -- "Step": পরবর্তী কমান্ড চালান, hotkey `key:F9`.

পরবর্তী স্টেটমেন্টটি চালান । যদি আমরা এখন এটি ক্লিক করি তাহলে `alert` দেখাবে ।

বার বার এটিতে ক্লিক করলে স্টেটমেন্টগুলো একের পর এক এক্সিকিউশান হতে থাকবে ।
=======
<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 (not a built-in, like `alert`, but a function of our own).

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 call.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
<span class="devtools" style="background-position:-62px -192px"></span> -- "Step over": পরবর্তী কমান্ড চালান তবে ফাংশানে যাবেন না, hotkey `key:F10`.

@@ -157,6 +190,7 @@ function hello(name) {

<span class="devtools" style="background-position:-32px -194px"></span> -- "Step out": বর্তমান ফাংশন শেষ না হওয়া পর্যন্ত এক্সিকিউশান চালিয়ে যান, hotkey `key:Shift+F11`.

<<<<<<< HEAD
এক্সিকিউশন চালিয়ে যান এবং বর্তমান ফাংশনের একেবারে শেষ লাইনে এটি বন্ধ করুন। এটি <span class="devtools" style="background-position:-200px -190px"></span> তখন কার্যকর যখন আমরা ভুলবশত একটি নেস্টেড কল ব্যবহার করে প্রবেশ করি । আর এটি আমাদের উপর ইন্টারেস্ট রাখে না যার কারনে আমরা শেষ না হওয়া পর্যন্ত কন্টিনিউ করতে থাকি যত দ্রুত সম্ভব ।

<span class="devtools" style="background-position:-61px -74px"></span> -- enable/disable সকল ব্রেক পয়েন্টগুলো
@@ -166,6 +200,10 @@ function hello(name) {
<span class="devtools" style="background-position:-90px -146px"></span> -- enable/disable অটোম্যাটিক পজ হয় যদি কোন ত্রুটি ধরা পড়ে

অন থাকা অবস্থায় এবং ডেভলপার টুল ওপেন থাকলে স্ক্রিপ্ট এক্সিকিউশনের সময় একটি ত্রুটি ধরা পড়লে স্বয়ংক্রিয়ভাবে এটি পজ হয় ৷ তারপর আমরা ডিবাগারে ভেরিয়েবল বিশ্লেষণ করে দেখতে পারি কি ভুল হয়েছে। সুতরাং যদি আমাদের স্ক্রিপ্ট একটি ত্রুটির জন্য এক্সিকিউশান বন্ধ হয়ে যায় তাহলে আমরা ডিবাগার খুলতে পারি এবং এই অপশানটি অন করে পেজ রিলোড দিয়ে দেখতে পারি যে কোথায় এটি বন্ধ হয় এবং বর্তমান অবস্থা কি তা জানতে পারি ।
=======
<span class="devtools" style="background-position:-90px -146px"></span> -- enable/disable automatic pause in case of an error.
: 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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```smart header="Continue to here"
একটি লাইনের উপর রাইট ক্লিক করে কন্টেক্সট মেনু ওপেন করলে একটা "Continue to here" অপশান পাবো ।
@@ -194,9 +232,13 @@ for (let i = 0; i < 5; i++) {

তো আমারা যা দেখলাম এখানে ৩ টি প্রধান উপায় রয়েছে স্ক্রিপ্ট থামানোর জন্য ঃ

<<<<<<< HEAD
1. ব্রেকপয়েন্ট
2. `debugger` স্টেটমেন্ট
3. এরর ( যদি ডেভটুল ওপেন থাকে এবং বাটন <span class="devtools" style="background-position:-90px -146px"></span> অন থাকলে).
=======
When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
যখন পজ হয় তখন আমরা ডিবাগ করতে পারি - ভেরিয়েবল পরীক্ষা করে এবং কোডটি ট্রেস করে দেখতে পারি যে এক্সিকিউশনটি কোথায় ভুল হয়েছে।

20 changes: 16 additions & 4 deletions 1-js/03-code-quality/02-coding-style/article.md
Original file line number Diff line number Diff line change
@@ -117,7 +117,11 @@ if (
ইন্ডেন্টশনের ক্ষেত্রে ট্যাব চিহ্ন থেকে স্পেস ব্যাবহারের একটি বাড়তি সুবিধা হল এর বেশি ফ্ল্যাক্সিবল কনফিগারেশনের
<<<<<<< HEAD
যেমন, এভাবে আমরা আর্গুমেন্টগুলোকে শুরুর ব্যাকেটের সাথে লম্বভাবে রাখতে পারি :
=======
For instance, we can align the parameters with the opening bracket, like this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js no-beautify
show(parameters,
@@ -302,11 +306,15 @@ function pow(x, n) {
এখনে কিছু পরিচিত লিন্টারস টুলঃ
- [JSLint](http://www.jslint.com/) -- one of the first linters.
- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
- [ESLint](http://eslint.org/) -- probably the newest one.
- [JSLint](https://www.jslint.com/) -- one of the first linters.
- [JSHint](https://jshint.com/) -- more settings than JSLint.
- [ESLint](https://eslint.org/) -- probably the newest one.
<<<<<<< HEAD
সবগুলিই তাদের কাজ ভালো করে। লেখন ব্যাবহার করেঃ [ESLint](http://eslint.org/).
=======
All of them can do the job. The author uses [ESLint](https://eslint.org/).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
অনেক কোড এডিটরে এটা আগে থেকেই থাকে: শুধুমাত্র প্লাগইন এনেবল করে কোড স্টাইল কনফিগার করলেই হয়।
@@ -329,14 +337,18 @@ function pow(x, n) {
},
"rules": {
"no-console": 0,
"indent": ["warning", 2]
"indent": 2
}
}
```
এখানে ডিরেক্টিভ `"extends"` মানে সেটিংসে কনফিগারেশনটির বেস "eslint:recommended" সেট করা. এরপর, আমরা আমাদেরটা নির্দিষ্ট করে দেই।
<<<<<<< HEAD
অয়েব থেকে স্টাইল রুলস ডাউনলোড করে এক্সটেন্ডও করা যায়। আরও জানতে দেখুন <http://eslint.org/docs/user-guide/getting-started>
=======
It is also possible to download style rule sets from the web and extend them instead. See <https://eslint.org/docs/user-guide/getting-started> for more details about installation.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
এছাড়া কিছু IDE তে লিন্টারস বিল্ট-ইন থাকে,যেটা সুবিধাজনক কিন্তু ESLint মত চাহিদা মত পরিবর্তন করতে পারি না।
4 changes: 4 additions & 0 deletions 1-js/03-code-quality/03-comments/article.md
Original file line number Diff line number Diff line change
@@ -141,7 +141,11 @@ function pow(x, n) {

প্রসঙ্গত উল্লেখ্য, অনেক এডিটর যেমন [WebStorm](https://www.jetbrains.com/webstorm/) এই ধরনের ল্যাংগুয়েজ বুঝতে পারে এবং অটোকমপ্লিট ও স্বয়ংক্রিয় কোড-পরীক্ষায় তা ব্যবহার করে থাকে।

<<<<<<< HEAD
এছাড়াও, কমেন্ট থেকে এইচটিএমএল-ডকুমেন্টেশন তৈরির জন্য [JSDoc 3](https://github.com/jsdoc3/jsdoc) এর মত টুল রয়েছে। JSDoc সম্পর্কে আরো জানতে <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>.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
কাজটি কেনো এভাবে সমাধান করা হয়েছে? : যা লিখিত থাকে তা গুরুত্বপূর্ণ। তবে যা *অলিখিত* সেটা কি ঘটছে তা বোঝার জন্য অধিক গুরুত্বপূর্ণ হতে পারে। এই কাজটি কেনো ঠিক এইভাবেই সমাধান করা হয়েছে? এক্ষেত্রে কোড কোন উত্তর দেয় না।

18 changes: 9 additions & 9 deletions 1-js/03-code-quality/05-testing-mocha/article.md
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

Automated testing will be used in further tasks, and it's also widely used in real projects.

## Why we need tests?
## Why do we need tests?

When we write a function, we can usually imagine what it should do: which parameters give which results.

@@ -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`:
91 changes: 91 additions & 0 deletions 1-js/03-code-quality/06-polyfills/article.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@

<<<<<<< HEAD
# পলিফিল (Polyfills)

জাভাস্ক্রিপ্ট ভাষাটি ধীরে ধীরে উন্নত হচ্ছে। নিয়মিত নতুন নতুন প্রস্তাবনা আসছে, সেগুলো বিশ্লেষণ করা হচ্ছে এবং, যদি যোগ্য বলে বিবেচিত হয় তাহলে এই তালিকাতে <https://tc39.github.io/ecma262/> নিবন্ধিত হচ্ছে, এবং তারপর [স্পেসিফিকেশন](http://www.ecma-international.org/publications/standards/Ecma-262.htm) এ উন্নীত হচ্ছে।
=======
# 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](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
জাভাস্ক্রিপ্টের পেছনে যে দলটি কাজ করছে তারা তাদের মত বিবেচনা করছে কোনটিকে আগে বাস্তবায়ন করা দরকার। তারা হয়তো সিদ্ধান্ত নিতে পারে, যেগুলো খসড়া তালিকাভুক্ত সেগুলো আগে করার এবং যেগুলো ইতিমধ্যে স্পেসিফিকেশনে আছে সেগুলো পরে করার, কারণ সেগুলো কম আকর্ষণীয় বা করা কঠিন।

<<<<<<< HEAD
তাই প্রায়শ ইঞ্জিনগুলো স্ট্যান্ডার্ড এর শুধু আংশিক বাস্তবায়ন করে।

ভাষার কোন কোন বৈশিষ্ট্য বর্তমানে সমর্থিত সেটি জানার একটি ভাল পেইজ হল এটি <https://kangax.github.io/compat-table/es6/> (এটি অনেক বড়, আমাদের এখনও অনেককিছুই জানতে হবে)।
@@ -50,3 +57,87 @@ alert('Press the "Play" button in the upper-right corner to run');
```

গুগল ক্রোম সাধারণত ভাষার ফিচারগুলোর সাথে সবচাইতে বেশী আপ-টু-ডেট থাকে, এটি ব্লিডিং-এজ ডেমোগুলো ট্রান্সপাইলার ছাড়াই রান করার জন্য খুবই ভালো, কিন্তু যেকোনো আধুনিক ব্রাউজারই ভালভাবেই কাজ করবে।
=======
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://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!

On the other hand, how to make our modern code work on older engines that don't understand recent features yet?

There are two tools for that:

1. Transpilers.
2. Polyfills.

Here, in this chapter, our purpose is to get the gist of how they work, and their place in web development.

## Transpilers

A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines.

E.g. JavaScript before year 2020 didn't have the "nullish coalescing operator" `??`. So, if a visitor uses an outdated browser, it may fail to understand the code like `height = height ?? 100`.

A transpiler would analyze our code and rewrite `height ?? 100` into `(height !== undefined && height !== null) ? height : 100`.

```js
// before running the transpiler
height = height ?? 100;

// after running the transpiler
height = (height !== undefined && height !== null) ? height : 100;
```
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.
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
New language features may include not only syntax constructs and operators, but also built-in functions.
For example, `Math.trunc(n)` is a function that "cuts off" the decimal part of a number, e.g `Math.trunc(1.23)` returns `1`.
In some (very outdated) JavaScript engines, there's no `Math.trunc`, so such code will fail.
As we're talking about new functions, not syntax changes, there's no need to transpile anything here. We just need to declare the missing function.
A script that updates/adds new functions is called "polyfill". It "fills in" the gap and adds missing implementations.
For this particular case, the polyfill for `Math.trunc` is a script that implements it, like this:
```js
if (!Math.trunc) { // if no such function
// implement it
Math.trunc = function(number) {
// Math.ceil and Math.floor exist even in ancient JavaScript engines
// they are covered later in the tutorial
return number < 0 ? Math.ceil(number) : Math.floor(number);
};
}
```
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 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](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://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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
44 changes: 43 additions & 1 deletion 1-js/04-object-basics/01-object/article.md
Original file line number Diff line number Diff line change
@@ -44,7 +44,11 @@ let user = { // একটি অবজেক্ট

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

<<<<<<< HEAD
আমরা যেকোনো সময় ফাইল যুক্ত করা, মুছে দেয়া বা পড়তে পারি।
=======
We can add, remove and read files from it at any time.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
প্রোপার্টির ভ্যালুগুলো ডট নোটেশন দিয়ে এক্সেস করা যায়ঃ

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

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

<<<<<<< HEAD
কোন একটা প্রোপার্টিকে মুছে দিতে আমরা `delete` অপারেটরটি ব্যবহার করতে পারিঃ
=======
To remove a property, we can use the `delete` operator:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
delete user.age;
@@ -92,6 +100,7 @@ let user = {
```
একে বলা হয় "ট্রেইলিং" বা "হ্যাঙ্গিং" কমা। এটি এড/রিমুভ এবং পরিবর্তন করা সহজ করে, কারণ সবগুলো লাইন দেখতে একই রকম হয়।

<<<<<<< HEAD
<<<<<<< HEAD
## তৃতীয় বন্ধনী
=======
@@ -119,6 +128,8 @@ The `const` would give an error only if we try to set `user=...` as a whole.
There's another way to make constant object properties, we'll cover it later in the chapter <info:property-descriptors>.
````

=======
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Square brackets
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d
@@ -232,11 +243,19 @@ let bag = {
};
```

<<<<<<< HEAD
তৃতীয় বন্ধনী ডট নোটেশনের চাইতে অনেক বেশী শক্তিশালী। কিন্তু তাদের লেখাটা একটু কষ্টকর।
=======
Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
সুতরাং অধিকাংশ সময়, যখন প্রোপার্টির নাম সহজ এবং আগে থেকেই জানা, ডট নোটেশন ব্যবহৃত হয়। এবং যদি আমাদের জটিল কিছু করতে হয়, তখন আমরা তৃতীয় বন্ধনী ব্যবহার করি।


<<<<<<< HEAD
=======
In real code, we often use existing variables as values for property names.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````smart header="সংরক্ষিত শব্দগুলো প্রোপার্টির নাম হিসেবে ব্যবহার করা যায়"
ভেরিয়েবল এর নাম ভাষা কর্তৃক সংরক্ষিত শব্দ, যেমন "for", "let", "return" ইত্যাদি হতে পারবে না।
@@ -320,7 +339,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:

@@ -401,11 +420,15 @@ alert( "blabla" in user ); // false, user.blabla নেই

মনে রাখবেন `in` অপারেটরের বাম পাশে অবশ্যই একটি  "প্রোপার্টির নাম" থাকতে হবে। সাধারণত এটিকে উদ্ধৃতি চিহ্নের ভেতর রাখা হয়।

<<<<<<< HEAD
<<<<<<< HEAD
উদ্ধৃতি চিহ্ন না দিলে এটিকে একটি ভেরিয়েবল হিসেবে ধরা হবে, এবং ওই ভেরিয়েবলের ভ্যালুর সাথে তুলনা করা হবে। যেমনঃ
=======
If we omit quotes, that means a variable, it should contain the actual name to be tested. For instance:
>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d
=======
If we omit quotes, that means a variable should contain the actual name to be tested. For instance:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let user = { age: 30 };
@@ -451,7 +474,11 @@ Situations like this happen very rarely, because `undefined` should not be expli

>>>>>>> d6e88647b42992f204f57401160ebae92b358c0d

<<<<<<< HEAD
## "for..in" লুপ
=======
## The "for..in" loop [#forin]
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

অবজেক্টের সবগুলো কী এর উপর ভিজিট করার জন্য একটি বিশেষ ধরণের লুপ আছেঃ `for..in`। এটি `for(;;)` এর চাইতে পুরোপুরি আলাদা, যেটি আমরা পূর্বে দেখেছি।

@@ -513,7 +540,11 @@ for (let code in codes) {
*/!*
```

<<<<<<< HEAD
এই অবজেক্টটি হয়তো ইউজারকে একটি অপশনের লিস্ট দেখানোর জন্য ব্যবহার করা হবে। যদি সাইটটি মূলত জার্মান ইউজারদের জন্য হয়, তাহলে আমরা চাইব `49` যেন প্রথমেই থাকে।
=======
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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
কিন্তু কোড রান করলে আমরা পুরোপুরি অন্যরকম অবস্থা দেখিঃ
@@ -525,9 +556,14 @@ for (let code in codes) {
````smart header="ইন্টিজার প্রোপার্টি?"
"ইন্টিজার প্রোপার্টি" হল একটি স্ট্রিং যেটি ইন্টিজার (পূর্ণসংখ্যা) থেকে বা ইন্টিজারে কোন পরিবর্তন ছাড়াই পরিবর্তন করা যায়।
<<<<<<< HEAD
তাই, "49" একটি ইন্টিজার প্রোপার্টির নাম, কারণ যখন এটিকে ইন্টিজারে পরিবর্তন এবং ইন্টিজার থেকে স্ট্রিং এ পরিবর্তন করা হয় এটি একই থাকে। কিন্তু "+49" এবং "1.2" ইন্টিজার নয়ঃ
=======
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:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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
@@ -840,9 +876,15 @@ alert(clone.sizes.width); // 51, অন্য জায়গায় পরিবর
- প্রোপার্টির কী অবশ্যই স্ট্রিং বা সিম্বল হতে হবে (সাধারণত স্ট্রিং)।
- ভ্যালু যেকোনো টাইপের হতে পারে।
<<<<<<< HEAD
একটি প্রোপার্টিকে এক্সেস করতে আমরা ব্যবহার করিঃ
- ডট নোটেশনঃ `obj.property`.
- তৃতীয় বন্ধনী `obj["property"]`। তৃতীয় বন্ধনী নোটেশন আমাদের ভেরিয়েবল থেকে কী ব্যবহার করতে দেয়, এভাবে `obj[varWithKey]`
=======
To access a property, we can use:
- The dot notation: `obj.property`.
- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
অন্যান্য অপারেটরসমূহঃ
- প্রোপার্টি মুছে দিতেঃ `delete obj.prop`
168 changes: 131 additions & 37 deletions 1-js/04-object-basics/02-object-copy/article.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

# Object references and copying

One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", as opposed to primitive values: strings, numbers, booleans, etc -- that are always copied "as a whole value".
One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value".

That's easy to understand if we look a bit "under a cover" of what happens when we copy a value.
That's easy to understand if we look a bit under the hood of what happens when we copy a value.

Let's start with a primitive, such as a string.

@@ -15,17 +15,17 @@ let message = "Hello!";
let phrase = message;
```

As a result we have two independent variables, each one is storing the string `"Hello!"`.
As a result we have two independent variables, each one storing the string `"Hello!"`.

![](variable-copy-value.svg)

Quite an obvious result, right?

Objects are not like that.

**A variable assigned to an object stores not the object itself, but its "address in memory", in other words "a reference" to it.**
**A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.**

Let's look at an example of such variable:
Let's look at an example of such a variable:


```js
@@ -41,13 +41,13 @@ 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 of a sheet of paper with the address.
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`, JavaScript engine looks into that address and performs the operation on the actual object.
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.

Now here's why it's important.

**When an object variable is copied -- the reference is copied, the object is not duplicated.**
**When an object variable is copied, the reference is copied, but the object itself is not duplicated.**

For instance:

@@ -58,13 +58,13 @@ let user = { name: "John" };
let admin = user; // copy the reference
```

Now we have two variables, each one with the reference to the same object:
Now we have two variables, each storing a reference to the same object:

![](variable-copy-reference.svg)

As you can see, there's still one object, now with two variables that reference it.
As you can see, there's still one object, but now with two variables that reference it.

We can use any variable to access the object and modify its contents:
We can use either variable to access the object and modify its contents:


```js run
@@ -79,8 +79,7 @@ admin.name = 'Pete'; // changed by the "admin" reference
alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference
```
It's just as if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents.
## Comparison by reference
@@ -106,18 +105,44 @@ let b = {}; // two independent objects
alert( a == b ); // false
```
<<<<<<< HEAD
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.
=======
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.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Cloning and merging, Object.assign
````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.

So, copying an object variable creates one more reference to the same object.
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>.
````

But what if we need to duplicate an object? Create an independent copy, a clone?
## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]

That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time.
So, copying an object variable creates one more reference to the same object.

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:

@@ -144,22 +169,23 @@ 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](mdn:js/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 };
@@ -171,6 +197,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:
@@ -183,10 +212,14 @@ 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:
<<<<<<< HEAD
```js
=======
```js run
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
let user = {
name: "John",
age: 30
@@ -195,13 +228,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:
@@ -217,9 +255,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
@@ -236,18 +272,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 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.


### structuredClone

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

Here's how we can use it in our example:
```js run
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
*!*
let clone = structuredClone(user);
*/!*
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
```
The `structuredClone` method can clone most data types, such as objects, arrays, primitive values.
It also supports circular references, when an object property references the object itself (directly or via a chain or references).
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() {}
});
```
To fix that, we should use the 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".
Function properties aren't supported.
We can use recursion to implement it. Or, not to reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
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.
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).
26 changes: 13 additions & 13 deletions 1-js/04-object-basics/03-garbage-collection/article.md
Original file line number Diff line number Diff line change
@@ -14,16 +14,16 @@ Simply put, "reachable" values are those that are accessible or usable somehow.

For instance:

- Local variables and parameters of the current function.
- Variables and parameters for other functions on the current chain of nested calls.
- The currently executing function, its local variables and parameters.
- Other functions on the current chain of nested calls, their local variables and parameters.
- Global variables.
- (there are some other, internal ones as well)

These values are called *roots*.

2. Any other value is considered reachable if it's reachable from a root by a reference or by a chain of references.

For instance, if there's an object in a global variable, and that object has a property referencing another object, that object is considered reachable. And those that it references are also reachable. Detailed examples to follow.
For instance, if there's an object in a global variable, and that object has a property referencing another object, *that* object is considered reachable. And those that it references are also reachable. Detailed examples to follow.

There's a background process in the JavaScript engine that is called [garbage collector](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)). It monitors all objects and removes those that have become unreachable.

@@ -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.
Original file line number Diff line number Diff line change
@@ -15,6 +15,11 @@ describe("calculator", function() {
afterEach(function() {
prompt.restore();
});

it('the read get two values and saves them as object properties', function () {
assert.equal(calculator.a, 2);
assert.equal(calculator.b, 3);
});

it("the sum is 5", function() {
assert.equal(calculator.sum(), 5);
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]

Original file line number Diff line number Diff line change
@@ -11,5 +11,6 @@ let ladder = {
},
showStep: function() {
alert(this.step);
return this;
}
};
Original file line number Diff line number Diff line change
@@ -32,6 +32,14 @@ describe('Ladder', function() {
it('down().up().up().up() ', function() {
assert.equal(ladder.down().up().up().up().step, 2);
});

it('showStep() should return this', function() {
assert.equal(ladder.showStep(), ladder);
});

it('up().up().down().showStep().down().showStep()', function () {
assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0)
});

after(function() {
ladder.step = 0;
Original file line number Diff line number Diff line change
@@ -21,9 +21,9 @@ let ladder = {
return this;
*/!*
}
}
};

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

We also can write a single call per line. For long chains it's more readable:
@@ -33,7 +33,7 @@ ladder
.up()
.up()
.down()
.up()
.showStep() // 1
.down()
.showStep(); // 1
.showStep(); // 0
```
12 changes: 7 additions & 5 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,19 +21,21 @@ 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();
ladder.up();
ladder.down();
ladder.showStep(); // 1
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(); // 1
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.
6 changes: 3 additions & 3 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;
@@ -81,7 +81,7 @@ user = {
// method shorthand looks better, right?
user = {
*!*
sayHi() { // same as "sayHi: function()"
sayHi() { // same as "sayHi: function(){...}"
*/!*
alert("Hello");
}
@@ -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
@@ -4,14 +4,14 @@ importance: 2

# Two functions – one object

Is it possible to create functions `A` and `B` such as `new A()==new B()`?
Is it possible to create functions `A` and `B` so that `new A() == new B()`?

```js no-beautify
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
@@ -10,6 +10,11 @@ describe("calculator", function() {
calculator = new Calculator();
calculator.read();
});

it("the read method asks for two values using prompt and remembers them in object properties", function() {
assert.equal(calculator.a, 2);
assert.equal(calculator.b, 3);
});

it("when 2 and 3 are entered, the sum is 5", function() {
assert.equal(calculator.sum(), 5);
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.

27 changes: 26 additions & 1 deletion 1-js/04-object-basics/06-constructor-new/article.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# কন্সট্রাকটর এবং "new" অপারেটর

<<<<<<< HEAD
সাধারণত আমরা `{...}` এর সাহায্যে শুধুমাত্র একটি অবজেক্ট তৈরি করতে পারি। কিন্তু প্রায়সময় আমাদের একই ধরণের অনেক অবজেক্ট তৈরি করা লাগে, যেমন ইউজার বা টিচার অবজেক্ট।
=======
The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
আমরা এটি করতে পারি কনস্ট্রাকটর ফাংশনের `"new"` অপারেটরের সাহায্যে।

@@ -64,13 +68,21 @@ let user = {

কন্সট্রাকটর ব্যবহারের প্রধান উদ্দেশ্যই হল পুনরায় ব্যবহারযোগ্য অবজেক্ট তৈরি সহজ করা।

<<<<<<< HEAD
একটি ব্যাপার সম্পর্কে পরিষ্কার ধারণা থাকা দরকার। সাধারণত, যে কোন ফাংশনকে আমরা কন্সট্রাকটর ফাংশন হিসেবে ব্যবহার করতে পারি। অর্থাৎ যেকোন ফাংশনকে `new` দ্বারা কল করা হলে এটি কন্সট্রাকটর ফাংশন হিসেবে কাজ করবে। অর্থাৎ আপনি যদি ফাংশনের নামের সব অক্ষর ছোট হাতের ব্যবহার করেন তাও কাজ করবে, তবে কন্সট্রাকটর ফাংশনকে বড় হাতের অক্ষর দিয়ে শুরু করা সার্বজনীন স্বীকৃত, এবং এটি নির্দেশ করে আমাদের ফাংশনটি ডিক্লেয়ার করতে হবে `new` কী-ওয়ার্ড দ্বারা।

````smart header="new function() { ... }"
যদি আমাদের একটি কমপ্লেক্স অবজেক্ট শুধুমাত্র একবার তৈরি করা লাগে, তাহলে এটি অ্যানোনিমাস ফাংশন কন্ট্রাকটরের সাহায্যে তৈরি করতে পারি, এভাবে:
=======
Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
````smart header="new function() { ... }"
If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
let user = new function() {
// create a function and immediately call it with new
let user = new function() {
this.name = "John";
this.isAdmin = false;
@@ -80,7 +92,11 @@ let user = new function() {
};
```
<<<<<<< HEAD
এখানে আমরা কন্সট্রাকটরটিকে পুনরায় কল করতে পারব না, কেননা এটি কোথাও সংরক্ষন করা হয়নি, তৈরি করেই কল করা হয়ে গিয়েছে। এই ধরণের এনক্যাপসুলেশন প্রয়োজন হয় একটি অবজেক্টের জন্য, যা পুনরায় ব্যবহার করা যাবে না।
=======
This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````

## Constructor কিনা যাচাই: new.target
@@ -91,7 +107,11 @@ let user = new function() {

একটি ফাংশনের মধ্যে আমরা চাইলে যাচাই করতে পারি, এটি `new` দ্বারা কল করা হয়েছে নাকি হয়নি, এজন্য একটি বিশেষ প্রপার্টি আছে `new.target`

<<<<<<< HEAD
নিচের কোডে আমরা `User` কে `new` দ্বারা কল করলে `new.target` এর মান পাব একটি খালি অবজেক্ট অন্যথায় `undefined`:
=======
It is undefined for regular calls and equals the function if called with `new`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
function User() {
@@ -169,8 +189,13 @@ alert( new SmallUser().name ); // John

সাধারণত কন্সট্রাকটরে `return` স্টেটমেন্ট ব্যবহার করা হয়না। তারপরও আমরা এটি আলোচনা করেছি যদি ব্যবহার করি তাহলে তা কেমন আচরণ করে তা জানার জন্য।

<<<<<<< HEAD
````smart header="প্রথমবন্ধনী ছাড়া কল"
আমরা new অপারেটর ব্যবহারের সময় `()` ছাড়াও কন্সট্রাকটর ফাংশনকে কল করতে পারি, যদি এতে কোন আর্গুমেন্ট না থাকে:
=======
````smart header="Omitting parentheses"
By the way, we can omit parentheses after `new`:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
let user = new User; // <-- no parentheses
96 changes: 58 additions & 38 deletions 1-js/04-object-basics/07-optional-chaining/article.md
Original file line number Diff line number Diff line change
@@ -9,52 +9,64 @@ The optional chaining `?.` is a safe way to access nested object properties, eve

If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.

As an example, consider objects for user data. Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.
As an example, let's say we have `user` objects that hold the information about our users.

In such case, when we attempt to get `user.address.street`, we may get an error:
Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.

In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error:

```js run
let user = {}; // a user without "address" property

alert(user.address.street); // Error!
```

That's the expected result, JavaScript works like this. As `user.address` is `undefined`, the attempt to get `user.address.street` fails with an error. Although, in many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error.

In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").

...And another example. In the web development, we may need the information about an element on the page. The element is returned by `document.querySelector('.elem')`, and the catch is again - that it sometimes doesn't exist:
...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element.

```js run
// the result of the call document.querySelector('.elem') may be an object or null
// document.querySelector('.elem') is null if there's no element
let html = document.querySelector('.elem').innerHTML; // error if it's null
```

Once again, we may want to avoid the error in such case.
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?

The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing it, like this:
The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing its property, like this:

```js
let user = {};

alert(user.address ? user.address.street : undefined);
```

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

Here's how the same would look for `document.querySelector`:

```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.

E.g. let's try getting `user.address.street.name`.
For more deeply nested properties, it becomes even uglier, as more repetitions are required.

We need to check both `user.address` and `user.address.street`:
E.g. let's get `user.address.street.name` in a similar fashion.

```js
let user = {}; // user has no address

alert(user.address ? user.address.street ? user.address.street.name : null : null);
```

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

Before the optional chaining `?.` was added to the language, people used the `&&` operator for such cases:
There's a little better way to write it, using the `&&` operator:

```js run
let user = {}; // user has no address
@@ -64,16 +76,20 @@ alert( user.address && user.address.street && user.address.street.name ); // und

AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn't ideal.

As you can see, the property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times.
As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times.

And now, finally, the optional chaining comes to the rescue!
That's why the optional chaining `?.` was added to the language. To solve this problem once and for all!

## Optional chaining

The optional chaining `?.` stops the evaluation and returns `undefined` if the part before `?.` is `undefined` or `null`.
The optional chaining `?.` stops the evaluation if the value before `?.` is `undefined` or `null` and returns `undefined`.

**Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`.**

In other words, `value?.prop`:
- works as `value.prop`, if `value` exists,
- otherwise (when `value` is `undefined/null`) it returns `undefined`.

Here's the safe way to access `user.address.street` using `?.`:

```js run
@@ -84,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
@@ -95,16 +117,14 @@ alert( user?.address.street ); // undefined
Please note: the `?.` syntax makes optional the value before it, but not any further.
In the example above, `user?.address.street` allows only `user` to be `null/undefined`.
On the other hand, if `user` does exist, then it must have `user.address` property, otherwise `user?.address.street` gives an error at the second dot.
E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/undefined` (and returns `undefined` in that case), but that's only for `user`. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`.
```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"
@@ -121,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
```
@@ -143,39 +163,40 @@ For example, `?.()` is used to call a function that may not exist.
In the code below, some of our users have `admin` method, and some don't:

```js run
let user1 = {
let userAdmin = {
admin() {
alert("I am admin");
}
}
};

let user2 = {};
let userGuest = {};

*!*
userAdmin.admin?.(); // I am admin
*/!*

*!*
user1.admin?.(); // I am admin
user2.admin?.();
userGuest.admin?.(); // nothing happens (no such method)
*/!*
```
Here, in both lines we first use the dot (`user1.admin`) to get `admin` property, because the user object must exist, 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 `user1`). Otherwise (for `user2`) 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.
```js run
let key = "firstName";

let user1 = {
firstName: "John"
};

let user2 = null; // Imagine, we couldn't authorize the user

let key = "firstName";
let user2 = null;

alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined

alert( user1?.[key]?.something?.not?.existing); // undefined
```
Also we can use `?.` with `delete`:
@@ -185,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
@@ -210,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 to 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.
86 changes: 84 additions & 2 deletions 1-js/04-object-basics/08-symbol/article.md

Large diffs are not rendered by default.

135 changes: 133 additions & 2 deletions 1-js/04-object-basics/09-object-toprimitive/article.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -15,4 +15,4 @@ str.test = 5;
alert(str.test);
```

How do you think, will it work? What will be shown?
What do you think, will it work? What will be shown?
7 changes: 4 additions & 3 deletions 1-js/05-data-types/01-primitives-methods/article.md
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ Objects are "heavier" than primitives. They require additional resources to supp

Here's the paradox faced by the creator of JavaScript:

- There are many things one would want to do with a primitive like a string or a number. It would be great to access them as methods.
- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods.
- Primitives must be as fast and lightweight as possible.

The solution looks a little bit awkward, but here it is:
@@ -48,7 +48,7 @@ The solution looks a little bit awkward, but here it is:
2. The language allows access to methods and properties of strings, numbers, booleans and symbols.
3. In order for that to work, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.

The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean` and `Symbol`. Thus, they provide different sets of methods.
The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods.

For instance, there exists a string method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized `str`.

@@ -104,9 +104,10 @@ if (zero) { // zero is true, because it's an object
}
```

On the other hand, using the same functions `String/Number/Boolean` without `new` is a totally sane and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).
On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).

For example, this is entirely valid:

```js
let num = Number("123"); // convert a string to number
```
Original file line number Diff line number Diff line change
@@ -28,6 +28,6 @@ Note that `63.5` has no precision loss at all. That's because the decimal part `


```js run
alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
```

145 changes: 100 additions & 45 deletions 1-js/05-data-types/02-number/article.md

Large diffs are not rendered by default.

8 changes: 1 addition & 7 deletions 1-js/05-data-types/03-string/1-ucfirst/solution.md
Original file line number Diff line number Diff line change
@@ -8,12 +8,7 @@ let newStr = str[0].toUpperCase() + str.slice(1);

There's a small problem though. If `str` is empty, then `str[0]` is `undefined`, and as `undefined` doesn't have the `toUpperCase()` method, we'll get an error.

There are two variants here:

1. Use `str.charAt(0)`, as it always returns a string (maybe empty).
2. Add a test for an empty string.

Here's the 2nd variant:
The easiest way out is to add a test for an empty string, like this:

```js run demo
function ucFirst(str) {
@@ -24,4 +19,3 @@ function ucFirst(str) {

alert( ucFirst("john") ); // John
```

2 changes: 1 addition & 1 deletion 1-js/05-data-types/03-string/3-truncate/solution.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The maximal length must be `maxlength`, so we need to cut it a little shorter, to give space for the ellipsis.

Note that there is actually a single unicode character for an ellipsis. That's not three dots.
Note that there is actually a single Unicode character for an ellipsis. That's not three dots.

```js run demo
function truncate(str, maxlength) {
4 changes: 2 additions & 2 deletions 1-js/05-data-types/03-string/3-truncate/task.md
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ The result of the function should be the truncated (if needed) string.
For instance:

```js
truncate("What I'd like to tell on this topic is:", 20) = "What I'd like to te…"
truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to te…"

truncate("Hi everyone!", 20) = "Hi everyone!"
truncate("Hi everyone!", 20) == "Hi everyone!"
```
259 changes: 51 additions & 208 deletions 1-js/05-data-types/03-string/article.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions 1-js/05-data-types/04-array/10-maximal-subarray/solution.md
Original file line number Diff line number Diff line change
@@ -57,9 +57,9 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6
alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
```

The solution has a time complexety of [O(n<sup>2</sup>)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.
The solution has a time complexity of [O(n<sup>2</sup>)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.

For big arrays (1000, 10000 or more items) such algorithms can lead to a serious sluggishness.
For big arrays (1000, 10000 or more items) such algorithms can lead to serious sluggishness.

# Fast solution

@@ -91,4 +91,4 @@ alert( getMaxSubSum([-1, -2, -3]) ); // 0

The algorithm requires exactly 1 array pass, so the time complexity is O(n).

You can find more detail information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
You can find more detailed information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
2 changes: 1 addition & 1 deletion 1-js/05-data-types/04-array/2-create-array/task.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ Let's try 5 array operations.

1. Create an array `styles` with items "Jazz" and "Blues".
2. Append "Rock-n-Roll" to the end.
3. Replace the value in the middle by "Classics". Your code for finding the middle value should work for any arrays with odd length.
3. Replace the value in the middle with "Classics". Your code for finding the middle value should work for any arrays with odd length.
4. Strip off the first value of the array and show it.
5. Prepend `Rap` and `Reggae` to the array.

2 changes: 1 addition & 1 deletion 1-js/05-data-types/04-array/3-call-array-this/task.md
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ let arr = ["a", "b"];

arr.push(function() {
alert( this );
})
});

arr[2](); // ?
```
103 changes: 96 additions & 7 deletions 1-js/05-data-types/04-array/article.md
Original file line number Diff line number Diff line change
@@ -92,6 +92,38 @@ let fruits = [
"trailing comma" স্ট্যাইল এর জন্য কোন আইটেম সংযোগ বা বাদ দেয়া সহজ হয়।
````

## Get last elements with "at"

[recent browser="new"]

Let's say we want the last element of the array.

Some programming languages allow the use of negative indexes for the same purpose, like `fruits[-1]`.

Although, in JavaScript it won't work. The result will be `undefined`, because the index in square brackets is treated literally.

We can explicitly calculate the last element index and then access it: `fruits[fruits.length - 1]`.

```js run
let fruits = ["Apple", "Orange", "Plum"];

alert( fruits[fruits.length-1] ); // Plum
```

A bit cumbersome, isn't it? We need to write the variable name twice.

Luckily, there's a shorter syntax: `fruits.at(-1)`:

```js run
let fruits = ["Apple", "Orange", "Plum"];

// same as fruits[fruits.length-1]
alert( fruits.at(-1) ); // Plum
```

In other words, `arr.at(i)`:
- is exactly the same as `arr[i]`, if `i >= 0`.
- for negative values of `i`, it steps back from the end of the array.

## pop/push, shift/unshift মেথডস

@@ -121,9 +153,15 @@ let fruits = [

স্ট্যাক LIFO (Last-In-First-Out) প্রিন্সিপাল অনুসারে কাজ করে, অন্যদিকে কিউ FIFO (First-In-First-Out) অনুসারে কাজ করে।

<<<<<<< HEAD
জাভাস্ক্রিপ্টে অ্যারের সাহায্যে স্ট্যাক বা কিউ উভয়ই ইমপ্লিমেন্ট করা যায়। কেননা অ্যারেতে সবার শেষে বা শুরুতে কোন আইটেম সংযুক্ত বা বাদ করা যায়।

কম্পিউটার সায়েন্সে এই ধরণের ডাটা স্ট্রাকচার সমূহকে বলা হয় [deque](https://en.wikipedia.org/wiki/Double-ended_queue)ওঁ।
=======
Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements, both to/from the beginning or the end.

In computer science, the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**অ্যারের শেষ এলিমেন্ট নিয়ে কাজ করে মেথডদুটি হল:**

@@ -138,6 +176,8 @@ let fruits = [
alert( fruits ); // Apple, Orange
```

Both `fruits.pop()` and `fruits.at(-1)` return the last element of the array, but `fruits.pop()` also modifies the array by removing it.

`push`
: অ্যারেতে সবার শেষে নতুন একটি এলিমেন্ট যোগ করবে:

@@ -209,7 +249,11 @@ arr.push("Pear"); // modify the array by reference
alert( fruits ); // Banana, Pear - 2 items now
```

<<<<<<< HEAD
...তবে ইন্টারনাল রিফ্রেশেন্টেশন অ্যারেকে বিশেষ সুবিধা দেয়। জাভাস্ক্রিপ্ট ইঞ্জিন এলিমেন্ট সমূহকে মেমোরিতে পাশাপাশি ক্রম অনুসারে সংরক্ষণ করে, যার ফলে এদের মধ্যে বিভিন্ন অপারেশন অপ্টিমাইজ করে চালানো যায়, এবং এরা দ্রুত কাজ করে।
=======
...But what makes arrays really special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
তবে যদি আমরা কোন একটি অ্যারের "ordered collection" কে নষ্ট করে ফেলি, এবং এদের সাধারণ অবজেক্ট হিসেবে ডিক্লেয়ার করি তাহলে অ্যারের সুবিধাগুলো থেকে আমরা বঞ্চিত হব।

@@ -247,7 +291,11 @@ fruits.age = 25; // এবং এখানে কী হিসেবে এক
fruits.shift(); // take 1 element from the start
```

<<<<<<< HEAD
এটি শুধুমাত্র অ্যারের `0` নং ইনডেক্স প্রদান করে রিমুভ করে না পাশাপাশি অ্যারের বাকী এলিমেন্ট সমূহকে পুনরায় ইনডেক্সিং করে।
=======
It's not enough to take and remove the element with the index `0`. Other elements need to be renumbered as well.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`shift` অপারেশনে ৩টি ব্যাপার ঘটে:

@@ -363,11 +411,19 @@ alert( arr[3] ); // পূর্বের ভ্যালু আর ফেরত
let arr = *!*new Array*/!*("Apple", "Pear", "etc");
```

<<<<<<< HEAD
এটির ব্যবহার কদাচিৎ, কেননা স্কয়ার ব্রাকেট সংক্ষিপ্ত `[]`। Also there's a tricky feature with it.
=======
It's rarely used, because square brackets `[]` are shorter. Also, there's a tricky feature with it.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`new Array` একটি `number` টাইপ আর্গুমেন্ট নিতে পারে, যদি আমরা `number` প্রদান করি তাহলে অ্যারেটি এভাবে তৈরি হবে: *একটি নির্দিষ্ট length থাকবে তবে কোন আইটেম থাকবে না*

<<<<<<< HEAD
উদাহরণস্বরূপ:
=======
Let's see how one can shoot themselves in the foot:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let arr = new Array(2); // will it create an array of [2] ?
@@ -377,9 +433,13 @@ alert( arr[0] ); // undefined! no elements.
alert( arr.length ); // length 2
```

<<<<<<< HEAD
উপরের কোডে, `new Array(number)` এর সকল ইনডেক্স এর মান `undefined` দেখাবে।

এই ধরণের সারপ্রাইজ এড়াতে আমরা স্কয়ার ব্রাকেট ব্যবহার করি।
=======
To avoid such surprises, we usually use square brackets, unless we really know what we're doing.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## Multidimensional arrays

@@ -392,7 +452,7 @@ let matrix = [
[7, 8, 9]
];

alert( matrix[1][1] ); // 5, the central element
alert( matrix[0][1] ); // 2, the second value of the first inner array
```

## toString
@@ -435,11 +495,19 @@ alert( "1,2" + 1 ); // "1,21"

চলুন পুনরায় অবজেক্ট তুলনার নিয়মগুলো দেখি:

<<<<<<< HEAD
- দুটি অবজেক্ট `==` সমান হবে যদি তারা একই অবজেক্ট কে রেফারেন্স করে।
- `==` এর সাহায্যে তুলনা করার সময় যদি একটি অবজেক্ট হয় এবং অন্যটি primitive হয়, তাহলে অবজেক্টটি primitive ভ্যালুতে পরিবর্তন হয়ে যায়, বিস্তারিত এই অধ্যায়ে <info:object-toprimitive>
- ...তবে `null` এবং `undefined` এরা সমান হবে `==`

strict comparison `===` আর সহজবোধ্য, এটি ডাটা টাইপও তুলনা করে।
=======
- Two objects are equal `==` only if they're references to the same object.
- If one of the arguments of `==` is an object, and the other one is a primitive, then the object gets converted to primitive, as explained in the chapter <info:object-toprimitive>.
- ...With an exception of `null` and `undefined` that equal `==` each other and nothing else.

The strict comparison `===` is even simpler, as it doesn't convert types.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
সুতরাং আমরা যদি দুটি অ্যারের তুলনা `==` করতে চায়, তাহলে তারা সমান হবে না, যদিনা অ্যারে দুটির রেফারেন্স একই হয়।

@@ -459,7 +527,11 @@ alert( 0 == [] ); // true
alert('0' == [] ); // false
```

<<<<<<< HEAD
এখানে উভয়ই ক্ষেত্রে আমরা একটি primitive ভ্যালু কে একটি অবজেক্টের সাথে তুলনা করছি। সুতরাং অবজেক্টটি `[]` primitive এ পরিবর্তন হয়ে একটি এম্পটি `''` স্ট্রিং এ রুপান্তর হবে।
=======
Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
এবং তুলনাটি দুটি primitive ভ্যালুতে করা হয়, বিস্তারিত এই অধ্যায়ে <info:type-conversions>:

@@ -478,22 +550,39 @@ alert('0' == '' ); // false, no type conversion, different strings

অ্যারে হল একটি বিশেষ ধরণের অবজেক্ট, যার সাহায্যে আমরা ডাটা কে উর্ধক্রমে রাখতে পারি।

<<<<<<< HEAD
- অ্যারে ডিক্লেয়ার করার উপায়:
=======
The declaration:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
// square brackets (usual)
let arr = [item1, item2...];
```js
// square brackets (usual)
let arr = [item1, item2...];

// new Array (exceptionally rare)
let arr = new Array(item1, item2...);
```
// new Array (exceptionally rare)
let arr = new Array(item1, item2...);
```

<<<<<<< HEAD
`new Array(number)` এর আর্গুমেন্ট number পাস করলে তাহলে এটি অ্যারের length বুঝায়, তবে কোন এলিমেন্ট থাকবে না।
=======
The call to `new Array(number)` creates an array with the given length, but without elements.
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- `length` প্রপার্টি দ্বারা অ্যারের দৈর্ঘ্য বুঝায়, নির্দিষ্ট করে বলতে গেলে শেষ ইনডেক্সে এর সাথে ১ যোগ। অ্যারের মেথড সমূহের জন্য এটি স্বয়ংক্রিয়ভাবে পরিবর্তন হয়।
- If we shorten `length` manually, the array is truncated.

<<<<<<< HEAD
আমরা অ্যারেকে deque হিসেবে ব্যবহার করতে পারব, এর জন্য নিম্নোক্ত মেথডসমূহ আছে:
=======
Getting the elements:

- we can get element by its index, like `arr[0]`
- also we can use `at(i)` method that allows negative indexes. For negative values of `i`, it steps back from the end of the array. If `i >= 0`, it works same as `arr[i]`.

We can use an array as a deque with the following operations:
>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- `push(...items)` কালেকশনে সবার শেষে একটি `items` যোগ করে।
- `pop()` সবার শেষ এলিমেন্টটি রিটার্ন করে এবং অ্যারে হতে এলিমেন্টটি বাদ দেয়।
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ importance: 4

# Create keyed object from array

Let's say we received an array of users in the form `{id:..., name:..., age... }`.
Let's say we received an array of users in the form `{id:..., name:..., age:... }`.

Create a function `groupById(arr)` that creates an object from it, with `id` as the key, and array items as values.

Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@ describe("filterRangeInPlace", function() {

let arr = [5, 3, 8, 1];

filterRangeInPlace(arr, 1, 4);
filterRangeInPlace(arr, 2, 5);

assert.deepEqual(arr, [3, 1]);
assert.deepEqual(arr, [5, 3]);
});

it("doesn't return anything", function() {
assert.isUndefined(filterRangeInPlace([1,2,3], 1, 4));
});

});
});
Loading