JavaScript is a programming language: A way for humans to order computers around. A human who has become a "programmer" can order computers to do useful things for themselves and others. Really good programmers write new languages which become widely used.1 Today, JavaScript is called ECMAScript^ and runs in the V8 engine^ in Chrome^, and now Microsoft Edge, as WebKit^ / Nitro in Apple's Safari^, and as SpiderMonkey^ in Firefox^. On the backend it runs as Node.JS^ and you can use Electron^ to make full on desktop applications.
Not Java: JavaScript has nothing to do with Java1 . "Java is to Javascript as Car is to Carpet." It's more closely related to ( LISP ), C, and Pascal.
Syntax and Semantics: Like any language, JavaScript has a "syntax" you have to follow. Syntax is like grammar in human languages; the list of words, spelling of those words, and rules for how you can and can not put them together. Beyond syntax is meaning. Once we have a working grammar, we still have to figure out what those words mean; this is the languages "semantics".
A language is a mapping between syntax and semantics.
In natural languages like English, the syntax, the semantics, and the mapping between the two is very complex, often resulting in ambiguity of meaning. Programming languages attempt to overcome these deficiencies by having smaller, more controlled, and more consistent vocabulary as well as grammar for describing data structures and processes.
Exercise: Write two sentences in English. In one, make a syntax error, but make sure the sentence is semantically correct. In the other, make a semantic error, but ensure good syntax. For example: "Mother is crasy. She has handelbars in her head."
When Brendan Eich1 wrote the language (in only 10 days!1) he was attempting to build something that could understand the idea you are trying to type in and then turn it into code for the computer that makes it understand exactly what you meant it to do. There are many (many) different ways to express the same idea in human languages. He didn't have time to figure out every way you could mess up typing something or every way you could express your idea. Communication is always difficult and it's even more difficult between humans and computers; you may understand what you said, and your best friend may normally understand you to some degree, but for programming, you have to explain what you mean in a grammar Brendan's twisted mind understood so his JavaScript language program can translate it to the computer.
Statements: Each line (or part of a line terminated by a ";") is a statement. These are the "sentences" of JavaScript; they express one basic idea per line.
Examples:
Hopefully those examples explained a lot about how Javascript works.
There are a zillion possible statements, but only a few core words from which those statements are built. Good IDEs (Integrated Development Environments) can help you figure out what words are available by "hinting" them as you type:
Keywords /
Operators / Reserved
words: The words JavaScript knows right from the start. These are the
starting entries in the dictionary of JavaScript. Here are most of the common
JavaScript Keywords:
break
case
catch
const
do
else
eval false
finally
for
function
if
in
isNaN
length
let
Math
NaN name
new
return
switch
this
throw true
try
typeof undefined
var
while with
This is not a complete list, and there are a bunch more related to documents in browsers and other special stuff. And you can add keywords yourself. Notice some are standard english (if, false, true) and actually mean pretty much the same thing. Some are English words that don't mean the same thing (for, throw). Others are made up words (var, NaN). A few are two words crammed together (typeof, isNaN).
Also, case is important in JavaScript. Math (object prototype with math functions) is not math (which doesn't exist). NaN is not nan or NAN but it stands for "Not a Number". Syntax. Or else. (Use the IDE, Luke... to hint which one to use). But even then, Document is not document and each is valid so basic spell checkers can't help.
Exercise: ('b' + 'a' + + 'a' + 'a').toLowerCase() Can you figure out what that evaluates to? Try it in the debug console. (Press Ctrl + Shift + I, and enter it into the console, press enter). Now, WHY does it produce that? Can you find the source of the extra letters? Key point: Any computer language can do unexpected things, test often and learn how to break things down to find the cause.
Blocks "{ }" Some keywords need to work with other keywords. By default, they only work with one other keyword. e.g. if (false) this_dont_happen(); but_this_still_does(); So if you need to work with more than one, you put them in a "block", meaning you put { } around them. if (false) { this_dont_happen(); and_this_dont_either(); }. Notice that blocks are defined using {} (when executing a statement) but later on we will see that objects are also defined using {} (when returning a value) ^
Variables: Names you give to pieces of the computers memory. They can be thought of as boxes in the memory closet, with names you use to label the front of the box, and values which are stored inside. JavaScript, like all computer languages, has specific types of boxes, of specific sizes, for specific uses. For example, there is a type of box for numbers, and one for text (strings, messages, etc...), and even for lists of boxes (arrays) or boxes of boxes (objects), etc... JavaScript is a "weakly typed" language, meaning that it will figure out what datatype, what type of box, to use for you on the fly... but it will switch from one sort of box to the next without telling you. And it will select the type based on it's best guess, which can get a bit weird. e.g. Here are some BAD things that can happen:
var myvar myvar = +"12" //this is now a number, and it's value is 12 myvar = "12"*1 //this is now a number, and it's value is 12 myvar = "12"+0 //this is now a string, and it's value is "120"
Hint: Instead, use parseInt and toString to convert between numbers and strings. You can use typeof() to find out what type it picked.
Exercise: Make a variable using your first or last name. Set it's value to your age (or some number). Make a loop that outputs "I was " followed by a number, starting from 0 and going until one less than your age. Add a line that outputs "Now I am " and your names value. Hints: for, console.log(message) or document.write(message),
Scope: Variables "have scope" which means they can be hidden from different parts of the program. A "global" variable is visible everywhere in the program. But a "local" variable is only accessible in the local part of the program. This is really good when programs start to get large and you forget that you already used a variable name for something else and accidentally overwrite it's value.
It's like the idea of "context" in language. We have words (homonyms) which are spelled the same, but have different meanings in different contexts. e.g. "Arms" can be body parts, or weapons. "Bark" can be the sound a dog makes, or the outside of a tree.^
let makes global variables or local variable if it's in a block { } scope or in any parameter list related to the block. Even if you use the same name for the new local box that use used for the global box, it just makes a new box, and puts the prior box with the same name away for later. When you leave the block, it brings the old box, with that name, back. E.g.
let i = 123 for (let i = 0; i < 2; ++i) { console.log("i is:"+i); //i is 0 then 1 inside this block } console.log("i is:"+i) //i is 123 after the block
var makes global variables outside a function, or local variables inside a function, not just inside a block. That gets weird if you make a var part way down in a function, because the name of the box will be known all through the function, but it will only have the value you set from there down. To avoid that... just don't use var. That's why they replaced it with let.
const is just like let, but for two things: You must assign a value and you can not change that value. It's a constant. If you try to change the value after you set it, you get an error and the program stops.
Exercise: Run the code above and verify the result. Change the first line to var i = 123 and note the results. Copy and reload the page, then change the first line to const i = 123 and note the results. Now change the first line back to let i = 123 and change the "let" inside the for, on the second line, to "var". Notice the change. Now change the second "let" to "const"
Scope gets really complex and causes a lot of problems. It's good to take the time to learn it fully:
Objects { }: Almost everything in JavaScript is actually an object. e.g. myvar above is an object of type string or number. Objects are basically boxes of boxes. So there is a primitive value like a string or number, but there are also other named boxes in the variable box and those boxes keep track of things like what type of box it is, how to do stuff to the value in the box, and so on. e.g. with our string variable from above. myvar = "12"+0
myvar.length //tells us how long the value in myvar is. Length is an attribute. myvar.toString //contains a program that will convert myvars value to a string. myvar.toString() //gives us the result of calling that program; the value as a string
Primitive objects, like strings or numbers, are immutable, they can't be assigned new attributes; they can only be assigned new values. JavaScript doesn't call these objects, although they really are under the hood. The word "object" is used to refer to the mutable object to which you can add other things.
Objects are defined by including attributes and values, separated by colons, inside curly braces {}. e.g.
var i = { name: "James", count: 1 }
And they can be added and accessed via that "dot notation" where we follow the object name by a period "." and then the name of the attribute.
i.name /"James" i.count //1 i.age = 55 // as if we had started with { name: "James", count: 1, age: 55}
Note that despite also using { }, objects do NOT use the statement block syntax which also uses { }. E.g. you can not do { var count = 0 } in an object declaration. It would be { count: 0 } instead.
Functions ( ): Functions take in parameters, (which automatically have local scope) then do stuff to those parameters by executing a group of statements which "define" the function, and finally return values. Functions are also just objects like anything else, and can be stored in other objects (we call them "methods" then), or have other objects or variables stored in them. For example:
let myprog = function(myparm){return "you said:"+myparm} console.log(myprog) //prints out ' (myparm){return "you said:"+myparm}' console.log(myprog("Hello")) //prints out 'you said:Hello'
It's critical to understand that a function is just defined by the evaluation of a string that follows a specific format; the block of statements format for valid Javascript. The name of the function returns the definition of the function. The addition of parenthesis "()" after the function name causes the language to execute that function definition. So you can copy functions from one variable or object attribute (method) to another. You can replace them. But they don't actually DO anything until you reference them followed by parenthesis (optionally enclosing "arguments" which replace the parameters).
let argument = "something" function foo(parameter) { return parameter + 1; } var result = foo(argument) //this returns argument + 1 var bar = foo //bar is now a copy of foo var result = bar(argument) //this also returns argument + 1
In fact, you don't really need a function name. You can define an "anonymous function" without naming it and then call it right away,
(function(firstname) { console.log(firstname+', I happen right now'); }("James"))
Note that the parenthesis are necessary to convert it from a statement to an expression. Or you can hand off an anonymous function to something that needs a function. Like when you will call it later...
setTimeout( function(firstname) { console.log(firstname+', I happen a second (1000 milliseconds) later'); }, 1000, "James");
And, actually, you don't even need the word function in the current versions
of JavaScript. ECMAScript 6 added the very confusing "arrow functions"
which use a trailing => instead:
var name = (
arguments
) => { statement
}
Notice there is no "function" and it returns a function definition. When
it's called, as in name(arguments), then it returns the result of
the statement as if there was a "return" in there. E.g. let
square = (n) => { n*n } called with square(5) returns 25.
And parts of that can even drop out. e.g. if your statement is just an
expression, you don't need the {} so you can do let square = (n) =>
n*n and if you only have one argument, you can drop the ( ) in
the definition (not in the call) so you can do let square = n =>
n*n but it's still called with square(5) or whatever. And...
you don't even need the name if it's an anonymous function. So you can do
things like this:
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); //66
var even = arr.filter(v => v % 2 == 0); //[ 6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
Arrow functions can make for very compact code, and may appear to simplify things... but they can also get very tricky and very very hard to understand when reading the resulting code. They are only mentioned here to help you "decode" them when looking at code written by other programmers.
Variables declared in a function have local scope. var makes one
for the entire function, let for the local block. Except... when
called via "comma operator" which causes global scope by default.
See:
https://jsbin.com/kucutojono/edit?js,console
"Central to constructing working code is understanding how the computer interprets your code. eval is the function in JavaScript that accepts a string of source code and "runs" it. By running "eval" in your head as you are reading code, you can know what the computer will do with it. This is the core technique of understanding and debugging JavaScript source code. The best way to know what eval does is to know how to write eval. This webinar helps you understand how eval works by incrementally defining it in JavaScript."
See also: