I'm looking for a relatively simple but efficient mechanism to implement clean looking:
public, private and protected members (with actual public/private/protected access, but still extensible)
inheritance (single or multiple)
constructor overloading (prefer not to have to count args and check types with a complex set of nested conditionals)
All right...made myself a cup of coffee before writing this. Only thing I can't help you with is overloading. But never mind, here we go:
// Class pattern with
// - dynamic prototypes
// - public, private, static, static private members
// Keeps functions named the way you want it to.
// Working example:
var YourClass = (function(){
var Pseudo = function(){
var args = arguments;
// constuct the instance in here:
var YourClass = function(){
var public = this,
private = {};
public.foo = args[0] ? args[0] : "bar";
public.staticPrivateInt = ++static_private.someInt;
private.fibo = "nacci";
// fibo is private - return it's value
// with a getter to make it "protected"
public.getFibo = function(){
return private.fibo;
}
public.setFibo = function(value){
if(typeof value === "string"){
// handle optional events here
return private.fibo = value;
}else{
return false;
}
}
};
var static = Pseudo,
static_private = {};
// statics:
static_private.someInt = 100;
static.increaseSomeInt = function(){
++static_private.someInt;
}
// extend on creation of an instance:
YourClass.prototype = args[0] || new Object(); // or anything else, just an example
return new YourClass;
};
return Pseudo;
}());
Usage:
var myInstance = new YourClass({
someCfg: true
});
console.log(myInstance.someCfg === true); // will log true
Thanks to JavaScript's lexical scoping and closures one can indeed simulate the way classes are designed in other languages like C++, Java etc.
Keep a few things in mind when using that pattern:
Variable names like static, private or public will lead to errors
when in strict mode. You can rename them if needed.
Static private variables should not be stored as static.private cause they wouldnt be private anymore (thus the variable static_private).
How it works
Basically, what you'll want is:
public members to be accessible with <object>.<member>. In Javascript, that is usually done with this.<member> = <assignment>;.
=> For convenienve, create a simple alias:
var public = this;
private members to be visible in the constructor, but not in the instance. Still they need to be accessible for public methods.
=> var private = {};
You can create simple variables to, for example var fibo="nacci";, I find private.fibo="nacci"; more readable though. Any variable created with the var keyword will not be accessible from the outer scope of the constructor function.
static members to be ready even if no instance of the class has been created yet. The usual way to do that in JavaScript is assigning a value or function to the constructor itself. See SO question here
=> Again, for readability:
var static = Pseudo;
static private members: Occasionaly, you might want to have static members that are invisible outside your constructor.
=> Use lexical scope to store them. var static_private = {};
For further reading on class patterns:
The YAHOO module pattern:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
Douglas Crockford (the JS-Hercules) on private members: http://javascript.crockford.com/private.html
http://www.google.de/search?q=javascript+class+pattern&aq=f&oq=javascript+class+pattern
Related
How do I add properties to a constructor function in JavaScript? For example. If I have the following function.
function Hotel(name)
{
this.name = name;
};
var hotel1 = new Hotel('Park');
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this". Of course it would not be private since objects created will be able to use it correct?
Can I do something like this. Do I use the this keyword or do I use the var keyword
which one is it? I have example 2 on the function constructor on the bottom
1. var numRooms = 40;
2. this.numRooms = 40;
3. numRooms : 40,
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
};
I know that if I want a function within the object constructor I need to use the this word. Will that work as well for normal variables as I have asked above.
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
this.addNumRoomsPlusFive = function()
{
return this.numRooms + 5;
}
};
You can simple add a private variable to your constructor:
function Hotel(name) {
var private = 'private';
this.name = name;
};
But if you will use your Hotel function without a new operator, all properties and functions which was attached to this will become global.
function Hotel(name) {
var private = 'private';
this.name = name;
};
var hotel = Hotel('test');
console.log(name); // test
It is good idea to return an object in constructor function:
function Hotel(name) {
var
private_var = 'private',
private_func = function() {
// your code
};
retur {
name: 'name',
public_func: private_func
}
};
var hotel = Hotel('test');
console.log(name); // undefined
So if you will use Hotel constructor without new operator no global variable will be created. This is possible only if the return value is an object. Otherwise, if you try to return anything that is not an object, the constructor will proceed with its usual behaviour and return this.
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this".
Yes we can:
// API implementation in the library
function Hotel(name) {
// only our library code knows about the actual value
const numRooms = 'privateNoRoomsVar';
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// also, users don't have access to 'numRooms' variable so they can't use hotel[numRooms].
If a user looks at the source code and finds out the value privateNoRoomsVar, then they can misuse the API.
For that we need to use symobls:
// API implementation in the library
function Hotel(name) {
// no one can duplicate a symbol so the variable is really private
const numRooms = Symbol();
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// there is no way users will get access to the symbol object so the variable remains private.
Private class features, #privateField, are supported by all the browsers so we don’t have to worry about this anymore.
// API implementation in the library
class Hotel {
// private field
#numRooms = 40;
constructor(name) {
this.name = name;
}
addNumRoomsPlusFive() {
return this.#numRooms + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
//console.log('hotel.numRooms =', hotel.#numRooms); // throws error
Javascript historically creates objects from prototypes of other objects. It was a result of EMCA2015, that you have a distinct syntax of a class that specifies an object. As an aside, if you mouse over the table in that link it gives dates of when the feature was implemented.
A javascript object created by the new operator is more or less a combination of an associative array ( what you make with let avar={}; ) that can access the function level scopes it is defined in. The keys of the array are its properties. According to its creator, Javascript was created to be an easy to use program language without a hierarchy of types. One of the ways it accomplished this is by more or less considering its mapping type to be equivalent to the prototypical Object which object oriented programming languages describe.
Adding properties in 2022
function AProtoype(arg1, arg2, arg3){
//this defines a property
this.pa=arg1;
/* unicorns in this section */
let x = 1;
/*
a getter which has the same syntax as a property
but returns x from the scope which it references and
not the object.
*/
get getx() => x;
}
let object = new AProtoype(2,3,4);
Is equivalent to the following code for the purposes of data access but not inheritance and typing. The new operator also sets variables on an object that are used for these purposes.
function NewObject(arg1, arg2, arg3){
let prototype = {};
/*dragons in this section, as you are not using the this keyword to accomplish things*/
prototype.pa = arg1;
Object.defineProperty(prototype, "getx", {get:()=>x});
return prototype;
}
//If you do this instead of using the new operator it is an anti-pattern.
//And like all anti-patterns: "But it works!"
let object = NewObject(2,3,4);
The relevant property defining methods where in some sense supported as early as 2010, 2011. I do not have a contemporary source to that time to confirm if you could pull off what I'm doing though, and you'd only want to if all else failed and it needed to run on Internet Explorer 9. In the event all else is failing, you may want to read the documentation for Object.create, which is also of interest because more or less provides an api to make new objects.
Now, for a fun time and horror, you can also define a function that returns this, and get an object back with an equivalent binding of that function. The horror comes when it is an object in global scope, and you rename a property of that object; as Javascript will resolve the name collision by happily writing on whatever it finds if it can. You can then use this to re-implement the prototype pattern that javascripts new operator is built off of conceptually, for the sake of science.
When you use a "constructor function" in Javascript, any properties defined on the instance using the this keyword become public. This is unavoidable, because Javascript objects have no concept of private properties - if it exists, it can be accessed directly as object.property.
For example, if you tried to do as in the following snippet, mimicking a typical getter/setter pattern with a private variable in Java or C# (note that even if this worked, this is not idiomatic Javascript):
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
then while you can indeed use the getter and setter to do as you expect, you can also just access and set the private variable directly! Demonstration:
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - not intended to work
console.log(obj.privateVar); // 2
obj.privateVar = 3;
console.log(obj.getVar()); // 3 (using public API to get it to show that the direct update to the private variable also affects the intended public methods)
There is though a way to mimic the effect of private variables. They're not actually object properties - because, as I have just demonstrated, such are intrinsically public - but the same can be mimicked by:
not using a "constructor function" at all, but a regular function that happens to return an object. This is all a constructor function really does, anyway - the difference in JS is only syntactic, that you do not need to use the new keyword when you call the function. (Although you still can, if you really prefer - any function that returns an object can be called with new and behave in the same way as without it, although performance will likely suffer a little as the function would then construct a brand new object and throw it away. See MDN for a justification of these statements, particularly step 4.)
inside this function, using a regular variable as the private variable. This variable will be completely inaccessible from outside by the simple rules of scope, but you can still have the returned object retain access to it by the "magic" of closures.
Here is the above getter/setter example translated to this procedure, as well as demonstrations of it working. (I hasten to add again though, that this wouldn't be considered idiomatic code in Javascript.)
function makeObjectWithPrivateVar(privateVar) {
function getPrivateVar() {
return privateVar;
}
function setPrivateVar(newVal) {
privateVar = newVal;
}
return { getPrivateVar, setPrivateVar };
}
var obj = makeObjectWithPrivateVar(1);
// getter
console.log(obj.getPrivateVar()); // 1
// setter
obj.setPrivateVar(2);
// getter again to observe the change
console.log(obj.getPrivateVar()); // 2
// but how could we access the private var directly??
// answer, we can't
console.log(obj.privateVar); // undefined
console.log(privateVar); // ReferenceError, privateVar is not in scope!
Note finally though that it's rare in modern Javascript to use the function-based constructors in this style, since the class keyword makes it easier to mimic traditional class-based languages like Java if you really want to. And in particular, more recent browsers support private properties directly (you just have to prefix the property name with a #), so the initial code snippet translated into a class and using this feature, will work fine:
class MyObject {
#privateVar
constructor(privateVar) {
this.#privateVar = privateVar;
}
getVar() {
return this.#privateVar;
}
setVar(newVal) {
this.#privateVar = newVal;
}
}
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - now doesn't work
console.log(obj.privateVar); // undefined, it doesn't exist
// console.log(obj.#privateVar); // error as it's explicitly private, uncomment to see error message
Usually it's performed using closures:
var Hotel = (function() {
var numrooms=40; // some kind of private static variable
return function(name) { // constructor
this.numrooms = numrooms;
this.name = name;
};
}());
var instance = new Hotel("myname");
I'm asked to make a Javascript Module that acts as counter of browser events and is not possible to modify the actual counted events (Private method).
var CountingLogger = (function() {
var secret ={};
var uid = 0;
function CountingLogger(events) {
secret[this.id = uid++] = {};
// Store private stuff in the secret container
// instead of on `this`.
secret[this.id].events = events || 0;
}
CountingLogger.prototype.log = function (eventName) {
alert(secret[this.id].events[eventName]);
if (typeof secret[this.id].events[eventName] === 'undefined') {
secret[this.id].events[eventName] = 0;
}
secret[this.id].events[eventName]++;
var count = secret[this.id].events[eventName];
$('#logContents').append('<li>' + eventName + ': ' + count + '</li>');
};
return CountingLogger;
}());
in the main.js I define:
var logger = new CountingLogger();
then call
logger.log('EventName');
And should appear as callback a counter "EventName" + Counter, so Eventname: 1, SecondEvent: 4...
But in the log always shows 'WhateverEvent' undefined.
Can anybody please have an idea how this can be solved?
Regards
You don't want secrets at the level you have it. As Bergi said, it's a memory leak.
(Note: When I say "truly private" below, remember that nothing is truly private if someone's using a debugger. "Truly private" below just makes it's impossible for anyone to write code that, using a reference to the object, gets or modifies the private data.)
ES7 will have truly private properties. Until then, you basically have three options:
Truly private data, held via closures over the call to the constructor
"Keep your hands off" properties via a property naming convention
Very-hard-to-use properties that, while not private, are very hard to write code against
Truly Private Data
If you want truly private information on a per-instance basis, the standard way to do that is using variables in the constructor, and define methods that need that private data within the constructor:
function Foo() {
var secret = Math.floor(Math.random() * 100);
this.iWillTellYouASecret = function() {
console.log("The secret is " + secret);
};
}
Foo.prototype.iDoNotKnowTheSecret = function() {
console.log("I don't know the secret");
};
Yes, that means a new iWillTellYouASecret function is created for every instance, but it (and the secret) are also reclaimed when that instance is removed from memory, and a decent JavaScript engine can reuse the function's code across those function objects.
"Keep your hands off" Properties
But most of the time, you don't need truly private information, just information saying "keep your hands off me." The convention for that in JavaScript is properties beginning with an _. Yes, that means that code with access to instances can use or change that property's value, but that's actually true in most languages that have "truly private" properties as well, such as Java, via reflection.
Very-Hard-to-Use Properties
If you want to make life harder on people trying to use your private data, you can use this trick from an old blog article of mine *(it was written back when ES6 was going to have true privacy via Name objects; since then, Name has turned into Symbol and it isn't used for privacy anymore):
First, you create a Name psuedo-class:
var Name = function() {
var used = {};
function Name() {
var length, str;
do {
length = 5 + Math.floor(Math.random() * 10);
str = "_";
while (length--) {
str += String.fromCharCode(32 + Math.floor(95 * Math.random()));
}
}
while (used[str]);
used[str] = true;
return new String(str); // Since this is called via `new`, we have to return an object to override the default
}
return Name;
}();
Then you use this pattern for your private instance properties:
// Nearly-private properties
var Foo = (function() {
// Create a random string as our private property key
var nifty = new Name();
// Our constructor
function Foo() {
// We can just assign here as normal
this[nifty] = 42;
}
// ***On ES5, make the property non-enumerable
// (that's the default for properties created with
// Object.defineProperty)
if (Object.defineProperty) { // Only needed for ES3-compatibility
Object.defineProperty(Foo.prototype, nifty, {
writable: true
});
}
// ***End change
// Methods shared by all Foo instances
Foo.prototype.method1 = function() {
// This method has access to `nifty`, because it
// closes over the private key
console.log("Truly private nifty info: " + this[nifty]);
};
Foo.prototype.method2 = function() {
// Also has access, for the same reason
console.log("Truly private nifty info: " + this[nifty]);
};
return Foo;
})();
var f = new Foo();
f.method1(); // Can use nifty!
f.method2(); // Can too! :-)
// Both `method1` and `method2` are *reused* by all `Foo` objects
Now, the name of your private property is different every time your code runs.
This still isn't private. It's just harder to find.
Private methods in javascript should only be used for encapsulation purposes.
It's impossible to prevent someone from manipulating any method in javascript.
A user can simply place a debug point on your private method and start to manipulate your private logic.
I know you can achieve something as "privateness" in JavaScript by using closures and Immediate Invoked Functions.
But what if I need full featured prototyping? There simply is no way I know of of having private members in an object's prototype. If I used privileged methods I can have private variables and public methods but I lose the option of prototyping.
Douglas Crockford "forbids" the use of dangling (putting an underscore in front of an identifier to indicate that it is not part of the public interface).
But is it that bad to use it? Since there is no way to make it real private.
What is your opinion about this? How do you handle it?
Well at first, you don't really lose the prototyping-effect when using a functional-inheritance pattern. I just assume you're talking about The good parts, crockford also introduced a pretty easy and effective way to have shared variables for that pattern aswell. Which basically looks like:
var Human = (function(my, priv) {
var my = my || {},
priv = priv || {};
my.privatedata = "foobar";
priv.walk = function() {
console.log('walking');
return priv;
};
priv.talk = function() {
console.log('blah blah');
return priv;
};
return priv;
}());
var Andy = (function(my, priv) {
var my = my || {},
priv = Human(my, priv);
priv.SpecialAndyThing = function() {
console.log('bloggin at typeofnan.com');
return priv;
};
return priv;
}());
var myAndy = Andy();
myAndy.talk().SpecialAndyThing();
You can even simply extend this techniqe to have somekind of super methods. Using cryptic variable-conventions like underscores or whatnot is just bad practice in general. Its confusing since nobody just knows what is going on there (probably that argument fails if you're the only one using the codebase).
However, ECMAscript Edition 5 introduces some goodys to have more "private" members in a prototype chain. One important method for that is .defineProperty, where you can define a property which does not "shallow" through. Would look like:
var Human = {};
Object.defineProperty(Human, 'privateStuff', {
value: 'secret',
enumerable: false
});
Now, the property privateStuff is not visible for an object that inherits from Human's prototype chain. Anyway, this stuff requires Javascript 1.8.5 and is only available in cutting edge browsers for now. See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
You may be interested in JavaScript Design Patterns. It discusses the Module Pattern too.
Here is an example of how to allow prototypal functions to access private variables in all browsers:
var Book = (function() {
var $ = {};
var Book = function(newFirst, newLast) {
// Private variables stored in an object literal.
var _ = {
author_first : newFirst,
author_last : newLast
};
// Public privileged method for accessing private variables.
this._ = function(key) {
if(key === $)
return _;
throw new Error("The _() function must be called internally.");
};
};
// Public accessor method.
Book.prototype.getAuthor = function() {
var _ = this._($);
return _.author_first + " " + _.author_last;
};
return Book;
})();
var bookA = new Book("Chris", "West"),
bookB = new Book("Douglas", "Crockford");
alert(bookA.getAuthor());
alert(bookB.getAuthor());
This is the same way that I implemented the Color class in jPaq.
I am from c# object oriented background and which to work similar priniciples in javascript. Any good I articles that could help with me research?
This is an example i put together for a Product Javascript object:
function Product() {
this.reset = function () {
this.id = 0;
this.name = '';
}
}
Product.prototype = {
loadFromJson: function (json) {
this.reset();
this.id = json.Id;
this.name = json.Name;
},
checkAvailability: function (qty) {
// Just to illustrate
return true;
}
};
So to create an instance of Product:
var p = new Product();
To access a public method:
var isAvailable = p.checkAvailability(1);
To access a public property:
var name = p.name;
Is the reset function I create a valid private function?
Is what I am doing above correct or is there a better way? I am new to this!
Also, if I create an instance of product in another javascript file, can I get intellisence on the properties of the Product object?
The reset is this.reset(); so that is in the scope of the object and thus could be called public, but remains in that scope. In your example p.reset(); but reset(); fails.
Better way? It depends, some circumstances require this complex, some do not. There are a number of ways to instantiate objects (everything is an object in JavaScript) and your examples are some of the ways.
No intellisence unless you build and attach your own (a LOT of work). (search on jQuery intellisence to see how that is done)
See this for some more regarding namespace. Note the internal and public functions and variables.
var myStuffApp = new function()
{
var internalFunction = function()
{
alert('soy una función interna');
};
this.publicFunction = function()
{
alert('soy una función pública');
};
var test1 = 'testing 1';//private/internal
this.test2 = 'testing 2';// namespaced
testA="ho";// global
};
I suggest the read this msdn page for basic information. It's like a crash course for c# oriented developers.
Is the reset function I create a valid private function?
No. It differs from the functions set on prototype because you get a different copy of reset for every instance of Product:
var p1= new Product();
var p2= new Product();
alert(p1.loadFromJson===p2.loadFromJson); // true
alert(p1.reset===p2.reset); // false
but it is not private. You can still do:
var p= new Product();
p.reset();
Whilst you can do private functions in JavaScript using closures, it's almost never worth it. Consider just using the Python convenition of naming all members you don't intend to be used outside the implementation with a preceding underscore.
See this question for extensive discussion of JS object models.
I was just wondering about the difference between the following declaration of JavaScript objects. Specifically, the difference between thing object literal and thing1 object from thing class.
Code:
var thing = {
sanity:0,
init:function(){
//code
},
send:function(){
//code
}
}
function thing(){
this.sanity = 0;
this.init = function(){
//code
};
this.send = function(){
//code
};
}
thing1 = new thing();
Static Objects / Object Literals
Static objects, or object literals, don't require instantiation with the new operator and also behave like singletons. Consider the following example:
Code:
var staticObject1 = {
a: 123,
b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);
Output:
Object a=123 b=456 Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats
Notice that changing staticObject2.b also affected staticObject1.b. However, this may not always be the desired effect. Many libraries, such as Dojo, offer an object cloning method that can alleviate this situation if you want to make a copy of a static object. Continuing the previous example, consider the following:
Code:
var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);
Output:
Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats
Notice that the values of the members of staticObject1 and staticObject2 are the same, whereas staticObject3 is not affected by changes to these other objects.
Static objects are also useful for creating project or library namespaces, rather than filling up the global scope, and promotes compatibility like no one's business.
This is useful when creating libraries that require portability or interoperability. This can be seen in popular libraries such as Dojo, YUI and ExtJs, where all or most methods are called as dojo.examplMethod(), YUI().exampleMethod(), or Ext.exampleMethod() respectively.
Static objects can also be considered loosely analogous to struct's in C/C++.
Class Constructors / Instantiated Objects
Classes in JavaScript are based on prototypal inheritance, which is a far more complex subject and can be read about here, here and here.
As opposed to static objects, this method of object creation gives the unique opportunity for private scope object members and methods because of JavaScript's closuer property. Consider the following example of private class members:
Code:
var SomeObject = function() {
var privateMember = "I am a private member";
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
};
var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();
Output:
undefined string
I am a private member I am a public member
Notice that typeof o.privateMember is "undefined" and not accessible outside of the object, but is from within.
Private methods can also be made, but are not as straight forward yet are still simple to implement. The issue lies in that the value of this inside of the private method defaults to window and one of two techniques must be applied to ensure that this refers to the object that we are working within, in this case, the instance of SomeObject. Consider the following example:
Code:
var SomeObject = function() {
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(this.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod.call(this);
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
Output:
undefined function function
I am a public member
Notice that withing privateMethodWrapper(), privatemethod was executed using call and passing in this for the function's context. This is all fine; however, the following technique is preferable (in my opinion) as it simplifies the calling scope and produces identical results. The previous example can be changed to the following:
Code:
var SomeObject = function() {
var self = this;
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(self.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod();
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
Output:
undefined function function
I am a public member
This answer was the basis for a post on my blog, where I give additional examples. Hope that helps ;)
Case 2 is referencing javascript class constructors. A glaring difference is that the variable is not yet an object, so you cannot internally reference thing1.sanity. You would have to initialize the class by creating an instance of said class prior to calling any internal members:
var myConstructor = function() {
this.sanity = 0;
}
// wont work
alert(myConstructor.sanity);
// works
var thing1 = new myConstructor();
alert(thing1.sanity);
Here is an article going further in-depth than my quick example:
Class Constructors vs. Object Literals
The difference is that the thing1 object is associated with the thing1 class, and will inherit (not literally) the thing1 prototype.
For example, you can later write
thing.prototype.initAndSend = function() { this.init(); this.send(); };
You will then be able to write thing1.initAndSend() without modifying thing1. In addition, thing1.constructor will be equal to the thing method, whereas {}.constructor is equal to Object.
By the way, standard convention is to capitalize class names.
Functions are objects and also constructors (you can instantiate them using new).
Hash-tables/Objects ({}) are not able to be instantiated, thus they are commonly used as data structures. And I am not so sure if it is wise to call them "Objects".
With the first method, you are declaring a single object. With the second, you are declaring a class from which you can instantiate (i.e. create) many different copies.