Javascript OO syntax - javascript

There seem to be many different ways of doing OO in JavaScript.
I like:
function ClassA(){};
ClassA.prototype={
someFunc:function(a,b,c){},
otherFunc:function(){}
}
var c=new ClassA();
and have never used features beyond what this provides (despite being a proficient OOer). I suspect this is old fashioned, because every so often I see new spangled variants, and it makes me wonder if I'm choosing the best approach. For instance, you can do magic in the constructor method to create private variables and accessor methods, something I believed (until relatively recently) to be impossible. What about subclassing? I wouldn't know how to achieve this, but it must have some sort of common pattern by now.
How do you do it and why?

function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
return {
publicMethod: function() { alert(iAmAPrivateVariable); },
publicVariable: bar()
}
}
//usage
var thing = foo()
This is known as a functional appoach, since you are actually leveraging closures for encapsulation (which is the only way to do it in javascript).
In a general way, you shouldn't be doing OO in javascript, it isn't that great a language for it for a great many reasons. Think scheme with squiggly brackets and semi-colons, and you will start writing the language like the pros do. That being said, sometime OO is a better fit. In those cases, the above is typically the best bet
EDIT: to bring inheritance into the mix
function parent() {
return { parentVariable: 2 };
}
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
me = parent();
me.publicMethod = function() { alert(iAmAPrivateVariable); };
me.publicVariable = bar();
return me;
}
This makes things a tad more complected, but accomplishes the desired end result while still taking a functional approach to OO concepts (in this case, using decorator functions instead of real inheritance). What I like about the whole approach is we are still really treating objects the way they are intended to be in this kind of language -- a property bag you can attach stuff to at will.
EDIT2:
Just wanted to give credit where credit is due, this approach is a very slight simplification to what doug crockford suggests in Javascript: The Good Parts. If you want to take your js skills to the next level, I would highly suggest starting there. I don't think I have ever learned so much from such a small book.
Another note is this is wildly different then what you will see most of the time in most of the jobs you will ever work at, and often is very hard to explain a) what is going on, and b) why it is a good idea to coworkers.

Simple JavaScript Inheritance
Because John Resig said so.

"Subclassing" in JavaScript generally refers to prototype-based inheritance, which basically follows this pattern:
function Superclass() { }
Superclass.prototype.someFunc = function() { };
function Subclass() { }
Subclass.prototype = new Superclass();
Subclass.prototype.anotherFunc = function() { };
var obj = new Subclass();
This builds a "prototype chain" from obj -> Subclass.prototype -> Superclass.prototype -> Object.prototype.
Pretty much every OOP library for JavaScript builds upon this technique, providing functions that abstract most of the prototype "magic".

I think joose is a pretty cool way to do OOP in javascript
http://code.google.com/p/joose-js/

Objects in JavaScript are unlike almost all the other high-profile languages. Instead of being class-based (like in Java, C++, PHP, etc etc), they are prototype-based. As such, the basic paradigm of object-oriented programming has to be considerably modified. People who can't or don't want to re-think this and insist on using class-based thinking have to build class-based logic in JavaScript or use code from someone else who has already built it.

I like to do something like
// namespace "My"
var My = new function {
// private methods
/**
* Create a unique empty function.
* #return {Function} function(){}
*/
function createFn () {return function(){}}
/** A reusable empty function. */
function emptyFn () {}
/**
* Clone an object
* #param {Object} obj Object to clone
* #return {Object} Cloned object
*/
function clone (obj) { emptyFn.prototype=obj; return new emptyFn() }
// public methods
/**
* Merge two objects
* #param {Object} dst Destination object
* #param {Object} src Source object
* #param {Object} [options] Optional settings
* #return {Object} Destination object
*/
this.merge = function (dst, src, options) {
if (!options) options={};
for (var p in src) if (src.hasOwnProperty(p)) {
var isDef=dst.hasOwnProperty(p);
if ((options.noPrivate && p.charAt(0)=='_') ||
(options.soft && isDef) ||
(options.update && !isDef)) continue;
dst[p]=src[p];
}
return dst;
}
/**
* Extend a constructor with a subtype
* #param {Function} superCtor Constructor of supertype
* #param {Function} subCtor Constructor of subtype
* #param {Object} [options] Optional settings
* #return {Function} Constructor of subtype
*/
this.extend = function (superCtor, subCtor, options) {
if (!subCtor) subCtor=createFn();
if (!options) options={};
if (!options.noStatic) this.merge(subCtor, superCtor, options);
var oldProto=subCtor.prototype;
subCtor.prototype=clone(superCtor.prototype);
this.merge(subCtor.prototype, oldProto);
if (!options.noCtor) subCtor.prototype.constructor=subCtor;
return subCtor;
}
}
And then something like...
// namespace "My.CoolApp"
My.CoolApp = new function(){
// My.CoolApp.ClassA
this.ClassA = new function(){
// ClassA private static
var count=0;
// ClassA constructor
function ClassA (arg1) {
count++;
this.someParam=arg1;
}
// ClassA public static
My.merge(ClassA, {
create: function (arg1) {
return new ClassA(arg1);
}
}
// ClassA public
My.merge(ClassA.prototype, {
doStuff : function (arg1) {
alert('Doing stuff with ' + arg1);
},
doOtherStuff : function (arg1) {
alert('Doing other stuff with ' + arg1);
}
}
return ClassA;
}
// My.CoolApp.ClassB
this.ClassB = new function(){
My.extend(My.CoolApp.ClassA, ClassB);
// ClassB constructor
function ClassB () {
ClassA.apply(this, arguments);
}
return ClassB;
}
}
...the clone function is the key to inheritance. In short:
Clone an object by making it the prototype of a throwaway function and calling the function with 'new'.
Clone the parent constructor's prototype, and set it the result as the prototype of the child class.

OOP in Javascript for Canvas
Check out how useful OOP in js can be in a different situation... This lets you draw squares and circles as objects so that you can go back and loop over or manipulate them as you like.
function Shape(x,y,color){
this.x = x
this.y = y
this.color = color
}
function Square(height,width,color){
Shape.call(this, event.x, event.y, color)
this.height = height
this.width = width
this.x -= canvas.offsetLeft + (this.height/2)
this.y -= canvas.offsetTop + (this.width/2)
}
Square.prototype = new Shape();
Square.prototype.draw = function(color){
ctx.fillStyle = color
ctx.fillRect(this.x,this.y,this.height,this.width)
}
function Circle(color, width){
Shape.call(this)
this.x = event.x -60
this.y = event.y -60
this.width = width
}
Circle.prototype = new Shape();
Circle.prototype.draw = function(color){
ctx.beginPath()
ctx.arc(this.x,this.y,this.width,0,2*Math.PI, false);
ctx.fillStyle = color
ctx.fill()
}

Related

Adding functions to the same namespace [duplicate]

How do I create a namespace in JavaScript so that my objects and functions aren't overwritten by other same-named objects and functions? I've used the following:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
Is there a more elegant or succinct way of doing this?
I use the approach found on the Enterprise jQuery site:
Here is their example showing how to declare private & public properties and functions. Everything is done as a self-executing anonymous function.
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
So if you want to access one of the public members you would just go skillet.fry() or skillet.ingredients.
What's really cool is that you can now extend the namespace using the exact same syntax.
//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
The third undefined argument
The third, undefined argument is the source of the variable of value undefined. I'm not sure if it's still relevant today, but while working with older browsers / JavaScript standards (ecmascript 5, javascript < 1.8.5 ~ firefox 4), the global-scope variable undefined is writable, so anyone could rewrite its value. The third argument (when not passed a value) creates a variable named undefined which is scoped to the namespace/function. Because no value was passed when you created the name space, it defaults to the value undefined.
I like this:
var yourNamespace = {
foo: function() {
},
bar: function() {
}
};
...
yourNamespace.foo();
Another way to do it, which I consider it to be a little bit less restrictive than the object literal form, is this:
var ns = new function() {
var internalFunction = function() {
};
this.publicFunction = function() {
};
};
The above is pretty much like the module pattern and whether you like it or not, it allows you to expose all your functions as public, while avoiding the rigid structure of an object literal.
Is there a more elegant or succinct way of doing this?
Yes. For example:
var your_namespace = your_namespace || {};
then you can have
var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg)
{
alert(arg);
};
with(your_namespace)
{
Bar(Foo.toAlert);
}
I normally build it in a closure:
var MYNS = MYNS || {};
MYNS.subns = (function() {
function privateMethod() {
// Do private stuff, or build internal.
return "Message";
}
return {
someProperty: 'prop value',
publicMethod: function() {
return privateMethod() + " stuff";
}
};
})();
My style over the years has had a subtle change since writing this, and I now find myself writing the closure like this:
var MYNS = MYNS || {};
MYNS.subns = (function() {
var internalState = "Message";
var privateMethod = function() {
// Do private stuff, or build internal.
return internalState;
};
var publicMethod = function() {
return privateMethod() + " stuff";
};
return {
someProperty: 'prop value',
publicMethod: publicMethod
};
})();
In this way I find the public API and implementation easier to understand. Think of the return statement as being a public interface to the implementation.
Because you may write different files of JavaScript and later combine or not combine them in an application, each needs to be able to recover or construct the namespace object without damaging the work of other files...
One file might intend to use the namespace namespace.namespace1:
namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};
namespace.namespace1.doSomeThing = function(){}
Another file might want to use the namespace namespace.namespace2:
namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};
namespace.namespace2.doSomeThing = function(){}
These two files can live together or apart without colliding.
Here's how Stoyan Stefanov does it in his JavaScript Patterns book which I found to be very good (it also shows how he does comments that allows for auto-generated API documentation, and how to add a method to a custom object's prototype):
/**
* My JavaScript application
*
* #module myapp
*/
/** #namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};
/**
* A maths utility
* #namespace MYAPP
* #class math_stuff
*/
MYAPP.math_stuff = {
/**
* Sums two numbers
*
* #method sum
* #param {Number} a First number
* #param {Number} b Second number
* #return {Number} Sum of the inputs
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
*
* #method multi
* #param {Number} a First number
* #param {Number} b Second number
* #return {Number} The inputs multiplied
*/
multi: function (a, b) {
return a * b;
}
};
/**
* Constructs Person objects
* #class Person
* #constructor
* #namespace MYAPP
* #param {String} First name
* #param {String} Last name
*/
MYAPP.Person = function (first, last) {
/**
* First name of the Person
* #property first_name
* #type String
*/
this.first_name = first;
/**
* Last name of the Person
* #property last_name
* #type String
*/
this.last_name = last;
};
/**
* Return Person's full name
*
* #method getName
* #return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
return this.first_name + ' ' + this.last_name;
};
I use this approach:
var myNamespace = {}
myNamespace._construct = function()
{
var staticVariable = "This is available to all functions created here"
function MyClass()
{
// Depending on the class, we may build all the classes here
this.publicMethod = function()
{
//Do stuff
}
}
// Alternatively, we may use a prototype.
MyClass.prototype.altPublicMethod = function()
{
//Do stuff
}
function privateStuff()
{
}
function publicStuff()
{
// Code that may call other public and private functions
}
// List of things to place publically
this.publicStuff = publicStuff
this.MyClass = MyClass
}
myNamespace._construct()
// The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
// Build namespace
}
myNamespace.subName._construct()
External code can then be:
var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
This is a follow-up to user106826's link to Namespace.js. It seems the project moved to GitHub. It is now smith/namespacedotjs.
I have been using this simple JavaScript helper for my tiny project and so far it seems to be light yet versatile enough to handle namespacing and loading modules/classes. It would be great if it would allow me to import a package into a namespace of my choice, not just the global namespace... sigh, but that's besides the point.
It allows you to declare the namespace then define objects/modules in that namespace:
Namespace('my.awesome.package');
my.awesome.package.WildClass = {};
Another option is to declare the namespace and its contents at once:
Namespace('my.awesome.package', {
SuperDuperClass: {
saveTheDay: function() {
alert('You are welcome.');
}
}
});
For more usage examples, look at the example.js file in the source.
Sample:
var namespace = {};
namespace.module1 = (function(){
var self = {};
self.initialized = false;
self.init = function(){
setTimeout(self.onTimeout, 1000)
};
self.onTimeout = function(){
alert('onTimeout')
self.initialized = true;
};
self.init(); /* If it needs to auto-initialize, */
/* You can also call 'namespace.module1.init();' from outside the module. */
return self;
})()
You can optionally declare a local variable, same, like self and assign local.onTimeout if you want it to be private.
The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.
When working with the Module pattern, we may find it useful to define a simple template that we use for getting started with it. Here's one that covers name-spacing, public and private variables.
In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we're able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
Advantages
why is the Module pattern a good choice? For starters, it's a lot cleaner for developers coming from an object-oriented background than the idea of true encapsulation, at least from a JavaScript perspective.
Secondly, it supports private data - so, in the Module pattern, public parts of our code are able to touch the private parts, however the outside world is unable to touch the class's private parts.
Disadvantages
The disadvantages of the Module pattern are that as we access both public and private members differently, when we wish to change visibility, we actually have to make changes to each place the member was used.
We also can't access private members in methods that are added to the object at a later point. That said, in many cases the Module pattern is still quite useful and when used correctly, certainly has the potential to improve the structure of our application.
The Revealing Module Pattern
Now that we're a little more familiar with the module pattern, let’s take a look at a slightly improved version - Christian Heilmann’s Revealing Module pattern.
The Revealing Module pattern came about as Heilmann was frustrated with the fact that he had to repeat the name of the main object when we wanted to call one public method from another or access public variables.He also disliked the Module pattern’s requirement for having to switch to object literal notation for the things he wished to make public.
The result of his efforts was an updated pattern where we would simply define all of our functions and variables in the private scope and return an anonymous object with pointers to the private functionality we wished to reveal as public.
An example of how to use the Revealing Module pattern can be found below
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
Advantages
This pattern allows the syntax of our scripts to be more consistent. It also makes it more clear at the end of the module which of our functions and variables may be accessed publicly which eases readability.
Disadvantages
A disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions.
Public object members which refer to private variables are also subject to the no-patch rule notes above.
If you need the private scope:
var yourNamespace = (function() {
//Private property
var publicScope = {};
//Private property
var privateProperty = "aaa";
//Public property
publicScope.publicProperty = "bbb";
//Public method
publicScope.publicMethod = function() {
this.privateMethod();
};
//Private method
function privateMethod() {
console.log(this.privateProperty);
}
//Return only the public parts
return publicScope;
}());
yourNamespace.publicMethod();
else if you won't ever use the private scope:
var yourNamespace = {};
yourNamespace.publicMethod = function() {
// Do something...
};
yourNamespace.publicMethod2 = function() {
// Do something...
};
yourNamespace.publicMethod();
You can declare a simple function to provide namespaces.
function namespace(namespace) {
var object = this, tokens = namespace.split("."), token;
while (tokens.length > 0) {
token = tokens.shift();
if (typeof object[token] === "undefined") {
object[token] = {};
}
object = object[token];
}
return object;
}
// Usage example
namespace("foo.bar").baz = "I'm a value!";
I'm 7 years late to the party, but did quite a bit of work around this 8 years ago:
http://blogger.ziesemer.com/2008/05/javascript-namespace-function.html
http://blogger.ziesemer.com/2007/10/respecting-javascript-global-namespace.html
It is important to be able to easily and efficiently create multiple nested namespaces to keep a complex web application organized and manageable, while respecting the JavaScript global namespace (preventing namespace pollution), and with not clobbering any existing objects in the namespace path while doing so.
From the above, this was my circa-2008 solution:
var namespace = function(name, separator, container){
var ns = name.split(separator || '.'),
o = container || window,
i,
len;
for(i = 0, len = ns.length; i < len; i++){
o = o[ns[i]] = o[ns[i]] || {};
}
return o;
};
This isn't creating a namespace, but provides a function for creating namespaces.
This can be condensed to a minified one-liner:
var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};
Example of use:
namespace("com.example.namespace");
com.example.namespace.test = function(){
alert("In namespaced function.");
};
Or, as one statement:
namespace("com.example.namespace").test = function(){
alert("In namespaced function.");
};
Either is then executed as:
com.example.namespace.test();
If you don't need support for legacy browsers, an updated version:
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
Now, I'd be leery of exposing namespace to the global namespace itself. (Too bad the base language doesn't provide this for us!) So I'd typically use this myself in a closure, such as:
(function(){
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
const ns = namespace("com.ziesemer.myApp");
// Optional:
ns.namespace = ns;
// Further extend, work with ns from here...
}());
console.log("\"com\":", com);
In a larger application, this only needs to be defined once at the beginning of a page load (for client-based web apps). Additional files can then reuse the namespace function if kept (included as "optional" in the above). At worst, if this function is re-declared a few times - it's only a few lines of code, and less if minified.
I created namespace which is inspired by Erlang's modules. It is a very functional approach, but that is how I write my JavaScript code these days.
It gives a closure a global namespace and exposes a defined set functions within that closure.
(function(){
namespace("images", previous, next);
// ^^ This creates or finds a root object, images, and binds the two functions to it.
// It works even though those functions are not yet defined.
function previous(){ ... }
function next(){ ... }
function find(){ ... } // A private function
})();
After porting several of my libraries to different projects, and having to constantly be changing the top level (statically named) namespace, I've switched to using this small (open source) helper function for defining namespaces.
global_namespace.Define('startpad.base', function(ns) {
var Other = ns.Import('startpad.other');
....
});
Description of the benefits are at my blog post. You can grab the source code here.
One of the benefits I really like is isolation between modules with respect to load order. You can refer to an external module BEFORE it is loaded. And the object reference you get will be filled in when the code is available.
I use the following syntax for the namespace.
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
I think you all use too much code for such a simple problem.
No need to make a repo for that.
Here's a single line function.
namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
Try it :
// --- definition ---
const namespace = name => name.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
// --- Use ----
const c = namespace("a.b.c");
c.MyClass = class MyClass {};
// --- see ----
console.log("a : ", a);
ES6 Modules Namespace imports
// circle.js
export { name, draw, reportArea, reportPerimeter };
// main.js
import * as Circle from './modules/circle.js';
// draw a circle
let circle1 = Circle.draw(myCanvas.ctx, 75, 200, 100, 'green');
Circle.reportArea(circle1.radius, reportList);
Circle.reportPerimeter(circle1.radius, reportList);
This grabs all the exports available inside circle.js, and makes them available as members of an object Circle, effectively giving it its own namespace.
My favorite pattern has become lately this:
var namespace = (function() {
// expose to public
return {
a: internalA,
c: internalC
}
// all private
/**
* Full JSDoc
*/
function internalA() {
// ...
}
/**
* Full JSDoc
*/
function internalB() {
// ...
}
/**
* Full JSDoc
*/
function internalC() {
// ...
}
/**
* Full JSDoc
*/
function internalD() {
// ...
}
})();
Of course, return can be at the end, but if only function declarations follow it, it's much easier to see what's the namespace all about, and what API is exposed.
The pattern of using function expressions in such cases results in not being able to know what methods are exposed without going over the entire code.
I like Jaco Pretorius' solution, but I wanted to make the "this" keyword a bit more useful by pointing it to the module/namespace object.
My version of skillet:
(function ($, undefined) {
console.log(this);
}).call(window.myNamespace = window.myNamespace || {}, jQuery);
JavaScript does not yet have a native representation of namespaces, but TypeScript does.
For example, you could use the following TS code (playground)
namespace Stack {
export const hello = () => console.log('hi')
}
Stack.hello()
If you can't update your code to TS, you can at least use the pattern employed by TS when generating the JS output for namespaces, which looks like this:
var Stack;
(function (Stack) {
Stack.hello = () => console.log('hi');
})(Stack || (Stack = {}));
Stack.hello();
Further Reading:
TS - Namespaces
TS - Namespaces and Modules
If using a Makefile you can do this.
// prelude.hjs
billy = new (
function moduleWrapper () {
const exports = this;
// postlude.hjs
return exports;
})();
// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;
// clientfile.js
billy.bob();
I prefer to use a Makefile anyway once I get to about 1000 lines because I can effectively comment out large swaths of code by removing a single line in the makefile. It makes it easy to fiddle with stuff. Also, with this technique the namespace only appears once in the prelude so it's easy to change and you don't have to keep repeating it inside the library code.
A shell script for live development in the browser when using a makefile:
while (true); do make; sleep 1; done
Add this as a make task 'go' and you can 'make go' to keep your build updated as you code.
Quite a follow-up of Ionuț G. Stan's answer, but showing the benefits of uncluttered code by using var ClassFirst = this.ClassFirst = function() {...}, which takes advantage of JavaScript's closure scoping for less namespace cluttering for classes in the same namespace.
var Namespace = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 123;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
var Namespace2 = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 666;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
new Namespace.ClassSecond()
new Namespace2.ClassSecond()
Output:
Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
I've written another namespacing library that works a bit more like packages / units do in other languages. It allows you to create a package of JavaScript code and the reference that package from other code:
File hello.js
Package("hello", [], function() {
function greeting() {
alert("Hello World!");
}
// Expose function greeting to other packages
Export("greeting", greeting);
});
File Example.js
Package("example", ["hello"], function(greeting) {
// Greeting is available here
greeting(); // Alerts: "Hello World!"
});
Only the second file needs to be included in the page. Its dependencies (file hello.js in this example) will automatically be loaded and the objects exported from those dependencies will be used to populate the arguments of the callback function.
You can find the related project in Packages JS.
We can use it independently in this way:
var A = A|| {};
A.B = {};
A.B = {
itemOne: null,
itemTwo: null,
};
A.B.itemOne = function () {
//..
}
A.B.itemTwo = function () {
//..
}
In JavaScript there are no predefined methods to use namespaces. In JavaScript we have to create our own methods to define NameSpaces. Here is a procedure we follow in Oodles technologies.
Register a NameSpace
Following is the function to register a name space
//Register NameSpaces Function
function registerNS(args){
var nameSpaceParts = args.split(".");
var root = window;
for(var i=0; i < nameSpaceParts.length; i++)
{
if(typeof root[nameSpaceParts[i]] == "undefined")
root[nameSpaceParts[i]] = new Object();
root = root[nameSpaceParts[i]];
}
}
To register a Namespace just call the above function with the argument as name space separated by '.' (dot).
For Example
Let your application name is oodles. You can make a namespace by following method
registerNS("oodles.HomeUtilities");
registerNS("oodles.GlobalUtilities");
var $OHU = oodles.HomeUtilities;
var $OGU = oodles.GlobalUtilities;
Basically it will create your NameSpaces structure like below in backend:
var oodles = {
"HomeUtilities": {},
"GlobalUtilities": {}
};
In the above function you have register a namespace called "oodles.HomeUtilities" and "oodles.GlobalUtilities". To call these namespaces we make an variable i.e. var $OHU and var $OGU.
These variables are nothing but an alias to Intializing the namespace.
Now, Whenever you declare a function that belong to HomeUtilities you will declare it like following:
$OHU.initialization = function(){
//Your Code Here
};
Above is the function name initialization and it is put into an namespace $OHU. and to call this function anywhere in the script files. Just use following code.
$OHU.initialization();
Similarly, with the another NameSpaces.
Hope it helps.
My habit is to use function myName() as property storage, and then var myName as "method" holder...
Whether this is legitimate enough or not, beat me! I am relying on my PHP logic all the time, and things simply work. :D
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(myObj instanceof Function !== false)
? Object.create({
$props: new myObj(),
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
: console.log('Object creation failed!')
);
if (this !== that) myObj.fName1(); else myObj.fName2();
You can also do it in a 'vice versa' way to check before object creation which is much better:
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(typeof(myObj) !== "function" || myObj instanceof Function === false)
? new Boolean()
: Object.create({
$props: new myObj(),
init: function () { return; },
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
);
if (myObj instanceof Boolean) {
Object.freeze(myObj);
console.log('myObj failed!');
debugger;
}
else
myObj.init();
Reference to this: JavaScript: Creating Object with Object.create()
JavaScript doesn’t support namespace by default. So if you create any element(function, method, object, variable) then it becomes global and pollute the global namespace. Let's take an example of defining two functions without any namespace,
function func1() {
console.log("This is a first definition");
}
function func1() {
console.log("This is a second definition");
}
func1(); // This is a second definition
It always calls the second function definition. In this case, namespace will solve the name collision problem.

Extending a javascript object

I'm currently working on a platform game engine using javascript and the HTML5 canvas.
I have an object, "platform" which looks something like this...
var platform = function(pid,px,py,pw,ph) {
//Some variables here... and then we have some functions
this.step = function() {
//Update / step events here
}
this.draw = function() {
//Drawing events here
}
//etc.
}
The step() function has all of the calculations for collision detection while the draw() function draws the platform.
What I want to do is make another object called movingPlatform. This will be almost identical to the current platform except for the fact this one moves.
Rather than copying all of the collision detection code I'd like to be able to extend movingPlatform from platform... and then be able to add some additional code into the step() function to the moving platform can... well... move.
Some additional information...
When the game loads, it generates the level using data from a CSV file. I have an array, platforms[] that stores all of the platforms within it.
So to create a platform it looks like this...
platforms.push(new platform(i,data[1],data[2],data[3],data[4]));
I then make the platforms perform their step and draw events during the game's main step and draw events.
i.e.
for(var i=0; i<platforms.length; i++) {
platforms[i].step();
}
Any help would be awesome. Thanks!
I would use the platform class as a "base" object for the moving platform object.
I would do this via the prototype which is JavaScript's implementation of object oriented programming.
More info here How does JavaScript .prototype work?
+ many more articles on the web
You can use Javascript prototype inheritance functionality:
var baseItem = {
push: function(){alert('push');},
pull: function(){alert('pull')}
}
var childItem = {}
childItem.prototype = baseItem;
childItem.push = function(){
//call base function
childItem.prototype.push.call(this);
//do your custom stuff.
alert('I did it again.');
}
childItem.push();
Fiddle
Rather than pure inheritance, here, I'd go with prototype-extension, unless you build some big, ugly factory, just for the sake of saying that "MovingPlatform" inherited from "Platform" in a pure sense, it's not really what you'd expect it to be.
There are a few concerns (cheating, for one), but if your objects are all based wholly around this, and you're okay with people potentially hacking away in the console, then you don't really have much to worry about.
First, understand what you're doing inside of Platform:
var MyObject = function (a) {
this.property = a;
this.method = function (b) { this.property += b; };
};
Every time you make a new MyObject, you're creating a brand new version of the .method function.
That is to say, if you make 10,000 of these, there will be 10,000 copies of that function, as well.
Sometimes that's a very good and safe thing.
It can also be a very slow thing.
The problem is, because everything in your object is using this, and because nothing inside of the function changes, there's no benefit to creating new copies -- just extra memory used.
...so:
MyObject = function (a) {
this.property = a;
};
MyObject.prototype.method = function (b) { this.property += b; };
var o = new MyObject(1);
o.method(2);
o.property; //3
When you call new X, where X has properties/methods on its prototype, those properties/methods get copied onto the object, during its construction.
It would be the same as going:
var method = function (b) { this.property += b; },
o = new MyObject(1);
o.method = method;
o.method(2);
o.property; // 3
Except without the extra work of doing it yourself, by hand.
The benefit here is that each object uses the same function.
They basically hand the function access to their whole this, and the function can do whatever it wants with it.
There's a catch:
var OtherObj = function (a, b) {
var private_property = b,
private_method = function () { return private_property; };
this.public_property = a;
this.unshared_method = function () { var private_value = private_method(); return private_value; };
};
OtherObj.prototype.public_method = function () {
return private_property;
};
var obj = new OtherObj(1, "hidden");
obj.public_property; // 1
obj.unshared_method(); // "hidden"
obj.public_method(); // err -- private_property doesn't exist
So assuming you don't have much you care about staying private, the easiest way of doing this would be to make reusable function, which rely on this, which you then give to multiple prototypes, through extension.
// collision-handling
var testCollision = function (target) { this./*...*/ },
handleCollision = function (obj) { this./* ... */ };
// movement-handling
var movePlatform = function (x, y, elapsed) { this.x += this.speed.x*elapsed; /*...*/ };
// not really the cleanest timestep implementation, but it'll do for examples
var Platform = function (texture, x, y, w, h) {
this.x = x;
// ...
},
MovingPlatform = function (texture, x, y, w, h, speedX, speedY, etc) {
this.etc = etc;//...
};
Platform.prototype.testCollision = testCollision;
Platform.prototype.handleCollision = handleCollision;
MovingPlatform.prototype. // both of the above, plus the movePlatform method
This is a lot by hand.
That's why functions in different libraries will clone or extend objects.
var bunchOfComponents = {
a : function () { },
b : 32,
c : { }
},
myObj = {};
copy(myObj, bunchOfComponents);
myObj.a();
myObj.b; //32
Your function-reuse goes up, while the horror of writing proper Class-based, hierarchical inheritance, with virtual-overrides, abstracts, and shared-private properties, by hand, goes down.
Getting inheritance right in Javascript is somewhat tricky if you're used to class-based languages.
If you're not sharing a lot of behaviours, you might find it easier to just create some shared methods, then make them available to objects of each platform type.
//Create constructors for each type
var Platform = function(pid,px,py,pw,ph) { //By convention, constructors should start with an uppercase character
...
}
var MovingPlatform = function() {
...
}
//Create some reuseable methods
var step = function() {
...
}
var draw = function() {
...
}
var move = function() {
...
}
//Attach your methods to the prototypes for each constructor
Platform.prototype.step = step;
Platform.prototype.draw = draw;
MovingPlatform.prototype.step = step;
MovingPlatform.prototype.draw = draw;
MovingPlatform.prototype.move = move;
...etc
That said, if you do want to build up a proper inheritance chain, there are plenty of articles available to help you: 1 2 3 4

Prototype of prototype function in Javascript

I know that it's possible to add to the prototype of a function such that
function main(){}
main.prototype.load = function()
{
}
...
and run the function called main.load.
Is it possible to make a prototype of a function within that prototype? In other words, can I do something like this:
main.prototype.get = function(){}
main.prototype.get.prototype.registration = function()
{
// load registration info
}
and call the function using main.get.registration();?
When I try to do this, I am given this error message in the console:
Uncaught TypeError: Object function (){} has no method 'registration'
EDIT: I am doing this after calling new main();. So I would be doing something like
var thisMain = new main();
thisMain.get.registration();
I think you misunderstand prototypes a bit.
Given a function Foo, Foo.prototype is not the prototype of the Foo object. It is the prototype that will be assigned to objects created using new Foo(). For example:
// This is a constructor that creates objects whose prototype is Person.prototype
var Person = function(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
}
var drew = new Person('Drew');
drew.sayHello(); // <-- Logs a message
drew.__proto__; // <-- Not part of the Javascript spec, but it some browsers this is a reference to Person.prototype
Your main.get.registration could be implemented without prototypes:
main = function() {/* do stuff*/}
main.get = function() {/* this is a getter function? */}
main.get.registration = function() {/* I don't know what this does */}
What kind of interface or API are you hoping to create? Does it involve creating objects using new?
UPDATE: Here's one of many possible ways to implement what you want:
main = function() {
// store a reference to this instance.
var self = this;
// Construct the get object. It doesn't need to be a function because it's never invoked
this.get = {};
this.get.registration = function() {
// Use self to refer to the specific instance of main you're interacting with.
retrieveRegistrationFor(self); // <-- pseudo-code
}
}
UPDATE 2: Here's how to construct the get object using a constructor, allowing you to use prototypes for everything. I've capitalized the names of your constructors, which is a best practice that helps to differentiate between normal functions/methods and constructors.
// Constructor for the get object. This is only ever invoked in Main's constructor.
Getter = function(mainInstance) {
this.self = mainInstance;
}
Getter.prototype.registration = function() {
retrieveRegistrationFor(this.self); // <-- pseudo-code
}
Main = function() {
// Construct the get object and attach it to this object.
this.get = new Getter(this);
}
As the other answers have pointed out, there are lots of ways to construct objects in Javascript. It all depends on the situation and your personal coding style.
I did get it to work with
main.prototype.get.prototype.registration();
But remember, as #the_system mentioned, that you can't use main.get directly; you have to go through the prototype to find the get function (and similarity with the registration function).
This is just my personal opinion, but I've always found the protypical inheritance model in JavaScript hard to grok. It's difficult to reason with when writing the code, and it's more difficult to reason with maintaining the code 6 months later.
However, what I think you're asking is really just this: "Can I write a class which inherits methods on its members from an anonymous class?" When you rephrase it this way, I think it becomes clear that there is uncertain value in the approach. The whole purpose of writing classes is to support simple abstraction and encapsulation while keeping composition tight.
It would be more straightforward to use a tradition Object, ala:
var main = {
get: {
registration: function() {
//TODO
}
}
}
and main.get.registration() is simple as pie. If you can leverage Object.create() and Object.defineProperties() to do this, all the better.
If you absolutely have to use prototypical inheritance, I like the simple Function.prototype extension that Mr. Kistner proposes:
Function.prototype.inheritsFrom = function(parentClassOrObject) {
if (parentClassOrObject.constructor === Function) {
//Normal Inheritance
this.prototype = new parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject.prototype;
} else {
//Pure Virtual Inheritance
this.prototype = parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject;
}
return this;
};
This allows you to then compose classes and inheritance like so:
/***
* Method to create a Class with optional inheritance.
* Generally, I oppose this semantic in JS:
* partly because of the ineffability of the 'this' operator,
* and partly because of the difficulty in grokking this.
* What we're really saying here (through the wonders of functional programming) is this:
*
* var MyClass1 = function(param1) {
* var ret = this;
* ret.id = param1;
* return ret;
* };
*
* var MyClass2 = function(param1, param2) {
* var ret = this;
* MyClass1.apply(this, Array.prototype.slice.call(arguments, 0));
* ret.name = param2;
* return ret;
* };
*
* MyClass2.prototype = new MyClass1;
* MyClass2.prototype.constructor = MyClass1;
* MyClass2.prototype.parent = MyClass1.prototype;
*
* I find this whole mode of operation as dull as it is stupid.
* Nonetheless, there are occasions when the convention is suitable for type/instance checking
*
* Obviously, this method has very little utility if you are not using prototypal inheritance
*/
var MyClassCreatorMethod = function(name, inheritsFrom, callBack) {
var obj = Object.create(null);
obj[name] = function() {
try {
if(inheritsFrom ) {
inheritsFrom.apply(this, Array.prototype.slice.call(arguments, 0));
}
callBack.apply(this, Array.prototype.slice.call(arguments, 0));
} catch(e) {
//do something
}
};
if(inheritsFrom) {
obj[name].inheritsFrom(inheritsFrom);
}
return obj[name];
};
From here, it becomes trivial to daisy-chain inherited classes. I just pulled this out of one of my projects, so not all of the semantics of this apply to you--it's just to illustrate a way to functionalize the behavior in a way that's easier to reason with.
Perhaps what you want to do is this:
function main(){}
main.prototype.load = function()
{
};
main.prototype.get = function(){};
main.prototype.get.prototype.registration = function()
{
// load registration info
alert('hi, I\'m working');
};
var thisMain = new main();
var other = new thisMain.get();
other.registration();

Javascript OOP public and private variable scope

I've got a question regarding public and private variables in a Javascript object. Here's the simple code I've been playing with to get my head around variable scope as well as private and public properties.
var fred = new Object01("Fred");
var global = "Spoon!";
function Object01(oName) {
var myName = oName;
this.myName = "I'm not telling!";
var sub = new subObject("underWorld");
this.sub = new subObject("Sewer!");
Object01.prototype.revealName = function() {
return "OK, OK, my name is: " + myName + ", oh and we say " + global;
}
Object01.prototype.revealSecretName = function() {
console.log ("Private: ");
sub.revealName();
console.log("Public: ");
this.sub.revealName();
}
}
function subObject(oName) {
var myName = oName;
this.myName = "My Secret SubName!";
subObject.prototype.revealName = function() {
console.info("My Property Name is: " + this.myName);
console.info("OK, my real name is: " + myName + ", yeah and we also say: " + global);
}
}
The funny thing I've observed so far is within my objects, a plain var is treated as private (obviously, since they are in a function block), and a this version is public. But I've noticed that the a variable with the same name with this.xxx seems to be considered a different variable. So, in the example above, my object fred will report something different for this.myName compared with my function to pull my var myName.
But this same behavior isn't the same for a sub-object I create. In the case of var sub vs this.sub both above use a new subObject call to supposedly make two subObjects. But it seems both this.sub and var sub return the Sewer! version.
Som I'm a bit confused about why if I use Strings for this.myName and var myName I get two different results, but my attempt to do the same with another object doesn't produce a similar result? I guess it could be that I'm using them wrong, or not understanding the differences between a this and var version.
Your biggest problem here isn't actually the difference between this-based object properties and var-declared variables.
Your problem is that you're trying to make prototype act as a wrapper that will give you protected class properties which are available to sub-classes, let alone instances of your main class.
prototype can not work on "private" members of a class at all (that being the variables defined within the scope of the constructor function, rather than being properties added to the constructed object you're returning).
function Person (personName) {
var scoped_name = personName;
this.name = "Imposter " + scoped_name;
}
Person.prototype.greet = function () { console.log("Hi, I'm " + this.name + "!"); };
var bob = new Person("Bob");
bob.greet(); // "Hi, I'm Imposter Bob!"
The point of the prototype string is either to provide methods which operate on the publicly-accessible properties of your objects (like if you wanted to change the value of this.name, but you'd forever lose the hidden scoped_name reference)...
...or if you want ALL of the same kind of object to have access to the SAME value.
function Student (name, id) {
function showIDCard () { return id; }
function greet () { console.log("I'm " + name + ", and I attend " + this.school); }
this.showID = showIDCard;
this.greet = greet;
}
Student.prototype.school = "The JS Academy of Hard-Knocks";
Student.prototype.comment_on_school = function (feeling) {
console.log("I " + feeling + " " + this.school);
}
var bob = new Student("Bob", 1);
var doug = new Student("Doug", 2);
var mary = new Student("Mary", 1);
mary.school = "The JS School of Closure";
bob.greet(); // I'm Bob and I attend The JS School of Hard-Knocks
mary.greet(); // I'm Mary and I attend the JS School of Closure
mary.comment_on_school("love"); // I love The JS School of Closure
prototype has defined a default value for school, for Students who aren't given their own.
prototype also provided functions which can be shared between objects, because the functions use this to access the actual properties of the object.
Any internal variables of the function can ONLY be accessed by properties or methods which are defined INSIDE of the function.
So in this case, the prototype methods can NEVER access id, except through this.showID, because this.showID is a reference to the showIDCard function, which is created for each and every single student, who has their own unique id, and their own copy of that function has a reference to their own unique copy of that argument.
My suggestion for applying large-scale "class" methodology to JS is to go with a style which favours composition of objects.
If you're going to sub-class, make each sub-class a module, with its own public-facing interface, and its own privately-scoped vars, and then make that module the property of whatever you were trying to make, rather than trying to get chains of inheritance working.
That is way, way too much work in JS, if you're anticipating doing something like inheriting from a base-class, and then extending it 8 or 10 generations.
It will just end in tears, and complaints that JS isn't "OOP" (in the style you'd like it to be).
There's no private or public, there's variables and object properties.
Variables and object properties are different in many more ways than the one of variables having a variable scope and object properties not having a variable scope. Variable scope is not the same as private property of an object, because it's not a property but a variable.
Variables do not belong to any object but they can be sustained through closures. You can invoke those closures as a property of any object or without any object at all and the supposed private properties will work:
function A() {
var private = 0;
this.setPrivate = function( value ) {
private = value;
};
this.getPrivate = function() {
return private;
};
}
var a = new A();
a.getPrivate() //0;
var b = [];
b.fn = a.setPrivate; //The function is fully promiscuous, especially since the data is closed over by it,
//so it doesn't matter at all where or how it's invoked.
b.fn(1);
a.getPrivate(); //1
You are redefining functions in a prototype object every time the constructor is called. The whole point of prototypes is that you only have to create certain function objects just once. You are assigning methods to the prototype object inside a function,
so every time that function is called, the functions are recreated and form new closures that refer to specific state.
I showed above that closures, because they hold state in the closed over variables, don't care about how they are invoked. So when you assign a closure as a property to the prototype, all the instances you have refer to the latest closure assigned, and you are getting its state.
I recommend using the standard way of defining "classes" in JS and not mixing it up with closures:
function A() {
this._private = 1;
}
//Note, this code is outside any function
//The functions assigned to prototype are therefore only defined once.
A.prototype.getPrivate = function() {
return this._private;
};
A.prototype.setPrivate = function( value ) {
this._private = value;
};
var a = new A();
You can find a good tutorial here: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model
Actually, I advocate using a non-standard approach to defining javascript classes. The following coding convention makes code easy to read and understand for anyone with an object-oriented background; it is also very easy to maintain unlike the Method.prototype=function(){}; method which sucks anytime you want to rename a class, add more methods, understand the hierarchy of a class or even re-interpret what your own code is doing.
Instead, you can declare object-oriented structures using the following architecture:
/**
* public class Animal
**/
(function(namespace) {
var __class__ = 'Animal';
/**
* private static:
**/
var animalCount = 0;
/**
* public Animal(string name)
**/
var constructor = function(name) {
// here you can assert arguments are correct
if(arguments.length == 0) {
return global.error('needs a name');
}
/**
* private:
**/
var animalIndex = animalCount++;
/**
* public:
**/
var operator = {
speak: function() {
console.log('?');
},
getName: function() {
return name;
},
getAnimalIndex: function() {
return animalIndex;
},
};
return operator;
};
/**
* public static Animal()
**/
var global = namespace[__class__] = function() {
// new Animal();
if(this !== namespace) {
// construct a new instance of this class
instance = constructor.apply(this, arguments);
return instance;
}
// Animal();
else {
// return the last instantiation of this class
return instance; // or do whatever you want
}
};
/**
* public static:
**/
// overrides the default toString method to describe this class from a static context
global.toString = function() {
return __class__+'()';
};
// prints a message to the console's error log
global.error = function() {
var args = Array.prototype.slice.apply(arguments);
args.unshift(__class__+':');
console.error.apply(console, args);
};
})(window);
/**
* publc class Dog extends Animal
**/
(function(namespace) {
var __class__ = 'Dog';
/**
* private static:
**/
var dogCount = 0;
/**
* public Dog()
**/
var construct = function(name) {
/**
* private:
**/
var dogIndex = dogCount++;
/**
* public operator() ();
**/
var operator = new Animal(name);
/**
* public:
**/
// overrides parent method 'speak'
operator.speak = function() {
console.log(operator.getName()+': bark!');
};
// method returns value of private variable
operator.getSpeciesIndex = function() {
return dogIndex;
};
return operator;
};
/**
* public static Dog()
**/
var global = namespace[__class__] = function() {
// new Dog();
if(this !== namespace) {
// construct a new instance of this class
instance = construct.apply(this, arguments);
return instance;
}
// Dog();
else {
// return the last instantiation of this class
return instance; // or do whatever you want
}
};
})(window);
/**
* publc class Cat extends Animal
**/
(function(namespace) {
var __class__ = 'Cat';
/**
* private static:
**/
var catCount = 0;
/**
* public Cat()
**/
var construct = function(name) {
// here you can assert arguments are correct
if(arguments.length == 0) {
return global.error('needs a name');
}
/**
* private:
**/
var catIndex = catCount++;
/**
* public operator() ();
**/
var operator = new Animal(name);
/**
* public:
**/
// overrides parent method 'speak'
operator.speak = function() {
console.log(name+': meow!');
};
// method returns value of private variable
operator.getSpeciesIndex = function() {
return catIndex;
};
return operator;
};
/**
* public static Cat()
**/
var global = namespace[__class__] = function() {
// new Cat();
if(this !== namespace) {
// construct a new instance of this class
instance = construct.apply(this, arguments);
return instance;
}
// Cat();
else {
// return the last instantiation of this class
return instance; // or do whatever you want
}
};
})(window);
Now with the above classes declared: Animal, Dog extends Animal, and Cat extends Animal...
We get the following:
new Dog(); // prints: "Animal: needs a name" to error output
var buddy = new Dog('Buddy');
buddy.speak(); // prints: "Buddy: bark!"
var kitty = new Cat('Kitty');
kitty.speak(); // prints: "Kitty: meow!"
var oliver = new Dog('Oliver');
oliver.speak(); // prints: "Oliver: bark!"
buddy.getSpeciesIndex(); // returns 0;
buddy.getAnimalIndex(); // returns 0;
kitty.getSpeciesIndex(); // returns 0;
kitty.getAnimalIndex(); // returns 1;
oliver.getSpeciesIndex(); // returns 1;
oliver.getAnimalIndex(); // returns 2;
I provide this javascript coding convention solely as a means to maintain organized object-oriented structures. I do not boast the performance of such coding style over other conventions, but if you want performance from your code I strongly suggest using Google's Closure Compiler which will optimize the same.
I have derived this javascript coding style from many years of coding experience on my own and the assimilation of critiquing other's code. I swear by it's robustness and modularity and welcome any comments regarding otherwise.
You goofed. Constructors should not change the prototype. Either:
function subObject(oName)
{
var myName = oName;
this.myName = "My Secret SubName!";
}
subObject.prototype.revealName = function()
{
console.info("My Property Name is: " + this.myName);
console.info("OK, my real name is: " + myName + ", yeah and we also say: " + global);
}
Or:
function subObject(oName)
{
var myName = oName;
this.myName = "My Secret SubName!";
subObject.revealName = function()
{
console.info("My Property Name is: " + this.myName);
console.info("OK, my real name is: " + myName + ", yeah and we also say: " + global);
}
}
Blake's answer inspired me, but I found it not doing everything that I wanted, so I hacked away at it until I have something that covers most of the OOP features of C++ in a simple and elegant syntax.
The only things not supported at the moment (but it's a matter of implementing them):
multiple inheritance
pure virtual functions
friend classes
See the github repo for examples and a serious readme:
https://github.com/najamelan/TidBits_Javascript_OoJs

How do you define an OOP class in JavaScript?

Based on my observation, the book that I am reading about JavaScript states that there's an OOP with JavaScript? It doesn't tell much about it, I mean it wasn't explained how to define a class. Can someone give me a sample snippet?
Thanks
JavaScript is Prototype based and not class based.
Prototype-based programming is a style
of object-oriented programming in
which classes are not present, and
behavior reuse (known as inheritance
in class-based languages) is performed
via a process of cloning existing
objects that serve as prototypes. This
model can also be known as class-less,
prototype-oriented or instance-based
programming. Delegation is the
language feature that supports
prototype-based programming.
I recommend this book for a concise, precise explanation of both how to use JS's prototypal inheritance as well as how to emulate classical OO inheritance in JS.
Any function in javascript can be used to create an object:
Example:
function MyPoint(x, y) {
this.x = x;
this.y = y;
this.distanceTo = getDistance;
}
function getDistance(p) {
var dx = this.x-p.x;
var dy = this.y-p.y;
return Math.sqrt(dx*dx + dy*dy);
}
var p0 = new MyPoint(1, 2);
var p1 = new MyPoint(2, 3);
window.alert('The distance is ' + p0.distanceTo(p1));
The following snippet may help you getting started with JavaScript's class-less, instance-based objects:
function getArea() {
return (this.radius * this.radius * 3.14);
}
function getCircumference() {
var diameter = this.radius * 2;
var circumference = diameter * 3.14;
return circumference;
}
function Circle(radius) {
this.radius = radius;
this.getArea = getArea;
this.getCircumference = getCircumference;
}
var bigCircle = new Circle(100);
var smallCircle = new Circle(2);
alert(bigCircle.getArea()); // displays 31400
alert(bigCircle.getCircumference()); // displays 618
alert(smallCircle.getArea()); // displays 12.56
alert(smallCircle.getCircumference()); // displays 12.56
Example from: SitePoint - JavaScript Object-Oriented Programming
Here are couple different ways
if (typeof FFX == "undefined") {
FFX = {};
}
//Static class
FFX.Util = ({
return {
method:function(){
}
})();
FFX.Util.method();
//Instance class
FFX.Util2 = ({
// private method
var methodA=function(){
alert("Hello");
};
return {
method:function(){
//Call private method
methodA();
}
});
var x= new FFX.Util();
x.method();
Another way
function MyClass(){
}
/* privileged functions */
MyClass.prototype.hello = function(){
alert("Hello");
}
Also you could see how jquery, prototype and alike handle classes and see if thats fits you needs.
There is no one standard way of doing OOP in JavaScript. Everyone uses slightly different class/instance systems and most books fudge the issue. See this question for discussion of ways to work with OO in JS and pick your favourite.
In JavaScript everything is a object. So even a function is a object. So in js (less then < version 2), function makes classes (which are first class objects themselves). Go here, here and herefor understanding better

Categories

Resources