Reputation: 11112
Given the following code (StoriesMap.js)...
// Initalization; Creates Map
var StoriesMap = function StoriesMap( id, location, tileset ) {
this.map = L.map( id ).setView([ location.lat, location.lon ], location.zoom);
// Add inital points to map
this.populate( location );
// Redraw on map movement
this.map.on("viewreset", function( event ) {
var location = {
lat: event.target._animateToCenter.lat,
lon: event.target._animateToCenter.lng,
zoom: event.target._animateToZoom
};
this.redraw( location );
});
var mapTiles = L.tileLayer( tileset.url, { attribution: tileset.attribution, minZoom: 4, maxZoom: 12 } ).addTo( this.map );
}
// Put some points on the map
StoriesMap.prototype.populate = function populate( location ) {
var priority = location.zoom - 3;
if ( typeof points === "object" ) {
var buffer = [];
for ( var i in points ) {
var point = points[i];
if ( point.priority <= priority ) {
var circle = L.circle([ point.lat, point.lon ], 100000, {
color: '#f03', fillColor: '#f03', fillOpacity: 0.5
}).addTo( this.map );
}
}
}
}
// Filters map contents
StoriesMap.prototype.filter = function filter( map, location ) {
console.log( "filter" );
}
// Redraws map points
StoriesMap.prototype.redraw = function redraw( map, location ) {
console.log ( this.map )
for ( var i in map._layers ) {
if ( map._layers[i]._path != undefined ) {
try {
map.removeLayer( map._layers[i] );
}
catch(e) {
console.log("problem with " + e + map._layers[i]);
}
}
}
}
StoriesMap.prototype.fake = function fake() {
console.log("Always Called when object is Initialized");
}
When I run (from my html):
var map = new Map();
I always get:
Always Called when object is Initialized
in my console. For whatever reason, my last defined prototype is being treated like a constructor, and I'm not sure why. I don't want that function to run when I initialize my object, is it assumed to be a constructor? This has happened to me before and my normal reaction has been to create a last prototype function with the name "fake" and to leave it empty, but what is the proper resolution to this issue?
Upvotes: 0
Views: 204
Reputation: 115970
This code has other code concatenated to it at some point (probably during some kind of build process or minificaiton). The other code begins with a parenthesized statement:
StoriesMap.prototype.fake = function fake() {
console.log("Always Called when object is Initialized");
}
// start of other code...
(...);
However, JavaScript reads this as:
StoriesMap.prototype.fake = function fake() {
console.log("Always Called when object is Initialized");
}(...);
So StoriesMap.prototype.fake
is not equal to the function, but instead the function is immediately invoked, using the parenthesized expression as an argument. StoriesMap.prototype.fake
is set to the return value of the immediately invoked function.
Simply add a semicolon at the end of the function expression, and this won't happen, because the parenthesized statement and the function will be separated by a semicolon:
StoriesMap.prototype.fake = function fake() {
console.log("Always Called when object is Initialized");
};
(...);
JavaScript's automatic semicolon insertion only occurs when the lack of a semicolon would cause a violation of the language grammar. See the bottom of ES 7.9.2 for an example similar to this one:
The source
a = b + c (d + e).print()
is not transformed by automatic semicolon insertion, because the parenthesised expression that begins the second line can be interpreted as an argument list for a function call:
a = b + c(d + e).print()
In the circumstance that an assignment statement must begin with a left parenthesis, it is a good idea for the programmer to provide an explicit semicolon at the end of the preceding statement rather than to rely on automatic semicolon insertion.
Upvotes: 2