开发者

Difference between a constructor and an Object

I definitely need some light 开发者_StackOverflow中文版on this.

What's the diference between:

var MY_APP = function(){
    this.firstMethod = function(){
       //something
    };
    this.secondMethod = function(){
       //something
    };
};

and

var MY_APP = {
    firstKey: function(){
       //something
    },
    secondKey: function(){
       //something
    }
};

besides the obvious fact that one is a Function and the other an Object, what are the differences in code flow, prototypes, patterns... whatever, and when should we use the first or the second?

I'm so spaced out in this area that i'm not sure if i'm correctly explaining the doubt, but further info can be given if you ask.


The key difference between the two is in how they are intended to be used. A constructor, as its name suggests, is designed to create and set up multiple instances of an object. An object literal on the other hand is one-off, like string and number literals, and used more often as configuration objects or global singletons (e.g. for namespacing).

There are a few subtleties about the first example to note:

  1. When the code is executed, an anonymous function is created and assigned to MY_APP, but nothing else happens. firstMethod and secondMethod don't exist until MY_APP is explicitly called.
  2. Depending on how MY_APP is called, the methods firstMethod and secondMethod will end up in different places:
    1. MY_APP(): Since no context is supplied, the this defaults to window and the methods will become global.
    2. var app1 = new MY_APP(): Due to the new keyword, a new object is created and becomes the default context. this refers to the new object, and the methods will get assigned to the new object, which subsequently gets assigned to app1. However, MY_APP.firstMethod remains undefined.
    3. MY_APP.call(YOUR_APP): This calls my MY_APP but sets the context to be another object, YOUR_APP. The methods will get assigned to YOUR_APP, overriding any properties of YOUR_APP with the same names. This is a really flexible method that allows multiple inheritance or mixins in Javascript.

Constructors also allow another level of flexibility since functions provide closures, while object literals do not. If for example firstMethod and secondMethod rely on a common variable password that is private to the object (cannot be accessed outside the constructor), this can be achieved very simply by doing:

var MY_APP = function(){
    var password = "GFHSFG";

    this.firstMethod = function(){
       // Do something with password
       alert(password); // Woops!
    };
    this.secondMethod = function(){
       // Do something else with password
    };
};

MY_APP();

alert(password); // undefined
alert(MY_APP.password); // undefined


The first is a function, the second is an object literal. Since Functions in JS are first class objects, a function can have properties on it, just like any other object can.

Typically, if you want to create a "class" that you might be familiar with from classical inheritance languages, you would do something like

function MyClass() {...}

as is documented here http://www.crockford.com/javascript/inheritance.html

To answer the question posed in your edits, you would use them both in different situations. Object literals are used to pass configurations around. A typical usage pattern would be a method that accepts an object literal like so

 something.init({
      length: 10,
      height: 10,
      text: 'some text'
 });

and so on.

You could use something similar to your first example when creating a namespace. Javascript has some interesting language features in that you can have so-called "self-invoking functions" that are of the form:

var myApp = (function(){
    var firstMethod = function() {...}
    ...
})();

the motivations behind doing something like this are detailed here
http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/

You can also investigate the differences via your favorite javascript debugging console. In firebug and chrome, I did the following:

var ol = {}; ol.prototype;

var fn = function(){}; fn.prototype;

the first line prints undefined, the second returns a prototype with a constructor of 'function'


The constructor can be reused as is, the object literal would need to be repeated or wrapped in a function to be reused.

Example of wrapping the object literal in a function:

function MY_APP() {
  return {
    firstKey: function(){
       //something
    },
    secondKey: function(){
       //something
    }
  };
}

The object created using the constructor will have it's constructor property set to the constructor function. However, as you used an anonymous function assigned to a variable instead of a named function, the constructor will still be nameless.

Other than that, there isn't really any differences. Both create anonymous functions that are assigned to the properties of the object, so the resulting objects are the same. You can compare this to assigning named functions to the properties, or using prototype functions, both having the difference that each function only exists once instead of being created over and over for each object.


There is some confusion in JavaScript regarding the difference between a function and an object.

In the first case,

  var MY_APP = function() { this.v = 7; ... }

or

  function MY_APP(x) { this.v = x; ... }

a function is declared, not an object. In MY_APP, this refers to the global object.
Meaning that calling the function MY_APP(7) will assign v globally to the value of 7. (and in your case the function firstMethod would be declared globally).

  MY_APP(3);  // The global variable v is set to 3
  MY_APP(4);  // The global variable v is overwritten and set to 4

To use MY_APP as an object, it needs to be instantiated, for instance

  var obj1 = new MY_APP(3);
  var obj2 = new MY_APP(4);

will have obj1.v to be 3, and obj2.v to be 4.

Note you can also add methods using the prototype keyword (instead of this.firstMethod...)

  MY_APP.prototype.firstMethod = function () { ... }

In the second case

  var MY_APP = { ... };

an object, one object, is created and its name is MY_APP. The this keywords refers to that object, MY_APP.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜