Javascript OOP public and private variable scope - javascript

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

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.

JS using class variable [duplicate]

Can JavaScript classes/objects have constructors? How are they created?
Using prototypes:
function Box(color) // Constructor
{
this.color = color;
}
Box.prototype.getColor = function()
{
return this.color;
};
Hiding "color" (somewhat resembles a private member variable):
function Box(col)
{
var color = col;
this.getColor = function()
{
return color;
};
}
Usage:
var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue
var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
Here's a template I sometimes use for OOP-similar behavior in JavaScript. As you can see, you can simulate private (both static and instance) members using closures. What new MyClass() will return is an object with only the properties assigned to the this object and in the prototype object of the "class."
var MyClass = (function () {
// private static
var nextId = 1;
// constructor
var cls = function () {
// private
var id = nextId++;
var name = 'Unknown';
// public (this instance only)
this.get_id = function () { return id; };
this.get_name = function () { return name; };
this.set_name = function (value) {
if (typeof value != 'string')
throw 'Name must be a string';
if (value.length < 2 || value.length > 20)
throw 'Name must be 2-20 characters long.';
name = value;
};
};
// public static
cls.get_nextId = function () {
return nextId;
};
// public (shared across instances)
cls.prototype = {
announce: function () {
alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
}
};
return cls;
})();
I've been asked about inheritance using this pattern, so here goes:
// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
// We use an intermediary empty constructor to create an
// inheritance chain, because using the super class' constructor
// might have side effects.
var construct = function () {};
construct.prototype = superCls.prototype;
cls.prototype = new construct;
cls.prototype.constructor = cls;
cls.super = superCls;
}
var MyChildClass = (function () {
// constructor
var cls = function (surName) {
// Call super constructor on this instance (any arguments
// to the constructor would go after "this" in call(…)).
this.constructor.super.call(this);
// Shadowing instance properties is a little bit less
// intuitive, but can be done:
var getName = this.get_name;
// public (this instance only)
this.get_name = function () {
return getName.call(this) + ' ' + surName;
};
};
inherit(cls, MyClass); // <-- important!
return cls;
})();
And an example to use it all:
var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"
var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"
alert(john instanceof MyClass); // true
As you can see, the classes correctly interact with each other (they share the static id from MyClass, the announce method uses the correct get_name method, etc.)
One thing to note is the need to shadow instance properties. You can actually make the inherit function go through all instance properties (using hasOwnProperty) that are functions, and automagically add a super_<method name> property. This would let you call this.super_get_name() instead of storing it in a temporary value and calling it bound using call.
For methods on the prototype you don't need to worry about the above though, if you want to access the super class' prototype methods, you can just call this.constructor.super.prototype.methodName. If you want to make it less verbose you can of course add convenience properties. :)
It seems to me most of you are giving example of getters and setters not a constructor, ie http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming).
lunched-dan was closer but the example didn't work in jsFiddle.
This example creates a private constructor function that only runs during the creation of the object.
var color = 'black';
function Box()
{
// private property
var color = '';
// private constructor
var __construct = function() {
alert("Object Created.");
color = 'green';
}()
// getter
this.getColor = function() {
return color;
}
// setter
this.setColor = function(data) {
color = data;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
If you wanted to assign public properties then the constructor could be defined as such:
var color = 'black';
function Box()
{
// public property
this.color = '';
// private constructor
var __construct = function(that) {
alert("Object Created.");
that.color = 'green';
}(this)
// getter
this.getColor = function() {
return this.color;
}
// setter
this.setColor = function(color) {
this.color = color;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
So what is the point of "constructor"
property? Cannot figure out where it
could be useful, any ideas?
The point of the constructor property is to provide some way of pretending JavaScript has classes. One of the things you cannot usefully do is change an object's constructor after it's been created. It's complicated.
I wrote a fairly comprehensive piece on it a few years ago: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
Example here: http://jsfiddle.net/FZ5nC/
Try this template:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
v1: null
,v2: null
,f1: function Name_Space_ClassName_f1(){}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;
//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>
You must adjust your namespace if you are defining a static class:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>
Example class:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
this.Width = width;
this.Height = height;
this.Color = color;
}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
Width: null
,Height: null
,Color: null
,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.fillStyle = this.Color;
context.fillRect(x, y, this.Width, this.Height);
}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;
//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
return new Shape.Rectangle(50,25,'#ff0000');
}
</script>
Example instantiation:
<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");
var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);
var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);
Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>
Notice functions are defined as A.B = function A_B(). This is to make your script easier to debug. Open Chrome's Inspect Element panel, run this script, and expand the debug backtrace:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};
//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
A.Func.That.Does.Not.Exist();
}
Fail.Test();
</script>
This is a constructor:
function MyClass() {}
When you do
var myObj = new MyClass();
MyClass is executed, and a new object is returned of that class.
Yes, you can define a constructor inside a class declaration like this:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
I found this tutorial very useful. This approach is used by most of jQuery plug-ins.
http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK
var Class = function(methods) {
var klass = function() {
this.initialize.apply(this, arguments);
};
for (var property in methods) {
klass.prototype[property] = methods[property];
}
if (!klass.prototype.initialize) klass.prototype.initialize = function(){};
return klass;
};
Now ,
var Person = Class({
initialize: function(name, age) {
this.name = name;
this.age = age;
},
toString: function() {
return "My name is "+this.name+" and I am "+this.age+" years old.";
}
});
var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
This pattern has served me well. With this pattern, you create classes in separate files, load them into your overall app "as needed".
// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};
// "Package"
// Similar to how you would establish a package in other languages
(function() {
// "Class"
var MyClass = function(params) {
this.initialize(params);
}
// "Private Static" vars
// - Only accessible to functions in this class.
// - Doesn't get wiped out when we create a new instance.
var countInstances = 0;
var allInstances = [];
// "Private Static" functions
// - Same as above, but it's a function accessible
// only to other functions in this class.
function doSomething(){
}
// "Public Static" vars
// - Everyone has access.
// - Doesn't get wiped out when we create a new instance.
MyClass.counter = 0;
// "Public Static" functions
// - Same as above, but anyone can call this "static method".
// - Kinda like a singleton class situation.
MyClass.foobar = function(){
}
// Public properties and methods are built into the "prototype"
// - This is how each instance can become unique unto itself.
// - Establishing "p" as "local" (Static Private) variable
// simply so we don't have to keep typing "MyClass.prototype"
// for each property and function.
var p = MyClass.prototype;
// "Public" vars
p.id = null;
p.firstname = null;
p.lastname = null;
// "Private" vars
// - Only used by "this" instance.
// - There isn't "true" privacy for each
// instance so we have to fake it.
// - By tradition, we indicate "privacy"
// by prefixing it with an underscore.
// - So technically, anyone can access, but we simply
// don't tell anyone about it (e.g. in your API)
// so no one knows about it :)
p._foo = null;
p.initialize = function(params){
this.id = MyClass.counter++;
this.firstname = params.firstname;
this.lastname = params.lastname;
MyClass.counter++;
countInstances++;
allInstances.push(this);
}
p.doAlert = function(theMessage){
alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ". Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
}
// Assign class to app
myApp.MyClass = MyClass;
// Close the "Package"
}());
// Usage example:
var bob = new myApp.MyClass({ firstname : "bob",
lastname : "er"
});
bob.doAlert("hello there");
I guess I'll post what I do with javascript closure since no one is using closure yet.
var user = function(id) {
// private properties & methods goes here.
var someValue;
function doSomething(data) {
someValue = data;
};
// constructor goes here.
if (!id) return null;
// public properties & methods goes here.
return {
id: id,
method: function(params) {
doSomething(params);
}
};
};
Comments and suggestions to this solution are welcome. :)
Maybe it's gotten a little simpler, but below is what I've come up with now in 2017:
class obj {
constructor(in_shape, in_color){
this.shape = in_shape;
this.color = in_color;
}
getInfo(){
return this.shape + ' and ' + this.color;
}
setShape(in_shape){
this.shape = in_shape;
}
setColor(in_color){
this.color = in_color;
}
}
In using the class above, I have the following:
var newobj = new obj('square', 'blue');
//Here, we expect to see 'square and blue'
console.log(newobj.getInfo());
newobj.setColor('white');
newobj.setShape('sphere');
//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());
As you can see, the constructor takes in two parameters, and we set the object's properties. We also alter the object's color and shape by using the setter functions, and prove that its change remained upon calling getInfo() after these changes.
A bit late, but I hope this helps. I've tested this with a mocha unit-testing, and it's working well.
Using Nick's sample above, you can create a constructor for objects without parameters using a return statement as the last statement in your object definition. Return your constructor function as below and it will run the code in __construct each time you create the object:
function Box()
{
var __construct = function() {
alert("Object Created.");
this.color = 'green';
}
this.color = '';
this.getColor = function() {
return this.color;
}
__construct();
}
var b = new Box();
They do if you use Typescript - open source from MicroSoft :-)
class BankAccount {
balance: number;
constructor(initially: number) {
this.balance = initially;
}
deposit(credit: number) {
this.balance += credit;
return this.balance;
}
}
Typescript lets you 'fake' OO constructs that are compiled into javascript constructs. If you're starting a large project it may save you a lot of time and it just reached milestone 1.0 version.
http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf
The above code gets 'compiled' to :
var BankAccount = (function () {
function BankAccount(initially) {
this.balance = initially;
}
BankAccount.prototype.deposit = function (credit) {
this.balance += credit;
return this.balance;
};
return BankAccount;
})();
In JavaScript the invocation type defines the behaviour of the function:
Direct invocation func()
Method invocation on an object obj.func()
Constructor invocation new func()
Indirect invocation func.call() or func.apply()
The function is invoked as a constructor when calling using new operator:
function Cat(name) {
this.name = name;
}
Cat.prototype.getName = function() {
return this.name;
}
var myCat = new Cat('Sweet'); // Cat function invoked as a constructor
Any instance or prototype object in JavaScript have a property constructor, which refers to the constructor function.
Cat.prototype.constructor === Cat // => true
myCat.constructor === Cat // => true
Check this post about constructor property.
While using Blixt's great template from above, I found out that it doesn't work well with multi-level inheritance (MyGrandChildClass extending MyChildClass extending MyClass) – it cycles on calling first parent's constructor over and over. So here is a simple workaround – if you need multi-level inheritance, instead of using this.constructor.super.call(this, surName); use chainSuper(this).call(this, surName); with the chain function defined like this:
function chainSuper(cls) {
if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
var depth = cls.__depth;
var sup = cls.constructor.super;
while (depth > 1) {
if (sup.super != undefined) sup = sup.super;
depth--;
}
return sup;
}
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
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
Here we need to notice one point in java script, it is a class-less language however,we can achieve it by using functions in java script. The most common way to achieve this we need to create a function in java script and use new keyword to create an object and use this keyword to define property and methods.Below is the example.
// Function constructor
var calculator=function(num1 ,num2){
this.name="This is function constructor";
this.mulFunc=function(){
return num1*num2
};
};
var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call
//Constructors With Prototypes
var calculator=function(){
this.name="Constructors With Prototypes";
};
calculator.prototype.mulFunc=function(num1 ,num2){
return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call
In most cases you have to somehow declare the property you need before you can call a method that passes in this information. If you do not have to initially set a property you can just call a method within the object like so. Probably not the most pretty way of doing this but this still works.
var objectA = {
color: '';
callColor : function(){
console.log(this.color);
}
this.callColor();
}
var newObject = new objectA();

Javascript OOP - private/public methods [duplicate]

To make a JavaScript class with a public method I'd do something like:
function Restaurant() {}
Restaurant.prototype.buy_food = function(){
// something here
}
Restaurant.prototype.use_restroom = function(){
// something here
}
That way users of my class can:
var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();
How do I create a private method that can be called by the buy_food and use_restroom methods but not externally by users of the class?
In other words, I want my method implementation to be able to do:
Restaurant.prototype.use_restroom = function() {
this.private_stuff();
}
But this shouldn't work:
var r = new Restaurant();
r.private_stuff();
How do I define private_stuff as a private method so both of these hold true?
I've read Doug Crockford's writeup a few times but it doesn't seem like "private" methods can be called by public methods and "privileged" methods can be called externally.
You can do it, but the downside is that it can't be part of the prototype:
function Restaurant() {
var myPrivateVar;
var private_stuff = function() { // Only visible inside Restaurant()
myPrivateVar = "I can set this here!";
}
this.use_restroom = function() { // use_restroom is visible to all
private_stuff();
}
this.buy_food = function() { // buy_food is visible to all
private_stuff();
}
}
Using self invoking function and call
JavaScript uses prototypes and does't have classes (or methods for that matter) like Object Oriented languages. A JavaScript developer need to think in JavaScript.
Wikipedia quote:
Unlike many object-oriented languages, there is no distinction between
a function definition and a method definition. Rather, the distinction
occurs during function calling; when a function is called as a method
of an object, the function's local this keyword is bound to that
object for that invocation.
Solution using a self invoking function and the call function to call the private "method" :
var MyObject = (function () {
// Constructor
function MyObject(foo) {
this._foo = foo;
}
function privateFun(prefix) {
return prefix + this._foo;
}
MyObject.prototype.publicFun = function () {
return privateFun.call(this, ">>");
}
return MyObject;
}());
var myObject = new MyObject("bar");
myObject.publicFun(); // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined
The call function allows us to call the private function with the appropriate context (this).
Simpler with Node.js
If you are using Node.js, you don't need the IIFE because you can take advantage of the module loading system:
function MyObject(foo) {
this._foo = foo;
}
function privateFun(prefix) {
return prefix + this._foo;
}
MyObject.prototype.publicFun = function () {
return privateFun.call(this, ">>");
}
module.exports= MyObject;
Load the file:
var MyObject = require("./MyObject");
var myObject = new MyObject("bar");
myObject.publicFun(); // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined
(new!) Native private methods in future JavaScript versions
TC39 private methods and getter/setters for JavaScript classes proposal is stage 3. That means any time soon, JavaScript will implement private methods natively!
Note that JavaScript private class fields already exists in modern JavaScript versions.
Here is an example of how it is used:
class MyObject {
// Private field
#foo;
constructor(foo) {
this.#foo = foo;
}
#privateFun(prefix) {
return prefix + this.#foo;
}
publicFun() {
return this.#privateFun(">>");
}
}
You may need a JavaScript transpiler/compiler to run this code on old JavaScript engines.
PS: If you wonder why the # prefix, read this.
(deprecated) ES7 with the Bind Operator
Warning: The bind operator TC39 proposition is near dead https://github.com/tc39/proposal-bind-operator/issues/53#issuecomment-374271822
The bind operator :: is an ECMAScript proposal and is implemented in Babel (stage 0).
export default class MyObject {
constructor (foo) {
this._foo = foo;
}
publicFun () {
return this::privateFun(">>");
}
}
function privateFun (prefix) {
return prefix + this._foo;
}
You can simulate private methods like this:
function Restaurant() {
}
Restaurant.prototype = (function() {
var private_stuff = function() {
// Private code here
};
return {
constructor:Restaurant,
use_restroom:function() {
private_stuff();
}
};
})();
var r = new Restaurant();
// This will work:
r.use_restroom();
// This will cause an error:
r.private_stuff();
More information on this technique here: http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html
In these situations when you have a public API, and you would like private and public methods/properties, I always use the Module Pattern. This pattern was made popular within the YUI library, and the details can be found here:
http://yuiblog.com/blog/2007/06/12/module-pattern/
It is really straightforward, and easy for other developers to comprehend. For a simple example:
var MYLIB = function() {
var aPrivateProperty = true;
var aPrivateMethod = function() {
// some code here...
};
return {
aPublicMethod : function() {
aPrivateMethod(); // okay
// some code here...
},
aPublicProperty : true
};
}();
MYLIB.aPrivateMethod() // not okay
MYLIB.aPublicMethod() // okay
Here is the class which I created to understand what Douglas Crockford's has suggested in his site Private Members in JavaScript
function Employee(id, name) { //Constructor
//Public member variables
this.id = id;
this.name = name;
//Private member variables
var fName;
var lName;
var that = this;
//By convention, we create a private variable 'that'. This is used to
//make the object available to the private methods.
//Private function
function setFName(pfname) {
fName = pfname;
alert('setFName called');
}
//Privileged function
this.setLName = function (plName, pfname) {
lName = plName; //Has access to private variables
setFName(pfname); //Has access to private function
alert('setLName called ' + this.id); //Has access to member variables
}
//Another privileged member has access to both member variables and private variables
//Note access of this.dataOfBirth created by public member setDateOfBirth
this.toString = function () {
return 'toString called ' + this.id + ' ' + this.name + ' ' + fName + ' ' + lName + ' ' + this.dataOfBirth;
}
}
//Public function has access to member variable and can create on too but does not have access to private variable
Employee.prototype.setDateOfBirth = function (dob) {
alert('setDateOfBirth called ' + this.id);
this.dataOfBirth = dob; //Creates new public member note this is accessed by toString
//alert(fName); //Does not have access to private member
}
$(document).ready()
{
var employee = new Employee(5, 'Shyam'); //Create a new object and initialize it with constructor
employee.setLName('Bhaskar', 'Ram'); //Call privileged function
employee.setDateOfBirth('1/1/2000'); //Call public function
employee.id = 9; //Set up member value
//employee.setFName('Ram'); //can not call Private Privileged method
alert(employee.toString()); //See the changed object
}
ES12 Private Methods
You can do this now with es12 private methods. You just need to add a # before the method name.
class ClassWithPrivateMethod {
#privateMethod() {
return 'hello world';
}
getPrivateMessage() {
return #privateMethod();
}
}
I conjured up this: EDIT: Actually, someone has linked to a identical solution. Duh!
var Car = function() {
}
Car.prototype = (function() {
var hotWire = function() {
// Private code *with* access to public properties through 'this'
alert( this.drive() ); // Alerts 'Vroom!'
}
return {
steal: function() {
hotWire.call( this ); // Call a private method
},
drive: function() {
return 'Vroom!';
}
};
})();
var getAwayVechile = new Car();
hotWire(); // Not allowed
getAwayVechile.hotWire(); // Not allowed
getAwayVechile.steal(); // Alerts 'Vroom!'
ES2021 / ES12 - Private Methods
Private method names start with a hash # prefix and can be accessed only inside the class where it is defined.
class Restaurant {
// private method
#private_stuff() {
console.log("private stuff");
}
// public method
buy_food() {
this.#private_stuff();
}
};
const restaurant = new Restaurant();
restaurant.buy_food(); // "private stuff";
restaurant.private_stuff(); // Uncaught TypeError: restaurant.private_stuff is not a function
I think such questions come up again and again because of the lack of understanding of the closures. Сlosures is most important thing in JS. Every JS programmer have to feel the essence of it.
1. First of all we need to make separate scope (closure).
function () {
}
2. In this area, we can do whatever we want. And no one will know about it.
function () {
var name,
secretSkills = {
pizza: function () { return new Pizza() },
sushi: function () { return new Sushi() }
}
function Restaurant(_name) {
name = _name
}
Restaurant.prototype.getFood = function (name) {
return name in secretSkills ? secretSkills[name]() : null
}
}
3. For the world to know about our restaurant class,
we have to return it from the closure.
var Restaurant = (function () {
// Restaurant definition
return Restaurant
})()
4. At the end, we have:
var Restaurant = (function () {
var name,
secretSkills = {
pizza: function () { return new Pizza() },
sushi: function () { return new Sushi() }
}
function Restaurant(_name) {
name = _name
}
Restaurant.prototype.getFood = function (name) {
return name in secretSkills ? secretSkills[name]() : null
}
return Restaurant
})()
5. Also, this approach has potential for inheritance and templating
// Abstract class
function AbstractRestaurant(skills) {
var name
function Restaurant(_name) {
name = _name
}
Restaurant.prototype.getFood = function (name) {
return skills && name in skills ? skills[name]() : null
}
return Restaurant
}
// Concrete classes
SushiRestaurant = AbstractRestaurant({
sushi: function() { return new Sushi() }
})
PizzaRestaurant = AbstractRestaurant({
pizza: function() { return new Pizza() }
})
var r1 = new SushiRestaurant('Yo! Sushi'),
r2 = new PizzaRestaurant('Dominos Pizza')
r1.getFood('sushi')
r2.getFood('pizza')
I hope this helps someone better understand this subject
Personally, I prefer the following pattern for creating classes in JavaScript :
var myClass = (function() {
// Private class properties go here
var blueprint = function() {
// Private instance properties go here
...
};
blueprint.prototype = {
// Public class properties go here
...
};
return {
// Public class properties go here
create : function() { return new blueprint(); }
...
};
})();
As you can see, it allows you to define both class properties and instance properties, each of which can be public and private.
Demo
var Restaurant = function() {
var totalfoodcount = 0; // Private class property
var totalrestroomcount = 0; // Private class property
var Restaurant = function(name){
var foodcount = 0; // Private instance property
var restroomcount = 0; // Private instance property
this.name = name
this.incrementFoodCount = function() {
foodcount++;
totalfoodcount++;
this.printStatus();
};
this.incrementRestroomCount = function() {
restroomcount++;
totalrestroomcount++;
this.printStatus();
};
this.getRestroomCount = function() {
return restroomcount;
},
this.getFoodCount = function() {
return foodcount;
}
};
Restaurant.prototype = {
name : '',
buy_food : function(){
this.incrementFoodCount();
},
use_restroom : function(){
this.incrementRestroomCount();
},
getTotalRestroomCount : function() {
return totalrestroomcount;
},
getTotalFoodCount : function() {
return totalfoodcount;
},
printStatus : function() {
document.body.innerHTML
+= '<h3>Buying food at '+this.name+'</h3>'
+ '<ul>'
+ '<li>Restroom count at ' + this.name + ' : '+ this.getRestroomCount() + '</li>'
+ '<li>Food count at ' + this.name + ' : ' + this.getFoodCount() + '</li>'
+ '<li>Total restroom count : '+ this.getTotalRestroomCount() + '</li>'
+ '<li>Total food count : '+ this.getTotalFoodCount() + '</li>'
+ '</ul>';
}
};
return { // Singleton public properties
create : function(name) {
return new Restaurant(name);
},
printStatus : function() {
document.body.innerHTML
+= '<hr />'
+ '<h3>Overview</h3>'
+ '<ul>'
+ '<li>Total restroom count : '+ Restaurant.prototype.getTotalRestroomCount() + '</li>'
+ '<li>Total food count : '+ Restaurant.prototype.getTotalFoodCount() + '</li>'
+ '</ul>'
+ '<hr />';
}
};
}();
var Wendys = Restaurant.create("Wendy's");
var McDonalds = Restaurant.create("McDonald's");
var KFC = Restaurant.create("KFC");
var BurgerKing = Restaurant.create("Burger King");
Restaurant.printStatus();
Wendys.buy_food();
Wendys.use_restroom();
KFC.use_restroom();
KFC.use_restroom();
Wendys.use_restroom();
McDonalds.buy_food();
BurgerKing.buy_food();
Restaurant.printStatus();
BurgerKing.buy_food();
Wendys.use_restroom();
McDonalds.buy_food();
KFC.buy_food();
Wendys.buy_food();
BurgerKing.buy_food();
McDonalds.buy_food();
Restaurant.printStatus();
See also this Fiddle.
All of this closure will cost you. Make sure you test the speed implications especially in IE. You will find you are better off with a naming convention. There are still a lot of corporate web users out there that are forced to use IE6...
Don't be so verbose. It's Javascript. Use a Naming Convention.
After years of working in es6 classes, I recently started work on an es5 project (using requireJS which is already very verbose-looking). I've been over and over all the strategies mentioned here and it all basically boils down to use a naming convention:
Javascript doesn't have scope keywords like private. Other developers entering Javascript will know this upfront. Therefore, a simple naming convention is more than sufficient. A simple naming convention of prefixing with an underscore solves the problem of both private properties and private methods.
Let's take advantage of the Prototype for speed reasons, but lets not get anymore verbose than that. Let's try to keep the es5 "class" looking as closely to what we might expect in other backend languages (and treat every file as a class, even if we don't need to return an instance).
Let's demonstrate with a more realistic module situation (we'll use old es5 and old requireJs).
my-tooltip.js
define([
'tooltip'
],
function(
tooltip
){
function MyTooltip() {
// Later, if needed, we can remove the underscore on some
// of these (make public) and allow clients of our class
// to set them.
this._selector = "#my-tooltip"
this._template = 'Hello from inside my tooltip!';
this._initTooltip();
}
MyTooltip.prototype = {
constructor: MyTooltip,
_initTooltip: function () {
new tooltip.tooltip(this._selector, {
content: this._template,
closeOnClick: true,
closeButton: true
});
}
}
return {
init: function init() {
new MyTooltip(); // <-- Our constructor adds our tooltip to the DOM so not much we need to do after instantiation.
}
// You could instead return a new instantiation,
// if later you do more with this class.
/*
create: function create() {
return new MyTooltip();
}
*/
}
});
Take any of the solutions that follow Crockford's private or priviledged pattern. For example:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
In any case where the attacker has no "execute" right on the JS context he has no way of accessing any "public" or "private" fields or methods. In case the attacker does have that access he can execute this one-liner:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Note that the above code is generic to all constructor-type-privacy. It will fail with some of the solutions here but it should be clear that pretty much all of the closure based solutions can be broken like this with different replace() parameters.
After this is executed any object created with new Foo() is going to have an eval method which can be called to return or change values or methods defined in the constructor's closure, e.g.:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
The only problem I can see with this that it won't work for cases where there is only one instance and it's created on load. But then there is no reason to actually define a prototype and in that case the attacker can simply recreate the object instead of the constructor as long as he has a way of passing the same parameters (e.g. they are constant or calculated from available values).
In my opinion, this pretty much makes Crockford's solution useless. Since the "privacy" is easily broken the downsides of his solution (reduced readability & maintainability, decreased performance, increased memory) makes the "no privacy" prototype based method the better choice.
I do usually use leading underscores to mark __private and _protected methods and fields (Perl style), but the idea of having privacy in JavaScript just shows how it's a misunderstood language.
Therefore I disagree with Crockford except for his first sentence.
So how do you get real privacy in JS? Put everything that is required to be private on the server side and use JS to do AJAX calls.
The apotheosis of the Module Pattern: The Revealing Module Pattern
A neat little extension to a very robust pattern.
If you want the full range of public and private functions with the ability for public functions to access private functions, layout code for an object like this:
function MyObject(arg1, arg2, ...) {
//constructor code using constructor arguments...
//create/access public variables as
// this.var1 = foo;
//private variables
var v1;
var v2;
//private functions
function privateOne() {
}
function privateTwon() {
}
//public functions
MyObject.prototype.publicOne = function () {
};
MyObject.prototype.publicTwo = function () {
};
}
var TestClass = function( ) {
var privateProperty = 42;
function privateMethod( ) {
alert( "privateMethod, " + privateProperty );
}
this.public = {
constructor: TestClass,
publicProperty: 88,
publicMethod: function( ) {
alert( "publicMethod" );
privateMethod( );
}
};
};
TestClass.prototype = new TestClass( ).public;
var myTestClass = new TestClass( );
alert( myTestClass.publicProperty );
myTestClass.publicMethod( );
alert( myTestClass.privateMethod || "no privateMethod" );
Similar to georgebrock but a little less verbose (IMHO)
Any problems with doing it this way? (I haven't seen it anywhere)
edit: I realised this is kinda useless since every independent instantiation has its own copy of the public methods, thus undermining the use of the prototype.
Here's what i enjoyed the most so far regarding private/public methods/members and instantiation in javascript:
here is the article: http://www.sefol.com/?p=1090
and here is the example:
var Person = (function () {
//Immediately returns an anonymous function which builds our modules
return function (name, location) {
alert("createPerson called with " + name);
var localPrivateVar = name;
var localPublicVar = "A public variable";
var localPublicFunction = function () {
alert("PUBLIC Func called, private var is :" + localPrivateVar)
};
var localPrivateFunction = function () {
alert("PRIVATE Func called ")
};
var setName = function (name) {
localPrivateVar = name;
}
return {
publicVar: localPublicVar,
location: location,
publicFunction: localPublicFunction,
setName: setName
}
}
})();
//Request a Person instance - should print "createPerson called with ben"
var x = Person("ben", "germany");
//Request a Person instance - should print "createPerson called with candide"
var y = Person("candide", "belgium");
//Prints "ben"
x.publicFunction();
//Prints "candide"
y.publicFunction();
//Now call a public function which sets the value of a private variable in the x instance
x.setName("Ben 2");
//Shouldn't have changed this : prints "candide"
y.publicFunction();
//Should have changed this : prints "Ben 2"
x.publicFunction();
JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/
The module pattern is right in most cases. But if you have thousands of instances, classes save memory. If saving memory is a concern and your objects contain a small amount of private data, but have a lot of public functions, then you'll want all public functions to live in the .prototype to save memory.
This is what I came up with:
var MyClass = (function () {
var secret = {}; // You can only getPriv() if you know this
function MyClass() {
var that = this, priv = {
foo: 0 // ... and other private values
};
that.getPriv = function (proof) {
return (proof === secret) && priv;
};
}
MyClass.prototype.inc = function () {
var priv = this.getPriv(secret);
priv.foo += 1;
return priv.foo;
};
return MyClass;
}());
var x = new MyClass();
x.inc(); // 1
x.inc(); // 2
The object priv contains private properties. It is accessible through the public function getPriv(), but this function returns false unless you pass it the secret, and this is only known inside the main closure.
What about this?
var Restaurant = (function() {
var _id = 0;
var privateVars = [];
function Restaurant(name) {
this.id = ++_id;
this.name = name;
privateVars[this.id] = {
cooked: []
};
}
Restaurant.prototype.cook = function (food) {
privateVars[this.id].cooked.push(food);
}
return Restaurant;
})();
Private variable lookup is impossible outside of the scope of the immediate function.
There is no duplication of functions, saving memory.
The downside is that the lookup of private variables is clunky privateVars[this.id].cooked is ridiculous to type. There is also an extra "id" variable.
Wrap all code in Anonymous Function: Then , all functions will be private ,ONLY functions attached to window object :
(function(w,nameSpacePrivate){
w.Person=function(name){
this.name=name;
return this;
};
w.Person.prototype.profilePublic=function(){
return nameSpacePrivate.profile.call(this);
};
nameSpacePrivate.profile=function(){
return 'My name is '+this.name;
};
})(window,{});
Use this :
var abdennour=new Person('Abdennour');
abdennour.profilePublic();
FIDDLE
I prefer to store private data in an associated WeakMap. This allows you to keep your public methods on the prototype where they belong. This seems to be the most efficient way to handle this problem for large numbers of objects.
const data = new WeakMap();
function Foo(value) {
data.set(this, {value});
}
// public method accessing private value
Foo.prototype.accessValue = function() {
return data.get(this).value;
}
// private 'method' accessing private value
function accessValue(foo) {
return data.get(foo).value;
}
export {Foo};
2021 HERE!
This polyfill effectively hides your private properties and methods returning undefined when you try to read your private property and a TypeError when you try to execute your private method thus effectively making them both PRIVATE to the outside but giving you access to them by using your public methods.
If you check it you will see it is very easy to implement. For the most part you don't need to do anything quirky like using Proxy objects, underscore functions (_myprivate), getters or setters. None of that. The only thing required is to place in your constructor that like snippet of code that is aimed to let you expose your public interface to the outside world.
((self) => ({
pubProp: self.pubProp,
// More public properties to export HERE
// ...
pubMethod: self.pubMethod.bind(self)
// More public mehods to export HERE
// Be sure bind each of them to self!!!
// ...
}))(self);
The above code is where the magic happens. It is an IIFE that returns an object with just the properties and methods you want to exposed and bound to the context of the object that was first instantiated.
You can still access your hidden properties and methods but only through your public methods just the way OOP should do.
Consider that part of the code as your module.exports
BTW, this is without using the latest ECMAScript 2022 # addition to the language.
'use strict';
class MyClass {
constructor(pubProp) {
let self = this;
self.pubProp = pubProp;
self.privProp = "I'm a private property!";
return ((self) => ({
pubProp: self.pubProp,
// More public properties to export HERE
// ...
pubMethod: self.pubMethod.bind(self)
// More public mehods to export HERE
// Be sure to bind each of them to self!!!
// ...
}))(self);
}
pubMethod() {
console.log("I'm a public method!");
console.log(this.pubProp);
return this.privMethod();
}
privMethod() {
console.log("I'm a private method!");
return this.privProp
}
}
const myObj = new MyClass("I'm a public property!");
console.log("***DUMPING MY NEW INSTANCE***");
console.dir(myObj);
console.log("");
console.log("***TESTING ACCESS TO PUBLIC PROPERTIES***");
console.log(myObj.pubProp);
console.log("");
console.log("***TESTING ACCESS TO PRIVATE PROPERTIES***");
console.log(myObj.privProp);
console.log("");
console.log("***TESTING ACCESS TO PUBLIC METHODS***");
console.log("1. pubMethod access pubProp ");
console.log("2. pubMethod calls privMethod");
console.log("3. privMethod access privProp");
console.log("")
console.log(myObj.pubMethod());
console.log("");
console.log("***TESTING ACCESS TO PRIVATE METHODS***");
console.log(myObj.privMethod());
Check my gist
Private functions cannot access the public variables using module pattern
Since everybody was posting here his own code, I'm gonna do that too...
I like Crockford because he introduced real object oriented patterns in Javascript. But he also came up with a new misunderstanding, the "that" one.
So why is he using "that = this"? It has nothing to do with private functions at all. It has to do with inner functions!
Because according to Crockford this is buggy code:
Function Foo( ) {
this.bar = 0;
var foobar=function( ) {
alert(this.bar);
}
}
So he suggested doing this:
Function Foo( ) {
this.bar = 0;
that = this;
var foobar=function( ) {
alert(that.bar);
}
}
So as I said, I'm quite sure that Crockford was wrong his explanation about that and this (but his code is certainly correct). Or was he just fooling the Javascript world, to know who is copying his code? I dunno...I'm no browser geek ;D
EDIT
Ah, that's what is all about: What does 'var that = this;' mean in JavaScript?
So Crockie was really wrong with his explanation....but right with his code, so he's still a great guy. :))
In general I added the private Object _ temporarily to the object.
You have to open the privacy exlipcitly in the "Power-constructor" for the method.
If you call the method from the prototype, you will
be able to overwrite the prototype-method
Make a public method accessible in the "Power-constructor": (ctx is the object context)
ctx.test = GD.Fabric.open('test', GD.Test.prototype, ctx, _); // is a private object
Now I have this openPrivacy:
GD.Fabric.openPrivacy = function(func, clss, ctx, _) {
return function() {
ctx._ = _;
var res = clss[func].apply(ctx, arguments);
ctx._ = null;
return res;
};
};
This is what I worked out:
Needs one class of sugar code that you can find here. Also supports protected, inheritance, virtual, static stuff...
;( function class_Restaurant( namespace )
{
'use strict';
if( namespace[ "Restaurant" ] ) return // protect against double inclusions
namespace.Restaurant = Restaurant
var Static = TidBits.OoJs.setupClass( namespace, "Restaurant" )
// constructor
//
function Restaurant()
{
this.toilets = 3
this.Private( private_stuff )
return this.Public( buy_food, use_restroom )
}
function private_stuff(){ console.log( "There are", this.toilets, "toilets available") }
function buy_food (){ return "food" }
function use_restroom (){ this.private_stuff() }
})( window )
var chinese = new Restaurant
console.log( chinese.buy_food() ); // output: food
console.log( chinese.use_restroom() ); // output: There are 3 toilets available
console.log( chinese.toilets ); // output: undefined
console.log( chinese.private_stuff() ); // output: undefined
// and throws: TypeError: Object #<Restaurant> has no method 'private_stuff'
Class({
Namespace:ABC,
Name:"ClassL2",
Bases:[ABC.ClassTop],
Private:{
m_var:2
},
Protected:{
proval:2,
fight:Property(function(){
this.m_var--;
console.log("ClassL2::fight (m_var)" +this.m_var);
},[Property.Type.Virtual])
},
Public:{
Fight:function(){
console.log("ClassL2::Fight (m_var)"+this.m_var);
this.fight();
}
}
});
https://github.com/nooning/JSClass
I have created a new tool to allow you to have true private methods on the prototype
https://github.com/TremayneChrist/ProtectJS
Example:
var MyObject = (function () {
// Create the object
function MyObject() {}
// Add methods to the prototype
MyObject.prototype = {
// This is our public method
public: function () {
console.log('PUBLIC method has been called');
},
// This is our private method, using (_)
_private: function () {
console.log('PRIVATE method has been called');
}
}
return protect(MyObject);
})();
// Create an instance of the object
var mo = new MyObject();
// Call its methods
mo.public(); // Pass
mo._private(); // Fail
You have to put a closure around your actual constructor-function, where you can define your private methods.
To change data of the instances through these private methods, you have to give them "this" with them, either as an function argument or by calling this function with .apply(this) :
var Restaurant = (function(){
var private_buy_food = function(that){
that.data.soldFood = true;
}
var private_take_a_shit = function(){
this.data.isdirty = true;
}
// New Closure
function restaurant()
{
this.data = {
isdirty : false,
soldFood: false,
};
}
restaurant.prototype.buy_food = function()
{
private_buy_food(this);
}
restaurant.prototype.use_restroom = function()
{
private_take_a_shit.call(this);
}
return restaurant;
})()
// TEST:
var McDonalds = new Restaurant();
McDonalds.buy_food();
McDonalds.use_restroom();
console.log(McDonalds);
console.log(McDonalds.__proto__);
I know it's a bit too late but how about this?
var obj = function(){
var pr = "private";
var prt = Object.getPrototypeOf(this);
if(!prt.hasOwnProperty("showPrivate")){
prt.showPrivate = function(){
console.log(pr);
}
}
}
var i = new obj();
i.showPrivate();
console.log(i.hasOwnProperty("pr"));

How do I set up a javascript Class with inheritance + private properties + getters / setters

I wish to use https://github.com/mozilla/BrowserQuest/blob/master/server/js/lib/class.js with private inheritable properties and also some getters and setters in there.
Basically I want the getter / setter to modify a private property and subclasses to inherit the setter, getter and the private property of course.
This is what I got so far:
var Person = Class.extend({
init: function( name )
{
var name = "~";
this.myName = name;
return {
set myName( value )
{
name = value + " +?";
},
get myName()
{
return name + "^^^^^^^^^";
}
}
}
});
var c = new Person( "cheese" );
console.log(c.myName);
c.myName = "zoom";
console.log(c.myName);
Trace:
undefined
zoom
Its weird, my editor (Webstorm) sees c.myName as the setter/getter but the compilers consider it an undefined public property :(
Any help would be appreciated. This is Nodejs but I think the issues is javascript.
I'm assuming Node.js or any other environment where the whole EcmaScript 5 is available.
The only way to have true private data in JavaScript these days is to keep a variable in the constructor, which is what you're doing. However, you're confusing the use of return in the init function. While the init function is pretty much the constructor, it is not being called exactly as such, so return does nothing. Even if it did something, what you want is to add a property to this, not return a new object. So basically you'd have to change that return to Object.defineProperty:
init: function (name) {
// notice that the private variable has a different name
// than the parameter
var privateName = '~';
Object.defineProperty(this, 'myName', {
set: function (value) {
privateName = value + " +?";
},
get: function () {
return privateName + "^^^^^^^^^";
}
});
this.myName = name;
}
This still has a limitation in inheritance. If you wanted to inherit from the Person class and modify the getters and setters you'd have to get the property descriptor, modify it and redefine the property. That's painful. And it doesn't support accessing the "super getter/setter". In order to avoid that what we usually do in JavaScript is to forget about having true privates and use privates by convention, starting the private property's name with _. Then you can simply define your getters and setters in the prototype like this:
var Person = Class.extend({
init: function(name) {
// the private name property
this._name = '~';
this.myName = name;
},
set myName(value) {
this._name = value + " +?";
},
get myName() {
return this._name + "^^^^^^^^^";
}
});
This will let you access the super getter/setter when using inheritance.
There is a cutting edge feature that would let you have both true privates and inherit getters and setters: WeakMap. WeakMap is basically an object with creates a relationship between two other objects that doesn't count for garbage collection. That last part is important for memory management and that first part is the one that lets you have true privates. You can try WeakMaps in Beta versions of Firefox and in Node.js with a --harmony_collections flag. Here's how it would work:
function privatize() {
var map = new WeakMap();
return function (obj) {
var data = map.get(obj);
if (!data) {
map.set(obj, data = {});
}
return data;
};
}
var Person = (function () {
var _private = privatize();
return Class.extend({
init: function(name) {
// the private name property
_private(this).name = '~';
this.myName = name;
},
set myName(value) {
_private(this).name = value + " +?";
},
get myName() {
return _private(this).name + "^^^^^^^^^";
}
});
}());

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();

Categories

Resources