I'm developing a node.js application. Looking for ways to create the datamodel.
The data being sent to/from the client is JSON. Since database is MongoDb, the data to/from the db is JSON.
I'm new to JS, I could find so many js libraries dedicated to creating encapsulated objects. Is it still required?
What are the possible consequence of just defining models as simple js objects, and use prototype based inheritance where necessary?
Any help is appreciated. Thanks.
What are the possible consequence of just defining models as simple js
objects, and use prototype based inheritance where necessary?
IMO, You will lose maintainability over the time as your application size increases or your team size increases as many developers start working on the same code.
In other words - Without proper encapsulation it is easy to modify objects one doesn't own - easy to meddle with the parts that you don't want to be touched.
If you are writing a library/framework of some sort where the just APIs are exposed to the user and you don't have proper encapsulation one could probably bring everything down by just one modification.
For example:
var myObj = {
mySecretPrivateCrucialFunction: function () {
// all the awesome crucial logic
},
//This is what you want other parts of the code ...
// ... to be interacting with in this object
myPublicMethod: function () {
// some logic
mySecretPrivateCrucialFunction();
// some thing else
}
}
I can do this.
myObj.mySecretPrivateCrucialFunction = function () {
alert('yay..i got you..');
};
But if you do this way - you don't give that chance.
var myObj = (function () {
var mySecretPrivateCrucialFunction = function () {
// all the awesome crucial logic
}
//This is what you want other parts of the code ...
// ... to be interacting with in this object
return {
myPublicMethod: function () {} /*some logic */
mySecretPrivateCrucialFunction(); /*some thing else */
}
})();
In case you want to make all your properties hidden/private and still want to get the JSON representation of the object - you can do something like this -
var myObj = (function () {
// your private properties
var prop1 = 1;
var prop2 = 2;
// your getters
var getProp1 = function () {
return prop1;
};
var getProp2 = function () {
return Prop2;
};
// your setters
var setProp1 = function (newValue) {
prop1 = newValue;
};
var setProp2 = function (newValue) {
prop2 = newValue;
};
// your JSON representation of the object
var toString = function () {
return JSON.stringify({
prop1: prop1,
prop2: prop2
});
};
// Object that gets exposed -
return {
"getProp1": getProp1,
"getProp2": getProp2,
"setProp1": setProp1,
"setProp2": setProp2,
"toString": toString
}
})();
There are two ways to approach this question as I see it:
I'm assuming that your data is being transfered as a JSON string.
"[{\"key\":\"val\"}]" is showing up in your responses, and you are then putting them through JSON.parse to turn them into viable arrays and objects.
So the first way would be to make "class-instances" (no new or inheritance necessary, just a constructor function which encapsulates data and exposes an interface, based on the data-type).
function makeTweet (data) {
var tweet = {
from_user : data.from_user || "anonymous",
/* ... */
},
toString = function () {},
public_interface : {
toString : toString,
/* getters, etc */
};
return public_interface;
}
I know you already know this stuff, but consider a situation where you've got two or three different data-types inside of the same process (like at the end of the line, when you're ready to print to the client), and you have a process which is reading and writing to public fields on every object. If different objects have different properties, things end poorly, or end in a sea of flakey if statements.
The other way to look at it might be an entity/service system
function handleTweets (tweetArr) {
var templateFormat = system.output_format,
string = "";
if (templateFormat === "HTML") {
string = HTMLtemplateTweets(tweetArr);
} else { /* ... */ }
}
function HTMLtemplateTweets (tweetArr) {}
function JSONtemplateTweets (tweetArr) {}
function XMLtemplateTweets (tweetArr) {}
...
With the point being that you would turn the JSON string into an array of data-only objects, and feed them down a line of type-specific library/system functions.
This would be more like a very simplified entity/system approach, rather than an OO (as classically accepted) approach.
Now, your data safety comes from making sure that your objects only ever go down one intended path, and thus transforms will be predictable for every object of that type.
If you want "inheritance" for performance/memory purposes in JS, then this might also be a direction to look.
Related
I'm developing a website using Knockout.js, but my question is way more general, so don't focus on that.
I reference the object within itself by its variable name, in this case viewModel, like so:
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propA); //the same as this.propA
}
};
That way, I don't run into any trouble when it comes to sub-objects and other "fancy" stuff.
Now, I need to merge another object into my viewModel, but I run into a reference problem:
g_test = {}; //The way with this global variable is just for demonstration purposes
(function () {
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propB);
}
};
g_test.vmA = viewModel;
})();
(function () {
var viewModel = {
propB: "propB",
fnB: function () {
alert("I am " + viewModel.propA);
}
}
/** merge viewModel "A" into viewModel "B" */
var vmA = g_test.vmA;
for (var key in vmA) {
if (vmA.hasOwnProperty(key)) {
viewModel[key] = vmA[key];
}
}
viewModel.fnA(); //I am undefined
viewModel.fnB(); //I am propA
})();
As you can see, fnB knows propA, but fnA does not know propB.
Using this as reference to the viewModel object however does the job. But I don't want to run through my whole object and replace every viewModel with this or introduce respective "helper variables" where needed, because this would take me ages. Plus, to my eyes it would mean that it's impossible to merge two objects which don't have bidirectional knowledge of each other.
Is there a senseful way of letting the viewModel variable in fnA point to viewModel "B" without having to know viewModel "B"?
Creating multiple viewModels and then trying to merge them seems like a problematic approach, and I don't know what you're trying to achieve with it. There is probably a better way (at the very least, using this would have been the right choice for creating mixins). But assuming that either there's a good reason or it's too much effort to rework it now, let's look at your issue.
You have two viewModels, and you want to merge them in such a way that each knows about the members of the other. You merge them in one direction, so B knows about A, but A doesn't know about B. You need to merge the other direction, as well. Object.assign is a convenient way to do what your loop does, but if you are on a pre-Object.assign browser, you can add another loop that goes through viewModel and copies properties from it into vmA.
The result is that you have two viewModels whose methods refer to each other. Each has propA, propB, fnA, and fnB, but fnA (in both objects) refers to the member of object A and vice-versa.
g_test = {}; //The way with this global variable is just for demonstration purposes
function mergeObjects(obj1, obj2) {
Object.assign(obj1, obj2);
Object.assign(obj2, obj1);
}
(function() {
var viewModel = {
propA: "propA",
fnA: function() {
alert("fnA: I am " + viewModel.propB);
}
};
g_test.vmA = viewModel;
})();
(function() {
var viewModel = {
propB: "propB",
fnB: function() {
alert("fnB: I am " + viewModel.propA);
}
}
mergeObjects(g_test.vmA, viewModel);
// to demonstrate which value is outputted by which function
g_test.vmA.propA = "A.propA"; // not used
g_test.vmA.propB = "A.propB"; // used by fnA
viewModel.propA = "B.propA"; // used by fnB
viewModel.propB = "B.propB"; // not used
viewModel.fnA(); //I am A.propB
viewModel.fnB(); //I am B.propA
// also
g_test.vmA.fnA();
g_test.vmA.fnB();
})();
In JavaScript I see a few different ways, certain tasks can be performed within an object for example, the object Egg I have below.
Can anyone tell me the difference between each one, why I would use one and not the other etc
var Egg = function(){
//Properties
var shell = "cracked" // private property
this.shell = "cracked" // public property
shell: "cracked" // what is this??
//functions
function cook(){
//standard function
}
cook: function(){
//what kind of function is this?
}
//not sure what this is
details: {
//What is this? an array :S it holds 2 elements?
cost: 1.23,
make: 'Happy Egg';
}
}
Your code snippet isn't quite valid, but here are a few things it raises:
Property initializers, object initializers
You've asked what shell: cracked is. It's a property initializer. You find them in object initializers (aka "object literals"), which are written like this:
var obj = {
propName: "propValue"
};
That's equivalent to:
var obj = {};
obj.propName = "propValue";
Both of the above create an object with a property called propName which has a string value "propValue". Note that this doesn't come into it.
Functions
There are a couple of places where functions typically come into it vis-a-vis objects:
Constructor functions
There are constructor functions, which are functions you call via the new operator. Here's an example:
// Constructor function
function Foo(name) {
this.name = name;
}
// Usage
var f = new Foo("Fred");
Note the use of the keyword this in there. That's where you've seen that (most likely). When you call a constructor function via new, this refers to the new object created by the new operator.
this is a slippery concept in JavaScript (and completely different from this in C++, Java, or C#), I recommend these two (cough) posts on my blog:
You must remember this
Mythical methods
Builder/factory functions
You don't have to use constructor functions and new, another pattern uses "builder" or "factory" functions instead:
// A factory function
function fooFactory(name) {
var rv = {}; // A new, blank object
rv.name = name;
return rv;
}
// Usage
var f = fooFactory("Fred");
Private properties
You mentioned "private" properties in your question. JavaScript doesn't have private properties at all (yet, they're on their way). But you see people simulate them, by defining functions they use on the object as closures over an execution context (typically a call to a constructor function or a factory function) which contains variables no one else can see, like this:
// Constructor function
function EverUpwards() {
var counter = 0;
this.increment = function() {
return ++counter;
};
}
// Usage:
var e = new EverUpwards();
console.log(e.increment()); // "1"
console.log(e.increment()); // "2"
(That example uses a constructor function, but you can do the same thing with a factory function.)
Note that even though the function we assign to increment can access counter, nothing else can. So counter is effectively a private property. This is because the function is a closure. More: Closures are not complicated
Sure, Ben.
This sort of gets to the bottom of the dynamism of JavaScript.
First, we'll look at basics -- if you're coming from a place where you understand class-based languages, like, say, Java or C++/C#, the one that is going to make the most sense is the constructor pattern which was included very early on:
function Egg (type, radius, height, weight) {
// private properties (can also have private functions)
var cost = (type === "ostrich") ? 2.05 * weight : 0.35 * weight;
// public properties
this.type = type;
this.radius = radius;
this.height = height;
this.weight = weight;
this.cracked = false;
// this is a public function which has access to private variables of the instance
this.getCost = function () { return cost; };
}
// this is a method which ALL eggs inherit, which can manipulate "this" properly
// but it has ***NO*** access to private properties of the instance
Egg.prototype.Crack = function () { this.cracked = true; };
var myEgg = new Egg("chicken", 2, 3, 500);
myEgg.cost; // undefined
myEgg.Crack();
myEgg.cracked; // true
That's fine, but sometimes there are easier ways of getting around things.
Sometimes you really don't need a class.
What if you just wanted to use one egg, ever, because that's all your recipe called for?
var myEgg = {}; // equals a new object
myEgg.type = "ostrich";
myEgg.cost = "......";
myEgg.Crack = function () { this.cracked = true; };
That's great, but there's still a lot of repetition there.
var myEgg = {
type : "ostrich",
cost : "......",
Crack : function () { this.cracked = true; }
};
Both of the two "myEgg" objects are exactly the same.
The problem here is that EVERY property and EVERY method of myEgg is 100% public to anybody.
The solution to that is immediately-invoking functions:
// have a quick look at the bottom of the function, and see that it calls itself
// with parens "()" as soon as it's defined
var myEgg = (function () {
// we now have private properties again!
var cost, type, weight, cracked, Crack, //.......
// this will be returned to the outside var, "myEgg", as the PUBLIC interface
myReturnObject = {
type : type,
weight : weight,
Crack : Crack, // added benefit -- "cracked" is now private and tamper-proof
// this is how JS can handle virtual-wallets, for example
// just don't actually build a financial-institution around client-side code...
GetSaleValue : function () { return (cracked) ? 0 : cost; }
};
return myReturnObject;
}());
myEgg.GetSaleValue(); // returns the value of private "cost"
myEgg.Crack();
myEgg.cracked // undefined ("cracked" is locked away as private)
myEgg.GetSaleValue(); // returns 0, because "cracked" is true
Hope that's a decent start.
You are mixing syntaxes between object property declaration and simple javascript statements.
// declare an object named someObject with one property
var someObject = {
key: value
};
// declare an anonymous function with some statements in it
// and assign that to a variable named "someFunction"
var someFunction = function () {
// any javascript statements or expressions can go here
};
There's a key distinction in JavaScript between objects and functions. Objects hold a bunch of data (including functions), and functions can be used to make or modify objects, but they aren't inherently the same thing. OOP in JavaScript is based around using functions as classes. For example, take the following class:
Test = function(){
this.value = 5;
}
If you just call the function Test(), then nothing will happen. Even if you say var x = Test(), the value of x will be undefined. However, using the new keyword, magic happens! So if we say var x = new Test(), then now the variable x will contain a Test object. If you do console.log(x.value), it would print 5.
That's how we can use functions to make objects. There's also a key different in syntax--a function can contain any sort of JavaScript block you want, whether that's if statements or for loops or what have you. When declaring an object, though, you have to use the key: value syntax.
Hope that clears things up a little bit!
I want to implement setter and getter on local
javascript variable. Here is an example function:
function someThing() {
var someLocalvariable = '';
}
// with this function I want to
// return value of someLocalvariable
// also if it is possible to implement
// setter in this way.
someThing.prototype.getLocalVar = function() {
}
I want variable to be 'realy' private. I don't wont
to use something like this:
someThing.prototype.someLocalvariable =
or
function someThing() {
this.someLocalvariable = '';
}
or attaching function inside someThing() like this:
function someThing() {
var someLocalvariable = '';
this.getLocalvariable = function() {
return someLocalvariable;
}
}
I would be very grateful for any guidance and assistance.
Your last example of what you don't want to do won't work (it has syntax errors), (it's been fixed) but I think you may have meant the usual way of doing this, which is to make the getter and setter closures within the constructor function (below).
Unfortunately, if you want truly private variables, this is just about your only option. There is no other way to get truly private, instance-specific variables. However, see "hack" below.
Here's the correct version of the usual way of doing this (which I think you said you don't want, but for completeness):
function SomeThing() {
var privateVar;
this.setPrivateVar = function(val) {
privateVar = val;
};
this.getPrivateVar = function() {
return privateVar;
};
}
// use:
var t = new Something();
t.setPrivateVar("foo");
console.log(t.getPrivateVar()); // "foo"
Like most, I first read of this pattern on Douglas Crockford's site.
This option does carry a downside: Every instance created via the SomeThing constructor function gets its own two functions. They cannot be shared between instances. So if there are going to be hundreds or thousands of SomeThing instances in your app, that's something to be considered from a memory perspective. If there are going to be a couple of hundred or fewer, it probably doesn't matter. (Those numbers are pulled out of a hat and you should not trust them, you'll have to review your code's memory use when/if there's some kind of issue; but you get the idea.)
The hack: If your instances will already have some kind of unique identifier on them as public data (or you're willing to add one, again it will be public), and if you're willing to add a fair bit of complication into the use of the instances, you can have a private cache that holds the data for all of your instances that only your code can access, and key into that cache via the unique identifier of the object. Like this (in this example, I'm allocating the id values, but you can use existing unique IDs if you have them):
var SomeThing = (function() {
var cache = {}, idAllocator = 0;
function SomeThing() {
this.id = ++idAllocator; // The unique identifier, can be a string if desired
cache[this.id] = {};
}
SomeThing.prototype.getPrivateVar = function() {
var data = cache[this.id];
return data && data.privateVar;
};
SomeThing.prototype.setPrivateVar = function(value) {
cache[this.id].privateVar = value;
};
SomeThing.prototype.destroy = function() {
delete cache[this.id];
};
return SomeThing;
})();
Here's how that works: All of the functions are closures over the cache local variable in the outer scoping function. We index into that using the unique ID of the object, which gives us an object on which we put our private data members. When the code using the instance is done using it, that code must call destroy (which is a major downside to this pattern) so we remove the private data object from cache by deleting the property for our id.
Caveats and costs:
You still have a public piece of data that is the key to your private data (id in the above)
Users of the instances created by SomeThing must call destroy on those instances when they're done with them. This is anathema to the way JavaScript's garbage handling works, but it's a requirement of the pattern above because otherwise you end up with cruft building up in the cache object.
(I wouldn't worry about this one) Eventually, if you're using the automatic id values above, you'll run out of them, if your app creates and destroys a lot of these instances. But JavaScript numbers go very high up indeed, and if that's an issue just find a different way to allocate IDs rather than the simplistic always-increasing system above.
I haven't had to use the pattern above in my work yet, but I expect there are use-cases for it involving thousands of SomeThing instances and thus the desire not to have per-instance functions.
Side note: In the above, I changed someThing to SomeThing. In JavaScript, the standard practice is for the names of normal functions to start with a lower-case letter, and for the names of constructor functions (ones you use with new) to start with a capital letter. Since SomeThing is meant to be used with new, I capped it. This is only convention, but it's an overwhelmingly popular one and, of course, it's used within the language definition itself (Date is a constructor, setHours is a function).
Use Object.defineProperty() in the function constructor in order to define your getter and setter more info here..
To make truly private (not visible to the outside) some values use a Closure,
more info can be found here.
In the following example we define a getter and setter for property temperature, where the inner "private" value is stored in a variable var temperature.
var temperature will never be visible/accessibly from the outside of Archiver() has it is a Closure.
Please note that this pattern works on ES5 as Object.defineProperty() it is not supported on ES3.
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
get: function () {
console.log('get!');
return temperature;
},
set: function (value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function () {
return archive;
};
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
Something like this:
function Field(val){
var value = val;
this.getValue = function(){
return value;
};
this.setValue = function(val){
value = val;
};
}
var field = new Field("test");
field.value
// => undefined
field.setValue("test2")
field.getValue()
Check ref: http://ejohn.org/blog/javascript-getters-and-setters/
Douglas Crockford has written this on implementing private members in JavaScript
That's not possible. If you have a local variable in someThing(), the function you attach to the prototype can't read its value (it's private, remember?). Your last example is the normal solution to this problem, why isn't this good enough for you?
Try these two ways to achieve setter and getter
var address = {
street : "No street",
city : "No city",
state : "No state",
get getAddress()
{
return (this.street+","+this.city+","+this.state);
},
set setAddress(theAddress)
{
var part = theAddress.toString().split(", ");
this.street = part[0] || "";
this.city = part[1] || "";
this.state = part[2] || "";
}
};
address.setAddress = "27 Sus Road, Pune, MH";
console.log(address.getAddress);
//Other setter and getter
function Square(side)
{
this._side = side;
};
Square.prototype = {
set setSide(side){
this._side = side;
},
get getSide(){
return this._side;
},
get getArea(){
return (this._side * this._side);
}
};
var mySquare = new Square(10);
mySquare.setSide = 15;
console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);
First method
var address = {
street : "No street",
city : "No city",
state : "No state",
get getAddress()
{
return (this.street+","+this.city+","+this.state);
},
set setAddress(theAddress)
{
var part = theAddress.toString().split(", ");
this.street = part[0] || "";
this.city = part[1] || "";
this.state = part[2] || "";
}
};
address.setAddress = "27 Sus Road, Pune, MH";
console.log(address.getAddress);
Second method
function Square(side)
{
this._side = side;
};
Square.prototype = {
set setSide(side){
this._side = side;
},
get getSide(){
return this._side;
},
get getArea(){
return (this._side * this._side);
}
};
var mySquare = new Square(10);
mySquare.setSide = 15;
console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);
My code is going to turn into a mess if I don't start using some sort of namespacing technique. I'm relatively new to programming large javascript projects but have significant experience with systems programming in C++/java/python etc.
Basically I'm trying to identify which is the preferred method for creating javascript namespaces, and what the pros/cons are for each method.
For example I could use either of the following three methods:
var proj.lib.layout = {
"centreElem":
function (elem, W, H){
},
"getAbsolutePosition":
function (elem){
}
};
OR
var proj.lib.layout = {};
(function(){
var l = proj.lib.layout;
l.centreElem = function (elem, winW, winH){
..
}
l.getAbsolutePosition = function (elem){
..
}
})();
OR
var proj.lib.layout = new function(){
function centreElem(elem, W, H){
..
}
function getAbsolutePosition(elem){
..
}
this.centreElem = centreElem;
this.getAbsolutePosition = getAbsolutePosition;
} ();
There are other ways to do it too obviously, but these were the first that I've seen and thought of. Can anyone say there is a "best" technique, or at least point me towards some pros/cons from which I can evaluate which is best for me?
Note that you have to create all the intermediary objects before you can assign to a sub-object like that:
window.one.two.three = {}; // fails
window.one = { two: { three: {} } };
Consider writing a namespacing method, so you can unify your namespace code. For example:
window.proj = {};
// n - {String} - A string representing a namespace to create on proj
// returns an object you can assign values to
window.proj.namespace = function(n) { /* ... */ };
(function(NS) {
NS.myMethod = function() {};
NS.myOtherMethod = function() {};
NS.myProperty = "FOO";
})(proj.namespace('lib.layout'));
assert(proj.lib.layout.myProperty === "FOO");
My preferred method is to have a single object (whose name is usually short, 2-3 characters, and all upper-case) as my namespace in which to contain all other objects.
The method shown below (which corresponds most closely with your second example) also shows how to hide any private functions:
// In this example the namespace is "QP"
if (!QP) {
var QP = {};
};
// Define all objects inside an closure to allow "private" functions
(function() {
QP.examplePublicFunction = function() {
...
}
function examplePrivateFunction() {
...
}
})();
This is the method used by a number of other JavaScript libraries, for example json2.js
I've never really felt the need to subdivide my namespaces into subnamespaces.
The Google Closure Javascript Library uses this style (which is not exactly like any of your examples)
goog.math.clamp = function(value, min, max) {
return Math.min(Math.max(value, min), max);
};
I would stick with this simple style. Don't bother with self-executing anonymous function wrappers. The one in your example doesn't actually do anything useful.
Basically all three examples use the same "namespace" technique, that is, create a basic object (your namespace) and then augment it with your functions.
usually the root namespace is in capital letters:
if (typeof (MYAPP) == "undefined" || !MYAPP) {
var MYAPP= {}
};
Then you can add functionality to this base object in various ways. In your code you show three of them, but each of them end up with the same result, you can call this two functions:
proj.lib.layout.centreElem(elem, W, H);
proj.lib.layout. getAbsolutePosition(elem);
I've put these together with the help of others and several resources. I've made a fiddle of everything, and the stripped down code is posted below.
Basically I've learned how to use each of these patterns but I'm curious about the more fundamental differences between these approaches. Downstream code is practically identical with any of these patterns, but is there a reason why one should use one over another, beyond personal preference? Also though I've tried to gather up the most common patterns, please suggest your own if it's better.
Pattern 1 (Object Based):
var mouseDiff = {
"startPoint" : {"x" :0, "y" : 0},
"hypotenuse" : function(a,b) {
// do something
},
"init" : function(){
// do something
}
}
mouseDiff.init();
Pattern 2 (Most traditional as far as I know):
function MouseDiff() {
this.startPoint = {"x" :0, "y" : 0};
}
MouseDiff.prototype.hypotenuse = function(a,b) {
// do something
}
MouseDiff.prototype.init = function() {
// do something
}
var myMouse = new MouseDiff;
myMouse.init();
Pattern 3 (Making use of closure):
var MouseDiff2 = (function() {
var startPoint = {"x" :0, "y" : 0};
var hypotenuse = function(a,b) {
// do something
};
return {
hypotenuse: hypotenuse,
init : function(){
// do something
}
};
}());
MouseDiff2.init();
Pattern 1 is a singleton. If you only need one such object, it's just fine.
Pattern 2 builds new objects, and takes advantage of the prototype object so that when a new MouseDiff object is created, it will not create new copies of the functions (which are themselves data in JavaScript).
Pattern 3 requires more memory in comparison to a regular singleton but it offers static privacy.
I like the following pattern, as it covers various features, though it is really a combination of the constructor (pattern 2) and closure (pattern 3):
var MouseDiff = (function () {
var aStaticVariable = 'Woohoo!';
// And if you really need 100% truly private instance
// variables which are not methods and which can be
// shared between methods (and don't mind the rather
// big hassle they require), see
// http://brettz9.blogspot.com/search?q=relator
// (see also the new plans for a Map/WeakMap in ECMAScript)
function _APrivateStaticMethod () {
alert(aStaticVariable);
}
// An instance method meant to be called on the
// particular object as via ".call(this)" below
function _APrivateInstanceMethod () {
alert(this.startPoint.x);
}
// Begin Constructor
function MouseDiff() {
this.startPoint = {"x" :0, "y" : 0};
}
MouseDiff.prototype.hypotenuse = function(a,b) {
// do something
};
MouseDiff.prototype.init = function() {
// do something
_APrivateStaticMethod(); // alerts 'Woohoo!'
_APrivateInstanceMethod.call(this); // alerts 0 (but if not
// called with this, _APrivateInstanceMethod's internal
// "this" will refer (potentially dangerously) to the
// global object, as in the window in the browser unless
// this class was defined within 'strict' mode in which
// case "this" would be undefined)
};
return MouseDiff;
}());
var myMouse = new MouseDiff;
myMouse.init();
I do not know enough about JavaScript to tell you what if any performance differences exist between these approaches. Here are just two differences between these I noticed. I'm sure there are others.
Pattern 1 creates one object with those properties, including attached methods. Pattern 2 allows us to easily create many objects with the same methods attached, without rewriting them.
Pattern 3 is like a factory. Instead of relying on prototype to automatically attach these methods, the factory just creates them anew and returns the object. The usage of a closure allows us to hide the "member variables" of the object. There is no way to access startPoint or hypotenuse() except through the "public" interface returned.
Whenever I answer these types of theoretical JavaScript questions, I always fear there is some technical detail I am forgetting or overlooking. If so, let me know, and I will fix the answer.
Pattern two is my personally preference because it is the closest to traditional object oriented programming and allows for easy inheritance.
This post by John Resig (the guy behind JQuery) uses that method...
http://ejohn.org/blog/simple-javascript-inheritance/
[edit]
In fact, I don't think methods 1 or 3 have any benefits. 1 is, as someone else said, a singleton and does not allow multiple instances and 3... I don't know where to start with 3.
There is one more possible way to do this.
var MouseDiff = {};
(function(context) {
var privateVarialble = 0;
context.hypotenuse = function() {
//code here
};
context.int = function() {
//code here
}
})(MouseDiff);
Here we simply pass the namespace as an argument to a self-invoking function. The privateVarialble variable is private because it does not get assigned to the context.
We can even set the context to the global object (with a one word change!). Inside brackets (MouseDiff) make it (this). This is a big asset for library vendors – who can wrap their features in a self-invoking function and leave it to the user to decide whether they should be global or not.
http://www.jsoops.net/ is quite good for oop in Js. If provide private, protected, public variable and function, and also Inheritance feature. Example Code:
var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public
pri.className = "I am A ";
this.init = function (var1)// constructor
{
pri.className += var1;
}
pub.getData = function ()
{
return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
+ ", ID=" + pro.getClassId() + ")";
}
pri.getClassName = function () { return pri.className; }
pro.getClassName = function () { return pri.className; }
pro.getClassId = function () { return 1; }
});
var newA = new ClassA("Class");
//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)
//***You can not access constructor, private and protected function
console.log(typeof (newA.init)); // undefined
console.log(typeof (newA.className)); // undefined
console.log(typeof (newA.pro)); // undefined
console.log(typeof (newA.getClassName)); // undefined
This has been answered elsewhere many times before but just to offer up some variety. ds.oop is a nice way to declare classes with constructors in javascript. It supports every possible type of inheritance (Including 1 type that even c# does not support) as well as Interfaces which is nice.
var Color = ds.make.class({
type: 'Color',
constructor: function (r,g,b) {
this.r = r; /* now r,g, and b are available to */
this.g = g; /* other methods in the Color class */
this.b = b;
}
});
var red = new Color(255,0,0); // using the new keyword to instantiate the class