reperiendi

Javascript OOP

Posted in Programming by Mike Stay on 2006 September 28

I linked a while ago to an article that I thought was doing OOP right in Javascript. It turns out that it wasn’t quite. Under that system, constructors can’t have parameters and other badness.

After working out the details, here’s what I found. Start with a base class A and derive a class B:

function A(args){
    // non-static args-independent code
    this.myMethod=function(){return 'A'+this.x;};
    this.x='x';
    if (arguments.length==0) return;
    // args-dependent code
    this.myArgsDependent=function(){return args;};
}

A.prototype.myStaticMethod=function(){return 'static A';};

function B(args){
    if (arguments.length==0) return;

    // args-dependent code
    // annoying to have two copies, but otherwise static members get overridden
    // (see below)
    // if that's not a problem, set this.super = B.prototype
    this.super=new A(args);
    A.call(this,args);

    // while not strictly args-dependent, overriding methods / properties
    // has to occur after the args-dependent call to the
    // superclass constructor
    this.myMethod=function(){return 'B'+this.x;};
    this.x='y';
}

// this says "if it's not here, look for it in A"
B.prototype = new A();
B.prototype.myStaticMethod=function(){return 'static B';};

b=new B('argsFromBConstructor');
alert(b.myMethod()); // By
alert(b.myStaticMethod()); // static B
alert(B.prototype.myStaticMethod.call(b)); // static B

alert(b.super.myMethod.call(b)); // Ay
alert(b.super.myMethod()); // Ax
alert(b.super.myStaticMethod.call(b)); // static A

alert(b.myArgsDependent()); // argsFromBConstructor

Javascript doesn’t do multiple inheritance or implement interfaces, but you can run several contructor methods on a single object with the same A.call(this,args) syntax.

function C(){
    // initialize this object with properties of both A and B
    A.call(this,args);
    B.call(this,args);
}

// If it's not in C, you have to tell it a single class to look in
C.prototype=new <which:A or B?>;

Greasemonkey closures

Posted in Programming by Mike Stay on 2006 September 27

I’m writing up a greasemonkey script that adds onclick behavior to the span. According to the site, you do something like

thisDiv.addEventListener('click',function(){
    // function code here
},true);

This works OK, but what if my code needs scope? Say I wanted to search for some divs and have them tell which match they are when clicked. This code won’t work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',function(){
        alert(i);
    },true);
}

If there were 10 matching divs, this will alert “10″ every time. On the other hand, this code will work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',(function(i){return function(){
        alert(i);
    };)(i),true);
}

This is helpful when you want your modifications to retain access to functions like GM_setValue without using unsafeWindow. This way won’t work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',function(){
        GM_setValue('mydata',i);
    },true);
}

This way will:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',(function(i,GM_setValue){return function(){
        GM_setValue('mydata',i);
    };)(GM_setValue,i),true);
}

Greasemonkey scripts

Posted in Programming by Mike Stay on 2006 September 19

I’ve posted a few greasemonkey scripts on my site.

I Got Another Journal Publication

Posted in Uncategorized by Mike Stay on 2006 September 5

Bit Commitment Blues” has been published in Journal of Craptology!

Follow

Get every new post delivered to your Inbox.