First, why is it better to inherit it?
I get several arguments for inheritance, though I prefer composition (modules/components and dependency-injection) myself.
Second, you get reuse out of doing:
function Vector2D (x, y) {
this.x = x;
this.y = y;
}
function Vector3D (x, y, z) {
Vector2D.call(this, x, y);
this.z = z;
}
Third, in a large-scale JS app, creating tens of thousands (or millions) of polygons, the extra function calls are just going to slow it down, unnecessarily.
Fourth, you can't use
Vector3D.prototype = new Vector2D();
First, you're not initializing x
and y
to anything inside of the Vector2D.
Second, prototype
is meant to hold STATIC properties and functions, if you're coming from other languages.
Even if you did initialize Vector2D
, it would still be the exact same Vector2D for every instance of your Vector3D class.
Why not just:
var point2D = function (x, y) {
return { x : x,
y : y };
},
point3D = function (x, y, z) {
return { x : x,
y : y,
z : z };
};
...and when you have those particular building-blocks as your base elements, compose different modules which use them?
EDIT
function anObj (x, y) {
var privateFunc = function () { return y; };
return {
x : x,
method : function () { return privateFunc(); }
};
}
var myObj = anObj(1, 2);
myObj.x; // 1
myObj.method(); // 2
The upside here is that you've now got private variables (privateFunc
and y
).
The downside is that in terms of memory-usage, each instance of your object needs to have its OWN copy of any private methods.
So if you're making hundreds of thousands of these objects (vertices/polygons, for example), and they don't NEED to have private state, this isn't the method to use.
If, however, you're making players or enemies, or controllers, or anything which you DON'T want tampered with, then you DO want to use a method like this (or more advanced).
If you have a situation where you might want STATIC data / methods which are also 100% private, then you should try a format like this:
var objectMaker = (function () {
var staticData = 32,
staticFunc = function (num) { return num + staticData; };
return function (x, y) {
var privateData = 12,
privateMethod = function (num) {
return y + privateData + staticFunc(num);
};
return { x : x,
method : function (num) { return privateMethod(num); }
};
};
}());
var myObj = objectMaker(3, 4);
myObj.x; // 3;
myObj.method(12); // 12 + y(y === 4) + privateData + staticData;
So what we've done here is we've got an immediately-firing function (it fires as soon as its defined, and returns the value of the function to the variable).
So in our particular case, this function immediately returns the actual function that we want to use to make new instances.
The private variables and functions that are inside of the immediate function (not the constructor we return) are static, in that every instance you create will have access to the exact same functions/data inside of that closure.
The downside is that those static functions have NO access to private (or even instance-specific) data.
This means that you have to pass your values into the static function, and catch the return from the static function, as you can't rely on the static methods to modify instance values (technically, you can modify objects/arrays, directly if you pass them into the function, but otherwise you must catch return values).
Now you can have plenty of helper functions which are shared amongst instances (lower memory), while still being private and secure.
If what you want is public properties, public methods, and static methods/properties, THEN you can access them like so:
var Obj = function (x, y) {
this.x = x;
this.per_instance_method = function () { return y; };
};
Obj.prototype.staticData = { z : 32 };
Obj.prototype.staticMethod = function () { return this.x + this.staticData.z; };
var myObj = new Obj(3, 4);
myObj.staticMethod();
...just don't expect any prototype method to have access to any instance's private data (like y
).