1

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.

Germaine
  • 11
  • 1
  • 1
    There is a lot of difference and no-one agrees on one method being better. Background: http://stackoverflow.com/questions/1595611/how-to-properly-create-a-custom-object-in-javascript – bobince May 04 '10 at 02:50

3 Answers3

2

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 ();
Thomas Eding
  • 35,312
  • 13
  • 75
  • 106
  • You can reuse the first method no more or less than the second method. The only difference is that the first must be declared before it is called or executed. –  May 04 '10 at 03:57
0
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.

0
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.

ekim
  • 141
  • 1
  • 3