JavaScript
Some notes and small examples about JavaScript. If you are looking for a proper tutorial, hopefully you will at least find a link here to help you. I also like the JavaScript book from Stefan Koch but it's in German, only. It is called "JavaScript: Einführung, Programmierung und Referenz inklusive Ajax".
Links und Sources
JavaScript Links
- Book (German) JavaScript: Einführung, Programmierung und Referenz - inklusive Ajax (amazon.de Link)
- Book (German) JavaScript von Christian Wenz
- Wikipedia JavaScript
- w3schools JavaScript
- selfhtml (German)JavaScript
- Tools
- Google V8 JavaScript engine
Version History
History of JavaScript Today most of JavaScript is described in the ECMAScript Standard.
Browser | JavaScript Version |
---|---|
Firefox 1.5 | JavaScript 1.6 |
Firefox 1.8 | JavaScript 1.8 |
InternetExplorer 6.0 | Jscript 5.6 |
InternetExplorer 7.0 | Jscript 5.7 |
InternetExplorer 8.0 | Jscript 6.0 |
Chrome | JavaScript 1.6 |
Preface
Strict mode
The Strict mode ensures for example that you no longer can use undeclared variables
// var x;
x=42; // error!
Good JavaScript Code
JavaScript conventions
- use 4 spaces for indentation
- end a simple statement with a semicolon
- do not end a complex statement with a semicolon
- put the opening bracket at the end of the first line
- variable and function names written as camelCase
- global variables and constants written in UPPERCASE
- don't start names with a $ sign as it is often used in JavaScript library names
JavaScript best practice
- use strict
- declare local variables with var
- initialize them
- declarations on top of file / function
- avoid new Number/String/Boolean
- use === instead of == (faster)
- check if arguments are undefined an provide a default value for that case
- end switch with default statement
JavaScript mistakes
- Use = and not == (or ===) in comparisons
is 10 which is always true
- switch compares internally with === not with ==
- avoid adding an extra "," after the last entry in an array or object definition as in x=[1,2,3,]
- if you need to test for undefined / null do it like this
- if you leave a code block variables are still available and filled!
JavaScript performance
- avoid using the "with" keyword
- avoid statements in loops, because they will be calculated in each loop
instead use
for (i = 0; i < le; i++) {
- don't create unnecessary variables if you want to save their values.
b="b";
x=a+b;
instead
JavaScript Reserved Words
Data types
var x = null;
var n = 42; // Number
var d=34.00; // Number
var e=123e4; // Number
var s = "John Doe"; // String
var a = ["John", "Doe", "Jane"]; // Array
var o = {id:42, name:"John", age:55}; // Object
var i = 2 / 0; // Infinity
var nan= 100 / "Foo"; // Not a number
isNan(nan + 7);
typeof s; // string
Data types in JavaScript are dynamic
x=x+5;
x=x+"John"
x=2+3+"John"+7+3; // "5John73"
Number.MIN_VALUE;
Number.NEGATIVE_INFINITY;
Number.POSITIVE_INFINITY;
Number.NaN;
Math
Date
Create the date object for the 12.2.2010. Watch out, the month starts with 0, not with 1!
Operators
var j=new String("abc"); // avoid this
var z=new String("abc"); // avoid this
(k==j) // true, same value
(k===j) // false, different type (string vs object)
(j==z) // false, objects cannot be compared
Boolean(1 >2) // True
(1>2) // True
("2"<"12") // false, String comparison, 2 comes after 1 in alphabet
¨¨ // and
|| // or
Strings
Have several methods and also properties
s.charAt(1);
s.length
s.substr(start, end)
s.substring(start, length)
s.search("bc");
If
...
} else if (condition2) {
...
} else {
...
}
Switch
case 0:
day = "Sunday";
break;
case 1:
day = "Monday";
break;
case 2:
day = "Tuesday";
break;
case 3:
day = "Wednesday";
break;
case 4:
day = "Thursday";
break;
case 5:
day = "Friday";
break;
case 6:
day = "Saturday";
break;
default:
day= "Unexpected";
}
Switch compares interally with === not with == so 10 and "10" do NOT match!
For
x[i];
}
For in
var x;
for (x in person) {
...
}
While
i++;
}
Do While
do {
i++;
} while (i < 42);
With break and continue, which may also use labels.
Throw, try and Catch
JavaScript Errors - Throw and Try to Catch
...
}
catch(err) {
...
}
finally {
...
}
Include JavaScript
Include JavaScript in a way that it will not cause troubles for Browsers not being able to execute JavaScript:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>JavaScript Demo</title>
</head>
<body>
<div>
HTML.
<script type="text/javascript">
<!--
alert("JavaScript 4*3="+(4*3));
// -->
</script>
<noscript>
No Script
</noscript>
</body>
</html>
It is preferable to put it in its own file and import it
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>JavaScript Demo</title>
</head>
<body>
<script type="text/javascript" src="myJavaScriptFile.js" />
<noscript>
JavaScript is not supported in your browser.
</noscript>
</body>
</html>
Functions
Parameters in functions are Call by Value for base types and Call by Reference for objects. If you need Call by Reference you need to put the base types into objects. It is possible to have functions with a dynamic number of parameters
{
var result="";
for (var i=0; i<myConcat.arguments.length; i++)
{
result+=myConcat.arguments[i];
}
return result;
}
// ab
alert(myConcat('a', 'b'));
// Hallo Welt
alert(myConcat('Hallo', ' ', 'Welt'));
Scope
function f() {
var b=2; // local, only within f
c=3; // c has never been declared, is automtically GLOBAL!
}
For global variables var is optional. Within a function you need to use var or the variable will be global. If you use in a function let instead of var, a global variable with the same name will not be overwritten.
You should always use let or const instead of var beacause than the variables will only exist in the block scope. If you use const the variable can only be assigned once and not changed again (final in Java)
var b=6;
b=7;
a=8; // not allowed
String to int
If you convert a String to Int always use the number system:
Array
Join, sort, and your own Comperator
{
if(a>b) return -1;
if(a<b) return +1;
return 0;
}
var myArray = new Array();
myArray[0] = "Foo";
myArray[1] = "Bar";
myArray[2] = "Dog";
myArray[myArray.length] = "Cat";
myArray.sort();
// Bar - Cat - Dog - Foo
alert(myArray.join(" - "));
//myArray.reverse();
myArray.sort(myReverseComperator);
// Foo; Dog; Cat; Bar
alert(myArray.join("; "));
Associative Arrays do not really exist in JavaScript, they are objects, which might surprise you
person["firstName"] = "John";
person["lastName"] = "Doe";
person.length; // 0 no array
Set
There was no Set in JavaScript but Objects might be used to simulate that
key='JohnDoe';
if (!(key in set)) {
mySet[key] = true;
}
Objects
Objects only
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"brown"
};
Access objects attributes
person["age"];
Instead of copying values like that from an object
const b=Foo.b;
You can also do this
Methods in Objects
o.myMethod; // get the method definition
Create Object with values and Getters and Setters
var john = {
name: "Doe",
firstName: "John",
get fullName() {
return this.firstName+" "+this.name;
},
set fullName(fullName) {
name=fullName; firstName="";
return this;
}
}
Once you access the attribute the getters jumps in automatically
Class via Prototyping
Define Class via a prototype. First define a function, it will be the Constructor of your Class. It may contain other functions (becoming the member methods) or variables (becoming the member attributes)
function TransportVehicle(pName) {
this.name =pName; // public member
var _me; // private member
// manual getter / setter for public member
this.getName = function() {
console.log("getter Name called");
return this.name;
}
this.setName=function(pName) {
console.log("setter Name called with value " + pName);
this.name=pName;
return this;
}
// method defined within the constructor
this.foo = function() {
return "Foo";
}
};
This is how you can create an object out of this class
Before you do this, better think about defining the Getter and Setters like this, instead of doing them manually. This way you avoid the risk to bypass the Getters and Setters
TransportVehicle.prototype = {
get price() { console.log("getter Price called"); return this._price; },
set price(price) { console.log("setter Price called with value " + price); this._price=price; return this;}
}
Object.defineProperty(TransportVehicle.prototype, "maxSpeed", {
get: function() {return this._maxSpeed;},
set: function(maxSpeed) {this._maxSpeed = maxSpeed; return this;}
});
Usage
tv.name; // name via public variable
tv.price=42; // price via setter
tv.price; // price via getter
// bmw.getPrice(); does not exit
tv.maxSpeed=203; // via setter
tv.maxSpeed; // via getter
// tv.getMaxSpeed(); does not exist
You may also add normal methods to your class outside the Constructor
TransportVehicle.prototype.bar = function() {
return "Bar";
}
Both will work the same way
tv.foo();
tv.bar();
Inheritance
Just define another function which will be your constructor. But this time set its prototype to an instance of the desired father class.
function Car(pName, pNrOfWheels) {
this.prototype=new TransportVehicle(pName);
//also add getters and setters via the prototype
Object.defineProperty(this, "nrOfWheels", {
get: function() { return this._nrOfWheels; },
set: function(nrOfWheels) { this._nrOfWheels = nrOfWheels; return this; }
});
// use setter implicitly because setter was defined before us
this.nrOfWheels=pNrOfWheels;
}
// Overwrite method in Car
Car.prototype.foo=function() {
// result from father class and change the result slightly
return this.prototype.foo()+"ooooo";
}
var bmw=new Car("BMW 3", 4);
bmw.nrOfWheels; // via implicit getter
bmw.foo(); // Fooooooo
JavaScript Object Natation (JSON)
JavaScript Object Natation (JSON), eine Kurzschreibweise für JavaObjekte
value:"120,12",
getString:function() { return this.value+"("+this.currency+")"; }
}
Important Objects
Objects | Example |
---|---|
window | z.B. window.alert(); |
document | Access to the website |
location | Access on the URL of the current page |
JavaScript, CSS, move objects
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>JavaScript Demo</title>
<style type="text/css">
#d1 { color:red; position:fixed; top:10px; left:10px; }
#d2 { color:blue; position:fixed; top:100px; left:100px; }
</style>
</head>
<body>
<div id="d1">Foo</div>
<div id="d2">Bar</div>
<script type="text/javascript">
var o1=document.getElementById("d1")
var o2=document.getElementById("d2")
var myCounter=0;
function moveIt()
{
o1.style.left=10+myCounter+'px';
o2.innerHTML='Value: '+myCounter;
myCounter++;
if(myCounter>100) clearInterval(myInterval);
}
var myInterval=setInterval("moveIt()", 20);
</script>
</body>
</html>
DOM
DOM Level 0
There are arrays for some objects (e.g. for links and pictures). For example
DOM Level 2
For all objects in an HTML page there is an object.
First
<div id="d2">
Second
<ul id="d3">
<li>A</li><li>B</li>
<li>C</li>
</ul>
</div>
<span id="d4"><a href="http://www.example.com">third</a></span>
</div>
<hr />
<div id="result">Result:</div>
<script type="text/javascript">
var o1=document.getElementById("d1");
var o2=document.getElementById("d2");
var o3=document.getElementById("d3");
var o4=document.getElementById("d4");
var result=document.getElementById("result").childNodes[0];
// First
result.nodeValue+=" "+o1.childNodes[0].nodeValue;
// Second
result.nodeValue+=" "+o2.childNodes[0].nodeValue;
// ul
for(var i=0; i<o3.childNodes.length; i++)
{
if("object"===typeof o3.childNodes[i].childNodes[0])
{
result.nodeValue+=i+": "+o3.childNodes[i].childNodes[0].nodeValue+" ";
}
}
// a href
var ol=o4.childNodes[0];
result.nodeValue+=ol.childNodes[0].nodeValue;
result.nodeValue+=" -> "+ol.getAttribute('href')
// other possibility
result.nodeValue+="; "+o3.innerHTML;
</script>
Events
List of important events, see also DOM Events
- onchange
- onclick
- onfocus
- onload
- onmouseon
- onmouseover
- onload
W3C Event Listener / IE Event Listener
W3C Event-Listener (not supported by IE) and Micrsoft Internet Explorer events
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>JavaScript Demo</title>
<style type="text/css">
.stylA { font-size:large; color:red; }
.stylB { font-size:normal; color:green; }
</style>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>
<body>
<div id="d1" class="stylB" onmouseover="this.className='stylA';" onmouseout="this.className='stylB';">
Foo
</div>
<script type="text/javascript">
var o=document.getElementById("d1");
if("function"===typeof o.addEventListener)
o.addEventListener("click", myFunction, false);
else if("function"===typeof o.attachEvent)
o.attachEvent("click", myFunctionIE);
function myFunction(pEvent)
{
o.childNodes[0].nodeValue+=".("+pEvent.clientX+"/"+pEvent.clientY+")";
}
function myFunctionIE()
{
o.childNodes[0].nodeValue+=".("+window.event.offsetX+"/"+window.event.offsetY+")";
}
</script>
</body>
</html>
Pass and read parameters
alert(myNewURL);
var myParams=location.search;
myParams=myParams.substring(1, myParams.length);
myParams=decodeURIComponent(myParams);
alert(myParams);
Links you can bookmark
location.hash can be used to make it possible to set a bookmark for state of a dynamic site.
Examples
Size of an element should grow
An input element for texts should grow while the text enlarges or shrinks.
The code can be placed directly at the element
or put it into its own method
<!--
/* this function can be used to enlarge text input
* fields while the users enters text into it.
* Usage: <input type="text" onkeyup="enlarge_size_with_value_length(this);" ...
*/
function enlarge_size_with_value_length(o)
{
var minsize=2;
var maxsize=1023;
var newsize=o.value.length;
if(newsize<minsize) {
newsize=minsize;
};
if(newsize>maxsize) {
newsize=maxsize;
};
o.setAttribute('size', newsize);
};
//-->
</script>
<input type="text" ... size="2" onkeyup="enlarge_size_with_value_length(this)"
Ajax
Asynchronous JavaScript and XML
function getXMLHttpRequest()
{
if(window.XMLHttpRequest) return new XMLHttpRequest();
if(typeof ActoveXObject!="undefined") return new ActiveXObject("Microsoft.XMLHTTP");
return null;
}
talk2me=getXMLHttpRequest();
talk2me.onreadystatechange=gotOne;
talk2me.open("get", "data1.xml", true);
talk2me.send(null);
function gotOne()
{
if(talk2me.readyState==4)
{
if(talk2me.status==200)
{
alert(talk2me.responseText);
}
}
}
Ask the browser where we are on exactly on earth
navigator.geolocation.getCurrentPosition(showPosition, onError); //
also monitor position as it changes
navigator.geolocation.watchPosition(showPosition); } else { onError();
}
function showPosition(position)
{
...
}
function onError()
{
if (navigator.geolocation)
{
// Error in geolocation service
}
else
{
// Warning: Browser does not support geolocation
}
}