JavaScript Classes - javascript

I understand basic JavaScript pseudo-classes:
function Foo(bar) {
this._bar = bar;
}
Foo.prototype.getBar = function() {
return this._bar;
};
var foo = new Foo('bar');
alert(foo.getBar()); // 'bar'
alert(foo._bar); // 'bar'
I also understand the module pattern, which can emulate encapsulation:
var Foo = (function() {
var _bar;
return {
getBar: function() {
return _bar;
},
setBar: function(bar) {
_bar = bar;
}
};
})();
Foo.setBar('bar');
alert(Foo.getBar()); // 'bar'
alert(Foo._bar); // undefined
But there are un-OOP-like properties to both of these patterns. The former does not provide encapsulation. The latter does not provide instantiation. Both patterns can be modified to support pseudo-inheritance.
What I'd like to know is if there is any pattern that allows:
Inheritance
Encapsulation (support for "private" properties/methods)
Instantiation (can have multiple instances of the "class", each with its own state)

what about this :
var Foo = (function() {
// "private" variables
var _bar;
// constructor
function Foo() {};
// add the methods to the prototype so that all of the
// Foo instances can access the private static
Foo.prototype.getBar = function() {
return _bar;
};
Foo.prototype.setBar = function(bar) {
_bar = bar;
};
return Foo;
})();
And now we have instantiation, encapsulation and inheritance.
But, there still is a problem. The private variable is static because it's shared across all instances of Foo. Quick demo :
var a = new Foo();
var b = new Foo();
a.setBar('a');
b.setBar('b');
alert(a.getBar()); // alerts 'b' :(
A better approach might be using conventions for the private variables : any private variable should start with an underscore. This convention is well known and widely used, so when another programmer uses or alters your code and sees a variable starting with underscore, he'll know that it's private, for internal use only and he won't modify it.
Here's the rewrite using this convention :
var Foo = (function() {
// constructor
function Foo() {
this._bar = "some value";
};
// add the methods to the prototype so that all of the
// Foo instances can access the private static
Foo.prototype.getBar = function() {
return this._bar;
};
Foo.prototype.setBar = function(bar) {
this._bar = bar;
};
return Foo;
})();
Now we have instantiation, inheritance, but we've lost our encapsulation in favor of conventions :
var a = new Foo();
var b = new Foo();
a.setBar('a');
b.setBar('b');
alert(a.getBar()); // alerts 'a' :)
alert(b.getBar()); // alerts 'b' :)
but the private vars are accessible :
delete a._bar;
b._bar = null;
alert(a.getBar()); // alerts undefined :(
alert(b.getBar()); // alerts null :(

I think what you're looking for is the "Revealing Prototype Pattern".
Dan Wahlin has a great blog post: http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx
and even better Pluralsight course on this and other related JavaScript structures: http://pluralsight.com/training/courses/TableOfContents?courseName=structuring-javascript&highlight=dan-wahlin_structuring-javascript-module1!dan-wahlin_structuring-javascript-module2!dan-wahlin_structuring-javascript-module5!dan-wahlin_structuring-javascript-module4!dan-wahlin_structuring-javascript-module3#structuring-javascript-module1

Closures are your friend!
Simply add the following tiny function to your top-level namespace and you're ready to OOP, complete with
encapsulation, with static and instance, private and public variables
and methods
inheritance
class-level injection (eg. for singleton services)
no constraints, no framework, just plain old Javascript
function clazz(_class, _super) {
var _prototype = Object.create((_super || function() {}).prototype);
var _deps = Array.isArray(_class) ? _class : [_class]; _class = _deps.pop();
_deps.push(_super);
_prototype.constructor = _class.apply(_prototype, _deps) || _prototype.constructor;
_prototype.constructor.prototype = _prototype;
return _prototype.constructor;
}
The above function simply wires up the given class' prototype and eventual parent constructor, and returns the resulting constructor, ready for instantiation.
Now you can most naturally declare your base classes (ie. that extend {}) in a few lines of code, complete with static, instance, public and private properties and methods:
MyBaseClass = clazz(function(_super) { // class closure, 'this' is the prototype
// local variables and functions declared here are private static variables and methods
// properties of 'this' declared here are public static variables and methods
return function MyBaseClass(arg1, ...) { // or: this.constructor = function(arg1, ...) {
// local variables and functions declared here are private instance variables and methods
// properties of 'this' declared here are public instance variables and methods
};
});
Extending a class? All the more natural as well:
MySubClass = clazz(function(_super) { // class closure, 'this' is the prototype
// local variables and functions are private static variables and methods
// properties of this are public static variables and methods
return function MySubClass(arg1, ...) // or: this.constructor = function(arg1, ...) {
// local variables and functions are private instance variables and methods
_super.apply(this, arguments); // or _super.call(this, arg1, ...)
// properties of 'this' are public instance variables and methods
};
}, MyBaseClass); // extend MyBaseClass
In other words, pass the parent class constructor to the clazz function, and add _super.call(this, arg1, ...) to the child class' constructor, which calls the parent class' constructor with the required arguments. As with any standard inheritance scheme, the parent constructor call must come first in the child constructor.
Note that you're free to either explicitly name the contructor with this.constructor = function(arg1, ...) {...}, or this.constructor = function MyBaseClass(arg1, ...) {...} if you need simple access to the constructor from the code inside the constructor, or even simply return the constructor with return function MyBaseClass(arg1, ...) {...} as in the above code. Whichever you feel most comfortable with.
Simply instantiate objects from such classes as you normally would from a constructor: myObj = new MyBaseClass();
Notice how closures nicely encapsulate all of a class' functionality, including its prototype and constructor, providing a natural namespace for static and instance, private and public properties and methods. The code within a class closure is completely free of constraints. No framework, no constraints, just plain old Javascript. Closures rule!
Oh, and if you want to inject singleton dependencies (eg. services) into your class (ie. prototype), clazz will do this for you à la AngularJS:
DependentClass = clazz([aService, function(_service, _super) { // class closure, 'this' is the prototype
// the injected _service dependency is available anywhere in this class
return function MySubClass(arg1, ...) // or: this.constructor = function(arg1, ...) {
_super.apply(this, arguments); // or _super.call(this, arg1, ...)
// the injected _service dependency is also available in the constructor
};
}], MyBaseClass); // extend MyBaseClass
As the above code attempts to illustrate, to inject singletons into a class simply place the class closure as the last entry into an array with all its dependencies. Also add the corresponding parameters to the class closure in front of the _super parameter and in the same order as in the array. clazz will inject the dependencies from the array as arguments into the class closure. The dependencies are then available anywhere within the class closure, including the constructor.
In fact, since the dependencies are injected into the prototype, they are available to static methods even before any object is instantiated from the class. This is very powerful for wiring up your apps or unit and end-to-end tests. It also removes the need to inject singletons into constructors, which otherwise unnecessarily clobbers the constructor's code.
Check this fiddle: http://jsfiddle.net/5uzmyvdq/1/
Feedback and suggestions most welcome!

Javascript is certainly OOP. You always have polymorphism, however you have to sacrifice either encapsulation or instantiation which is the problem you ran into.
Try this to just brush up on your options.
http://www.webmonkey.com/2010/02/make_oop_classes_in_javascript/
Also an old question that I had bookmarked:
Is JavaScript object-oriented?

JavaScript classes are introduced in ECMAScript 6 and are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.
You can see more in this link Mozilla Community
Github

I was thinking about this particular subject recently and the limitations of the various approaches. The best solution I've been able to come up with is below.
It seems to solve the problems with inheritance, instantiation and ecapsulation (at least from tests on Google Chrome v.24) although probably at a cost in memory usage.
function ParentClass(instanceProperty) {
// private
var _super = Object.create(null),
privateProperty = "private " + instanceProperty;
// public
var api = Object.create(_super);
api.constructor = this.constructor;
api.publicMethod = function() {
console.log( "publicMethod on ParentClass" );
console.log( privateProperty );
};
api.publicMethod2 = function() {
console.log( "publicMethod2 on ParentClass" );
console.log( privateProperty );
};
return api;
}
function SubClass(instanceProperty) {
// private
var _super = ParentClass.call( this, instanceProperty ),
privateProperty = "private sub " + instanceProperty;
// public
var api = Object.create(_super);
api.constructor = this.constructor;
api.publicMethod = function() {
_super.publicMethod.call(this); // call method on ParentClass
console.log( "publicMethod on SubClass" );
console.log( privateProperty );
}
return api;
}
var par1 = new ParentClass(0),
par2 = new ParentClass(1),
sub1 = new SubClass(2),
sub2 = new SubClass(3);
par1.publicMethod();
par2.publicMethod();
sub1.publicMethod();
sub2.publicMethod();
par1.publicMethod2();
par2.publicMethod2();
sub1.publicMethod2();
sub2.publicMethod2();

One problem with a lot of JS classes out there is that they do not secure their fields and methods which means that anyone using it may accidentally replace a method. For example the code:
function Class(){
var name="Luis";
var lName="Potter";
}
Class.prototype.changeName=function(){
this.name="BOSS";
console.log(this.name);
};
var test= new Class();
console.log(test.name);
test.name="ugly";
console.log(test.name);
test.changeName();
test.changeName=function(){
console.log("replaced");
};
test.changeName();
test.changeName();
will output:
ugly
BOSS
replaced
replaced
As you can see the changeName function gets overriden. The following code would secure the class methods and fields and the getters and setters would be used to access them making this more of a "regular" class found in other languages.
function Class(){
var name="Luis";
var lName="Potter";
function getName(){
console.log("called getter");
return name;
};
function setName(val){
console.log("called setter");
name = val
};
function getLName(){
return lName
};
function setLName(val){
lName = val;
};
Object.defineProperties(this,{
name:{
get:getName,
set:setName,
enumerable:true,
configurable:false
},
lastName:{
get:getLName,
set:setLName,
enumerable:true,
configurable:false
}
});
}
Class.prototype.changeName=function(){
this.name="BOSS";
};
Object.defineProperty(Class.prototype, "changeName", {
writable:false,
configurable:false
});
var test= new Class();
console.log(test.name);
test.name="ugly";
console.log(test.name);
test.changeName();
test.changeName=function(){
console.log("replaced")
};
test.changeName();
test.changeName();
This outputs:
called getter
Luis
called setter
called getter
ugly
called setter
called setter
called setter
Now your class methods cannot be replaced by random values or functions and the code in the getters and setters always run when attempting to read or write to field.

This closure allows instantiation and encapsulation but no inheritance.
function Foo(){
var _bar = "foo";
return {
getBar: function() {
return _bar;
},
setBar: function(bar) {
_bar = bar;
}
};
};
a = Foo();
b = Foo();
a.setBar("bar");
alert(a.getBar()); // "bar"
alert(b.getBar()); // "foo"

Related

Passing arguments to a Javascript IIFE constructor

I'm trying to get my head around Javascript OO, using the IIFE module pattern to mimic a class:
var MyClass = (function() {
// Constructor
return function() {
return {
foo: 'foo'
}
}
}());
I'm passing arguments with something like:
var MyClass = (function() {
// Constructor
return function(arg) {
return {
foo: function() {
return 'foo'+arg
}
}
}
}());
To mimic classical inheritance I am using the pattern suggested here:
function inherit(base, child, obj) {
child.prototype = Object.create(base.prototype);
child.prototype.constructor = child;
obj&&Object.keys(obj).forEach(function(key){
child.prototype[key] = obj[key];
})
}
var Base = (function() {
var init = function() {};
init.prototype = {
foo: function() {
return "foo";
}
};
return init;
}());
var Child = (function() {
var init = function() {
Base.call(this);
};
inherit(Base, init, {
bar: function() {
return 'bar';
}
});
return init;
}());
So far so good. My only problem is in understanding how to pass parameters to my class constructor when I'm doing inheritance in the above way. I like the fact that in the 'pure' IIFE module I can simply refer to the constructor parameter in any functions defined within it, so that they become closures. But how do I access constructor params when I'm adding these subsequent functions using the constructor variable, as in the inheritance example above? I suppose I could do something like:
var init = function(arg) {
this.theArg = arg;
};
Then I can access it within anything subsequent:
init.prototype = {
foo: function() {
return "foo"+this.theArg;
}
};
And for the child:
var init = function(arg) {
Base.call(this, arg);
};
This makes arg available to the outside world, so to make it read-only I suppose a getter would work:
var init = function(arg) {
var theArg = arg;
this.getArg = function() { return theArg };
};
On the face of it I can't see anything wrong with that, and I can't think of a better alternative. Is there one? Am I missing something obvious?
I can't think of a better alternative. Is there one?
No. Not in your example.
I like the fact that in the 'pure' IIFE module I can simply refer to the constructor parameter in any functions defined within it, so that they become closures.
You can access args in each function because, in your first example, you are defining foo on each object instance separately. Therefore each definition of foo has a separate closure containing the args passed when it was defined.
This is also only possible, because foo is defined within the scope containing your args.
But how do I access constructor params when I'm adding these subsequent functions ... in the inheritance example above?
By using the classical inheritance patten you found, you are now defining the foo function on the constructor prototype. This means that only a single foo definition exists which is inherited by all instances created using your constructor. So foo can not be made specific to each instance anymore.
As you have figured, it also means foo is no longer defined inside the scope containing args and has no direct access.
You are therefore correct by assigning args to this.thisArgs which allows foo to access thisArgs on each instance. You have made foo a general case function that can handle any instance it is applied to.
Passing arguments to the IIFE constructor: The IIFE itself is not the constructor, it simply builds the constructor object. The IIFE's scope has long since been returned by the time the constructor itself is invoked.
Am I missing something obvious?
Yes. Javascript is a prototypical language. It was never meant to be like "classical" languages. Just let it be Javascript. :)

Method Inheritance in JavaScript

JavaScript uses a Prototype system, which is fundamentally different than a Class system. This is my first serious encounter with the language. I had fooled around with it previously, but this is the first time I built a system with proper OO, inheritance, polymorphism, etc.
From what I read there seems to be a few common methods to do member function inheritance in Javascript. Assuming you have a parent foo as following
foo = function(){ this.one = 1; }
foo.prototype.func1 = function(){return this.one;}
The MDN Introduction to JavaScript Inheritance suggests the naive approach of invoking the parent's method in the context of the child, as shown below.
bar = function(){ foo.call(this); }
bar.prototype = Object.create(foo.prototype);
bar.prototype.func1 = function(){ return this.one + foo.prototype.func1();}
This has the advantage of being simple to understand, but can become cumbersome as pointed out in this Salsify Blog post. The blog post outlines an alternate method where a super property is defined in the child prototype, and the name of each member function is attached as a property to the method. This method, however, relies on the caller property of a method, which the article points out will soon be deprecated. Rather than duplicate the entire post, I believe a summary of the important points are these
Object.defineProperty(bar.prototype, "super", {
get: function get() {
...
// methodName is set as a property on each method in an omitted code segment
methodName = get.caller.methodName;
...
Object.getPrototypeOf(this.prototype)[methodName]
}
}
Which is to say that you find the method with the same name in your prototype's prototype. I was wondering if this can be done in a simpler manner, without having to attach the method name as a parameter and without the Function.caller.
foo.prototype.super = function(method) {
superMethod = Object.getPrototypeOf(this.constructor.prototype)[method];
return superMethod.call(this, Array.prototype.slice.call(arguments, 1));
}
bar.prototype.func1 = function(){ return this.one + super('func1'); }
I'm making a number of assumptions in the above, I'd like to verify some assumptions.
new bar().constructor.prototype === Object.getPrototypeOf(new bar())
If the above is always true, is one preferable over the other?
The Parent's member function will always live in the child's prototype's prototype (assuming that neither of the prototypes were mutated after object creation)
That Object.getPrototypeOf() is not the "language support for accessing super methods" that the blog refers to as being added in ES6
If Object.getPrototypeOf() isn't that language support, what is?
After seeing the error of using this, which does not change throughout the execution and always refers to the instance of the subclass, I've revisited and am thinking I need something like this
Grandfather = function(){};
Grandfather.prototype.function1 = function(){console.log("I am the Grandfather");};
Father = function(){Grandfather.apply(this);};
Father.prototype = Object.create(Grandfather.prototype);
Father.prototype.function1 = function f(){ f.super(); console.log("I am the Father");};
Father.prototype.function1.super = Grandfather.prototype.function1;
Child = function(){Father.apply(this);}
Child.prototype = Object.create(Father.prototype);
Child.prototype.function1 = function f(){ f.super(); console.log("I am the Child");};
Child.prototype.function1.super = Father.prototype.function1;
c = new Child();
c.function1();
// I am the Grandfather
// I am the Father
// I am the Child
And so the question becomes, how to set the super property on to each function in some automatic way?
One such way to do this is shown below, it has the benefit that functions added to the prototype after objects are instantiated still receive the benefit of being able to call superFunc, whereas an approach that sets a super property at class extension time would not set such a property if functions are added to the prototype later.
The downsides of this approach are that it only works in single threaded environment and that it requires functionality inherited from a common base class. It is not threadsafe since some state is held in a what is effectively a static variable of the function. This is fine for my purposes since browsers still have single threaded JavaScript. The requirement that all classes inherit from some base class containing this method isn't a huge blocker (especially if you do a "bad thing" and insert this into Object's prototype).
Grandfather.prototype.superFunc = function f(funcName){
currentPrototype = Object.getPrototypeOf(f.startingPrototype || Object.getPrototypeOf(this));
f.startingPrototype = currentPrototype;
return currentPrototype[funcName]();
}
Child.prototype.function2 = function(){this.superFunc('function2'); console.log("Still in the Child");};
Father.prototype.function2 = function(){this.superFunc('function2'); console.log("Still in the Father");};
GrandFather.prototype.function2 = function(){console.log("Still in the Grandfather");};
c = new Child();
c.function2();
// Still in the Grandfather
// Still in the Father
// Still in the Child
Question 1
new Bar().constructor.prototype should equal Object.getPrototypeOf(new Bar()), provided you haven't overrided Bar.prototype.constructor or Bar.prototype, or return a different object in the Bar constructor. Here's an example:
function Bar() {}
var foo = new Bar();
foo.constructor.prototype === Object.getPrototypeOf(foo); // true
function Bar2() {}
var foo2 = new Bar2();
Bar2.prototype = {};
foo2.constructor.prototype === Object.getPrototypeOf(foo2); // false
function Bar3() {}
var foo3 = new Bar3();
Bar3.prototype.constructor = function NotBar3() {};
foo3.constructor.prototype === Object.getPrototypeOf(foo3); // false
Question 2
If you're looking to get the actual prototype of an object, use Object.getPrototypeOf, as that's unaffected by any of the changes shown above.
Question 3
No, you will not be able to access Foo from new Bar(). In your example, new Bar() would not inherit from Foo.prototype and as a result, there's no way to access Foo unless you make it inherit from Foo.prototype or assign Foo to a property of new Bar() or Bar.prototype.
Question 4/5
No, that's not what they're referring to. ES6 will introduce a separate class contruct, where super takes on a special meaning (similar to how super works in other languages with classes). Here's an example of how classes work in ES6:
class Foo {
constructor() {
this.one = 1;
}
func1() {
return this.one;
}
}
class Bar extends Foo {
func1() {
return this.one + super();
}
}
When you use super in the way you do it'll break when inheritance is more than 2 levels.
Assuming you'd use it the following way:
//changed super to this.super since super is not shown to exist in global scope
bar.prototype.func1(){ return this.one + this.super('func1'); }
See the following example:
function GrandFather(){
this.i = 0;
};
GrandFather.prototype.test = function(){
console.log('test in GrandFather');
};
function Father(){
GrandFather.call(this);
};
Father.prototype = Object.create(GrandFather.prototype);
Father.prototype.constructor = Father;
Father.prototype.super = GrandFather.prototype;
Father.prototype.test = function(){
console.log('test in Father');
//prevent too many recursions
this.i++;
if(this.i>5){
return;
}
this.super.test.call(this);//because test in child was called
// with Child instance as invoking object this will be Child
// and this.super will be Father.prototype
};
function Child(){
Father.call(this);
}
Child.prototype = Object.create(Father.prototype);
Child.prototype.constructor = Child;
Child.prototype.super = Father.prototype;
Child.prototype.test = function(){
console.log('test in Child');
this.super.test.call(this);//because invoking object is Child
//this.super in Father is Child
};
var c = new Child();
c.test();
It's also common practice to start a constructor function with a capital so it's better to use Foo and Bar for constructor function names.
If you want to go through all the trouble of simulating super in JavaScript then the following way would be slightly more robust: http://ejohn.org/blog/simple-javascript-inheritance/

Creating inheritance on revealing modular pattern objects

I'm trying to create some kind of inheritance between objects:
var foo = (function(){
function doFooStuff(){
console.log(arguments.callee.name);
}
return {
doFooStuff: doFooStuff
}
})();
var bar = (function(){
$.extend(this, foo);
function doBarStuff(){
console.log(arguments.callee.name);
doFooStuff();
}
return {
doBarStuff: doBarStuff,
}
})();
bar.doBarStuff();
bar.doFooStuff(); //<-- Uncaught TypeError:
//Object #<Object> has no method 'doFooStuff'
http://jsfiddle.net/wRXTv/
Why isn't doFooStuff accessible here? Would you recommend another approach than using $.extend?
$.extend(this, foo);
this is not the object which you return from the function below (in fact it cannot be since it's created after this call), but the global object - check MDN's introduction to the this keyword.
For what you want to do, there are two ways:
Copy all properties from foo onto your bar object after it is created:
var bar = (function() {
…
return {…};
})();
$.extend(bar, foo);
You can do that as well directly on the returned object:
return $.extend({…}, foo);
A variant of this pattern allows you to overwrite foo properties. Copy foo into an empty object, then write your bar properties to it:
return $.extend({}, foo, {…});
Use prototypical inheritance. Create an object that inherits its properties from foo, and then write your bar properties to it:
return $.extend(Object.create(foo), {…});
Now when foo changes afterward, you still can access those new properties on bar (unless they're shadowed by own properties). Notice that Object.create might not be supported in legacy environments, but you can easily shim it.
As noted by #raina77ow, your doBarStuff function is flawed too. The doFooStuff function is not in the scope of your function, and you cannot change that. You never will be able to access the private declared functions and variables from the foo module, only those that are public - if you did need them, consider a different pattern or app design. However, doFooStuff is a property on the exported (public) foo object, from which bar inherits (regardless in which of the above demonstrated ways). Therefore, you can access it as a method of bar as well, usually by using this.doFooStuff().
You attempt to work with revealing module as if it were a constructor. Hence an attempt to extend this, wrong for many reasons. The most glaring, I suppose, is that neither the function is used as a constructor (no new) nor its context is changed. In plain words, this just points to a global object here.
But that's not the only problem. Consider that part of your code:
function doBarStuff(){
console.log(arguments.callee.name);
doFooStuff();
}
Here doFooStuff won't be in the scope even if you somehow manage to extend this. ) Remember, the scope resolution doesn't involve the context object.
So what's the solution? Well, I often use aggregation in similar cases:
var foo = (function(){
function doFooStuff(){
console.log(arguments.callee.name);
}
return {
doFooStuff: doFooStuff
}
})();
var bar = (function(){
var _super = foo;
function doBarStuff(){
console.log(arguments.callee.name);
_super.doFooStuff();
}
// static parent: further changes on `foo` won't affect `bar`,
// as $.extend takes the parent's current state
return $.extend({}, _super, {
doBarStuff: doBarStuff,
});
// dynamic parent: further changes on `foo` will affect `bar`,
// as extended object now has `foo` in its prototype chain
return $.extend(Object.create(_super), {
doBarStuff: doBarStuff,
});
})();
JS Fiddle.
Yes, it's aggregation, not inheritance. But so what? I'm still able to get the main prize - removing code duplication AND I'm able to control the usage of parent functions within the child module.
The problem with your code is that this in $.extend(this,foo) refers to the window object and not foo. Anonymous function are run in window's context.
I would recommend using a John Resig implementation of classical inheritance in javascript.
http://ejohn.org/blog/simple-javascript-inheritance/.
Extract:
var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});
var p = new Person(true);
p.dance(); // => true
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true
// Should all be true
p instanceof Person && p instanceof Class &&
n instanceof Ninja && n instanceof Person && n instanceof Class
It is because this is an anonymous function. This part of your function deceleration:
var foo = (function(){
function doFooStuff(){
console.log(arguments.callee.name);
}
return {
doFooStuff: doFooStuff
}
})();
Do you see that you are immediately invoking this function call and ultimately do not have access to doFooStuff within your return statement.
If you remove the anonymous function deceleration, it will work.

javascript singleton question

I just read a few threads on the discussion of singleton design in javascript. I'm 100% new to the Design Pattern stuff but as I see since a Singleton by definition won't have the need to be instantiated, conceptually if it's not to be instantiated, in my opinion it doesn't have to be treated like conventional objects which are created from a blueprint(classes). So my wonder is why not just think of a singleton just as something statically available that is wrapped in some sort of scope and that should be all.
From the threads I saw, most of them make a singleton though traditional javascript
new function(){}
followed by making a pseudo constructor.
Well I just think an object literal is enough enough:
var singleton = {
dothis: function(){},
dothat: function(){}
}
right? Or anybody got better insights?
[update] : Again my point is why don't people just use a simpler way to make singletons in javascript as I showed in the second snippet, if there's an absolute reason please tell me. I'm usually afraid of this kind of situation that I simplify things to much :D
I agree with you, the simplest way is to use a object literal, but if you want private members, you could implement taking advantage of closures:
var myInstance = (function() {
var privateVar;
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
},
publicMethod2: function () {
// ...
}
};
})();
About the new function(){} construct, it will simply use an anonymous function as a constructor function, the context inside that function will be a new object that will be returned.
Edit: In response to the #J5's comment, that is simple to do, actually I think that this can be a nice example for using a Lazy Function Definition pattern:
function singleton() {
var instance = (function() {
var privateVar;
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
},
publicMethod2: function () {
// ...
}
};
})();
singleton = function () { // re-define the function for subsequent calls
return instance;
};
return singleton(); // call the new function
}
When the function is called the first time, I make the object instance, and reassign singleton to a new function which has that object instance in it's closure.
Before the end of the first time call I execute the re-defined singleton function that will return the created instance.
Following calls to the singleton function will simply return the instance that is stored in it's closure, because the new function is the one that will be executed.
You can prove that by comparing the object returned:
singleton() == singleton(); // true
The == operator for objects will return true only if the object reference of both operands is the same, it will return false even if the objects are identical but they are two different instances:
({}) == ({}); // false
new Object() == new Object(); // false
I have used the second version (var singleton = {};) for everything from Firefox extensions to websites, and it works really well. One good idea is to not define things inside the curly brackets, but outside it using the name of the object, like so:
var singleton = {};
singleton.dothis = function(){
};
singleton.someVariable = 5;
The ES5 spec lets us use Object.create():
var SingletonClass = (function() {
var instance;
function SingletonClass() {
if (instance == null) {
instance = Object.create(SingletonClass.prototype);
}
return instance;
}
return {
getInstance: function() {
return new SingletonClass();
}
};
})();
var x = SingletonClass.getInstance();
var y = SingletonClass.getInstance();
var z = new x.constructor();
This is nice, since we don't have to worry about our constructor leaking, we still always end up with the same instance.
This structure also has the advantage that our Singleton doesn't construct itself until it is required. Additionally, using the closure as we do here prevents external code from using our "instance" variable, accidentally or otherwise. We can build more private variables in the same place and we can define anything we care to export publically on our class prototype.
The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist. If an instance already exists, it simply returns a reference to that object. 1
(function (global) {
var singleton;
function Singleton () {
// singleton does have a constructor that should only be used once
this.foo = "bar";
delete Singleton; // disappear the constructor if you want
}
global.singleton = function () {
return singleton || (singleton = new Singleton());
};
})(window);
var s = singleton();
console.log(s.foo);
var y = singleton();
y.foo = "foo";
console.log(s.foo);
You don't just declare the singleton as an object because that instantiates it, it doesn't declare it. It also doesn't provide a mechanism for code that doesn't know about a previous reference to the singleton to retrieve it. The singleton is not the object/class that is returned by the singleton, it's a structure. This is similar to how closured variables are not closures, the function scope providing the closure is the closure.
I am just posting this answer for people who are looking for a reliable source.
according to patterns.dev by Lydia Hallie, Addy Osmani
Singletons are actually considered an anti-pattern, and can (or.. should) be avoided in JavaScript.
In many programming languages, such as Java or C++, it's not possible to directly create objects the way we can in JavaScript. In those object-oriented programming languages, we need to create a class, which creates an object. That created object has the value of the instance of the class, just like the value of instance in the JavaScript example.
Since we can directly create objects in JavaScript, we can simply use
a regular object to achieve the exact same result.
I've wondered about this too, but just defining an object with functions in it seems reasonable to me. No sense creating a constructor that nobody's ever supposed to call, to create an object with no prototype, when you can just define the object directly.
On the other hand, if you want your singleton to be an instance of some existing "class" -- that is, you want it to have some other object as its prototype -- then you do need to use a constructor function, so that you can set its prototype property before calling it.
The latter code box shows what I've seen JS devs call their version of OO design in Javascript.
Singetons are meant to be singular objects that can't be constructed (except, I suppose, in the initial definition. You have one, global instance of a singleton.
The point of using the "pseudo constructor" is that it creates a new variable scope. You can declare local variables inside the function that are available inside any nested functions but not from the global scope.
There are actually two ways of doing it. You can call the function with new like in your example, or just call the function directly. There are slight differences in how you would write the code, but they are essentially equivalent.
Your second example could be written like this:
var singleton = new function () {
var privateVariable = 42; // This can be accessed by dothis and dothat
this.dothis = function () {
return privateVariable;
};
this.dothat = function () {};
}; // Parentheses are allowed, but not necessary unless you are passing parameters
or
var singleton = (function () {
var privateVariable = 42; // This can be accessed by dothis and dothat
return {
dothis: function () {
return privateVariable;
},
dothat: function () {}
};
})(); // Parentheses are required here since we are calling the function
You could also pass arguments to either function (you would need to add parentheses to the first example).
Crockford (seems to) agree that the object literal is all you need for a singleton in JavaScript:
http://webcache.googleusercontent.com/search?q=cache:-j5RwC92YU8J:www.crockford.com/codecamp/The%2520Good%2520Parts%2520ppt/5%2520functional.ppt+singleton+site:www.crockford.com&cd=1&hl=en&ct=clnk
How about this:
function Singleton() {
// ---------------
// Singleton part.
// ---------------
var _className = null;
var _globalScope = null;
if ( !(this instanceof arguments.callee) ) {
throw new Error("Constructor called as a function.");
}
if ( !(_className = arguments.callee.name) ) {
throw new Error("Unable to determine class name.")
}
_globalScope = (function(){return this;}).call(null);
if ( !_globalScope.singletons ) {
_globalScope.singletons = [];
}
if ( _globalScope.singletons[_className] ) {
return _globalScope.singletons[_className];
} else {
_globalScope.singletons[_className] = this;
}
// ------------
// Normal part.
// ------------
var _x = null;
this.setx = function(val) {
_x = val;
}; // setx()
this.getx = function() {
return _x;
}; // getx()
function _init() {
_x = 0; // Whatever initialisation here.
} // _init()
_init();
} // Singleton()
var p = new Singleton;
var q = new Singleton;
p.setx(15);
q.getx(); // returns 15
I stole this from CMS / CMS' answer, and changed it so it can be invoked as:
MySingleton.getInstance().publicMethod1();
With the slight alternation:
var MySingleton = { // These two lines
getInstance: function() { // These two lines
var instance = (function() {
var privateVar;
function privateMethod () {
// ...
console.log( "b" );
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
console.log( "a" );
},
publicMethod2: function () {
// ...
privateMethod();
}
};
})();
singleton = function () { // re-define the function for subsequent calls
return instance;
};
return singleton(); // call the new function
}
}

Javascript private member on prototype

Well I tried to figure out is this possible in any way. Here is code:
a=function(text)
{
var b=text;
if (!arguments.callee.prototype.get)
arguments.callee.prototype.get=function()
{
return b;
}
else
alert('already created!');
}
var c=new a("test"); // creates prototype instance of getter
var d=new a("ojoj"); // alerts already created
alert(c.get()) // alerts test
alert(d.get()) // alerts test from context of creating prototype function :(
As you see I tried to create prototype getter. For what? Well if you write something like this:
a=function(text)
{
var b=text;
this.getText=function(){ return b}
}
... everything should be fine.. but in fact every time I create object - i create getText function that uses memory. I would like to have one prototypical function lying in memory that would do the same... Any ideas?
EDIT:
I tried solution given by Christoph, and it seems that its only known solution for now. It need to remember id information to retrieve value from context, but whole idea is nice for me :) Id is only one thing to remember, everything else can be stored once in memory. In fact you could store a lot of private members this way, and use anytime only one id. Actually this is satisfying me :) (unless someone got better idea).
someFunc = function()
{
var store = new Array();
var guid=0;
var someFunc = function(text)
{
this.__guid=guid;
store[guid++]=text;
}
someFunc.prototype.getValue=function()
{
return store[this.__guid];
}
return someFunc;
}()
a=new someFunc("test");
b=new someFunc("test2");
alert(a.getValue());
alert(b.getValue());
JavaScript traditionally did not provide a mechanism for property hiding ('private members').
As JavaScript is lexically scoped, you could always simulate this on a per-object level by using the constructor function as a closure over your 'private members' and defining your methods in the constructor, but this won't work for methods defined in the constructor's prototype property.
Of course, there are ways to work around this, but I wouldn't recommend it:
Foo = (function() {
var store = {}, guid = 0;
function Foo() {
this.__guid = ++guid;
store[guid] = { bar : 'baz' };
}
Foo.prototype.getBar = function() {
var privates = store[this.__guid];
return privates.bar;
};
Foo.prototype.destroy = function() {
delete store[this.__guid];
};
return Foo;
})();
This will store the 'private' properties in another object seperate from your Foo instance. Make sure to call destroy() after you're done wih the object: otherwise, you've just created a memory leak.
edit 2015-12-01: ECMAScript6 makes improved variants that do not require manual object destruction possible, eg by using a WeakMap or preferably a Symbol, avoiding the need for an external store altogether:
var Foo = (function() {
var bar = Symbol('bar');
function Foo() {
this[bar] = 'baz';
}
Foo.prototype.getBar = function() {
return this[bar];
};
return Foo;
})();
With modern browsers adopting some ES6 technologies, you can use WeakMap to get around the GUID problem. This works in IE11 and above:
// Scope private vars inside an IIFE
var Foo = (function() {
// Store all the Foos, and garbage-collect them automatically
var fooMap = new WeakMap();
var Foo = function(txt) {
var privateMethod = function() {
console.log(txt);
};
// Store this Foo in the WeakMap
fooMap.set(this, {privateMethod: privateMethod});
}
Foo.prototype = Object.create(Object.prototype);
Foo.prototype.public = function() {
fooMap.get(this).p();
}
return Foo;
}());
var foo1 = new Foo("This is foo1's private method");
var foo2 = new Foo("This is foo2's private method");
foo1.public(); // "This is foo1's private method"
foo2.public(); // "This is foo2's private method"
WeakMap won't store references to any Foo after it gets deleted or falls out of scope, and since it uses objects as keys, you don't need to attach GUIDs to your object.
Methods on the prototype cannot access "private" members as they exist in javascript; you need some kind of privileged accessor. Since you are declaring get where it can lexically see b, it will always return what b was upon creation.
After being hugely inspired by Christoph's work-around, I came up with a slightly modified concept that provides a few enhancements. Again, this solution is interesting, but not necessarily recommended. These enhancements include:
No longer need to perform any setup in the constructor
Removed the need to store a public GUID on instances
Added some syntactic sugar
Essentially the trick here is to use the instance object itself as the key to accessing the associated private object. Normally this is not possible with plain objects since their keys must be strings. However, I was able to accomplish this using the fact that the expression ({} === {}) returns false. In other words the comparison operator can discern between unique object instances.
Long story short, we can use two arrays to maintain instances and their associated private objects:
Foo = (function() {
var instances = [], privates = [];
// private object accessor function
function _(instance) {
var index = instances.indexOf(instance), privateObj;
if(index == -1) {
// Lazily associate instance with a new private object
instances.push(instance);
privates.push(privateObj = {});
}
else {
// A privateObject has already been created, so grab that
privateObj = privates[index];
}
return privateObj;
}
function Foo() {
_(this).bar = "This is a private bar!";
}
Foo.prototype.getBar = function() {
return _(this).bar;
};
return Foo;
})();
You'll notice the _ function above. This is the accessor function to grab ahold of the private object. It works lazily, so if you call it with a new instance, it will create a new private object on the fly.
If you don't want to duplicate the _ code for every class, you can solve this by wrapping it inside a factory function:
function createPrivateStore() {
var instances = [], privates = [];
return function (instance) {
// Same implementation as example above ...
};
}
Now you can reduce it to just one line for each class:
var _ = createPrivateStore();
Again, you have to be very careful using this solution as it can create memory leaks if you do not implement and call a destroy function when necessary.
Personally, I don't really like the solution with the guid, because it forces the developer to declare it in addition to the store and to increment it in the constructor. In large javascript application developers might forget to do so which is quite error prone.
I like Peter's answer pretty much because of the fact that you can access the private members using the context (this). But one thing that bothers me quite much is the fact that the access to private members is done in a o(n) complexity. Indeed finding the index of an object in array is a linear algorithm. Consider you want to use this pattern for an object that is instanciated 10000 times. Then you might iterate through 10000 instances each time you want to access a private member.
In order to access to private stores in a o(1) complexity, there is no other way than to use guids. But in order not to bother with the guid declaration and incrementation and in order to use the context to access the private store I modified Peters factory pattern as follow:
createPrivateStore = function () {
var privates = {}, guid = 0;
return function (instance) {
if (instance.__ajxguid__ === undefined) {
// Lazily associate instance with a new private object
var private_obj = {};
instance.__ajxguid__ = ++guid;
privates[instance.__ajxguid__] = private_obj;
return private_obj;
}
return privates[instance.__ajxguid__];
}
}
The trick here is to consider that the objects that do not have the ajxguid property are not yet handled. Indeed, one could manually set the property before accessing the store for the first time, but I think there is no magical solution.
I think real privacy is overrated. Virtual privacy is all that is needed. I think the use of _privateIdentifier is a step in the right direction but not far enough because you're still presented with a listing of all the _privateIdentifiers in intellisense popups. A further and better step is to create an object in the prototype and/or constructor function for segregating your virtually private fields and methods out of sight like so:
// 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 tucked away inside a nested privacy object called x
x: {
private: function () {
console.log('PRIVATE method has been called');
}
},
}
// Create an instance of the object
var mo = new MyObject();
now when the coder types "mo." intellisense will only show the public function and "x". So all the private members are not shown but hidden behind "x" making it more unlikely for a coder to accidentally call a private member because they'll have to go out of their way and type "mo.x." to see private members. This method also avoids the intellisense listing from being cluttered with multiple private member names, hiding them all behind the single item "x".
I know this thread is really really old now, but thought this solution might be of interest to anyone passing by:
const Immutable = function ( val ) {
let _val = val;
this.$ = {
_resolve: function () {
return _val;
}
};
};
Immutable.prototype = {
resolve: function () {
return this.$._resolve();
}
};
Essentially hiding the internal _val from being manipulated and making an instance of this object immutable.
I have created a new library for enabling private methods on the prototype chain.
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

Categories

Resources