1

after experimenting with js's prototypal inheritance i've found that i'm not wild about the idea of having to declare my object's methods outside of the object:

function obj(){
  this.averyday='i\'m shuffle\'n';
  this.gibmo='dinero';
  this.pullOut='that\'s what she said lol';
}

obj.prototype.alertProp=function(){
    alert(this.averyday);
}
obj.prototype.alertProp2=function(){
    alert(this.gibmo);
}

so i came up with a way to organize my methods into one namespace

obj.prototype.m={
    //i'm passing in the object instance so the mathods can have access to it's properties
    alertProp:function(that){
          alert(that.theObj.everyday);
    },
    alertProp2:function(that){
          alert(that.myObj.gibmo+' '+that.myObj.someVal); // alerts "dinero some other value to be use "
    }
} 
var myobj = new obj;

then to use i just call the method and pass in the objects instance(if the method needs to modify the object's properties)

myobj.m.alertProp({theObj:myobj,someVal:'some other value to be use'}) //alerts "i'm shuffle'n"

so here are some pros that i've noticed:

PROS:

1) organizes the methods into one centralized area.

2) accesses the "prototype" of an object only once(in effect uses less code).

3) seems more readable(at lease to me).

CONS:...this is where i need you'alls help, does anyone see anything wrong with doing it this way? any performance issues or anything wrong with the pros i've outlined etc...?

also does anyone see any other pros that i may not be seeing or that aren't apparent?

zero
  • 2,999
  • 9
  • 42
  • 67

1 Answers1

1

I find it a little bit complicated, this is how I like to do it:

MyObject = function (options) {
   this.init(options);
};

MyObject.prototype = {
  /**
   * Documentation
   */
  variable1: null,

  init: function (options) {
    // do something with options.
  },

  alertVariable: function () {
    alert(this.variable1);
  }
};

So you don't have to worry about sending extra parameters, you just call it.

----------------------------EDIT---------------------------------

Well, I don't know if I got it right, but after some reading I believe this would "fixing the constructor" mean. If I create an object like this:

Foo = function () {
  // Do something
};

Then Foo.prototype.constructor == Foo, as one would expect. The problem with my method (thanks Raynos) is that when I'm doing this:

Foo.prototype = {...};

I'm overwriting all of Foo's prototype, so that Foo.property.constructor != Foo, and that is not what we would expect! Instead of that we have that Foo.property.constructor == Object.prototype.constructor.

So, how we fix it?

Foo.prototype = {
  constructor: Foo, // <-- FIXED!
  ...
};

Ta da!

(this helped a lot: http://beej.us/blog/data/javascript-prototypes-inheritance/ )

Chango
  • 6,754
  • 1
  • 28
  • 37
  • you forgot to fix the `constructor` property – Raynos Apr 12 '12 at 20:56
  • Excuse me, but I disagree, I see nothing missing, could you please be more clear? – Chango Apr 12 '12 at 20:58
  • As I see it, there is nothing to 'fix' about the constructor with this method. Here is a simple post explaining it: http://stackoverflow.com/questions/4012998/what-it-the-significance-of-the-javascript-constructor-property – Chango Apr 12 '12 at 21:05
  • Try to shim `Object.getPrototypeOf` without the `constructor` property – Raynos Apr 12 '12 at 21:14
  • I'm glad that we agree! it's not that important in every case to fix the constructor property. Thanks! – Chango Apr 13 '12 at 02:48
  • I'm writing some code right now that would fail if the mongoDB driver author choose to agree with "fixing the constructor property is not important" – Raynos Apr 13 '12 at 04:44
  • I believe that different problems call for different solutions. I haven't run into a problem that requires that solution (yet), but I would love to see an example, if you are so kind. – Chango Apr 13 '12 at 13:28
  • @Raynos it seems like his way also works well with inheritance: http://jsfiddle.net/4tYj9/ unless there's something i'm missing? by the way whats shim? – zero Apr 13 '12 at 13:44
  • also chango, in the example (jsfiddle) that i gave how would i add a new group of methods to baby if its prototype is now parent? i would have to group them in a new namespace like i was doing above correct? – zero Apr 13 '12 at 13:49
  • @Raynos sorry i didn't read your link at first(explaining legacy JavaScript) so would chango's way only be bad in legacy JavaScript engines(which i'm guessing are older browsers e.g.ie7 and below) – zero Apr 13 '12 at 13:59
  • 1
    I believe that you would have to add the methods one at the time: `baby.prototype.newMethod = function(){...};` If you still want to group all your methods you could create a simple extend method that copies all the properties in an object to baby's prototype: `baby.prototype = new parent()` and `babyPrototype={...};` and then `extend(baby.prototype, babyPrototype);`, it's not very clean though. – Chango Apr 13 '12 at 14:13
  • 3
    The correct thing to do is to make sure you add `{ ..., constructor: Foo }` back in your prototype assignment – Raynos Apr 13 '12 at 15:22
  • ah, nice...i like the way you added back the constructor link. the only thing i can see is when you go to inherit you'll lose the ability to organize this way example: newObj.prototype= new oldObj; doing it this way means i can't overwrite the newObj's prototype to group my methods, if i do it will overwrite the inheritance. so it seems like this way of organizing methods is good for a single object – zero Apr 13 '12 at 16:16
  • what would the guts of the extend function look like? – zero Apr 13 '12 at 16:22
  • You could study jQuery's solution: https://github.com/jquery/jquery/blob/master/src/core.js#L297 – Chango May 31 '12 at 15:23