<!--{{{-->
<div class="toolbar" macro="toolbar +finishEditing -cancelEditing"></div>
<div class="title" macro="view title"></div>
<div class="editor" macro="edit title"></div>
<div class="editor" macro="edit text"></div>
<div class="editor" macro="edit tags">Tags: </div>
<div class="editor" macro="edit parenttitle">Parent:</div>
<div class="editorFooter"><span macro="message views.editor.tagHint"></span><span macro="tagChooser"></span></div>
<!--}}}-->
<<importTiddlers>>
<!--{{{-->
<div id='navigationArea'>
	<div id='navigationCollapser' macro='collapseArea navigationPanel'></div>
	<div id='navigationPanel' refresh='content' force='true' tiddler='NavigationPanel'></div>
</div>
<div id='sidebar'>
	<div id='sidebarCollapser' macro='collapseArea sidebarContent true "Side Bar" "»«"'></div>
	<div id='sidebarContent'>
		<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
	</div>
</div>
<div id='displayArea'>
	<div id='navAndSearch'>
		<div id='navToolbar'>
			<span id='navButtons' macro='navigate'></span>
			<div id='breadcrumbsBox'></div>
		</div>
		<span id='search' macro='search'></span>
	</div>
	<div id='pageWrapper'>
		<div id='messageArea'></div>
		<div id='tiddlerDisplay'></div>
	</div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar'><span macro='toolbar startEditing deleteArticle > references <'></span></div>
<div class='title' macro='view title'></div>
<div class='articleContentContainer' macro='view text wikified'></div>
<!--}}}-->
|Name|Purpose|h
|jQuery|Mostly eye candy effects.|
|BootStrap|nopee.|
!Declaring

{{{
var dynamicLengthArray = new Array();
var fixedLengthArray = new Array(100); // 0..99
var stringArray = new Array("Anita", "Bettina", "Christa", "Doris"); // is equal to the following line
var stringArray = ["Anita", "Bettina", "Christa", "Doris"]
}}}

!Iterating

{{{
for (var i = 0; i < a.length; i++){
  value = a[i];
}
for (var i = arr.length - 1; i >= 0; i--) {
  value = a[i];
}
}}}

!Adding & removing items

|push(values)|Add value(s) at end.|var data = ["X"];<br>data.push("A");<br>data.push("B", "C");|["X", "A", "B", "C"]|
|pop() value|Return and Remove value from end.|var data = ["A", "B", "C"];<br>data.pop()|["A", "B"]|
|unshift(values)|Insert value(s) at beginning.|var data = ["X"];<br>data.unshift("A");<br>data.unshift("B", "C");|["B", "C", "A", "X"]|
|shift() value|Return and Remove value from beginning.|var data = ["A", "B", "C"];<br>data.shift();|["B", "C"]|

![[Slice|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice]]

{{{
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

// citrus contains ['Orange','Lemon']
}}}

!!Parameters

!!!begin

    Zero-based index at which to begin extraction.
    As a negative index, begin indicates an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence.
    If begin is omitted, slice begins from index 0.

!!!end

    Zero-based index at which to end extraction. slice extracts up to but not including end.
    slice(1,4) extracts the second element up to the fourth element (elements indexed 1, 2, and 3).
    As a negative index, end indicates an offset from the end of the sequence. slice(2,-1) extracts the third element through the second-to-last element in the sequence.
    If end is omitted, slice extracts to the end of the sequence (arr.length). 

!!Description

slice does not alter. It returns a shallow copy of elements from the original array. Elements of the original array are copied into the returned array as follows:

    For object references (and not the actual object), slice copies object references into the new array. Both the original and new array refer to the same object. If a referenced object changes, the changes are visible to both the new and original arrays.
    For strings and numbers (not String and Number objects), slice copies strings and numbers into the new array. Changes to the string or number in one array does not affect the other array.

If a new element is added to either array, the other array is not affected.

![[Splice|https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/splice]]



if (navigator.appName == "Microsoft Internet Explorer" || true) {
{{{
function getCaretPosition (ctrl) {
	var caretPos = 0;
	if (document.selection) { // IE Support
		ctrl.focus ();
		var sel = document.selection.createRange ();
		sel.moveStart ('character', -ctrl.value.length);
		CaretPos = sel.text.length;
	} else if (ctrl.selectionStart || ctrl.selectionStart == '0') { // Firefox support
		caretPos = ctrl.selectionStart;
	}
	return (CaretPos);
}

function setCaretPosition(ctrl, pos){
	if(ctrl.setSelectionRange){
		ctrl.focus();
		ctrl.setSelectionRange(pos,pos);
	} else if (ctrl.createTextRange) {
		var range = ctrl.createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
}
}}}
!Pasted HTML or Plain Text

{{{
<html><head><title>DEMO: Clipboard Paste HTML or Text</title></head>
<script>

window.addEventListener(
	"paste", 
	function(e){ // : ClipboardEvent
		var htmlValue = e.clipboardData.getData('text/html');
		if (htmlValue){
			console.log('htmlValue:'+'"' + htmlValue + '"');
		}		
		var stringValue = e.clipboardData.getData('text/plain');
		if (stringValue){
			console.log('stringValue:'+'"' + stringValue + '"');
		}
	}
);

</script>
</html>

}}}

!Weblinks

* StackOverflow: [[Javascript trick for 'paste as plain text` in execCommand|https://stackoverflow.com/questions/12027137/javascript-trick-for-paste-as-plain-text-in-execcommand]]
* WhatWg: [[The DataTransferItem interface|https://html.spec.whatwg.org/multipage/dnd.html#datatransferitem]]

!HTML DOM Nodes

In the HTML DOM (Document Object Model), everything is a node:

*The document itself is a document node
*All HTML elements are [[element]] nodes
*All HTML attributes are attribute nodes
*Text inside HTML elements are text nodes
*Comments are comment nodes

!Adressing the objects

Example:
{{{
<body>
	<form name="MyFancyForm">
		<input type="text" name="TextField1">
	</form>
	<div id="OutsideTheForm">Text</div>
<body>
}}}

!!Dot notation

{{{
document.MyFancyForm.TextField1.value
document.forms[0].elements.someObject
document.forms[0].someObject
}}}

!!Square bracket notation

{{{
document.forms[0]["objectID"]
document.forms[0]["objectID"]["property"]
}}}

!!Mixed

{{{
document.forms[0]["objectID"].property
document.forms[0].objectID["property"]
}}}

!!getElementById()

{{{
document.getElementById("objectID")
}}}
!Creating Stuff

{{{
	document.createTextNode("HELLO");

var newDiv = document.createElement("div");
newDiv.innerHTML = "HELLO";
}}}

!Adding Stuff

{{{
	document.body.innerHTML += "The trailing linebreak will be effecitve, because this text will be interpreted as HTML<br/>";

	document.body.appendChild(document.createTextNode("This <br/> will be no line break, but readable."));
}}}

!window.print()
{{{
<input type="button" value="Foo" onclick="window.print();" />
}}}
!Siehe auch
http://www.alistapart.com/articles/printtopreview/
In .net this is called //Reflection//.

Example Type

{{{

function Animal() {
	this.Name = "Fritz";
  this.Eat = function() { alert("Yum.") }
};

var anAnimal = new Animal();

}}}

!Analyzing stuff at runtime

*Getting source code of classes: toString()

{{{
Animal.toString();
}}}

*Getting member names (for ''objects'', not classes): for (... in ...)

{{{
for (propertyName in anAnimal){
	console.log(propertyName + "=" + teddy[propertyName]);
}
}}}

!Accessing ''object''-members dynamically: Square braces notation

{{{
console.log(anAnmial["Name"]);
}}}
!The Element Type

In the HTML DOM, the Element object represents an HTML element.
Element objects can have child nodes of type element nodes, text nodes, or comment nodes.
A NodeList object represents a list of nodes, like an HTML element's collection of child nodes.
Elements can also have attributes. Attributes are attribute nodes.

!Properties and Methods

|Property / Method|Description|h
|element.accessKey|Sets or returns the accesskey attribute of an element|
|element.addEventListener()|Attaches an event handler to the specified element|
|element.appendChild()|Adds a new child node, to an element, as the last child node|
|element.attributes|Returns a NamedNodeMap of an element's attributes|
|element.blur()|Removes focus from an element|
|element.childElementCount|Returns the number of child elements an element has|
|element.childNodes|Returns a collection of an element's child nodes (including text and comment nodes)|
|element.children|Returns a collection of an element's child element (excluding text and comment nodes)|
|element.classList|Returns the class name(s) of an element|
|element.className|Sets or returns the value of the class attribute of an element|
|element.click()|Simulates a mouse-click on an element|
|element.clientHeight|Returns the height of an element, including padding|
|element.clientLeft|Returns the width of the left border of an element|
|element.clientTop|Returns the width of the top border of an element|
|element.clientWidth|Returns the width of an element, including padding|
|element.cloneNode()|Clones an element|
|element.compareDocumentPosition()|Compares the document position of two elements|
|element.contains()|Returns true if a node is a descendant of a node, otherwise false|
|element.contentEditable|Sets or returns whether the content of an element is editable or not|
|element.dir|Sets or returns the value of the dir attribute of an element|
|element.firstChild|Returns the first child node of an element|
|element.firstElementChild|Returns the first child element of an element|
|element.focus()|Gives focus to an element|
|element.getAttribute()|Returns the specified attribute value of an element node|
|element.getAttributeNode()|Returns the specified attribute node|
|element.getElementsByClassName()|Returns a collection of all child elements with the specified class name|
|element.getElementsByTagName()|Returns a collection of all child elements with the specified tag name|
|element.getFeature()|Returns an object which implements the APIs of a specified feature|
|element.hasAttribute()|Returns true if an element has the specified attribute, otherwise false|
|element.hasAttributes()|Returns true if an element has any attributes, otherwise false|
|element.hasChildNodes()|Returns true if an element has any child nodes, otherwise false|
|element.id|Sets or returns the value of the id attribute of an element|
|element.innerHTML|Sets or returns the content of an element|
|element.insertBefore()|Inserts a new child node before a specified, existing, child node|
|element.isContentEditable|Returns true if the content of an element is editable, otherwise false|
|element.isDefaultNamespace()|Returns true if a specified namespaceURI is the default, otherwise false|
|element.isEqualNode()|Checks if two elements are equal|
|element.isSameNode()|Checks if two elements are the same node|
|element.isSupported()|Returns true if a specified feature is supported on the element|
|element.lang|Sets or returns the value of the lang attribute of an element|
|element.lastChild|Returns the last child node of an element|
|element.lastElementChild|Returns the last child element of an element|
|element.namespaceURI|Returns the namespace URI of an element|
|element.nextSibling|Returns the next node at the same node tree level|
|element.nextElementSibling|Returns the next element at the same node tree level|
|element.nodeName|Returns the name of a node|
|element.nodeType|Returns the node type of a node|
|element.nodeValue|Sets or returns the value of a node|
|element.normalize()|Joins adjacent text nodes and removes empty text nodes in an element|
|element.offsetHeight|Returns the height of an element, including padding, border and scrollbar|
|element.offsetWidth|Returns the width of an element, including padding, border and scrollbar|
|element.offsetLeft|Returns the horizontal offset position of an element|
|element.offsetParent|Returns the offset container of an element|
|element.offsetTop|Returns the vertical offset position of an element|
|element.ownerDocument|Returns the root element (document object) for an element|
|element.parentNode|Returns the parent node of an element|
|element.parentElement|Returns the parent element node of an element|
|element.previousSibling|Returns the previous node at the same node tree level|
|element.previousElementSibling|Returns the previous element at the same node tree level|
|element.querySelector()|Returns the first child element that matches a specified CSS selector(s) of an element|
|element.querySelectorAll()|Returns all child elements that matches a specified CSS selector(s) of an element|
|element.removeAttribute()|Removes a specified attribute from an element|
|element.removeAttributeNode()|Removes a specified attribute node, and returns the removed node|
|element.removeChild()|Removes a child node from an element|
|element.replaceChild()|Replaces a child node in an element|
|element.removeEventListener()|Removes an event handler that has been attached with the addEventListener() method|
|element.scrollHeight|Returns the entire height of an element, including padding|
|element.scrollLeft|Sets or returns the number of pixels an element's content is scrolled horizontally|
|element.scrollTop|Sets or returns the number of pixels an element's content is scrolled vertically|
|element.scrollWidth|Returns the entire width of an element, including padding|
|element.setAttribute()|Sets or changes the specified attribute, to the specified value|
|element.setAttributeNode()|Sets or changes the specified attribute node|
|element.style|Sets or returns the value of the style attribute of an element|
|element.tabIndex|Sets or returns the value of the tabindex attribute of an element|
|element.tagName|Returns the tag name of an element|
|element.textContent|Sets or returns the textual content of a node and its descendants|
|element.title|Sets or returns the value of the title attribute of an element|
|element.toString()|Converts an element to a string|

!External Links

*w3schools.com: [[The HTML DOM Element Object|http://www.w3schools.com/Jsref/dom_obj_all.asp]]
!External

{{{
<script src="foo.js"></script>
}}}

!Embedded

{{{
<script type="text/javascript">
	function Foo() {
	}
</script>
}}}

|\"|"|
|\\|\|
|\n|Line break|
|\t|Tab|
|\b|Back space|
|\l|Line feed (never used)|
|\f|Form feed (never used)|
!Weblinks

* developer.mozilla.org: [[addEventListener|https://developer.mozilla.org/en/docs/Web/API/EventTarget/addEventListener]]
!Event names are HTML attributes

{{{
<button onclick="alert('Hello world!');">Text</button>
}}}

!Listeners - add/remove dynamically

!!onclick direkt setzen

!!!Parameterlos

{{{
object.onclick = DoSomething;
}}}

!!!Mit Parametern

{{{
object.onclick = function(){DoSomething(this.src);};
}}}

!!Weitere Varianten

http://www.mediaevent.de/javascript/event_listener.html

!Keyboard events

{{{
document.body.onkeypress = function(e){
	if (e.ctrlKey && e.which==101){
		// your code here
	}
};
}}}

!Weblinks

*s. auch http://de.selfhtml.org/javascript/sprache/eventhandler.htm
!Creating

{{{
// Declaration (the only variant that is hoisted!)
function multiply(x, y) {
  return x * y;
} // No need for semicolon here

// Constructor
const multiply = new Function("x", "y", "return x * y");

// Expression; the function is anonymous but assigned to a variable
const multiply = function (x, y) {
  return x * y;
};
// Expression; the function has its own name
const multiply = function funcName(x, y) {
  return x * y;
};

// Arrow function
const multiply = (x, y) => x * y;

// Method
const obj = {
  multiply(x, y) {
    return x * y;
  },
};
}}}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

!!Recycled And Non-Recycled Anonymous Functions

Consider this code:

{{{
var elements = document.getElementsByTagName('input');
var n = elements.length;    // assume we have 10 elements for this example
for (var i = 0; i < n; i++) {
	elements[i].onclick = function() {
		console.log("This is element #" + i);
	};
}
}}}

Based on the above code, if there were 10 input elements, clicking any of them would display “This is element #10”! This is because, by the time onclick is invoked for any of the elements, the above for loop will have completed and the value of i will already be 10 (for all of them).

Here’s how we can correct the above code problems, though, to achieve the desired behavior:

{{{
var elements = document.getElementsByTagName('input');
var n = elements.length;    // assume we have 10 elements for this example
var makeHandler = function(num) {  // outer function
     return function() {   // inner function
         console.log("This is element #" + num);
     };
};
for (var i = 0; i < n; i++) {
    elements[i].onclick = makeHandler(i+1);
}
}}}

In this revised version of the code, makeHandler is immediately executed each time we pass through the loop, each time receiving the then-current value of i+1 and binding it to a scoped num variable. The outer function returns the inner function (which also uses this scoped num variable) and the element’s onclick is set to that inner function. This ensures that each onclick receives and uses the proper i value (via the scoped num variable).

!!Immediately-Invoked Functions

{{{
(function ImmediatelyInvokedFunction() {
	// Will be invoked once in place. Not accessible anywhere else (there will be no global variable 'ImmediatelyInvokedFunction')
})();
}}}

!Calling

{{{
<button onclick="Foo('Argument');">Text</button>
}}}

!Overriding

Durch simple Neudeklaration einer Function (mit identischer Signatur) wird die vorherige Deklaration übersteuert.
Möchte man weiterhin auf das Original zugreifen können, muss man es zuvor explizit in einer Variablen retten.

{{{
// Saving the original func
var org_doSomething = doSomething;

// Assigning proxy fucnc via the function()-function
doSomething = function(args){
  // Calling original function
  org_doSomething(args);
};
}}}

!Scope

*“this” is a context. It refers to the object upon which a function is invoked. That’s it.
*When JavaScript encounters a function, one of the first things it does is scan the full body of the code for any declared variables. When it encounters them, it initializes them by default with undefined.

{{{
Value = 'Global';

function DeclaredFunction(p) {
	this.Value = 'ActuallyGlobal!';
	
	var subFunction = function() {
		this.Value = 'EvenHereGlobal!';
	}
	
	subFunction();	
};
	
DeclaredFunction(); // Will modify the ''global'' Value

alert(Value); // Shows "EvenHereGlobal!"
}}}

!!Shared public members

*Inspired by StackOverflow [[Static variables in JavaScript|http://stackoverflow.com/questions/1535631/static-variables-in-javascript]]

{{{
// Define the class name and it's "constructor"

function DemoClass(id) {

	// The following code is both at the same time - the member declaration area and the constructor

	var Value = 'PrivateValue' + id;
	
	this.Value = 'PublicValue' + id;
	
	this.Dump = function() { 
		console.log(Value + ' | ' + this.Value + ' | ' + this.SharedValue); 
	}
};

// Shared members must be added to the class OUTSIDE the class declaration:

DemoClass._SharedValue = 'SharedValue'

// In order to make it accessible via each instance, we have to build a bridge property:

Object.defineProperty(
	DemoClass.prototype, 'SharedValue', {
    get: function() { return DemoClass._SharedValue; },
		set: function(value) { DemoClass._SharedValue = value }
	}
);

// Demonstrating the usage of the classes:

var instance1 = new DemoClass(1);
var instance2 = new DemoClass(2);

console.log('Before:');
instance1.Dump();
instance2.Dump();

instance1.Value = '*VALUE1*';
instance1.SharedValue = '*SHARED*';

console.log('After:');
instance1.Dump();
instance2.Dump();

console.log('-- Technical analysis of the physical property owners --');

// Interesting analysis:

console.log('DemoClass:');
console.log("  [Value] " + DemoClass.hasOwnProperty("Value")); // false - because "this" refers to the 
console.log("  [Dump] " + DemoClass.hasOwnProperty("Dump"));  // true
console.log("  [_SharedValue] " + DemoClass.hasOwnProperty("_SharedValue"));  // true
console.log("  [SharedValue] " + DemoClass.hasOwnProperty("SharedValue"));  // true

console.log('DemoClass.prototype:');
console.log("  [Value] " + DemoClass.prototype.hasOwnProperty("Value")); // false - because "this" refers to the 
console.log("  [Dump] " + DemoClass.prototype.hasOwnProperty("Dump"));  // true
console.log("  [_SharedValue] " + DemoClass.prototype.hasOwnProperty("_SharedValue"));  // true
console.log("  [SharedValue] " + DemoClass.prototype.hasOwnProperty("SharedValue"));  // true

console.log('instance1:');
console.log("  [Value] " + instance1.hasOwnProperty("Value")); // true
console.log("  [Dump] " + instance1.hasOwnProperty("Dump")); // false
console.log("  [_SharedValue] " + instance1.hasOwnProperty("_SharedValue")); // false
console.log("  [SharedValue] " + instance1.hasOwnProperty("SharedValue")); // false
}}}

!Reflection

!!Getting the Name

{{{
this.constructor.name
}}}

!!Getting the source code

*Treating a function name (= global variable) like a string will output the source code.

{{{
alert(Foo);
alert(Foo.toString());
}}}

!Perverse stuff like '.call', '.apply' and the scope of 'this'

*[[Defining Functions Madness|./Files/DefiningFunctionsMadness.maff]]
*[[FunctionPerversion.maff|./Files/FunctionPerversion.maff]]

!Declaring

{{{
var hash = {};
hash['bob'] = 123;
hash['joe'] = 456;

var hash = {key1: 100, key2: 200, "key with spaces": 300};
hash.key3 = 400;
hash["key 4"] = 500;
}}}

*Note: Accessing items via index is not possible

!Iterating

{{{
for(var key in hash){
  alert("key " + key + " has value " + hash[key]);
}
}}}

!Analyzing

*hash.length will be 'undefined', because this is a shit language

{{{
Object.keys(hash).length
}}}
!If

* The simple double-equals operator will implicitely do strange type conversions
* There is a triple-equals operator which will by type safe

{{{
// All of these evaluate to 'true'!
var zero = 0;
console.log(zero == '');
console.log(zero == false);
console.log('' == false);
console.log('0' == false);
console.log('' == 0);
console.log(" \t\r\n" == 0);
console.log(null == undefined);

// And these do too!
if ({}) // ...
if ([]) // ...

// These don't

if (zero === '') // false
}}}

!Switch

{{{
switch (Eingabe) {
  case "1":
    alert("Sie sind sehr bescheiden");
    break;
  case "2":
    alert("Sie sind ein aufrichtiger Zweibeiner");
    break;
  case "3":
    alert("Sie haben ein Dreirad gewonnen");
    break;
  case "4":
    alert("Gehen Sie auf allen Vieren und werden Sie bescheidener");
    break;
  default:
    alert("Sie bleiben leider dumm");
    break;
}}}

!Ternary operator (Like If-Function in VB)

!!Assigning a Value
{{{
var elvisLives = (Math.PI > 4) ? "Yep" : "Nope";
}}}

!!Executing Code
{{{
var stop = false, age = 16;
(age > 18) ? location.assign("continue.html") : stop = true;

//You can also do more than one single operation per case, separating them with a comma:
var stop = false, age = 23;

(age > 18) ? (
    alert("OK, you can go."),
    location.assign("continue.html")
) : (
    stop = true,
    alert("Sorry, you are much too young!")
);
}}}
!As Base64

{{{
<html><head><title>DEMO: Clipboard Paste Image</title></head>

<img id="targetImage" />
<pre id="targetDump" style="white-space: pre-line;"></pre>

<script>

window.addEventListener(
	"paste", 
	function(e){ // : ClipboardEvent
		var items = e.clipboardData.items; // : DataTransferItemList
		for (var i = 0; i < items.length; i++) {
			var item = items[i]; // : DataTransferItem			
						
			if (item.type.indexOf("image/") == -1){ // filter
				continue;
			}
			
			var blob = item.getAsFile();	

			var dummyCanvas = document.createElement("canvas");
			var dummyContext = dummyCanvas.getContext('2d');        
			var dummyImage = new Image();
        
			dummyImage.onload = function(){      
				dummyCanvas.width = this.width;
				dummyCanvas.height = this.height;            
				dummyContext.drawImage(dummyImage, 0, 0);
				var dataUrl = dummyCanvas.toDataURL(item.type); // the dummy stack is needed for base 64 encoding
				
				// console.log(dataUrl);
				document.getElementById("targetImage").src = dataUrl;				
				document.getElementById("targetDump").textContent = dataUrl;				
			}

			dummyImage.src = window.URL.createObjectURL(blob); // triggers onload()
		} // next		
	}
);

</script>
</html>
}}}
!Weblinks

*http://www.mediaevent.de/javascript/
*http://de.selfhtml.org/javascript/sprache/index.htm
![[Arrays]]

{{{
var stringArray = new Array("Anita", "Bettina", "Christa", "Doris"); // is equal to the following line
var stringArray = ["Anita", "Bettina", "Christa", "Doris"]
}}}

![[Objects]]

{{{
var customObject = {
	PublicMember1: 'some string value',
	PublicMember2: 4711,
	PublicMember3: function() { alert('I am an object method.'); }
};
}}}

![[Tenary Operator|If, switch]]

{{{
var elvisLives = (Math.PI > 4) ? "Yep" : "Nope";
}}}

!Unary + Operator

Converts string to numeric.

{{{
+"2e1";   // 20
+"0xF";   // 15
+"10";   // 10
}}}
!See also

*DOM: [[Dot Notation, Square Bracket Notation|DOM]]
*Language Elements: [[Loops]]

!For

{{{
for (var i = 1; i <= 3; i++){
	// 1..2..3
}
}}}

!While

{{{
var i = 1;
while (i <= 3) {
	// 1..2..3
	i++;
	// 2..3..4
}
}}}

!Do-While

{{{
var i = 1;
do {
	// 1..2
  i++;
	// 2..3
} while (i<=3);
}}}

!Break

!!Simple

{{{
for (var i = 1; i <= 3; i++){
	break;
}
}}}

!!With Label (useful for nested loops)

{{{
MyOuterLabel: for (var i = 1; i <= 3; i++){
	for (var j = 1; j <= 3; j++){
		break MyOuterLabel;
	}
}
}}}

!Continue

{{{
for (var i = 1; i <= 3; i++){
	// 1..2..3
	if (i==2) continue;
	// 1..3
}
}}}

! See also

*document.[[getElementsByTagName]]()
*[[Hashtable]]
Common Mistake #3: Creating memory leaks

Memory leaks are almost inevitable JavaScript problems if you’re not consciously coding to avoid them. There are numerous ways for them to occur, so we’ll just highlight a couple of their more common occurrences.

Memory Leak Example 1: Dangling references to defunct objects

Consider the following code:

{{{
var theThing = null;
var replaceThing = function () {
  var priorThing = theThing;  // hold on to the prior thing
  var unused = function () {
    // 'unused' is the only place where 'priorThing' is referenced,
    // but 'unused' never gets invoked
    if (priorThing) {
      console.log("hi");
    }
  };
  theThing = {
    longStr: new Array(1000000).join('*'),  // create a 1MB object
    someMethod: function () {
      console.log(someMessage);
    }
  };
};
setInterval(replaceThing, 1000);    // invoke `replaceThing' once every second
}}}

If you run the above code and monitor memory usage, you’ll find that you’ve got a massive memory leak, leaking a full megabyte per second! And even a manual GC doesn’t help. So it looks like we are leaking longStr every time replaceThing is called. But why?

Let’s examine things in more detail:

Each theThing object contains its own 1MB longStr object. Every second, when we call replaceThing, it holds on to a reference to the prior theThing object in priorThing. But we still wouldn’t think this would be a problem, since each time through, the previously referenced priorThing would be dereferenced (when priorThing is reset via priorThing = theThing;). And moreover, is only referenced in the main body of replaceThing and in the function unused which is, in fact, never used.

So again we’re left wondering why there is a memory leak here!?

To understand what’s going on, we need to better understand how things are working in JavaScript under the hood. The typical way that closures are implemented is that every function object has a link to a dictionary-style object representing its lexical scope. If both functions defined inside replaceThing actually used priorThing, it would be important that they both get the same object, even if priorThing gets assigned to over and over, so both functions share the same lexical environment. But as soon as a variable is used by any closure, it ends up in the lexical environment shared by all closures in that scope. And that little nuance is what leads to this gnarly memory leak. (More detail on this is available here.)

Memory Leak Example 2: Circular references

Consider this code fragment:

{{{
function addClickHandler(element) {
    element.click = function onClick(e) {
        alert("Clicked the " + element.nodeName)
    }
}
}}}

Here, onClick has a closure which keeps a reference to element (via element.nodeName). By also assigning onClick to element.click, the circular reference is created; i.e.: element -> onClick -> element -> onClick -> element…

Interestingly, even if element is removed from the DOM, the circular self-reference above would prevent element and onClick from being collected, and hence, a memory leak.

Avoiding Memory Leaks: What you need to know

JavaScript’s memory management (and, in paticular, garbage collection) is largely based on the notion of object reachability.

The following objects are assumed to be reachable and are known as “roots”:

    Objects referenced from anywhere in the current call stack (that is, all local variables and parameters in the functions currently being invoked, and all the variables in the closure scope)
    All global variables

Objects are kept in memory at least as long as they are accessible from any of the roots through a reference, or a chain of references.

There is a Garbage Collector (GC) in the browser which cleans memory occupied by unreachable objects; i.e., objects will be removed from memory if and only if the GC believes that they are unreachable. Unfortunately, it’s fairly easy to end up with defunct “zombie” objects that are in fact no longer in use but that the GC still thinks are “reachable”.
https://www.freecodecamp.org/news/javascript-modules-explained-with-examples/

!The NodeList Type

A node list is an array-like collection of nodes. ''A node list is not an array!''
A node list may look like an array, but it is not. You can loop through the node list and refer to its nodes like an array. However, you cannot use Array Methods, like valueOf() or join() on the node list.

!Properties and Methods

|Property / Method|Description|h
|nodelist.item()|Returns the node at the specified index in a NodeList|
|nodelist.length|Returns the number of nodes in a NodeList|

!See also

*document.[[getElementsByTagName]]

!External Links

*w3school: [[HTML DOM Node List|http://www.w3schools.com/js/js_htmldom_nodelist.asp]]
!Creating

We have...
*"object literals"
*The built-in "new Object()" constructor
*Custom "new MyType()" constructors
*The Object.create() method.

|Literal|new Object() constructor|Own constructor|h
|{{{o = {}}}<br>{{{ myProperty: "value",}}}<br>{{{ myMethod(){ return "result"; }}}}<br>{{{}}}}|{{{var o = new Object();}}}<br>{{{o.myProperty = "value";}}}<br>{{{o.myMethod = function(){ return "result"; };}}}|{{{function MyType() {}}}<br>{{{ this.myProperty = "value";}}}<br>{{{ this.myMethod = function(){ return "result"; };}}}<br>{{{}}}}<br>{{{var o = new MyType();}}}|

!Analyzing

!!Getting The Type

{{{
o.constructor.name
}}}

...will return "Object" or "MyType"

!Inheritance

*The ''prototype'' property of a type defines it's base type

{{{
function Animal() {
  this.Eat = function() { alert("Yum.") }
  this.OverrideMe = function() { alert("Override me!") }
};

function Cat(){
	this.Speak = function() { alert("Meow.") }
  this.OverrideMe = function() { alert("Done!") }
};

Cat.prototype = new Animal();

var teddy = new Cat();

teddy.Eat();
teddy.Speak();
teddy.OverrideMe();
}}}

!Weblinks

*https://www.w3schools.com/js/js_object_definition.asp
*https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
*http://de.selfhtml.org/javascript/sprache/objekte.htm
*https://stackoverflow.com/questions/1479319/simplest-cleanest-way-to-implement-a-singleton-in-javascript
!Weblinks

*http://de.selfhtml.org/javascript/sprache/operatoren.htm
Common Mistake #5: Inefficient DOM manipulation

JavaScript makes it relatively easy to manipulate the DOM (i.e., add, modify, and remove elements), but does nothing to promote doing so efficiently.

A common example is code that adds a series of DOM Elements one at a time. Adding a DOM element is an expensive operation. Code that adds multiple DOM elements consecutively is inefficient and likely not to work well.

One effective alternative when multiple DOM elements need to be added is to use document fragments instead, thereby improving both efficiency and performance.

For example:

{{{
var div = document.getElementsByTagName("my_div");

var fragment = document.createDocumentFragment();

for (var e = 0; e < elems.length; e++) {  // elems previously set to list of elements
    fragment.appendChild(elems[e]);
}
div.appendChild(fragment.cloneNode(true));
}}}

In addition to the inherently improved efficiency of this approach, creating attached DOM elements is expensive, whereas creating and modifying them while detached and then attaching them yields much better performance.
!Script
{{{
<script type="text/javascript">
function foo() {
  var w = 540, h = 480, x = 50, y = 50;

  if (screen) {
    sw = screen.availWidth;
    sh = screen.availHeight;
    w = sw * 0.8;
    h = sh * 0.8;
    x = (sw - w) / 2;
    y = (sh - h) / 2;
  }

  tWindow = window.open(
    "",
    "Druckvorschau",
    "menubar=no,status=no,location=no,toolbar=no,scrollbars=yes,resizable=yes,left=" + x + ",top=" + y + ",width=" + w + ",height=" + h + ")"
  )

  var myH1 = document.createElement("h1");
  var myText = document.createTextNode("Eine sehr dynamische Seite");
  myH1.appendChild(myText);

  tWindow.document.appendChild(myH1)
}
</script>
}}}
!Aufruf
{{{
<input type="button" value="Foo" onclick="foo();" />
}}}
A surprisingly high percentage of JavaScript developers fail to fully understand, and therefore to fully leverage, the features of prototypal inheritance.

Here’s a simple example. Consider this code:

{{{
BaseObject = function(name) {
    if(typeof name !== "undefined") {
        this.name = name;
    } else {
        this.name = 'default'
    }
};
}}}

Seems fairly straightforward. If you provide a name, use it, otherwise set the name to ‘default’; e.g.:

{{{
var firstObj = new BaseObject();
var secondObj = new BaseObject('unique');

console.log(firstObj.name);  // -> Results in 'default'
console.log(secondObj.name); // -> Results in 'unique'
}}}

But what if we were to do this:

{{{
delete secondObj.name;
}}}

We’d then get:

{{{
console.log(secondObj.name); // -> Results in 'undefined'
}}}

But wouldn’t it be nicer for this to revert to ‘default’? This can easily be done, if we modify the original code to leverage prototypal inheritance, as follows:

{{{
BaseObject = function (name) {
    if(typeof name !== "undefined") {
        this.name = name;
    }
};

BaseObject.prototype.name = 'default';
}}}

With this version, BaseObject inherits the name property from its prototype object, where it is set (by default) to 'default'. Thus, if the constructor is called without a name, the name will default to default. And similarly, if the name property is removed from an instance of BaseObject, the prototype chain will then be searched and the name property will be retrieved from the prototype object where its value is still 'default'. So now we get:

{{{
var thirdObj = new BaseObject('unique');
console.log(thirdObj.name);  // -> Results in 'unique'

delete thirdObj.name;
console.log(thirdObj.name);  // -> Results in 'default'
}}}
!arguments

*Can be used in functions
*Holds all arguments as array
*The caller can pass as many arguments as he wants (more than in the signature)

!See Also

*DOM: [[Root Objects]]

!External Links

*SelfHtml: [[Objekte|http://de.selfhtml.org/javascript/objekte/index.htm]]
!See Also

*Language Elements: [[Reserved Words]]

As explained in our JavaScript Hiring Guide, “strict mode” (i.e., including 'use strict'; at the beginning of your JavaScript source files) is a way to voluntarily enforce stricter parsing and error handling on your JavaScript code at runtime, as well as making it more secure.

While, admittedly, failing to use strict mode is not a “mistake” per se, its use is increasingly being encouraged and its omission is increasingly becoming considered bad form.

Here are some key benefits of strict mode:

* Makes debugging easier. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions, alerting you sooner to problems in your code and directing you more quickly to their source.

* Prevents accidental globals. Without strict mode, assigning a value to an undeclared variable automatically creates a global variable with that name. This is one of the most common errors in JavaScript. In strict mode, attempting to do so throws an error.

* Eliminates this coercion. Without strict mode, a reference to a this value of null or undefined is automatically coerced to the global. This can cause many headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a a this value of null or undefined throws an error.

* Disallows duplicate property names or parameter values. Strict mode throws an error when it detects a duplicate named property in an object (e.g., var object = {foo: "bar", foo: "baz"};) or a duplicate named argument for a function (e.g., function foo(val1, val2, val1){}), thereby catching what is almost certainly a bug in your code that you might otherwise have wasted lots of time tracking down.

* Makes eval() safer. There are some differences in the way eval() behaves in strict mode and in non-strict mode. Most significantly, in strict mode, variables and functions declared inside of an eval() statement are not created in the containing scope (they are created in the containing scope in non-strict mode, which can also be a common source of problems).

* Throws error on invalid usage of delete. The delete operator (used to remove properties from objects) cannot be used on non-configurable properties of the object. Non-strict code will fail silently when an attempt is made to delete a non-configurable property, whereas strict mode will throw an error in such a case.
{{{
         0123456789A
var x = 'Hello World'
}}}

|x.indexOf('not there')|-1||
|x.indexOf('ell')|1||
|x.substr(1, 4); |'ello'|startIndex, numberOfChars|
|x.substring(1, 4); |'ell'|startIndex, endIndex (NOT including!)|

!Weblinks

*http://www.w3schools.com/jsref/jsref_obj_string.asp
*http://de.selfhtml.org/javascript/objekte/string.htm
!The Style Type

*A Style object is a facade to access CSS style values of an [[Element]]
*Unfortunately, the names are sometimes different from original CSS attributes.

Examples
{{{
document.getElementById("myH1").style.backgroundColor = "red";
var allStyles = document.getElementsByTagName("STYLE");
}}}

!External Links

*w3schools: [[HTML DOM Style Object|http://www.w3schools.com/Jsref/dom_obj_style.asp]]
{{{
if (window.getComputedStyle) {
  var s = window.getComputedStyle(lis[i], "");
} else if (lis[i].currentStyle) {
  var s = lis[i].currentStyle;
}
}}}
!Declaring

{{{
var GlobalString1 = "Foo"; // Because we are outside of any function the scope becomes global, in spite of using 'var'.

function SomeFunction() {
	var localString = "Bar"; // 'var' makes the scope local
	GlobalString2 = "Batz"; // Naked assignemts make glabal variables
	var i=1, x=2, y=3; // One-line declaration of multiple variables
}
}}}

!There Is No Block-Level Scope!

As discussed in our JavaScript Hiring Guide, a common source of confusion among JavaScript developers (and therefore a common source of bugs) is assuming that JavaScript creates a new scope for each code block. Although this is true in many other languages, it is not true in JavaScript. Consider, for example, the following code:

{{{
for (var i = 0; i < 10; i++) {
  /* ... */
}
console.log(i);  // what will this output?
}}}

If you guess that the console.log() call would either output undefined or throw an error, you guessed incorrectly. Believe it or not, it will output 10. Why?

In most other languages, the code above would lead to an error because the “life” (i.e., scope) of the variable i would be restricted to the for block. In JavaScript, though, this is not the case and the variable i remains in scope even after the for loop has completed, retaining its last value after exiting the loop. (This behavior is known, incidentally, as variable hoisting).

It is worth noting, though, that support for block-level scopes is making its way into JavaScript through the new let keyword. The let keyword is already available in JavaScript 1.7 and is slated to become an officially supported JavaScript keyword as of ECMAScript 6.
!Properties and Methods

|Property / Method|Description|h
|console.log(string)|Writes text to the console.|
!Set

{{{
  // temporary (session) cookie
  document.cookie = 'FooName = FooValue';

  // persistent cookie
  document.cookie = 'FooName = I will disappear after 2 seconds; Expires = ' + new Date(new Date().setTime(new Date().getTime() + 2000)).toGMTString();

  // unusual, but possible: Value without a name. - exists once per document (= will be overwritten on multiple assignments)
  document.cookie = 'Value without the name'; 
}}}

!Read

{{{
function getCookieByKey(name) {
  var parts = document.cookie.split(name + "=");
  if (parts == null) {
    return '';
  } else if (parts.length == 2) {
    return parts.pop().split(";").shift();
  } else {
    return '';
  }
};
}}}

!Iterating Specifig Tags

{{{
function disableAllButtons(){  
  var elements = document.getElementsByTagName('button');  
  for (var i = 0; i < elements.length; i++) {
    elements[i].disabled = true;
  }
}
}}}
!Reading The Query String

This will store the arguments from the query string into 'arguments' which is a dictionary of (String, String).

{{{
var arguments = {};
var namesAndValues = document.location.search.substring(1).split('&');
for (var i in namesAndValues) {
  var nameAndValue = namesAndValues[i].split('=', 2);
  arguments[nameAndValue[0]] = unescape(nameAndValue[1]);
}
}}}

!!Explaination

*document.location.search will give the part after the '?' including it. E.g. {{{?foo=1&bar=2&batz=3}}}
*.substring(1) will drop the '?'
{{{
function popupWindow(url, name, w, h) {
  if (w == undefined) w = 580;
  if (h == undefined) h = 540;
  var left = (screen.width/2) - (w/2) + screen.left;
  var top = (screen.height/2) -(h/2) + screen.top;
  var win = window.open(url, name, 'top=' + top + ',left=' + left + ',width=' +w + ',height=' +h + ',copyhistory=no,directories=no,menubar=no,location=no,resizable=no,scrollbars=yes,status=no,toolbar=no');
  win.focus();
}
}}}
*Do NOT compare the meaning of "this" to OO languages like .net!
*"this" is not assigned at design time, but at runtime (during a call)
*"this" refers to the "owner" of a function
**if no other rue applies, it's the [[window]] object
*the "owner" can change, if a function is ''copied'', which can happen implicitely!
**e.g. when registering event listeners using the onclick-Property, the listener function will be copied an the new owner will be the dom-element!

{{{
Game.prototype.restart = function () {
  this.clearLocalStorage();
  this.timer = setTimeout(function() {
    this.clearBoard();    // what is "this"?
  }, 0);
};
}}}

"Uncaught TypeError: undefined is not a function"

The reason you get the above error is because, when you invoke setTimeout(), you are actually invoking window.setTimeout(). As a result, the anonymous function being passed to setTimeout() is being defined in the context of the window object, which has no clearBoard() method.

A traditional, old-browser-compliant solution is to simply save your reference to this in a variable that can then be inherited by the closure; e.g.:

{{{
Game.prototype.restart = function () {
  this.clearLocalStorage();
  var self = this;   // save reference to 'this', while it's still this!
  this.timer = setTimeout(function(){
    self.clearBoard();    // oh OK, I do know who 'self' is!
  }, 0);
};
}}}

Alternatively, in newer browsers, you can use the bind() method to pass in the proper reference:

{{{
Game.prototype.restart = function () {
  this.clearLocalStorage();
  this.timer = setTimeout(this.reset.bind(this), 0);  // bind to 'this'
};

Game.prototype.reset = function(){
    this.clearBoard();    // ahhh, back in the context of the right 'this'!
};
}}}

!!Meaning

!!!In functions

{{{
Value = 'Global';

function DeclaredFunction(p) {
	this.Value = 'ActuallyGlobal!';
	
	var subFunction = function() {
		this.Value = 'EvenHereGlobal!';
	}
	
	subFunction();	
};
}}}

!!!In event handlers

*'this' is the ''sender''!
*you can explicitely change the meaning of "this" by using ''bind'' (see 2nd example)

{{{
var Example = function(foo,bar){
    this.foo = foo;
    this.bar = bar;
};
Example.prototype.SetEvent = function(){
    this.bar.onclick = this.ClickEvent;
};
Example.prototype.ClickEvent = function(){
    console.log(this.foo); // logs undefined because 'this' is really 'this.bar'
};
}}}

{{{
this.bar.onclick = this.ClickEvent.bind(this);
}}}

!!!In Objects

*"this" is (unlike functions) the instance (as expected)

{{{
Value = 'Global';

var objectInstance = {
	Value : 'InitializedByObject',
	ModifyValue : function() { this.Value = 'ModifiedByObject';}
}

objectInstance.ModifyValue();

alert(Value); // Shows "Global"
}}}
!Properties and Methods

|Property / Method|Description|h
|window.getComputedStyle(element,pseudoElement)|Get the actual CSS style of the element.|