0

Possible Duplicate:
Preserving a reference to “this” in JavaScript prototype functions

I'm not good at English. Please understand

When my friends have javascript oop implement

function Item (a, b, c) {
    var _a = a, _b = b, _c = c;

    return {
        init: function () {
            ...
        },
        start: function () {
            ....
        }
    }
}
var item = new Item();
item.init();
item.start();

But I would like to know the following.

function Item (a, b, c) {
    this.a = a, this.b = b, this.c = c;
}

Item.prototype.init = function () {...}
Item.prototype.start = function () {...}
var item = new Item();
item.init();
item.start();

Which do you think you?

Community
  • 1
  • 1
Mr. Kim
  • 1
  • 4
  • 1
    They are both acceptable, with subtle differences in visibility, overriding, and number of function objects/scopes .. there are also a number of duplicate questions. (Generally though, the first form would use `this.init = function ..` to not "waste" the `new`.) –  Dec 13 '12 at 05:40
  • 1
    In the first case you'd do `var item = Item()`, I think that's the whole point of that approach is to not use `new`...or not? – elclanrs Dec 13 '12 at 05:42
  • http://stackoverflow.com/questions/907225/object-oriented-javascript-best-practices – Buzz Dec 13 '12 at 05:42

2 Answers2

1

They have some differences. In the first case:

function Item (a, b, c) {
    var _a = a, _b = b, _c = c;

there is no need for the second line, a, b, c are already local variables held in a closure and so emulate private variables. It could be written:

function Item (_a, _b, _c) {

and as others have pointed out, it should be called without new.

In the second:

function Item (a, b, c) {
    this.a = a, this.b = b, this.c = c;

the new object will have public a, b, c properties. It just depends on your requirements whether you need private members (rare) or need inheritance (it's fairly common not to). Often a singleton is sufficient so a plain object will do and you can use the first pattern.

It's only a short step to the module pattern developed by Richard Cornford et al and popularised by Douglas Crockford.

RobG
  • 142,382
  • 31
  • 172
  • 209
1

Parameters

Your friends:

Why are the params reassigned to '_' versions? The parameters are for all intents and purposes that I'm aware of the same thing as a local var.

Yours:

Why do you feel the need to expose those parameters? If those values only matter to the object instance, they should stay local vars. They will exist as long as the object exists and don't have to be properties.

Prototype

Why use prototype here? There are many good reasons but I use this.method first because it can access local vars defined inside the constructor. Prototype methods can't.

new function(){} vs. {}

I mostly reserve {} objects for data-only, or simple struct-type objects that are more of a collection of utility methods than proper OOP constructs. But once I'm modelling something that needs to maintain state I usually go with function constructors:

var sleepyInstance = new function(){
    var activeState = true;

    this.sleep = function(){
        activeState = false;
    }

    this.doSomething = function(){
        if(activeState){ alert ('did something!'); }
        else { alert('ZZZZZzzz'); }
    }

}

Prototype is better used for things like object factories, use of 'this' to override default prototype methods, and for inheritance. If you're not sure a property needs to be exposed, make it a var. If you're not sure why you're using prototype, just attach the method directly to the instance with 'this'. Prototype typically makes the most sense for building a similar object in different ways.

Erik Reppen
  • 4,605
  • 1
  • 22
  • 26