Schlagwort-Archive: Javascript

Slippery When Wet #4: this is it – the this keyword in Javascript

I proudly present to you the fourth in a infinite number of posts of “Slippery When Wet.” In these posts I show you a little bastard I stumbled on.

Coming from the C++/C#/Java world, the ‚this‘ keyword is well known for accessing the instance of the class itself. For accessing members, it is not mandantory but often favored for clearness.

With this background, a first try could look like this (complete html page in the package, file this1.html):

var marc = {
    name: "Marc",
    hello: function(visitor) {
        document.write("Hello " + visitor + ", my name is " + name + "!")
    }  
}

window.onload = function()
{
    marc.hello("Peter");
}

And the output is:

Hello Peter, my name is !

OK, let’s try again!
We call the name property explicit (this2.html):

        document.write("Hello " + visitor + ", my name is " + this.name + "!")

And the output is, as expected:

Hello Peter, my name is Marc!

So, it’s a piece of cake, we have only to put the this keyword for all members, and we’re done…

Wait, not so fast, youngster!

Let’s try it with a function reference like in the next example (this3.html):

var marc = {
    name: "Marc",
    hello: function(visitor) {
        document.write("Hello " + visitor + ", my name is " + this.name + "!")
    }  
}

var greet = marc.hello;

window.onload = function()
{
    greet("Peter");
}

And the output is:

Hello Peter, my name is !

The name is lost again!

This problem occurs because JavaScript doesn’t support implicit binding in a way C++ and others do.

With calling the function through the function reference, the this inside the hello function points not to marc but to the window. To verify this thesis, we just add a name to the window:

var marc = {
    name: "Marc",
    hello: function(visitor) {
        document.write("Hello " + visitor + ", my name is " + this.name + "!")
    }  
}

var greet = marc.hello;

window.name = "Sue";

window.onload = function()
{
    greet("Peter");
}

And the output is:

Hello Peter, my name is Sue!

But how can we solve this problem? The two easiest solutions are apply and call:

var marc = {
    name: "Marc",
    hello: function(visitor) {
        document.write("Hello " + visitor + ", my name is " + this.name + "!")
    }  
}

var greet = marc.hello;

window.onload = function()
{
    greet.apply(marc, ["Peter"]);
    document.write("<br />");
    greet.call(marc, "Peter");
}

And the output is:

Hello Peter, my name is Marc!
Hello Peter, my name is Marc!

With apply and call, you do an explicit binding. The object you pass as the first argument (in our example marc) does not need to have the function itself, but should of course have the members that are used inside the function.
The difference of apply and call is only in the signature of the function. With apply, the parameter have to be passed inside an array. With call, the parameters are lined up after the explicit binding object.

This should give you some ideas to identify problems coming from the binding and some solutions to solve them.

For further reading i suggest the following articles:

Fremde Webseite online editieren

Ein kleiner Trick im Firefox (getestet mit Version 4.0.1):

Einfach eine Webseite laden und dann folgende Zeile in das Adress-Feld eingeben und Enter drücken:

javascript:document.body.contentEditable='true'; document.designMode='on'; void 0

Erstmals ist keine Änderung ersichtlich. Man kann jetzt aber z.B. einen Text markieren und editieren. So kann man einfach kleine Änderungen vornehmen. Diese werden natürlich nicht gespeichert sondern gehen beim nächsten reload wieder verloren.

Weitere Tricks nehme ich gerne in den Kommentaren entgegen.

Internet Explorer Standard Support Dokumentation

Kurz nachdem ich den Verweis auf den Artikel über die CSS-Unterschiede in den verschiedenen Internet Explorer Versionen publiziert hatte habe ich den Artikel bei heise online entdeckt, der auf die Dokumentation von Microsoft verweist. Diese dokumentiert unter anderem auch die verschiedenen Erweiterungen gegenüber den Standards bei CSS, JavaScript und DOM. Es empfiehlt sich, die PDF-Version der Artikel zu lesen, da in der HTML-Version jedes Unterkapitel auf einer einzelnen Seite dargestellt wird.

Slippery When Wet #1: Javascript’s GetMonth()

I proudly present to you the first in a infinite number of posts of „Slippery When Wet.“ In these posts I show you a little bastard I stubled on.

I had to reformat a date in Javascript. There were all this little nice functions of a date object like

getFullYear(), getHours(), getMinutes()

and also

getMonth()

. Every of these functions returned the value as it would also be shown, but not getMonth(). getMonth() returns a value from 0 to 11, so 0 is January, 1 is February and so on untill 11, that is December.

I see a possible reason for this: With values from 0 to 11 you can use the value directly as the index for an array with the month names inside, like

alert(months[myDate.getMonth()]);