tags:

views:

147

answers:

4

I'm learning how to make OOP with javascript, and I wonder if it have the interface (such as Java interface) concept? So I would be able to create a listener...

+1  A: 

You need interfaces in Java since it is statically typed and contract between classes should be known during compilation. In javascript it is different. Javascript is dynamically typed, it means that when you get the object you can just check if it has specific method and call it.

Alex Reitbort
Actually, you don't need interfaces in Java, it's a fail safe to ensure objects have a certain API so you could swap them out for other implementations.
BGerrissen
No, they're actually needed in Java so that it can build vtables for classes that implement an interface at compile time. Declaring that a class implements an interface instructs the compiler to build a little struct that contains pointers to all of the methods needed by that interface. Otherwise, it would have to dispatch by name at runtime (like dynamically-typed languages do).
munificent
+12  A: 

There's no notion of "this class must have these functions" (ie: no interfaces per se), because:

  1. Javascript inheritance is based on objects, not classes. Not a big deal until you realize:
  2. Javascript is an extremely dynamically typed language -- you can create an object with the proper methods, which would make it conform to the interface, and then undefine all the stuff that made it conform. It'd be so easy to subvert the type system that it wouldn't be worth it to try and make a type system in the first place.

Instead, Javascript uses what's called "duck typing". (If it walks like a duck, and quacks like a duck, for all intents and purposes it's a duck.) If your object has quack(), walk(), and fly() methods, code can use it wherever it expects an object that can walk, quack, and fly, without requiring the implementation of some "Duckable" interface. The interface is exactly the set of functions that the code uses (and the return values from those functions), and with duck typing, you get that for free. Now, that's not to say your code won't fail halfway through -- it'll die when it tries and fails to call some_dog.quack(). But if you're telling dogs to quack, you have slightly bigger problems.

You can test for the existence of a particular method before trying to call it, something like

if (typeof(someObject.quack) == "function")
{
    // this thing can quack
}

So you can check for all the methods you can use before you use them. The syntax is kinda ugly, though. There's a slightly prettier way:

Object.prototype.can = function(methodName)
{
     return ((typeof this[methodName]) == "function");
};

if (someObject.can("quack"))
{
    someObject.quack();
}

Not sure if that works in all browsers, but i haven't had a problem with it in IE or Chrome, so it's almost definitely cross-browser friendly. It has the added benefit of reading like English.

Apparently, though, to some people, modifying Object.prototype is a bad idea. If you care about being able to blindly use for...in loops, or are using (IMO broken) code that does, try a slightly different version:

function can(obj, methodName)
{
     return ((typeof obj[methodName]) == "function");
}

if (can(someObject, "quack"))
{
    someObject.quack();
}
cHao
+1 duck type reference ;)
BGerrissen
+1 for Duckable
Daniel Vandersluis
Your `can` method is cross-browser compatible, but anyone who uses it needs to be aware that it will show up in for...in loops. For that reason, it's not generally a good idea to modify `Object.prototype`.
Matthew Crumley
http://erik.eae.net/archives/2005/06/06/22.13.54/ Object.prototype is verboten
BGerrissen
It's not as horrible as it's made out to be. `for...in` is -- and has always been -- fraught with such dangers, and anyone who does it without at least considering that someone added to `Object.prototype` (a not uncommon technique, by that article's own admission) will see their code break in someone else's hands.
cHao
+3  A: 

Pick up a copy of 'JavaScript design patterns' by Dustin Diaz. There's a few chapters dedicated to implementing JavaScript interfaces through Duck Typing. It's a nice read as well. But no, there's no language native implementation of an interface, you have to Duck Type.

// example duck typing method
var hasMethods = function(obj /*, method list as strings */){
    var i = 1, methodName;
    while((methodName = arguments[i++])){
        if(typeof obj[methodName] != 'function') {
            return false;
        }
    }
    return true;
}

// in your code
if(hasMethods(obj, 'quak', 'flapWings','waggle')) {
    //  IT'S A DUCK, do your duck thang
}
BGerrissen
+1 Thanks for the book recomendation!
Tom Brito