So there's this so-called module pattern for creating singletons with private members:
var foo = (function () {
var _foo = 'private!';
return {
foo: function () { console.log(_foo); },
bar: 'public!'
}
})();
There's also this method that I found on my own, but haven't seen anything written about:
var foo = new function () {
var _foo = 'private!';
this.bar = 'public!';
this.foo = function () { console.log(_foo); };
}
I'm thinking there must be a reason why nobody writes about this while there's tons of articles about the module pattern. Is there any downside to this pattern? Speed, or browser compatibility perhaps?
In this case it seems you are using only one instance object of that "class". So may want to take look at what Douglas Crockford thinks about putting new directly in front of function:
By using new to invoke the function, the object holds onto a worthless prototype object. That wastes memory with no offsetting advantage. If we do not use the new, we don’t keep the wasted prototype object in the chain. So instead we will invoke the factory function the right way, using ().
So according to the renown javascript architect of Yahoo! you should use the first method, and you have his reasons there.
More-or-less, they give you the same result. It's just a matter of which path you want to take for it.
The 1st may be more popular since it's simply the mixture of 2 already common patterns:
(function closure() {
var foo = 'private';
/* ... */
}())
var singleton = {
bar : 'public'
};
However, prototype chaining would be the benefit of the 2nd pattern since it has its own constructor.
var singleton = new function Singleton() { };
assert(singleton.constructor !== Object);
singleton.constructor.prototype.foo = 'bar';
assert(singleton.foo === 'bar');
I don't see any substantial difference between the two. I would prefer the latter simply since it has much less punctuation clutter.
On the other hand the "module pattern" approach seems to be the most common and is becoming a well known pattern (due to the rise in JQuery). It might be better to stick with this recognised pattern not because it has any more technical merit than the other approach but just because it will likely be more recognizable (despite the heavy punctuation).
Douglas Crockford writes about the second one. As Greg says in his comments, I thought it was quite common, and I've used it in the past.
Edit: to actually answer your question - there's no downsides, the two are functionally equivalent (both create a closure containing the "private variables" and exposing other variables/methods publically), and have exactly the same browser support and performance characteristics. It just comes down to a matter of syntax - basically, where you put the () to actually invoke this function and get your closure, and whether you use the new keyword.
Related
I am already familiar with the module pattern where we define a module with private state with the funcitons closure and an exposed set of public methods. However this seems to be closer to a singleton than an object.
However what if i wanted a more object orientated pattern can I use the same structure as the module pattern but don't immediately execute, Something like this:
function MyPseudoClass(constructorArg0, constructorArg1... ) {
var privateVar = "private!!";
var privateComplexVar = constructorArg0;
var privateComplexVar1 = constructorArg1;
return {
publicVar: "public Varaible!",
publicMethod: function() {
//code
return privateVar + 1;
}
};
Now in my code i can create instances of my pseudo class like so:
var instance = MyPseudoClass({p : 2, q : 100},"x")
var anotherInstance = MyPseudoClass({p : 3, q : 230},"y")
As far as i can tell this seems to do what i want but i haven't seen anyone using this online, are there any downsides to this approach that i should be aware of?
You aren't using prototypical inheritance; that is the main difference. Your main drawbacks are:
You cannot use instanceof to ensure that a variable is of some type (so you cannot do myVar instanceof MyPseudoClass. You don't create an instance with this method; you just create an object.
A prototype-based approach might be faster as there is overhead associated with closures. Furthermore, in a prototyped approach, each instance will share can share the same instance of a function (that is assigned to the prototype). But in the closure approach, each "instance" will have its own copy of the function. However, the difference is small (especially in newer browsers).
If you aren't concerned about these drawbacks, you should be ok.
The problem with functional inheritance is that if you want to create many instances then it will be slow because the functions have to be declared every time.
The problem with prototypal inheritance is that there is no way to truly have private variables.
Is it possible to mix these two together and get the best of both worlds? Here is my attempt using both prototypes and the singleton pattern combined:
var Animal = (function () {
var secret = "My Secret";
var _Animal = function (type) {
this.type = type;
}
_Animal.prototype = {
some_property: 123,
getSecret: function () {
return secret;
}
};
return _Animal;
}());
var cat = new Animal("cat");
cat.some_property; // 123
cat.type; // "cat"
cat.getSecret(); // "My Secret"
Is there any drawbacks of using this pattern? Security? Efficiency? Is there a similar pattern out there that already exists?
Your pattern is totally fine.
There are a few things that you'd want to keep in mind, here.
Primarily, the functions and variables which are created in the outermost closure will behave like private static methods/members in other languages (except in how they're actually called, syntactically).
If you use the prototype paradigm, creating private-static methods/members is impossible, of course.
You could further create public-static members/methods by appending them to your inner constructor, before returning it to the outer scope:
var Class = (function () {
var private_static = function () {},
public_static = function () {},
Class = function () {
var private_method = function () { private_static(); };
this.method = function () { private_method(); };
};
Class.static = public_static;
return Class;
}());
Class.static(); // calls `public_static`
var instance = new Class();
instance.method();
// calls instance's `private_method()`, which in turn calls the shared `private_static();`
Keep in mind that if you're intending to use "static" functions this way, that they have absolutely no access to the internal state of an instance, and as such, if you do use them, you'll need to pass them anything they require, and you'll have to collect the return statement (or modify object properties/array elements from inside).
Also, from inside of any instance, given the code above, public_static and Class.static(); are both totally valid ways of calling the public function, because it's not actually a static, but simply a function within a closure, which also happens to have been added as a property of another object which is also within the instance's scope-chain.
As an added bonus:
Even if malicious code DID start attacking your public static methods (Class.static) in hopes of hijacking your internals, any changes to the Class.static property would not affect the enclosed public_static function, so by calling the internal version, your instances would still be hack-safe as far as keeping people out of the private stuff...
If another module was depending on an instance, and that instance's public methods had been tampered with, and the other module just trusted everything it was given... ...well, shame on that module's creator -- but at least your stuff is secure.
Hooray for replicating the functionality of other languages, using little more than closure.
Is it possible to mix functional and prototypical inheritance together and get the best of both worlds?
Yes. And you should do it. Instead of initializing that as {}, you'd use Object.create to inherit from some proto object where all the non-priviliged methods are placed. However, inheriting from such a "class" won't be simple, and you soon end up with code that looks more like the pseudo-classical approach - even if using a factory.
My attempt using both prototypes and the singleton pattern combined. Is there a similar pattern out there that already exists?
OK, but that's something different from the above? Actually, this is known as the "Revealing Prototype Pattern", a combination of the Module Pattern and the Prototype Pattern.
Any drawbacks of using this pattern?
No, it's fine. Only for your example it is a bit unnecessary, and since your secret is kind of a static variable it doesn't make much sense to me accessing it from an instance method. Shorter:
function Animal(type) {
this.type = type;
}
Animal.prototype.some_property = 123;
Animal.getSecret = function() {
return "My Secret";
};
Are there any important/subtle/significant differences under the hood when choosing to use one of these four patterns over the others? And, are there any differences between the them when "instantiated" via Object.create() vs the new operator?
1) The pattern that CoffeeScript uses when translating "class" definitions:
Animal = (function() {
function Animal(name) {
this.name = name;
}
Animal.prototype.move = function(meters) {
return alert(this.name + (" moved " + meters + "m."));
};
return Animal;
})();
and
2) The pattern that Knockout seems to promote:
var DifferentAnimal = function(name){
var self = this;
self.name = name;
self.move = function(meters){
return alert(this.name + (" moved " + meters + "m."));
};
}
and
3) a similar, simple pattern I've often seen:
var DifferentAnimalWithClosure = function(name){
var name = name;
var move = function(meters){
};
return {name:name, move:move};
}
and
4) The pattern that Backbone promotes:
var OneMoreAnimal= ClassThatAlreadyExists.extend({
name:'',
move:function(){}
});
Update 1: Changed pattern #2 and added pattern #3 in response to Elias' response // minor formatting
Just to be clear: JS doesn't know of classes, just objects and custom, self-defined constructor functions, but that's besides the point.
To answer your question in short: yes, there are some small and even some fairly large differences between the various ways of creating a new object you're posting here.
CoffeeScript:
This is actually the most clear-cut and traditional way to create your own constructor, but it has been "optimized" in the sense that it's been ready set-up to use (optional) closure variables.
Basically, what this code does, is use an IIFE, to wrap both the constructor definition and the proptotype method assignments in their own, private scope, that returns a reference to the new constructor. It's just clean, simple JS, no different from what you might write yourself.
Knockout:
Now this threw me a little, because to me, at least, the snippet you provide looks either like part of a module pattern, or a power constructor. But since you're not using strict mode, omitting the new would still make for dangerous situations, and since the entire function goes trough the trouble of creating a new instance of DifferentAnimal, only to then construct a second object literal, assigning all properties of DifferentAnimal to that secondary object, I'd say you're missing something. Because, truth be told, omitting the last return {}; statement here, would probably make no difference at all. Plus: as you can see, you're declaring a method (move) in what is, in essence, a constructor. This means that every instance will be assigned its own function object move, rather then getting it from the prototype.
In short: have another close look at where you got this snippet from, and double-check if this is the full version, because if it is, I can only see arguments against this.
Using a variable, defined inside the constructor is simply: a closure, suppose your properties have a distinct initial state, determined by some arguments, passed to that constructor:
function MyConstructor(param)
{
var paramInit = param/2;//or something
this.p = paramInit;//this property can change later on, so:
this.reInit = function()
{//this method HAS to be inside constructor, every instance needs its own method
this.p = paramInit;//var paramInit can't, it's local to this scope
};
}
var foo = new MyConstructor(10);
console.log(foo.p);//5
foo.p = 'hi';
console.log(foo.p);//hi
foo.reInit();
console.log(foo.p);//5
console.log(foo.paramInit);//undefined, not available outside object: it's a pseudo-private property
That's all there is too it, really. When you see ppl using var that = this; or something, that's often to create a reference to the main object that is available anywhere, without having to deal with the headaches of this (what does this reference? What should the method do when applied to an object other than the one it was originally intended for? etcetera...)
Backbone:
Here, we're dealing with another case: extending objects (IE: using methods, properties of either an existing "class" (constructor) or a particular instance) is not the same as simply creating an object.
As you well know, JS objects can be assigned new properties at any given time. Those properties can be removed, too. Sometimes, prototype properties can be redefined on the instance itself (masking the prototypal behaviour) etc... So it all depends on what you want the resulting object (the newly created object, that extends the given instance) to look like: do you want it to take all properties from the instance, or do you want both objects to use the same prototype somewhere down the line?
Both of these things can be achieved by using simple JS, too, but they just take a bit more effort to write yourself. However, if you write, for example:
function Animal(name)
{
this.name = name;
}
Animal.prototype.eat= function()
{
console.log(this.name + ' is eating');
};
That could be deemed the equivalent of writing:
var Animal = Object.extend({name:'',eat:function()
{
console.log(this.name + ' is eating');
}});
A lot shorter, but lacking the constructor.
new vs Object.create
Well, that's an easy one: Object.create just is a lot more powerful that new: you can define prototype methods, properties (including weather or not they are enumerable, writeable etc...) right at the time you need to create an object, instead of having to write a constructor and a prototype, or create an object literal and mess around with all those Object.defineProperty lines.
The downsides: Some people still aren't using ECMA5 compliant browsers (IE8 is still not quite dead). In my experience: it does become quite hard to debug sizeable scripts after a while: though I tend to use power-constructors more than I do regular constructors, I still have them defined at the very top of my script, with distinct, clear and quite descriptive names, whereas object-literals are things I just create "on-the-fly". Using Object.create, I noticed I tend to create objects that are really a little too complex to qualify as actual object literals, as though they are object literals:
//fictional example, old:
var createSomething = (function()
{
var internalMethod = function()
{//method for new object
console.log(this.myProperty || '');
};
return function(basedOn)
{
var prop, returnVal= {};
returnVal.myProperty = new Date();
returnVal.getCreated = internalMethod;//<--shared by all instances, thx to closure
if (!basedOn || !(basedOn instanceof Object))
{//no argument, or argument is not an object:
return returnVal;
}
for (prop in basedOn)
{//extend instance, passed as argument
if (basedOn.hasOwnProperty(prop) && prop !== '_extends')
{
returnVal[prop] = basedOn[prop];
}
}
returnVal._extends = basedOn;//<-- ref as sort-of-prototype
return returnVal;
};
}());
Now this is pretty verbose, but I've got my basic constructor ready, and I can use it to extend an existing instance, too. It might seem less verbose to simply write:
var createSomething = Object.create(someObject, {getCreated:function()
{
console.log(this.myProperty);
},
myProperty:new Date()});
But IMO, this makes it harder on you do keep track of what object is created where (mainly because Object.create is an expression, and will not be hoisted.Ah well, that's far from a conclusive argument of course: both have their pro's and con's: I prefer using module patters, closures and power constructors, if you don't that's just fine.
Hope this cleared up a thing or 2 for you.
The first example puts the move function in the prototype which will be shared between all Animal instances.
The second example creates a new move function for every the animal instance.
The third example generates a Animal class with the move function in the prototype similar to the first example but with allot less code.
(In your example the name is also shared between all instances, which you probably don't want)
Putting the function in the prototype makes instantiating Animals faster, and because of the way JIT engines work even the execution of the function is faster.
I've been trying to learn closures (in Javascript), which kind of hurts my brain after way too many years with C# and C++. I think I now have a basic understanding, but one thing bothers me: I've visited lots of websites in this Quest for Knowledge, and nowhere have I seen a word (or even a simple two-word phrase) that means "a set of Javascript closures that share a common execution context". For example:
function CreateThingy (name, initialValue)
{
var myName = name;
var myValue = initialValue;
var retObj = new Object;
retObj.getName = function() { return myName; }
retObj.getValue = function() { return myValue; }
retObj.setValue = function(newValue) { myValue = newValue; }
return retObj;
};
From what I've read, this seems to be one common way of implementing data hiding. The value returned by CreateThingy is, of course, an object, but what would you call the set of functions which are properties of that object? Each one is a closure, but I'd like a name I can used to describe (and think about) all of them together as one conceptual entity, and I'd rather use a commonly accepted name than make one up.
Thanks!
-- Ed
Crockford popularized the term "privileged method" to name the functions that have access to the scope of its constructor (where the private members are declared).
I would call them "A set of JavaScript functions that share a common enclosing scope".
The "execution context" part of the phrase you post, can create confusion between the Execution Contexts described in the specification, the this value, which also is popularly known as "the function context" or "object context", and the function scope, which is really what is being referenced here.
You could call it a class, but it's just a hash table with a bunch of entries, some of which are functions (or closures). The more idiomatic way to do this in Javascript is through the use of prototypes.
Some links to help you:
http://javascript.crockford.com/prototypal.html
http://www.crockford.com/javascript/private.html
Its close to the module pattern. Use an expression like so:
var thingy = (function(specObj) {
var my = {},
privateVar = blah,
someOtherPrivateVar = [];
my.getSomeVal() {
return specObj.someVal;
}
my.getAnotherVal() {
return specObj.AnotherVal;
}
}({
someVal: "value",
anotherVal: "foo"
}));
I initialized with an object literal because using a named object would allow the state of thingy to be changed by changing the named object. There are other options to do this.
Here's another good link on variations of the module pattern:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
Almost goes without saying, but Crockford's Javascript: The Good Parts contains a good treatment of this style and its specific benefits.
Just finished reading Crockford's "JavaScript: The Good Parts" and I have a question concerning his stance on the psuedo-classical vs. prototypal approaches. Actually I'm not really interested in his stance; I just want to understand his argument so I can establish a stance of my own.
In the book, Crockford seems to infer that constructor functions and "all that jazz" shouldn't be used in JavaScript, he mentions how the 'new' keyword is badly implemented - i.e. non-Constructor functions can be called with the 'new' keyword and vice versa (potentially causing problems).
I thought I understood where he was coming from but I guess I don't.
When I need to create a new module I would normally start of like this:
function MyModule(something) {
this.something = something || {};
}
And then I would add some methods to its prototype:
MyModule.prototype = {
setSomething : function(){},
getSomething : function(){},
doSomething : function(){}
}
I like this model; it means I can create a new instance whenever I need one and it has its own properties and methods:
var foo = new MyModule({option1: 'bar'});
// Foo is an object; I can do anything to it; all methods of the "class"
// are available to this instance.
My question is: How do I achieve the above using an approach more suited to JavaScript? In other words, if "JavaScript" were a person, what would she suggest?
Also: What does Crockford mean when he says a particular design pattern "is more expressive" then another?
See: Is JavaScript's “new” Keyword Considered Harmful?
It's important to remember that Crockford, like so many other JavaScript programmers, first approached the language with an eye toward "fixing" it - making it more like other (so-called "classical") OO languages. So a large amount of structural code was written, libraries and frameworks built, and... then they started to realize that it wasn't really necessary; if you approach JS on its own terms, you can get along just fine.
The prototypal variant for the example you have looks like the following in my understanding:
Object.beget = function (o) { /* Crockfords replacement for the new */ }
var myModule = {
something : null,
getSomething : function () {},
setSomething : function () {},
doSomething : function () {}
};
And then you can do:
var foo = Object.beget(myModule);
foo.something = bar;
UPDATE: You can also use the builder pattern to replace a constructor like this:
var myModuleBuilder = {
buildMyModule : function (something) {
var m = Object.beget(myModule);
m.something = something || {};
return m;
}
}
so then you can do:
var foo = myModuleBuilder.buildMyModule(something);
Your implementation is problematic because you're replacing the entire prototype object, losing the properties of the inherited function prototype and it would also break, or at least make it more difficult, the ability to make use of inheritance later on if you wrote other classes the same way.
A method more suited to Javascript would be:
var MyClass = function (storeThis) {
this.storage = storeThis
}
MyClass.prototype.getStorage = function (){
return this.storage;
}
MyClass.prototype.setStorage = function (newStorage){
this.storage = newStorage;
}
Use it:
var myInstance = new MyClass("sup");
alert("myInstance storage: " + myInstance.getStorage());
myInstance.setStroage("something else");
As for the 'new' keyword and Crawford's problems with it, I can't really answer, because I haven't read the book, but I can see how you could create a new object by calling any function with the new keyword, including functions that are supposed to be methods of a class.
And when someone says something, such as a design pattern, is more 'expressive', he or she generally means that the design pattern is clear and simple to understand as to what it is achieving and how.
Javascript isn't a person so she can't really suggest what you do.
None of the answers above have mentioned the plain-old functional style of inheritance, which I tend to find is the simplest.
function myModuleMaker(someProperty){
var module = {}; //define your new instance manually
module.property = someProperty; //set your properties
module.methodOne = function(someExternalArgument){
//do stuff to module.property, which you can, since you have closure scope access
return module;
}
}
Now to make a new instance:
var newModule = myModuleMaker(someProperty);
You still get all the benefits of pseudoclassical this way, but you suffer the one drawback that you're making a new copy of all your instance's methods every time you instantiate. This is probably only going to matter when you start having many hundreds (or indeed, thousands) of instances, which is a problem most people seldom run into. You're better off with pseudoclassical if you're creating truly enormous data structures or doing hard-core animations with many, many instances of something.
I think it's hard to argue that either method is "bad practice" per se.