window.alert("Hello World!");
window.alert("Hello World!");
window
alert
()
"Hello World!"
als FunktionsparameterProgrammcode besteht aus…
vgl. Text – Abschnitt – Satz – Satzglied –
Wort – Morphem – Buchstabe
window.alert("Hello World!");
var one = 1;
var two = 2;
var three = one + two,
four = 4,
result = three + four;
alert(result);
Globale Variablen sind Eigenschaften des globalen Objekts window
:
var one = 1;
alert(one); // 1
alert(window.one); // 1
Gundregel: Globale Variablen vermeiden.
JSLint/JSHint warnt vor globalen Variablen.
var ausgabe;
for (var i = 1; i <= 10; i++) {
if (i % 2 == 0) {
ausgabe = "gerade";
} else {
ausgabe = "ungerade";
}
alert(i + " ist " + ausgabe);
}
var name = "";
while (name == "") {
name = window.prompt("Wie ist ihr Name?");
}
Abstrakte Syntaxbäume (AST)
window.alert("Hello World!");
Program
ExpressionStatement
CallExpression
MemberExpression
Identifier: window
Identifier: alert
arguments:
Literal: "Hello World!"
Funktionsausdruck (Function Expression)
var add = function (a, b) {
return a + b;
};
var sum = add(2, 3);
Funktionsdeklaration (Function Declaration)
var sum = add(2, 3);
function add (a, b) {
return a + b;
}
Viele Fallstricke, daher besser vermeiden.
var add = function (a, b) {
return a + b;
};
var sum = add(2, 3);
Einfacher und konsistenter
Schreiben Sie eine Funktion, die eine positive ganze Zahl entgegennimmt und die Summe der ganzen Zahlen von 1 bis zur gegebenen Zahl zurückgibt.
Beispiel: 5
1 + 2 + 3 + 4 + 5 = 15
var sum = function (n) {
var result = 0;
for (var i = 1; i <= n; i++) {
result += i;
}
return result;
};
alert( sum(5) );
var max = function (list) {
var i, l = list.length, biggest = 0, candidate;
for (i = 0; i < l; i++) {
candidate = list[i];
if (candidate > biggest) {
biggest = candidate;
}
}
return biggest;
};
alert( max( [65, 24, 98, 44] ) ); // 98
alert(biggest); // ReferenceError: max is not defined
undefined
, null
true
, false
0
, 1
, 2
, 3.75
, -56.1
, 1e6
, 0x10
"Hühnerstall"
, 'Motorrad'
Verhalten sich wie Objekte, besitzen Methoden:
(2.5172).toFixed(2) // 2.52
"Hello World".indexOf("World") // 6
"Hello World".charAt(6) // "W"
"Hello World".substring(6, 11) // "World"
"Hello World".replace("World", "there") // "Hello there"
Listen von Werten beliebigen Typs
var array = [1, 2, 3];
alert(array); // 1,2,3
alert(array.join(',')); // 1,2,3
alert(array.length); // 3
alert(array[0]); // 1
alert(array.indexOf(3)); // 2
var array = [1, 2, 3];
// Iteration mit for-Schleife
for (var i = 0, l = array.length; i < l; i++) {
alert(i + ": " + array[i]);
}
// Iteration mit Callback-Funktion
array.forEach(function (el, i, array) {
alert(i + ": " + el);
});
// Listenoperationen (map, filter, reduce…)
var newArray = array.filter(function (el) {
return el > 1;
});
alert(newArray); // 2,3
var objekt = {
eigenschaft: wert,
property: value,
…
};
alert(objekt.eigenschaft);
objekt.eigenschaft = …;
objekt.neueEigenschaft = …;
delete objekt.eigenschaft;
Hashes / Hash Maps / assoziative Arrays
var person = {
name: 'Mathias',
postcode: 44793,
employer: '9elements',
languages: ['JavaScript', 'Ruby'],
greet: function () {
alert('Hallo von ' + this.name);
}
};
person.greet();
Eines der mächtigsten Features von JavaScript
JavaScript Object Notation
Untermenge von JavaScript
[
{ "name": "Mathias", "postcode": 44793,
"languages": [ "JavaScript", "Ruby" ] },
{ "name": "Lena", "postcode": 10711,
"languages": [ "Objective-C", "Java" ] }
]
JSON.stringify()
und JSON.parse()
<script>
window.alert("Hello World!");
</script>
<script src="script.js"></script>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Titel</title>
<link rel="stylesheet" src="style.css">
</head>
<body>
<h1>Titel</h1>
<p>Inhalt</p>
<script src="script.js"></script>
</body>
</html>
»Put Stylesheets at the Top,
Put Scripts at the Bottom«
window
)window.document
)<p id="content">Hello World</p>
var el = document.getElementById('content');
alert(el.nodeName); // P
alert(el.childNodes.length); // 1
alert(el.innerHTML); // Hello World
el.innerHTML = 'Hallo Welt!';
var strong = document.createElement('strong');
var text = document.createTextNode('Hallo Welt!');
strong.appendChild(text);
el.appendChild(strong);
$("#content")
content
jQuery
-Objekt zurück$()
ist kurz für jQuery()
<p id="content">Hello World</p>
<script>
alert( $('#content').length ); // 1
alert( $('#content')[0] ); // [object HTMLParagraphElement]
</script>
jQuery wrappt Elementobjekte in eine Listenobjekt mit vielen nützlichen Methoden
<p id="content">Hello World</p>
alert( $('#content').html() ); // Hello World
$('#content').html('Hallo Welt!');
$('#content').click(function () {
$(this).html(text);
});
ajax()
oder getJSON()
html()
oder append()
html()
, click()
alert('…');
und console.log('…');
Objektorientierte und funktionale Programmierung
var modul = (function () {
var privateVariable = 1;
var privateFunktion = function () {…};
return {
öffentlicheEigenschaft: 1,
öffentlicheMethode: function () {…}
};
})();
Object.prototype, Function.prototype, Array.prototype, String.prototype, HTMLDocument.prototype, HTMLElement.prototype
usw.Wie erzeuge ich ein Objekt, das an ein anderes delegiert?
prototype
-Eigenschaft und der new
-Operator (ES3)Object.create()
(ES5)Wie bekomme ich den Prototyp eines Objekts?
obj.constructor.prototype
(ECMAScript 3)Object.getPrototypeOf(obj)
(ES5)obj.__proto__
(ES6, bereits viele Browser)In der ECMAScript-Spezifikation [[Prototype]]
genannt.
var o1 = { name: 'o1' };
// Erzeuge ein leeres Objekt, das o1 als Prototyp hat
var o2 = Object.create(o1);
// o2 hat keine Eigenschaft »name«, delegiert an o1
alert(o2.name); // o1
alert(o2.hasOwnProperty("name")); // false
o2.name = "o2";
// o2 hat nun eine Eigenschaft »name«
alert(o2.name); // o2
alert(o2.hasOwnProperty("name")); // true
Ein Objekt hat einen Prototyp. Der Prototyp hat einen Prototyp usw. bis zum obersten Prototyp Object.prototype
.
var o1 = { name: 'o1' };
var o2 = Object.create(o1);
o2.__proto__ === o1
o1.__proto__ === Object.prototype
o2 → o1 → Object.prototype
var str = "Hallo Welt!";
str.__proto__ === String.prototype
String.prototype.__proto__ === Object.prototype
str → String.prototype → Object.prototype
Die Kern-Prototypen sind erweiterbar:
Array.prototype.max = function () {
var i, l = this.length, biggest = 0, candidate;
for (i = 0; i < l; i++) {
candidate = this[i];
if (candidate > biggest) {
biggest = candidate;
}
}
return biggest;
};
alert([6, 2, 9, 3].max());
Konflikte sind vorprogrammiert
Konstruktoren, Prototypen, Instanzen
var Person = function (name) {
this.name = name;
};
Person.prototype.greet = function () {
alert("Hello, my name is " + this.name + "!");
};
var alice = new Person("Alice");
alice.greet();
alice → Person.prototype → Object.prototype
var Person = function (name) {
this.name = name;
};
var Person = function (name) {
this.name = name;
};
Konvention: Konstruktoren beginnen mit einem Großbuchstaben, um sie von normalen Funktionen zu unterscheiden
Person.prototype.greet = function () {
alert("Hello, my name is " + this.name + "!");
};
prototype
var alice = new Person("Alice");
alice.greet();
new
-Operator erzeugt eine InstanzKonstruktor.prototype
als Prototyp hatalice.greet
kommt vom Prototypenthis
hat viele Bedeutungenwindow
var f = function () { alert(this); };
var o = { f: f };
f(); // window bzw. undefined im Strict-Mode
o.f(); // o
this
nicht plötzlich window
ist.Schreiben Sie eine Klasse Robot
, die die Methoden stepForward
, turnLeft
, turnRight
und showLog
implementiert. Die ersten drei speichern die Bewegung intern und geben eine Bestätigung aus. Die Methode showLog
gibt auf der Konsole eine Liste aller aufgezeichneten Bewegungen aus. (Keine Visualisierung.)
Robot
Robot.prototype.methode = function () {…};
this.log = [];
this.log.push('action');
console.log(this.log.join(', '));
prototype
und new
?The pseudoclassical form can provide comfort to programmers who are unfamiliar with JavaScript, but it also hides the true nature of the language.
var plusTwo = function (addend) {
return addend + 2;
};
var createMultiplier = function (f1) {
return function (f2) {
return f1 * f2;
};
};
var timesTwo = createMultiplier(2);
var compose = function (f1, f2) {
return function (arg) {
return f1(f2(arg));
};
};
var plusTwoTimesTwo = compose(timesTwo, plusTwo);
alert(plusTwoTimesTwo(2)); // 8
on
, off
, trigger
, listenTo
attributes
-Objektget()
und set()
change
-Events
// Subclassing mit extend()
var Car = Backbone.Model.extend();
// Instanz mit vordefinierten Attributen
var car = new Car({
name: 'DeLorean DMC-12',
manufactured: 1981
});
// Attribut lesen
console.log( car.get('name') );
// Attribute schreiben
car.set('manufactured', 1982); // Ein Attribut
car.set({ manufactured: 1982 }); // Mehrere Attribute
console.log( car.get('manufactured') );
urlRoot
angeben, z.B. cars
model.fetch()
erzeugt ein GET /cars/:id
model.save()
erzeugt ein POST/PUT /cars/:id
model.destroy()
erzeugt ein DELETE /cars/:id
var Car = Backbone.Model.extend({
urlRoot: '/cars'
});
model.fetch().then(successCallback, failCallback);
model.save().then(successCallback, failCallback);
model.destroy().then(successCallback, failCallback);
car.on('change', function (car, options) {
console.log('Some attribute changed');
});
car.on('change:manufactured', function (car, newValue, options) {
console.log('manufactured changed:', newValue);
});
car.set({ manufactured: 1982 });
add
, remove
and reset
each
, map
, reduce
, sort
, filter
…)
var Car = Backbone.Model.extend();
var Cars = Backbone.Collection.extend({ model: Car });
var cars = new Cars([
{ name: 'DeLorean DMC-12', manufactured: 1981 },
{ name: 'Chevrolet Corvette', manufactured: 1953 }
]);
alert( cars.at(0).get('name') ); // DeLorean DMC-12
cars.push({ name: 'VW Scirocco', manufactured: 1974 });
alert( cars.length ); // 3
this.el
, this.$el
)
var CarView = Backbone.View.extend({
initialize: function () {
// Überwache Model-Änderungen: Neu rendern
this.listenTo(this.model, 'change', this.render);
},
render: function () {
this.$el.html('Name: ' + this.model.get('name'));
}
});
var carView = new CarView({
model: car,
el: $('#car')
});
carView.render();
Views übersetzen Modeldaten in HTML mithilfe eines Templates
Modeldaten: | { message: 'Hello World' } |
---|---|
Template: | <p>{{message}}</p> |
Ausgabe: | <p>Hello World</p> |
Der erzeugte HTML-Code wird ins DOM eingefügt
var CarView = Backbone.View.extend({
template: _.template('Name: {{name}}'),
initialize: function () {
this.listenTo(this.model, 'change', this.render);
},
render: function () {
this.$el.html(this.template(this.model.attributes));
}
});
var carView = new CarView({
model: car,
el: $('#car')
});
carView.render();
this.listenTo(this.model, 'change', this.changeHandler)
Backbone.js gives structure … by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
– backbonejs.org
Das ist alles (plus Routing).
Auf Basis von Backbone
var Car = Backbone.Model.extend({…});
var CarView = Backbone.View.extend({…});
main-content
, sidebar
)Router ⇢ Dispatcher → Controller → Model/View
⇢ | benachrichtigt |
---|---|
→ | erzeugt |
routes.js
routes.rb
in Rails
match('', 'homepage#show');
match('cars', 'cars#index');
match('cars/:id', 'cars#show');
/
– Controller homepage
– Action show
/cars
– Controller cars
– Action index
/cars/:id
– Controller cars
– Action show
var CarsController = Controller.extend({
// cars/1
// cars/:id
show: function (params) {
this.car = new Car({ id: params.id });
this.view = new CarView({ model: this.car });
}
});
this.model
/this.collection
)this.view
)dispose
-Methode als Destructormediator.publish()
, mediator.subscribe()
this.subscribeEvent()
, this.publishEvent()
mediator.user
require()
Module asynchron laden und dann Code ausführen
require(dependencies:Array, callback:Function)
require(['application'], function(Application) {
var app = new Application();
app.initialize();
});
define()
Module mit Abhängigkeiten definieren
define(name:String, dependencies:Array, callback:Function)
define(dependencies:Array, callback:Function) // Name implizit
controllers/hello_world_controller.js
define(
[
'controllers/base/controller',
'models/hello_world', 'views/hello_world_view'
],
function (Controller, HelloWorld, HelloWorldView) {
'use strict';
var HelloWorldController = Controller.extend({ … });
return HelloWorldController;
}
);
define()
pro Dateicontrollers/hello_world_controller
render
-Methodeevents
und listen
autoRender
und container
subview
-MethodelocalStorage