Benutzer-Werkzeuge

Webseiten-Werkzeuge


becki:linux:javascript

Dies ist eine alte Version des Dokuments!


Home

Javascript

Variables

var Keyword

Within functions always prefix variables with var, otherwise they become global! See Avoid Global namespace

Objects and Inheritance

Defining Methods

Method definition inline inside of the constuctor

function MyClass() {  // constructor
    this.method1= function(arg) {/* code */}; // method
}

Seems to cause overhead, see http://phrogz.net/JS/Classes/OOPinJS.html

function MyClass_method1(arg) {/* code */} //  method
function MyClass() {this.method1= MyClass_method1} // constructor

Not recommendable, because

  • its not easy to see to which object the method definitions belong to
  • method definitions could be called directly whitout existing this
function MyClass() {} // constructor
MyClass.method1= function(arg) {/* code */} //  method

Not possible, causes an js-error if called from an MyClass instace. This is a static method, see below

function MyClass() {} // constructor
MyClass.prototype.method1= function(arg) {/* code */} //  method

Seems to be the best solution :-)

Access Types

function MyClass() {         // The constructor
    this.publicVariable= 10; // A public instance variable
}
MyClass.prototype.publicMethod= function() { // A public (instace) method
    document.write(this.publicVariable + 1 + ' ');
    document.write(MyClass.publicVariable + 1 + ' ');
    document.write(this.publicStaticVariable + 1 + ' ');
    document.write(MyClass.publicStaticVariable + 1 + '<br>');
}
MyClass.publicStaticVariable = 20;           // A public class variable
MyClass.publicStaticMethod= function() {     // A public class method
    document.write(this.publicVariable + 2 + ' ');
    document.write(MyClass.publicVariable + 2 + ' ');
    document.write(this.publicStaticVariable + 2 + ' ');
    document.write(MyClass.publicStaticVariable + 2 + '<br>');
}
// Test:
var myclass= new MyClass();
 
document.write(myclass.publicVariable + '<br>');       // 10
document.write(MyClass.publicVariable + '<br>');       // undefined
 
myclass.publicMethod();   // 11 NaN NaN 21
//MyClass.publicMethod(); // error!
 
document.write(myclass.publicStaticVariable + '<br>'); // undefined
document.write(MyClass.publicStaticVariable + '<br>'); // 20
 
//myclass.publicStaticMethod(); // error!
MyClass.publicStaticMethod(); // NaN NaN 22 22

Private methods seem to be only possible as inline constructor functions, but those seem to cause overhead.

Object creation

The classic Java-like way:

function Point(x, y) {this.x=x; this.y=y;}
Point.prototype.toString = function() {return "("+this.x+"/"+this.y+")";}
Point.prototype.shift    = function(dx, dy) {this.x+=dx; this.y+=dy;}
 
var p  = new Point(3,4);
document.write("p:"+p.toString());

The closure way: (closures see below)

function makePoint(x, y) { return {
    toString: function() {return "("+x+"/"+y+")";}
    shift:    function(dx, dy) {x+=dx; y+=dy;}
};}
 
var p  = makePoint(3,4);
document.write("p:"+p.toString());

FIXME

  • Second variant is to be verified
  • Does second method cause overhead?
  • What about inheritance with 2nd method?

Object cloning

Objects are passed by refernce

> Something like a copy constructor is necessary:

function Point(x, y) {this.x=x; this.y=y;}
Point.prototype.clone= function() {return new Point(this.x, this.y);}
Point.prototype.toString= function() {return "("+this.x+"/"+this.y+") ";}
 
var p  = new Point(3,4);
var pr = p;		// a reference to p
var q  = p.clone();	// a new point whit the same coordinates as p
p.x= 9; p.y=-2;		// change content of p
document.write("p:"+p.toString()+ "pr:"+pr.toString()+ "q:"+ q.toString());
// result: p:(9/-2) pr:(9/-2) q:(3/4)

Inheritance

FIXME see JS Guide 1.5 and dynWidget.js

Misc

Events

Get the Source of the Event

/** conchange event handler function */
function getNameAndValueOfInputField(event) {
    var name, value;
    if (event) {
        name  = event.target.name;
        value = event.target.value;
    } else {  // IE specific code. I hate it!
        name  = window.event.srcElement.name;
        value = window.event.srcElement.value;
    }
    return {"name":name, "value":value};
}
 
// set conchange event for input field: 
var input = document.getElementById("franz"):
input.onchange = getNameAndValueOfInputField;

Event handler for value input fields
For event handling see: Mozilla & Micro$oft

Closures

From MDC

Principle

A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created. Consequently, you can use a closure anywhere that you might normally use an object with only a single method.

Instead of

function Statusbar(elementId) { /* class constructor */
    this.target  = document.getElementById(elementId);
    this.setText = function(text) { this.target.innerHTML= text; }
}
var statusbar = new Statusbar("statusbar");
statusbar.setText("some text");

you can use:

function makeStatusTextSetter(elementId) { /* closure factory */
    var target= document.getElementById(elementId);
    return function(text) { target.innerHTML= text; }
}
var setStatusText= makeStatusTextSetter("statusbar");
setStatusText("some text");

Practical Usage

Imho mainly as callbacks for events:

<html><head>
    <script type="text/javascript" src="copy.js"></script>
</head><body>
<form id="form" action="dummy">
  <textarea id="inbox" name="inbox" cols="80" rows="10"></textarea>
</form>
<pre id="outbox">...</pre>
</body></html>
function makeCopyFkt(inboxNode, outboxNode) {
    /* inner funct is a closure witch gets attached the environment (including
	passed arguments) of the outer function  */
    return function () { outboxNode.innerHTML= inboxNode.value; }
}
 
window.onload = function() { /* called when html is loaded completely */
    var inboxNode  = document.getElementById('inbox');
    var outboxNode = document.getElementById('outbox');
    var copyFkt= makeCopyFkt(inboxNode, outboxNode);
    inboxNode.onblur= copyFkt;
};

Using class member methods as event callbacks

Global functions, i.e. functions which are defined outside of a class can easily be used as event callbacks for DOM nodes, but what about class member methods?

The following example will not work, because the callback function copy has no access to this at the time being called:

function Copier(inboxNode, outboxNode) {
    this.inboxNode  = inboxNode;
    this.outboxNode = outboxNode;
    this.copy = function () { this.outboxNode.innerHTML= this.inboxNode.value; }
}
 
window.onload = function() { /* called when html is loaded completely */
    var inboxNode  = document.getElementById('inbox');
    var outboxNode = document.getElementById('outbox');
    var copier= new Copier(inboxNode, outboxNode);
    inboxNode.onblur= copier.copy;
};

But it works with the closure way:

function Copier(inboxNode, outboxNode) {
    this.inboxNode  = inboxNode;
    this.outboxNode = outboxNode;
    this.copy = function () { self.outboxNode.innerHTML= self.inboxNode.value; }
    var self= this; // reference to this is saved in environment for closures
}

Or even shorter:

function Copier(inboxNode, outboxNode) {
    this.copy = function () { outboxNode.innerHTML= inboxNode.value; }
}

But the best solution is imho to leave the class clean and pass the DOM node not directly the member function but an additional (anonymous) wrapper function as closure. This works also with real (prototype) methods:

function Copier(inboxNode, outboxNode) {
    this.inboxNode  = inboxNode;
    this.outboxNode = outboxNode;
}
Copier.prototype.copy= function() {this.outboxNode.innerHTML= this.inboxNode.value;};
 
window.onload = function() { /* called when html is loaded completely */
    var inboxNode  = document.getElementById('inbox');
    var outboxNode = document.getElementById('outbox');
    var copier= new Copier(inboxNode, outboxNode);
    inboxNode.onblur= function() { copier.copy(); }; // <== "wrapper" closure
};

:!: Take care if you want to initialize more than on DOM callback in a loop. For this a callback factory function is necessary. See JavaScript Guide

FIXME Check out Emulating private methods with closures

Ajax

Sending JSON to Server

To convert any javscript value to a JSON string, use json2.js at json.org

FIXME look in http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=Mastering+Ajax

Cookies

Code for writing and reading cookies by javascript is available here. An example can be found in my plainGTD App. Note that cookies can be manipulated easier by server side scripting, eg PHP

Dojo Toolkit

Cookies helfen bei der Bereitstellung von Inhalten. Diese Website verwendet Cookies. Mit der Nutzung der Website erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Computer gespeichert werden. Außerdem bestätigen Sie, dass Sie unsere Datenschutzerklärung gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website. Weitere Information
becki/linux/javascript.1234273985.txt.gz · Zuletzt geändert: 2010-02-09 18:16 (Externe Bearbeitung)

Impressum - Datenschutzerklärung