views:

163

answers:

6

How do you guys make "classes" in JavaScript!?

I am using:

function classFoo()
{
   var classLevelVariable = 0;

   this.classFunction = function()
   {
      alert("The classFunction has been called.");
      classFunction2(); //Crash.  classFunction2 is "undefined."  
   }

   this.classFunction2 = function()
   {
      alert("classFunction2 called.");
   }
}

I never was able to get constructors to work. Tried

this.New = function(arguments)

Which worked once, but not in a second class. So, I have now given up on those entirely, using my own "Initialize" functions which act as constructors.

The weirdness with it working once, but not twice, makes me think typographical errors between the two classes... but I think in 19 years of coding, that that probably isn't it.

I'm using Chrome's debugger, and I am not receiving any errors besides the second function being undefined when being called.

+4  A: 

JavaScript is a prototype based programming language. The concept of a class does not exist or the concept of a class is the same as an object. It's quite different from say the Java programming language. Do not be fooled by thier names, the similaries end there.

I asked this question I while back. I got an answer with a nice link to these presentation slides by John Resig. Look though that and see if it helps with understanding JavaScript and prototype chains.

John Leidegren
+7  A: 

Javascript does not use class-based inheritance. So, you can't make classes in Javascript, except to emulate them using workarounds that are IMHO clumsy and complicated.

Javascript is a prototypal language. Using the new keyword creates a new object based on the prototype property of the constructor object.

You can get an idea how you might use prototypal inheritance to instantiate a new object based on a prototypal object here: http://javascript.crockford.com/prototypal.html

thomasrutter
Javascript is a Prototype-based programming. A style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is performed via a process of cloning existing objects that serve as prototypes. Prototype-based programming (http://en.wikipedia.org/wiki/Prototype-based_programming) - Class-based programming (http://en.wikipedia.org/wiki/Class-based_programming)
Ph.E
+1  A: 

Here is a good article on sitepoint.com about Object Oriented Programming in JavaScript.

This one on javascriptkit.com is more straightforward.

You can use a function to creates an object set its properties and functions like this:

person = new Object()
person.name = "Tim Scarfe"
person.height = "6Ft"

person.run = function() {
    this.state = "running"
    this.speed = "4ms^-1"
}

or use constructors:

function person(name,height,speed){
    this.name = name;
    this.height = height;
    this.speed = speed;
}

var p1=new person('tom', '6ft','15kmph');

alert(p1.height);

or you can use prototyping to extend objects:

person.prototype.sayHello = function(){alert("Hi, I'm " + name;}

var p2 = new person('sam', '5.9ft', '12kmph');
p2.sayHello();//alert-> Hi, I'm sam

more in-depth details are on the linked pages.

TheVillageIdiot
A: 

By using the Prototype javascript framework.

BobTurbo
wow cool, man!!!
TheVillageIdiot
You're confusing Prototype the JS library (http://www.prototypejs.org/) with the general prototypal inheritance principles (mentioned elsewhere) / the prototype JS keyword.
Marc Bollinger
+2  A: 

I feel that your original rant (see question's revision history) deserves a response. It's very much against the spirit of programming and computer science, in my opinion, to declare a language broken merely because you can't make it go.

Please pardon me if I offend you when I say that I'm surprised that they can give CS degrees out to people with such paradigmatic ignorance. When I went to school, which was only about 5 years ago, I did my assignments in 6 different languages: MIPS, Verilog, Scheme, Java, C/C++ and Python. We used many paradigms, including functional and OOP but other styles as well. If you were not exposed to these different perspectives, none of which are new, your education is not complete.

Has it occurred to you that what you consider to be canonical OOP is merely one formulation of the OOP principles? In Javascript objects instantiate from a "prototype," and it's not the same thing as a class. When you expect it to work like a class-based OOP language, it will not meet your expectations. Java and C++ are not the gold standard of OOP, nor is OOP the be-all-end-all of programming.

When one considers the amazing apps that have been written in Javascript in the past 3-5 years, it's amazing that a person can make a statement like this:

One would think we would apply our best coding practices over the last six decades into it. No. Of course not. What do we have? Functions inside of functions... some weird bastardization of classes. Complete with no consistency...

To say that, despite the brilliant achievements made by teams of brilliant Javascript developers, the language is broken because you have difficulty understanding it is, well, astonishing.

Please consider that, instead of the language being flawed, you may not presently possess the perspective necessary to understand it.


PS, You mentioned that you are "using JavaScript to AVOID FLASH!" It seems like you have a very poor strategy for ascertaining facts, since Javascript and Actionscript both implement the same spec: ECMAScript.

Jesse Dhillon
Yay, debate! This is what I sought. :-DIt is true my computer science education and work experience has been dominated by C++, .NET, and Java, which definitely makes me bias. The last few years, I have had to do a lot of Flash work, which I find greatly frustrating, because much of the language appears to be "half way" between two worlds. While it has classes, they have many hiccups. The most scary one I've found is it occasionally confusing references, requiring you to use dirty tricks such as:
JKZ
class MyClass { function TryingToCall() { } function Foo() { //this.TryingToCall(); fails. Says TryingToCall doesn't exist. var me:MyClass = this; me.TryingToCall(); //works. } }
JKZ
With JavaScript, I am feeling similar frustrations arising, which is why I wrote a giant rant :-). We all know that feeling... the feeling where you know you're doing something "dirty," but you just have to do it to make it work at all. I am getting that feeling doing simple things in JavaScript :-P.
JKZ
Of course there are many ways to implement anything. As programmers, we're expected to adapt--and we do that daily. I have done my fair share of "great feats," like using DirectX7 in Visual Basic 6--so by no means am I disrespecting those great feats done in JavaScript. In due time, I will understand how JavaScript OOP works too. Ultimately, the final product just has to work, and the client doesn't care how. It doesn't mean the the language, whichever it is, can't be better :-). My argument is, if so many people are trying to make classical classes in JavaScript... why not have them?
JKZ
(I didn't say I was avoiding Flash because it drives me crazy [although it is a fact it drives me crazy :-P]. I am avoiding Flash because Flash isn't supported on iPhones and iPads.)
JKZ
You're not the first person to think that JS needs real classes. Even ECMA goes back and forth on the issue of whether classes should be added. I just think it's very unfair to say that the language is backwards because it doesn't behave like Java or C++. It's not supposed to. JS has a lot of very useful features, like the closures which it looks like your example is taking issue with. There are things that you can do in JS in a few lines that could take 20+ lines in compiled languages, sometimes there aren't equivalents. It's a powerful way of programming but it takes adjustment.
Jesse Dhillon
+1  A: 

JavaScript is a Prototyping Language, so things are a little different.

Here is a code snippet to explain:

(function(){ // create an isolated scope
    // My Object we created directly
    var myObject = {
        a: function(x,y) {
            console.log('a');
        },
        b: function(x,y) {
            console.log('b');
            this.a(x,y);
        }
    };
})();

(function(){ // create an isolated scope

    // Create a Object by using a Class + Constructor
    var myClass = function(x,y) {
        console.log('myClass: constructor');
        this.b(x,y);
    };
    myClass.prototype = {
        a: function(x,y) {
            console.log('myClass: a');
        },
        b: function(x,y) {
            console.log('myClass: b');
            this.a(x,y);
        }
    };

    // Define a function that should never inherit
    myClass.c = function(x,y) {
        console.log('myClass: c');
        this.a(x,y);
    };

    // Create Object from Class
    var myObject = new myClass();
    // Will output:
    // myClass: constructor
    // myClass: b
    // myClass: a

    // Define a function that should never inherit
    myObject.d = function(x,y) {
        console.log('myObject: d');
        this.a(x,y);
    };

    // Test the world is roung
    console.log(typeof myClass.c, 'should be undefined...');
    console.log(typeof myClass.d, 'should be function...');
})();

(function(){ // create an isolated scope
    // If you are using a framework like jQuery, you can obtain inheritance like so

    // Create a Object by using a Class + Constructor
    var myClass = function(x,y) {
        console.log('myClass: constructor');
        this.b(x,y);
    };
    myClass.prototype = {
        a: function(x,y) {
            console.log('myClass: a');
        },
        b: function(x,y) {
            console.log('myClass: b');
            this.a(x,y);
        }
    };

    // Create new Class that inherits
    var myOtherClass = function(x,y) {
        console.log('myOtherClass: constructor');
        this.b(x,y);
    };
    $.extend(myOtherClass.prototype, myClass.prototype, {
        b: function(x,y) {
            console.log('myOtherClass: b');
            this.a(x,y);
        }
    });

    // Create Object from Class
    var myOtherObject = new myOtherClass();
    // Will output:
    // myOtherClass: constructor
    // myOtherClass: b
    // myClass: a
})();

(function(){ // create an isolated scope
    // Prototypes are useful for extending existing classes for the future
    // Such that you can add methods and variables to say the String class
    // To obtain more functionality
    String.prototype.alert = function(){
        alert(this);
    };
    "Hello, this will be alerted.".alert();
    // Will alert:
    // Hello, this will be alerted.
})();

There are libraries to help with this such as:

balupton