So for this random project (another one) I'm working on geocodeing a spreadsheet of addresses and adding them to a map. I'm building with the constructor.prototype stuff that you showed me with Guss and am wondering how far I can extend the prototype for more organization. Say for instance I'd like to split my functions into categories such as "spreadsheet" and "map" where I could essentially do all spreadsheet functions by calling:
this.spreadsheet.get
OR this.spreadsheet.query
OR this.spreadsheet.print_to_dom
and similarly could use my mapping functions like:
this.map.init_tiles
OR this.map.add_points
basically keeping everything scoped within the same set of parent functions instead of all at the same parent constructor level.
Is the best way to to do this by essentially making that first-level prototype function a standard object like:
constructor.prototype.map = {
init_tiles: function () { ... },
add_points: function () { ... },
etc: function etc () { ... }
}
??
It doesn't seem to work by declaring the object literally in stride like constructor.map.add_points
because using this.map.add_points
within the scope results in an undefined error. Is this where I should start using constructor.Class
or something?
A couple things:
1)
There's no reason you have to use the keyword
prototype
to build your class. For example, you could create aBam
class like the snippet below. Both the way it's done above and below are mostly identical. There are subtle differences about where the attributes are stored. It's mostly a matter of 1) preference and slightly 2) code reuse for setting up inheritance. Word of advice, just choose one and stick with it like a pattern ( that's basically why i build everything off theprototype
). Number #2 below explains more about the subtle differences.2)
I think one thing to focus on is that
prototype
has a special relationship with aconstructor function
.For example, given this:
What do we expect the variable
x
to hold after executing this code?and what do we expect the variable 'x' to hold here?
The difference between a normal function and a constructor function is the use of the keyword
new
. The first example above is just a normal function and since nothing is returned, it returnsundefined
:The second example above uses the keyword
new
. In cases like these, the function does some magic which you should be familiar with andalways
returns a fresh object. Since one of those magic steps is binding aprototype
object to the new object, then let's illustrate whatx
would hold and where it holds it when usingprototype
:I'm glad you're reading the Leaflet code and used it here. That function above
L.Class.extend
has everything to do with reusing theprototype
to mimic inheritance. Notice all theproto
stuff in that code. Many projects use this same style ofextend
to do inheritance. For example, Rancho uses a very similar function that was stolen fromBackbone
.With generic extending functions like that, you can now dynamically create prototype chains by passing objects when doing inheritance. Here is an example on Rancho