Homepage

Javascript objects for PHP programmers

Or: PHP-JavaScript Rosetta Stone

Rutger de Knijf -

I recently broke the surface concerning jQuery and I guess therefore JavaScript. You know, when learning a new language (or anything really) there's the initial fase of chaotic guesswork and frustrating magical (non) working parts. You don't know how long it'll last until you're out of it. The clear marker for me is when I can comfortably identify the parts that I don't know yet, combined with the feeling that you can identify certain things as trivial and others as important. Obviously this only means the beginning , but it is also the time when you can finally start to effectively apply your previous experience in other languages to this new language.

Hence this post: objects and inheritance are standard fare in PHP, at least for me. I thought, well, let's just figure out how this works in JavaScript and we're off. Alas, no such luck. Articles about this are legion, but none explained it the way I would have liked it. So this is it, this is how I would have liked it to be explained to me.

First, two ways to create an object:

JavaScript
    // First way - "Module Pattern" - extendable
    
    function monkey1() {
    
        this.limbsCount = 4;
    
        this.color = 'black';
    
    }
    
    
    // Second way - "Object Literal" - NOT extendable
    
    monkey2 = {
    
        limbsCount : 4,
    
        color : 'black'
    
    }

There it is in a nutshell. Via the first way (Module Pattern) the object is extendable, and you can think of this as a class in PHP. And as in PHP you'll have to instantiate these classes into objects (if that's English). Like this:

JavaScript
	// Try getting the color
    
    console.log(monkey1.color); // nope, returns "undefined"
    
    // Instantiate the class into an object
    
    var Pete = new monkey1();
    
    // Now you can do this
    
    console.log(Pete.color); //returns 'black'
    
    // While for the second monkey...
    
    console.log(monkey2.color); // This would work just fine    

Via the second way (Object Literal) you have this one single object. Which is great if you need a single object. It is faster as well, at least in my benchmark. It doesn't need instantiation. And it is great as a namespace. (Namespace? Not now, some other time.)

Now, on to extending classes. I can be brief when it comes to the Literals: it's impossible. At least not in a non-ubernerdy way that I don't know about. They're not made to be fiddled with, so just don't.

Classes, or Module Pattern functions, or whatever, monkey1 can be extended. How? First the PHP way to refresh your mind:

PHP
    Class Animal {
    
    }
    
    Class Mammal extends Animal {
    
    }
    
    Class Monkey extends Mammal {
    
    }

Check? And now for JavaScript.... Drumroll... Read it and weep:

JavaScript
    function Animal() {
    
    }
        
    
    Mammal.prototype = new Animal();
    Mammal.prototype.constructor = Mammal;
    
    function Mammal() {
    
    }
    
    
    Monkey.prototype = new Mammal();
    Monkey.prototype.constructor = Monkey;
    
    function Monkey() {
    
    }

Yes, I did mean the weeping part... But hey, it's not that bad. From my earlier experience with JavaScript I'd expected it to be much worse. Not excluding calling down some heathen gods in order to infuse a flux engine that in turn would produce a class extension. Or something similarly magical. But no, just small magic.

Now, stop reading if you're on the verge of overloading your learning capabilities for now. This is all you need to know. It works just like a PHP class, with cascading function overrides and all that good stuff. So, go play! Oh, work, sorry, I meant work.

If however your wish to know how it comes to be... Which, I admit, is probably wise with knowledge building and all that. Read on then, and I'll try, no guarantees.

The prototype: You probably should read some more about this in other places, but for PHP developers: Think of it as the stdClass() of your class. Not that you would ever do this, but the following is the same:

PHP
class Monkey {

}

// ===

class Monkey extends stdClass {

}

However, JavaScript and PHP are two different languages and this translation is not exact. In reality the prototype in JavaScript is a sort of backup parent class. Or, ah, I just can't explain this in PHP terms. Just stick with what I said before.

Now, on to the constructor part. First, what is a constructor? Just look at the code:

PHP
	// Class
	class Monkey {
    	
        // Constructor function        
        function __construct($nameHere) {
        	
            $this->name = $nameHere;
            
        }
        
    }
    
    // And instantiate
    
    $nicemonkey = new Monkey('Pete');
JavaScript
	// The function/class IS the constructor function
    function Monkey(nameHere) { 
    
    	this.name = nameHere;
        
    }
    
    // And instantiate  
    
    var nicemonkey = new Monkey('Pete');

Got that? In JavaScript the class itself IS the constructor. Nuff' said.

Now, how does this help with extending the class? I don't know, I haven researched it before I wrote this. But it 'feels' logical, so how hard can it be: Since the constructor IS the class function itself, you set the parent class itself as the constructor of your new class.

And there you go, I have no idea how I can explain it more concise than that.

Literature