views:

95

answers:

5

How do I declare class variables in Javascript.

function Person(){
    fname = "thisfname"; //What needs to be put here
 }
alert(Person.fname) //It should alert "thisFrame"

I don't want to use this approach.

function Person(){

 }
Person.fname = "thisfname";
alert(Person.fname) //alerts "thisframe"
+1  A: 

The way you mentioned is how to define class variables, the other way (inside function Person) is to define instance properties.

function Person(name){
    this.name = name;
}
Person.specie = "Human";

alert(Person.specie) //alerts "Human", a class variable.

var john = new Person('John');
alert(john.name); //alerts "John", an object property.
aularon
Why the downvote?
Isaac Lubow
`Person` is not a class, there isn't anything like a class in JavaScript. JavaScript has objects with `prototypal inheritance`, but `Person` is merely an Object in this case, it doesn't even has a method it's just a HashMap/Dictionary whatever you want to call it. See BGerissen's answer below for some good explanations.
Ivo Wetzel
@Ivo It's to be considered a class when generally speaking. And no, `Person` above is a "function that is used to instantiate object", if you want to be more specific. Again, I believe that we can call it a class when speak in general, you can keep going more specific for ever and end up calling it **ECMA Script Memory Pointer to a script to be parsed(1) upon being called via the parenthesis syntax. (1): Executed in case of new javascript compilers.**. SO the point is, answer above is not meant to mislead and misuse terminology, but to explain something in a simple way.
aularon
A: 
function Person(){
    this.fname = null;
    this.lname = null;
    this.set_fname = set_fname;
    this.set_lname = set_lname;
    this.get_name = get_name;
}
/* Another way
function Person(fname, lname){
    this.fname = fname;
    this.lname = lname;
    this.get_name = get_name;
}*/
function set_fname(fname){
    this.fname = fname;
}
function set_lname(y){
    this.lname = lname;
}
function get_name(){
    with (this) {
        return fname + ' ' + lname;
    }
}

person_obj = new Person();
person_obj.set_fname('Foo');
person_obj.set_lname('Bar');

// person_obj = new Person('Foo', 'Bar');

person_obj = get_name(); // returns "Foo Bar"

Can't think of better example.

simplyharsh
defining `function Person(fname, lname)` will overwrite the definition of `function Person()`, this is not how to do function overloading in javascript.
aularon
Sir, i didn't intend to overload. Those are options. Wait let me edit the answer.
simplyharsh
This is a really bad example, did you ever hear about prototypes? :/ Also using `with` is considered harmful by Crockford and others, if the property in the `with` caluse does not exist on the object you will set a global variable instead.
Ivo Wetzel
A: 

3 ways to define a variables to JavaScript class:

1)To define properties created using function(), you use the 'this' keyword

function Apple (type) {
    this.type = type;
    this.color = "red";
}

To instantiate an object of the Apple class, set some properties you can do the following:

var apple = new Apple('macintosh');
apple.color = "reddish";

2) Using Literal Notation

var apple = {
type: "macintosh",
color: "red"

}

In this case you don't need to (and cannot) create an instance of the class, it already exists.

apple.color = "reddish";

3) Singleton using a function

var apple = new function() {
    this.type = "macintosh";
    this.color = "red";
}

So you see that this is very similar to 1 discussed above, but the way to use the object is exactly like in 2.

apple.color = "reddish";
Meryl
That's not JSON, though it looks like it. ECMAScript has had support for the object literal syntax since it was created. An object literal supports quite a lot more than the JSON spec allows (including, but not limited to, function values, constructed and typed objects, and unquoted parameter names [like those you used]).
eyelidlessness
Thanks for bringing it to my notice.. :)
Meryl
A: 

It is important to understand that there is no such thing as classes in JavaScript. There are some frameworks out there that simulate a classical inheritance pattern, but technically it all boils down to constructor functions and prototypes.

So, you may want to do something like

PersonProto = { // the "class", or prototype
    fname: "thisfname"
};

function Person() { // the constructor function
    this.instanceVar = 'foo';
}

Now, connect the constructor to the prototype:

Person.prototype = PersonProto;

And, voilà:

var a = new Person();
alert(a.fname);
Pumbaa80
+2  A: 

JavaScript does not have classes like others have said. Inheritance is resolved through prototyping which in essence does nothing more then create non-deletable property references on a newly created object. JavaScript also has alternatives for simple data objects, namely object literals.

The variation of a 'Class' in JavaScript should be defined as such:

// I use function statements over variable declaration 
// when a constructor is involved.
function Person(name) {
    this.name = name;
}

// All instances of Person create reference methods to it's prototype.
// These references are not deletable (but they can be overwritten).
Person.prototype = {
    speak: function(){
        alert(this.name + ' says: "Hello world!"');
    }
};

var Mary = new Person('Mary');
Mary.speak(); // alerts 'Mary says: "Hello world!"'

The this reference always points to the owner of the function. If you call Person without the new operator, the owner will be the global scope (window). If you do not use the this reference to assign properties to your instance, then the properties will simply be declared as variables. If you do not use the var statement, then those declarations will create global variables which is bad!

more about this

Using the this reference in a constructor function is exceedingly important if you want to add properties to the current instance. Without using this, you only create a variable (which is not the same as a property) and as mentioned, if you don't use the var statement either, you create global variables.

function Person(){
    name = 'Mary'
}
var p = new Person();
alert(p.name); // undefined, did not use 'this' to assign it to the instance.
alert(name); // 'Mary', boo, it created a global variable!

Use this!

function Person(){
    this.name = 'Mary'
}
var p = new Person();
alert(p.name); // 'Mary', yay!
alert(name)l // undefined, yay!

Note, anything assigned to an instance through the function constructor CANNOT BE INHERITTED unless you assign it to the prototype and overwrite it again in the function constructor to make it an owned property.

When you create a new instance of through a function doubling as a constructor, actually the following happens.

pseudo code:

   copy Person.prototype as person
   invoke Person function on person
   return person

Actually, this is what happens in every classical language when you create an instance of a class. But the main difference in JavaScript, is that it's not encapsulated inside a nice Class statement. Originally JavaScript didn't even have function constructors but where added on later because SUN demanded they wanted JavaScript to be more like Java.

Object literals

The alternative for function constructors for objects that carry only intrinsic data and no methods are object literals.

var Mary = {
    firstName: 'Mary',
    lastName: 'Littlelamb'
};

Which is the prefered way of declaring intrinsic objects rather then:

// do not ever do this!
var Mary = new Object();
Mary.firstName = 'Mary';
Mary.lastName = 'Littlelamb';

With object literals in your skill set, you can create a factory pattern for intrinsic data objects using the module pattern (which is usually for singletons).

var createPerson = function(firstName, lastName){
    return {
        firstName: firstName,
        lastName: lastName
    }
}
var Mary = createPerson('Mary', 'Littlelamb');

This achieves some comfortable encapsulation, but can only be used for intrinsic data objects.

Another thing you can do with Object literals and JavaScript is delegation, which should be prefered.

var personMethods = {
    speak: function(){
        alert(this.firstName + ' says: "Hello world!"');
    }
};

var Mary = {
    firstName: "Mary",
    lastName: "Littlelamb"
};

var Peter = {
    firstName: "Peter",
    lastName: "Crieswolf"
};

personMethods.speak.apply(Mary); // alerts 'Mary says: "Hello world!"'
personMethods.speak.apply(Peter); // alerts 'Peter says: "Hello world!"'

Why should this be prefered? Because it keeps your objects minute and readable, even prototypical references take up memory and when using inheritance and 'subclassing' you end up with child instances that have lots of unused method references. Delegation is always better.

BGerrissen
+1 This. Most of the other answers are just confusing with their use of the term `class`.
Ivo Wetzel
@BGerissen: You must have way too much time on your hands;) I disagree with the last part of your answer. An object *always* has a reference to its prototype, so you won't win anything using delegation. Objects do not inherit references to the prototype's members; they use dynamic runtime resolution (which is a good thing for extending or replacing inherited methods)
Pumbaa80
@Pumbaa80 give it some more thought ;)
BGerrissen
@BGerissen: After reading your answer again very carefully, I found that you your explanation on prototypal inheritance (the `pseudo code` part) is wrong, which is probably why you think that delegation saves memory. (See sections 13.2.2 and 11.2.2 of [ECMA-262](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf))
Pumbaa80