Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between var thing and function thing() in JavaScript?

I was just wondering about the difference between the following declaration of JavaScript objects. Specifically, the difference between thing object literal and thing1 object from thing class.

Code:

var thing = {
    sanity:0,
    init:function(){
        //code
    },
    send:function(){
        //code
    }
}

function thing(){
    this.sanity = 0;
    this.init = function(){
        //code
    };
    this.send = function(){
        //code
    };
}

thing1 = new thing();
like image 452
FurtiveFelon Avatar asked Nov 09 '09 23:11

FurtiveFelon


People also ask

Why VAR should not be used in JavaScript?

Scoping — the main reason to avoid var var variables are scoped to the immediate function body (hence the function scope) while let variables are scoped to the immediate enclosing block denoted by { } .

What is the use of VAR in JavaScript?

var is the keyword that tells JavaScript you're declaring a variable. x is the name of that variable. = is the operator that tells JavaScript a value is coming up next.

What are var functions known as?

Explanation: The "function" and "var" both are the Declaration statements. These both are used for defining, and declaring variable, function in anywhere in the program.

Should I use VAR or let in JavaScript?

As a general rule, you should always declare variables with const, if you realize that the value of the variable needs to change, go back and change it to let. Use let when you know that the value of a variable will change. Use const for every other variable. Do not use var.


2 Answers

Static Objects / Object Literals

Static objects, or object literals, don't require instantiation with the new operator and also behave like singletons. Consider the following example:

Code:

var staticObject1 = {
 a: 123,
 b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);

Output:

Object a=123 b=456  Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats

Notice that changing staticObject2.b also affected staticObject1.b. However, this may not always be the desired effect. Many libraries, such as Dojo, offer an object cloning method that can alleviate this situation if you want to make a copy of a static object. Continuing the previous example, consider the following:

Code:

var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);

Output:

Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats

Notice that the values of the members of staticObject1 and staticObject2 are the same, whereas staticObject3 is not affected by changes to these other objects.

Static objects are also useful for creating project or library namespaces, rather than filling up the global scope, and promotes compatibility like no one's business.

This is useful when creating libraries that require portability or interoperability. This can be seen in popular libraries such as Dojo, YUI and ExtJs, where all or most methods are called as dojo.examplMethod(), YUI().exampleMethod(), or Ext.exampleMethod() respectively.

Static objects can also be considered loosely analogous to struct's in C/C++.

Class Constructors / Instantiated Objects

Classes in JavaScript are based on prototypal inheritance, which is a far more complex subject and can be read about here, here and here.

As opposed to static objects, this method of object creation gives the unique opportunity for private scope object members and methods because of JavaScript's closuer property. Consider the following example of private class members:

Code:

var SomeObject = function() {
    var privateMember = "I am a private member";
    this.publicMember = "I am a public member";

    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
};

var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();

Output:

undefined string
I am a private member I am a public member

Notice that typeof o.privateMember is "undefined" and not accessible outside of the object, but is from within.

Private methods can also be made, but are not as straight forward yet are still simple to implement. The issue lies in that the value of this inside of the private method defaults to window and one of two techniques must be applied to ensure that this refers to the object that we are working within, in this case, the instance of SomeObject. Consider the following example:

Code:

var SomeObject = function() {
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(this.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod.call(this);
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

Output:

undefined function function
I am a public member

Notice that withing privateMethodWrapper(), privatemethod was executed using call and passing in this for the function's context. This is all fine; however, the following technique is preferable (in my opinion) as it simplifies the calling scope and produces identical results. The previous example can be changed to the following:

Code:

var SomeObject = function() {
    var self          = this;
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(self.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod();
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

Output:

undefined function function
I am a public member

This answer was the basis for a post on my blog, where I give additional examples. Hope that helps ;)

like image 96
Justin Johnson Avatar answered Sep 17 '22 21:09

Justin Johnson


Case 2 is referencing javascript class constructors. A glaring difference is that the variable is not yet an object, so you cannot internally reference thing1.sanity. You would have to initialize the class by creating an instance of said class prior to calling any internal members:

var myConstructor = function() {
    this.sanity = 0;
}

// wont work
alert(myConstructor.sanity);

// works
var thing1 = new myConstructor();
alert(thing1.sanity);

Here is an article going further in-depth than my quick example:

Class Constructors vs. Object Literals

like image 42
Corey Ballou Avatar answered Sep 17 '22 21:09

Corey Ballou