bizzehdee
bizzehdee

Reputation: 21023

Difference between creating javascript objects

When creating an object to use JS in an OO manner, is there any difference within a JS engine between (with the exception of being able to define a constructor:

var Uploader = Uploader || {};

and

var Uploader = function() {

}

and

function Uploader() {

}

Especially when later, you wish to do something along the lines of

Uploader.DOM = {    
    Create: function(file) {

    }
};

Is it all down to personal preference? Or is there a real difference?

Upvotes: 2

Views: 84

Answers (1)

Dmitry
Dmitry

Reputation: 7276

Objects:

var MyObj = {
    myArr: [1,2,3],
    find: function(/*some arguments*/) {
        //some logic that finds something in this.myArr
    }
}

In MyObj.find function this keyword will point to MyObj (which somewhat resembles how this works in languages those have classes). You can use this functionality to do mix-ins:

var MyObj2 = {
    myArr: [4,2,6]
}

MyObj2.find = MyObj.find;

In MyObj2.find function this keyword will point to MyObj2.

Also objects support getters and setters (works on IE9+ and all good browsers):

var MyObj = {
    myArr: [1,2,3],
    find: function(/*some arguments*/) {
        //some logic that finds something in this.myArr
    },
    get maxValue() {
        return Math.max.apply(null, this.myArr);// maxValue is calculated on the fly
    },
    a_: null,
    get a () {
        return this.a_;
    },
    set a (val) {
        //fire a change event, do input validation
        this.a_ = val;
    }
}

Now max value in the array can be accessed like this: MyObj.maxValue. I also added a property a_. It can't be named the same as its getter and setter so appended an underscore. Appending or prepending underscores is a naming convention for private variables which should not be accessed directly.

var qwe = MyObj.a // get a_
MyObj.a = 'something'; //set a_

Functions:

var u = new Uploader(); // will throw an exception
var Uploader = function() { }

Uploader is defined in runtime here. It does not exist yet when I try to instantiate it.

var u = new Uploader(); //will work
function Uploader() {}

Uploader is defined in compilation time here so it will work.

Functions can be used with revealing pattern to conceal some members. Functions don't support getters and setters but you can put objects inside functions.

function myFunc() {
    function privateFunc() {};
    function publicFunc() {};
    var obj = {
        //members, getters, setters
    };
    return {
       publicFunc: publicFunc,
       obj: obj
    }
}

You can call muFunc.publicFunc() outside of myFunc because it is returned. But you can not use privateFunc outside because it is not returned. Revealing pattern functions are not meant to be instantiated usually. This is because when you instantiate it everything inside will be copied to a new instance. So it will use up more memory than if you would add functions using prototype.

myFunc.prototype.someFunc = function() {};

Like this all instances of myFunc will share the same instance of someFunc.

Conclusion: with functions you can simulate a private access modifier but in objects the this keyword acts somewhat similar of what you'd expect in a language that have classes. But you always can use call, apply and bind to change the context (i.e. what 'this' keyword will be) of the function.

Upvotes: 1

Related Questions