JS Essentials They Don’t Tell You
I initially struggled learning JavaScript. This catalogues why. Coming from a C++/MATLAB background, it’s not intuitive. Corrections welcome.
First off, learning JavaScript is hard! For your first language, learn Python. Then consider Java or Go. Then maybe look around.
Avoid Online Editors, Use Chrome + Text Editor
Avoid Plunkr, JSFiddle etc. Instead, get Komodo Edit (or Notepad++ etc) and use Chrome to view your HTML. Disable Chrome’s aggressive caching by F12 -> Network -> Disable Cache. Use the Chrome Debugger to debug your code (Insert breakpoint with debugger;
) . Each time, write up your HTML from scratch and separate your JS into app.js
.
Avoid JQuery and Other Libraries
Plain JavaScript does most operations, such as getting tags and attributes, and fetching data. Newcomers see JQuery or other libraries as a shortcut but instead sticking to vanilla JS gives you a solid foundation. Plus, learning both JS and a library and their interaction simultaneously is confusing. First learn JS, then slowly branch out.
JS is Forgiving Making Debugging Hard
For example, undefined variables are usable with the value Undefined
! That Undefined
value is passed to the following code/function etc. which then might or might not error. Thus, tracking back errors to the actual problem can be confusing. Deciphering your JavaScript mistakes from console errors takes practice. Initially, add code a line at a time and verify by logging output to the console.
Another situation to know is that when you access a DOM node that doesn’t exist, then Javascript returns null
. This makes sense, but again code execution continues and the error could be thrown much later.
Lastly, if console.log
returns undefined
in the console then that just means you command didn’t return anything so the default of undefined
is shown. It does not mean your command was wrong. Example: Any assignment like var a = "abc"
will return undefined
. Yeah, talk about confusing.
Asychronous Operations Must Use Callbacks
Async operations, such as XMLHttpRequest, do not stop program execution. The code that depends on the async result must be contained in the callback function to the async call. Otherwise, the code will continue executing before the async completes, probably with the aforementioned “null” values, making the result confusing to debug. The code pattern to use is:
asyncCall(callback) { // code for async operation, returning data callback(data) });
Understand Scope in JavaScript
JavaScript uses lexical scope. Lexical scope means that when a function is called, its scope is where it’s defined. For example, in this common code pattern, when fun2
is passed to fun3
, and fun3
passes var
to the callback fun2
, then fun2
can still access both the variables v1
and v2
from fun1
and fun3
respectively.
fun1() { var v1; fun2(var) { // code } fun3(fn2); } fun3(callback) { // code callback(v2); }
Learn to Use Callbacks
Javascript is a callback-oriented language. Callbacks aren’t just for handling the result of an async operation. You can generically use them to return multiple values from a function. Here, showText
returns the fetched text to the callback function mycallback
for further processing. Thus, the function mycallback
can access the text and the variables/functions inside the function main
.
function main() { var file = 'some url'; var v1; showText(file,mycallback); function mycallback(data) { console.log(data); } } function showText(file,callback) { var xhr = new XMLHttpRequest(); request.open('GET',url); request.send(); request.onreadystatechange = function() { if(this.readyState == 4 && this.status == 200) { callback(this.responseText); } } }
Get Used to JS Code Patterns
JS code is quite confusing to read when first encountered. You need to get used to patterns like functions that accept a function as input and return an object whose field is a function. Example:
function fun1() { function fun2 () { //code } function fun3() { //code } fun4(fun2).fun(); } function fun4() { // code return { name: 'abc', fun: function() { console.log('abc');} } }
Avoid Learning Prototypes
Prototypes are unnecessary when first learning JavaScript. You won’t need them. They’re also conceptually challenging to learn. Learn them only if necessary.
Other
- “let” vs “var”: Always use “let” instead of “var”. Google the difference and read up.
- Variable/function hoisting: Always declare variables and nested functions at the beginning of the scope. Google “variable and function hoisting” for more.
Common JS Operations Reference
Read all values of a field in an object array.
var tmp = []; objArr.forEach(function(item,idx) { tmp.push(item.field); })
Check if a value already exists in an array:
objArr.map(function(a) {return a.id;}).indexOf(targetName) < 0