Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

JavaScript blast

2.
Thomas Bahn● Graduated in mathematics, University of Hannover● Developing in Java and RDBMS since 1997● Dealing with Notes/Domino since 1999: development, administration, consulting and trainings● Frequent speaker at technical conferences about IBM Lotus Notes/Domino and author for THE VIEW tbahn@assono.de www.assono.de/blog +49/4307/900-401www.assono.de Page 2

3.
Declaration of Variables● Simple variable declaration: var name;● Variable declaration with value assignment: var name = value;● SSJS only (Server Side JavaScript): typed variable declaration: var name : type = value;● Best Practice: Declare all variables at the top of a function (like you should in LotusScript, but not in Java, because of the scopes, covered later).www.assono.de Page 3

6.
String Object● Useful methods of the String object - toUpperCase(), toLowerCase(): like LotusScript - charAt(position): character at given position - indexOf(searchString): position of searchString - indexOf(searchString, startPos): Position of searchString after startPos - lastIndexOf(suchstring): ditto, but backwards - substring(start, end): part of string - slice(start, end): like substring, but when end is negative, length is added (counts from end) - split(separator): splits string into an arraywww.assono.de Page 6

7.
String Concatenation● + and += are fast in all browsers, but IE7 (and older)● array.join is fast in IE7, but slower than + or += in all other browsers.● string.concat is mostly slower then simple + or +=.www.assono.de Page 7

8.
String Trimming● You can trim strings with for loops and charAt to determine the first and the last non-whitespace char and using slice to cut the result out off the string.● Or you can use regular expressions, e.g. if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^s+/, ""). replace(/s+$/, ""); } }● Whats faster depends on the amount of whitespace at the start and at the end of the string.www.assono.de Page 8

14.
Boolean● ! Logical Not● && Logical And● || Logical Or● Lazy evaluation: calculate only, if (still) necessary● In LotusScript, both sides of And and Or are evaluated, even if not necessary for the result.● Example: var a = 1; true || (a = 2); a ⇒ a is still equal 1www.assono.de Page 14

16.
Heads up: Test, if Variable is Defined● Seen often, but (over-)simplified: if (a) { … }● Caution: the code block { … } will be executed, if a is undefined, but also, if its equal to false, null, "" or 0● Better way: if (typeof a !== "undefined") { … }www.assono.de Page 16

22.
Arrays● Arrays are objects (inherit from Object)● Their length attribute is always the greatest index plus 1● length can also be set. - setting a larger number enlarges the array by appending undefined values - setting it to a smaller number shortens the array by cutting surplus elements● Array literals: ["one", "two", "three"]● You can use strings like character arrays: var text = "abcd"; text[2] ⇒ "c"www.assono.de Page 22

23.
Arrays (cont.)● Useful methods of the Array object: - push and pop, to use an array as a stack - sort: sorts array - join(separator): joins the elements to a string - slice(start, end): returns part of array, doesnt change the source array - splice(start, end, additional parameters): returns part of array, replaces it by the additional parameters or removes it without leaving a gapwww.assono.de Page 23

27.
Loops and Conditions● for, while and do-while loops perform similarly.● Avoid for-in loop whenever possible.● Reduce the number of iterations and the amount of work done in one iteration when possible.● Tune if-else if-else if-...-else chains by putting the conditions in the “right” order: move most frequently met conditions up to the front.● Consider using look-up tables: instead of a long switch statement, put the results into an array once and access the results by index.www.assono.de Page 27

28.
Heads up: with● Instead of accessing object members through the dot operator (obj.member) you can use with, especially if you want to access a lot of members of one object: with (obj) { member = "value"; }● If obj contains an attribute with the name member, its value will be set to "value" …● … else a new global variable member is created and "value" is assignedwww.assono.de Page 28

29.
Heads up: Semicolon Insertion● When an error occurs, the JavaScript interpreter inserts an semicolon at the end of a line and retries the execution.● Example: return { state: "ok" };● will return undefined, because a semicolon will be inserted after the return statement.● This behavior can mask errors.www.assono.de Page 29

30.
Error Handling with try – catch – finally● Just try it... and react on errors● Example: try { // an error could occur in here } catch (e) { // e is an Error object // do something about this error alert(e.name + ": " + e.message); } finally { // will be executed regardless of an // error, e.g. to free up ressources }● Only one catch-block (not many as in Java)www.assono.de Page 30

31.
Error Handling (cont.)● throw creates (fires) a new error● Examples: throw new Error("Message"); throw { name: "Name", message: "Message" }● window.onerror = myErrorHandler Sets error handling function in the browser, which will be called on every error afterwards● Thus you can install a global error logging and e.g. use AJAX to send an error log to the server.www.assono.de Page 31

32.
Heads up: References● Variables contain references● Parameters are passed to functions as references, not values.● If a parameter is not an object: - If the function assigns a new value to it, its only modified in the function, the calling code still only sees the old value.● If a parameter is an object: - If the function assigns a new object to it, its only modified in the function. The calling code still has access to the old object (and only to the old one). - Caution: If the function modifies object members, the object is changed for the calling code, too!www.assono.de Page 32

34.
Functions – Data – Objects● Functions are first-class objects! - They can have attributes and methods (i.e. inner functions).● Functions are data! - They can be stored in variables. - They can be passed to and returned by functions.● This cant be done in LotusScript, nor Java.● JavaScript is a functional language.www.assono.de Page 34

40.
Configuration Object● Tip: Use an object as (only) parameter, which contains all needed information.● Benefits: - You can always add new “inner parameters” without changing existing code calling this function. - You have “named parameters”. - Defaults should be used for all parameters not in the value object.www.assono.de Page 40

42.
Heads up: Function Results● A function without return returns undefined.● A function with return x returns x.● A constructor (details follow) without return returns a reference to the new object.● Caution: A constructor with return x returns x, if x is an object, else it returns the new object.www.assono.de Page 42

44.
Function Calls and this● Functions always run in a context.● this points to the current context.● An inner function cannot access its outer functions current context.● Convention: var that = this;● There are (at least) 4 ways to call functions:www.assono.de Page 44

45.
Function Calls (cont.)● 1st Functional form f(args): f will be executed in the global context.● 2nd Method form obj.f(args) and obj["f"](args): f will be executed with obj as context.● 3rd Constructor form new f(args): f runs in the context of the newly created, empty object, which will be returned by the function.● 4th f.apply(obj, args) and f.call(obj, arg1, arg2, ...): f runs in the context of obj. f doesnt need to be method of obj!www.assono.de Page 45

46.
Function Calls (cont.)● Caution: If you want to call a method of an object, but forget to specify the object, no error will be thrown and the method will be executed in the global context.www.assono.de Page 46

48.
Anonymous Functions● Used as parameters for other functions - when they are used only for this purpose - in the called functions they have a name: the name of the parameter● Example: call-back functions for Ajax calls, for setTimeout() or setInterval(): setTimeout( function() { alert(new Date()); }, 1000 )● For immediate, one-time execution, e.g. for initializingwww.assono.de Page 48

53.
“eval is evil”● Performance is bad.● Security: use only on absolutely trustworthy argument● Same considerations apply to new Function(args, body)● and to call setInterval and setTimeout with strings instead of function literals.www.assono.de Page 53

55.
Heads up: Scopes● Scope: Where is a variable visible and accessible?● There are only two kinds of scopes in JavaScript: - global scope - function scope● In particular, there is no block scope like in Java● Caution: Accessing an undeclared variable doesnt throw an error, but creates a new, global variable (think about typos).● Example: function () { a = 1; // without var: a is global! }www.assono.de Page 55

58.
Scopes (cont.)● JavaScript has a lexical scope.● The context of a function is created, when the function is defined, not when it is executed.www.assono.de Page 58

59.
Speed of Data Access● Literal values are fastest to access● Local variables are second.● Array items and object members are considerably slower.● Going up the scope chain is costly.● This is true for the prototype chain, too.● Best Practice: Create local variables to cache array items, object members, global variables or those variables “up the chain”, especially when handling DOM/BOM objects.www.assono.de Page 59

60.
Context● Context: “place” where variables and members “live”● Each object has it own context.● Plus there is a global context.● Functions have access to the attributes and method of the context, in which they have been defined …● … and all the way up to the global context.www.assono.de Page 60

64.
Closures● Even after an outer function has been completed, inner functions can access its attributes and functions.● This feature is called Closure.● Most unusual concept of JavaScript for LotusScript and Java developers.● But Closures are probably the single most important feature of the JavaScript language!www.assono.de Page 64

65.
Heads up: Reference, not Copy of Value● f has a reference to o, not a copy of its value at definition time.● When o is modified after f has been defined, this effects f.● Decoupling with mediator function: a function, which is defined and immediately executed.www.assono.de Page 65

68.
Objects● Objects are sets of name-value pairs.● Names are Strings.● Values can be of any type.● Like lists in LotusScript● Correlate to “associative arrays” or “hash maps” in other programming languageswww.assono.de Page 68

72.
Constructors● Functions can be used as constructors (with new): function Factory(location) { this.location = location; }; var f = new Factory("Kiel")● A new, empty object is created and Factory is executed in its context.● Default return value is this newly constructed object.● When a constructor is completed with return x, x will be returned, (only) if x is an object, else the new object is returned.www.assono.de Page 72

74.
Constructors (cont.)● Convention: Constructor names should start with an capital letter.● Caution: If you forget new, the function will still be executed, but in the global context instead in the context of the newly created object.www.assono.de Page 74

75.
Self-Invoking Constructors● In order to avoid the problem with the missing new, write your constructors this way: function Car() { if (!(this instanceof Car)) { return new Car(); } // do the normal construction stuff }● If Car is executed without new, it runs in the global context, therefore this points the global object, which is not a Car.www.assono.de Page 75

77.
for ... in Loops● Iterate over all attributes and methods of an object – and its “ancestors” (but not all properties are “enumerable”).● Example: for (prop in obj) { alert(prop.toString()); }● Best Practice: Use obj.hasOwnProperty("name"), which is true, only if obj has the attribute name, to distinguish between “own” and “inherited” properties.www.assono.de Page 77

79.
Enhancing Existing Objects (cont.)● Caution: What if the next version of JavaScript has your addition built-in?● Or other developers have the same idea?● At least, you should check before you enhance language objects.● Example: if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^s+|s+$/g, ""); } }www.assono.de Page 79

84.
“Class Attributes”● In Java, there is a static modifier for class attributes and methods.● In JavaScript, there are no classes, but …● … you can add attributes to the constructor function itself (the Function object), which are usable like class attributes.● Useful for logging, book keeping (counting created objects), object pools, configuration of an “object factory” etc.www.assono.de Page 84

86.
Inheritance à la JavaScript● Each object has a prototype attribute, normally {}.● Functions are objects, constructors are functions, therefore constructors have this attribute, too.● You can add new properties to a prototype object or even replace it completely.www.assono.de Page 86

87.
Inheritance à la JavaScript (cont.)● Search sequence for properties: - current object a - a.constructor.prototype - a.constructor.prototype.constructor.prototype - etc. - at last: Object● Prototype chain● This can be used as “inheritance”.● All changes to an objects prototype take effect immediately – to the object itself and it “successors” in the prototype chain.www.assono.de Page 87

88.
Inheritance à la JavaScript (cont.)● Properties of an object superimpose properties with the same name up in the chain – they override “inherited” properties.● Methods in a constructor are copied into each created object and use up some memory.● You can add them to the objects prototype instead.● This consumes less memory, but costs some performance (more lookups up the chain).www.assono.de Page 88

90.
Prototypical Inheritance (cont.)● This works even after the objects creation!● In the example: Object f is created, then produce is defined and added to the Factorys prototype.● The function produce is not found directly in f, but in its prototype chain.● Instead of Factory.prototype.produce = ... you can write f.constructor.prototype.produce = ...www.assono.de Page 90

92.
Heads up: Replacing the prototype Object● If you replace the prototype object instead of enhancing the existing one, this only takes effect on objects created afterwards.● Objects has an internal pointer to the prototype object at the time, they were created. This pointer isnt changed, when you overwrite the prototype object.● In Firefox, this internal attribute is called __proto__.● Besides, after replacing the prototype object the constructor attribute sometimes points to the wrong object. Therefore you should also set the constructor after replacing the prototype object.www.assono.de Page 92

94.
Access the “Super Class” with uber● There is no direct access to the “super class”● Convention: set the uber attribute to the prototype of the “super class”● Example: User.prototype = new Person(); User.prototype.constructor = User; User.uber = Person.prototype;www.assono.de Page 94

102.
Binding● With function.call and function.apply you can borrow methods from other objects (remember use of function.slice with the arguments object).● You can use this to permanently bind a method to an object, using a function like this: function bind(o, m) { return function () { return m.apply(o, [].slice.call(arguments)); }; }● Usage: var newObj = bind(oldObj, anotherObj.m); newObj.m();● In HTML 5 there is a bind method in Function.www.assono.de Page 102

104.
Mix-Ins● Instead of just copying from one object, you can have the effect of “multiple inheritance” by having more than one source object: function mix() { var arg, prop, child = {}; for (arg=0; arg<arguments.length; arg+=1) { for (prop in arguments[arg]) { if (arguments[arg]. hasOwnProperty(prop)) { child[prop] = arguments[arg][prop]; } } } return child; }www.assono.de Page 104

105.
Global Variables Global Variables are evil and you should avoid using them, wherever possible. Imagine the problems, if some JavaScript libraries use the same global variables – youll get unpredictable (undeterministic) results...www.assono.de Page 105

107.
Loading JavaScript● <script> tag in an HTML file: loads (if external) and executes JavaScript● Loading JavaScript blocks loading of other resources (except some modern browsers).● Executing JavaScript blocks everything else (loading, rendering) in the browser.● Best Practice: Place <script> tags at the end of the HTML (where possible), then everything can be loaded and the page rendered beforehand.● The page “seems” to load faster, users can read it...● Best Practice: Combine many small JavaScript files to less bigger ones: Less requests, less overhead.www.assono.de Page 107

108.
Loading JavaScript (cont.)● <script> tag got a new, optional attribute in HTML 4: defer● but it is only implemented in IE 4+ and Firefox 3.5+● <script> tags programmatically created and inserted into the DOM dont block anything.● If code is self-executing, youre done, else you have to react, when its ready.● In IE use script.onreadystatechange and script.readyState, else use script.onload to install a function to run, when the script is ready.www.assono.de Page 108

110.
Helper function loadScript (cont.)function loadScript(url, callback){…} else { // other browsers script.onload = function(){ callback(); };}script.src = url;var head = document.getElementsByTagName("head");head[0].appendChild(script);}● If necessary, you can chain loadScript calls.● Very Best Practice: Load only loadScript directly in your page and use it to get the rest.www.assono.de Page 110

111.
Scripting the DOM● Accessing DOM objects is slow!● Minimize the access to them, use local variables.● One big modification is better than many small ones.● Using innerHTML can be faster then using DOM methods, but not considerably faster (and even slower in some WebKit based browsers).● Prefer the convenient and fast Selectors API methods (doc.querySelectorAll and doc.querySelector) to doc.getElementBy… whenever available (modern browsers).www.assono.de Page 111

112.
Scripting the DOM (cont.)● Reduce the number of repaints, and even more important, the number of reflows.● Repaint: visible change of DOM, but no change of sizes.● Reflow: visible change of DOM and the size and positions of the elements have to be recalculated.● Cache style information.● Combine or batch changes.● Take elements out of the DOM tree, manipulate them and put them back.● Use document fragments to build a DOM sub-tree (doc.createDocumentFragment) and add it in one step to the DOM.www.assono.de Page 112

113.
Event Delegation● Uncaught events bubble up the DOM tree.● For repeating structures like tables or lists its better to have one event handler for all events than one for each sub-element (e.g. row).● The original target is stored in the event object.www.assono.de Page 113

116.
Keeping the User Interface Responsive (cont.)● You can measure the time and continue, until a limit is reached. Then you set up a timer to continue from here on later.● Example (excerpt in pseudo code): var start = +new Date(); do { // do something } until (+new Date() - start > limit); if (still something to do) { // set up the timer }● You add overhead, but the UI keeps responsive.● Use the web workers API (new in HTML 5), when its available in “your” target browsers.www.assono.de Page 116