13

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.

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
JKZ
  • 149
  • 1
  • 3
  • There's nothing wrong with this question, it surprises me that people have given you several down votes already. – John Leidegren Jul 19 '10 at 04:28
  • 2
    @John: review the edit history. I hope I've edited the question sufficiently to make it a reasonable one. – Michael Petrotta Jul 19 '10 at 04:30
  • 3
    You can't call `classFunction2()` when it is a method of `classFoo()` You have to have `this.classFunction2()` if your inside `classFoo()`. – qw3n Jul 19 '10 at 04:31
  • Hehe, didn't like my rant eh? I'll grant it wasn't direct to the question. But, yes, my original question is still valid. Why we haven't overhauled JavaScript (or just invented a new script that would eventually replace JavaScript) is beyond me. Perhaps too open for StackOverflow. – JKZ Jul 19 '10 at 04:33
  • @qw3n: Yes, that's what I've been doing since I posted actually... starting to get some more consistent behavior. (Functions inside of functions... so dirty!) – JKZ Jul 19 '10 at 04:34
  • When first posted, this wasn't really a question; more of a rant about how Javascript is insulting to the history of computer science. It's been edited heavily and is now more of a question but bears not too much resemblance to the tone of the original. The editing HAS made it more suitable for stackoverflow though. – thomasrutter Jul 19 '10 at 04:35
  • @Michael Petrotta - Why edit that much, feels more like censorship to me. But yes JKZ is pretty much wrong and that's a rant, but editing seems like an awfully crude way to handle it, set this guy straight by giving an appropriate answer or a good critique. (There's a creed amoung us being able to edit questions, that we should respect the orignal author) – John Leidegren Jul 19 '10 at 04:36
  • One tool isn't the best for every problem. – Chris Jul 19 '10 at 04:36
  • @John: yep, it was censorship, and you've described well why that's appropriate in this case. SO is not the US government, nor is it a platform for rants. – Michael Petrotta Jul 19 '10 at 04:38
  • @Michael Petrotta - I still feel that people have to be allowed to vent thier ideas and frustration does bring about these kinds of questions. – John Leidegren Jul 19 '10 at 04:40
  • 4
    @John: we'll have to agree to disagree. You should note that his question would have been closed, rather quickly, if it were to stand unedited. – Michael Petrotta Jul 19 '10 at 04:43
  • Just for the record: I never said my original post wasn't a rant. :-P It definitely was. I was hoping for more debate on the topic, but it's your site, and it's up to you how you want to run it. I got what I absolutely needed, and I thank you all for that. – JKZ Jul 19 '10 at 04:44
  • 1
    I'm surprised that they can give CS degrees out to people with such paradigmatic ignorance. It's called a "prototype" and it's not the same thing as a class. Despite your CS prof's insistence, Java and C++ are not the gold standard of OOP, nor is OOP the be-all-end-all of programming. It seems like you have a very poor strategy for ascertaining facts, since Javascript and Actionscript both implement the same goddamn spec, ECMAScript. – Jesse Dhillon Jul 19 '10 at 05:28
  • @Michael Petrotta - Far too often people lean towards closing questions like this rather than addressing them, head on. We don't have to be that agressive. @JKZ - You're not on trial, I'm just having issues with the heavy moderation bordering on censorship. @Jesse Dhillon - Now that's an approriate response, you should have given it as an answer. – John Leidegren Jul 19 '10 at 06:32
  • I posted it just for you John. – Jesse Dhillon Jul 19 '10 at 10:40
  • @Jesse Dhillon - And I gave you a up vote for it! I hope more read the history and do the same. – John Leidegren Jul 19 '10 at 11:48
  • 1
    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 (en.wikipedia.org/wiki/Prototype-based_programming) - Class-based programming (en.wikipedia.org/wiki/Class-based_programming) – kran1um Jul 19 '10 at 17:16

6 Answers6

8

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
  • 114,488
  • 30
  • 148
  • 167
  • 1
    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) – kran1um Jul 19 '10 at 17:16
7

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
  • 7,841
  • 1
  • 34
  • 34
  • Yay, debate! This is what I sought. :-D It 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 Jul 19 '10 at 16:34
  • class MyClass { function TryingToCall() { } function Foo() { //this.TryingToCall(); fails. Says TryingToCall doesn't exist. var me:MyClass = this; me.TryingToCall(); //works. } } – JKZ Jul 19 '10 at 16:35
  • 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 Jul 19 '10 at 16:35
  • 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 Jul 19 '10 at 16:35
  • (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 Jul 19 '10 at 16:36
  • 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 Jul 20 '10 at 09:43
5

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.

Community
  • 1
  • 1
John Leidegren
  • 59,920
  • 20
  • 131
  • 152
2

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
  • 40,053
  • 20
  • 133
  • 188
1

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
  • 47,113
  • 32
  • 131
  • 182
-2

By using the Prototype javascript framework.

BobTurbo
  • 1,065
  • 1
  • 8
  • 16
  • 1
    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 Jul 19 '10 at 17:30