Germaine
Germaine

Reputation: 11

Which method of creating javascript objects is better?

I've seen objects defined in two different ways, which function similarly, but are, of course, fundamentally different. You can do it either like this:

var myobject = {property: 'hello',
                act: function() {
                    this.property += ' world';
               }};

and like this:

function myobject() {
    this.property = 'hello';
    this.act = function() {
        this.property += 'world';
    }
}

The second method could create objects like so

var newobj = new myobject();

but you could do something similar using the first notation by making the object the return value of a function. The new keyword has the advantage of being able to pass parameters that can be used to initialize the properties of the object, but you could just as easily add an init function to the first kind of object.

Just wondering if besides these two differences, if there was a fundamental difference that made one method definitely better than the other method.

Upvotes: 1

Views: 156

Answers (3)

ekim
ekim

Reputation: 141

javascript:
  canDo="b:c=function(){}";
  canNot="function a:d(){}";

  eval(canDo);

  alert(["Can do ",canDo,
         ".\n\n\nConfirmed result is: \n\n b:c=",
         eval("b:c")
        ].join(""));

  alert(
    confirm(
      "Click OK to confirm this is not valid (can NOT do):\n\n" + canNot) ?
    eval(canNot) : "Test will fail if attempted and 'a:d' will not exist."
  );

displays, in FireFox:

Can do b:c=function(){}.


Confirmed result is: 

 b:c=function () {
}

and

Click OK to confirm this is not valid (can NOT do):

function a:d(){}

which gives a runtime error if OK is chosen.

Upvotes: 0

austin cheney
austin cheney

Reputation:

var f = function () {};
function g () {}

if (typeof(f) === typeof(g)) {
    alert(typeof(f) + "\n" + f + "\n" + g);
}

The types are identical and variable f has an anonymous function assigned to it. Since f is a named variable with a function as its value it is a function that is not anonymous. JavaScript is a lambda language of downward inheritance that allows accidental creation of global variables. With regard to complex instances of inheritance where closures are used across the variance namespace scopes you have to be sure where your variables are defined to prevent collisions, especially with consideration for reuse. The first convention forces strict awareness of variable declaration, because the function must be declared before it can be executed. The second convention supplies no such awareness, which is potentially problematic with regards to instantiation and invocation as closure in complex logic prior described. Fortunately, JSLint is smart enough to throw an error when a function is used before it is declared. Since the two conventions are identical in representation I would suggest only using the one that is not open to abuse from flawed and sloppy programming.

In summary if g and f are both named variables with a function as assignment then always do it the right way using the first convention where you declare your variable using the var keyword.

Upvotes: 0

Thomas Eding
Thomas Eding

Reputation: 1

The second is better because you can reuse it. In addition, the constructor property of the constructed object is different in each case.

That aside, the second method wastes space by allocating a new function to the act property each time you call the constructor. (Note that the first method also wastes space in the same way.) Use prototypes instead:

function MyConstructor () {
  this.property = 'hello';
}

MyConstructor.prototype = {
  act: function () {
    this.property += 'world';
  }
};

MyConstructor.prototype.constructor = MyConstructor;

var obj = new MyConstructor ();

Upvotes: 2

Related Questions