Factory function vs Constructor functions memory penalies [duplicate] - javascript

I'm curious what the difference is between the following OOP javascript techniques. They seem to end up doing the same thing but is one considered better than the other?
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
vs
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title;
};
return book;
}
var myBook = Book('War and Peace');
alert(myBook.getTitle())

The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.
If you want to specify your object methods in the constructor, this is the proper way to do it:
function Book(title) {
this.title = title;
this.getTitle = function () {
return this.title;
};
}
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:
function Book(title) {
var title_;
this.getTitle = function() {
return title_;
};
this.setTitle = function(title) {
title_ = title;
};
// should use the setter in case it does something else than just assign
this.setTitle(title);
}
Code outside of the Book function can not access the member variable directly, they have to use the accessors.
Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx

Which is better can sometimes be defined by the context of their usage.
Three constraints of how I choose between Prototype and Closure methods of coding (I actively use both):
Performance/Resources
Compression requirements
Project Management
1. Performance/Resources
For a single instance of the object, either method is fine. Any speed advantages would most likely be negligible.
If I am instantiating 100,000 of these, like building a book library, then the Prototype Method would be preferred. All the .prototype. functions would only be created once, instead of these functions being created 100,000 times if using the Closure Method. Resources are not infinite.
2. Compression
Use the Closure Method if compression efficiency is important (ex: most browser libraries/modules). See below for explanation:
Compression - Prototype Method
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
Is YUI compressed to
function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};
A savings of about 18% (all spaces/tabs/returns). This method requires variables/functions to be exposed (this.variable=value) so every prototype function can access them. As such, these variables/functions can't be optimized in compression.
Compression - Closure Method
function Book(title) {
var title = title; // use var instead of this.title to make this a local variable
this.getTitle = function () {
return title;
};
}
Is YUI compressed to
function Book(a){var a=a;this.getTitle=function(){return a}};
A savings of about 33%. Local variables can be optimized. In a large module, with many support functions, this can have significant savings in compression.
3. Project Management
In a project with multiple developers, who could be working on the same module, I prefer the Prototype Method for that module, if not constrained by performance or compression.
For browser development, I can override the producton.prototype.aFunction from "production.js" in my own "test.js" (read in afterwords) for the purpose of testing or development, without having to modify the "production.js", which may be in active development by a different developer.
I'm not a big fan of complex GIT repository checkout/branch/merge/conflict flow. I prefer simple.
Also, the ability to redefine or "hijack" a module's function by a testbench can be beneficial, but too complicated to address here...

The former method is how JavaScript was intended to be used. The latter is the more modern technique, popularised in part by Douglas Crockford. This technique is much more flexible.
You could also do:
function Book(title) {
return {
getTitle: function () {
return title;
}
}
}
The returned object would just have an accessor called getTitle, which would return the argument, held in closure.
Crockford has a good page on Private Members in JavaScript - definitely worth a read to see the different options.

It's also a little bit about re-usability under the hood. In the first example with the Function.prototype property usage all the instances of the Book function-object will share the same copy of the getTitle method. While the second snippet will make the Book function execution create and keep in the heap 'bookshelf' different copies of the local closurable book object.
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title += '#';
};
return book;
}
var myBook = Book('War and Peace');
var myAnotherBook = Book('Anna Karenina');
alert(myBook.getTitle()); // War and Peace#
alert(myBook.getTitle()); // War and Peace##
alert(myAnotherBook.getTitle()); // Anna Karenina#
alert(myBook.getTitle());// War and Peace###
The prototype members exist in the only copy for all the new instances of the object on the other hand. So this is one more subtle difference between them that is not very obvious from the first sigh due to the closure trick.

here is an article about this
in general Book inharets from Book.prototype. In first example you add function to getTitle Book.prototype

Related

Encapsulation in JavaScript with protoypes

Probably many of you tried to achieve encapsulation in JavaScript. The two methods known to me are:
a bit more common I guess:
var myClass(){
var prv //and all private stuff here
//and we don't use protoype, everything is created inside scope
return {publicFunc:sth};
}
and second one:
var myClass2(){
var prv={private stuff here}
Object.defineProperty(this,'prv',{value:prv})
return {publicFunc:this.someFunc.bind(this)};
}
myClass2.prototype={
get prv(){throw 'class must be created using new keyword'},
someFunc:function(){
console.log(this.prv);
}
}
Object.freeze(myClass)
Object.freeze(myClass.prototype)
So, as second option is WAY more convenient to me (specifically in my case as it visually separates construction from workflow) the question is - are there any serious disadvantages / leaks in this case? I know it allows external code to access arguments of someFunc by
myClass.protoype.someFunc.arguments
but only in case of sloppily executed callbacks (synchronously inside caller chain). Calling them with setTimeout(cb,0) breaks chain and disallows to get arguments as well as just returning value synchronously. At least as far as i know.
Did I miss anything? It's kind of important as code will be used by external, untrusted user provided code.
I like to wrap my prototypes in a module which returns the object, this way you can use the module's scope for any private variables, protecting consumers of your object from accidentally messing with your private properties.
var MyObject = (function (dependency) {
// private (static) variables
var priv1, priv2;
// constructor
var module = function () {
// ...
};
// public interfaces
module.prototype.publicInterface1 = function () {
};
module.prototype.publicInterface2 = function () {
};
// return the object definition
return module;
})(dependency);
Then in some other file you can use it like normal:
obj = new MyObject();
Any more 'protecting' of your object is a little overkill for JavaScript imo. If someone wants to extend your object then they probably know what they're doing and you should let them!
As redbmk points out if you need private instance variables you could use a map with some unique identifier of the object as the key.
So, as second option is WAY more convenient to me (specifically in my case as it visually separates construction from workflow) the question is - are there any serious disadvantages / leaks in this case?
Hm, it doesn't really use the prototype. There's no reason to "encapsulate" anything here, as the prototype methods will only be able to use public properties - just like your untrusted code can access them. A simple
function myClass2(){
var prv = // private stuff here
Object.defineProperty(this, 'prv', {value:prv})
// optionally bind the publicFunc if you need to
}
myClass2.prototype.publicFunc = function(){
console.log(this.prv);
};
should suffice. Or you use the factory pattern, without any prototypes:
function myClass2(){
var prv = // private stuff here
return {
prv: prv,
publicFunc: function(){
console.log(this.prv); // or even just `prv`?
}
};
}
I know it allows external code to access arguments of someFunc by
myClass.protoype.someFunc.arguments
Simply use strict mode, this "feature" is disallowed there.
It's kind of important as code will be used by external, untrusted user provided code.
They will always get your secrets if the code is running in the same environment. Always. You might want to try WebWorkers instead, but notice that they're still CORS-privileged.
To enforcing encapsulation in a language that doesn't properly support private, protected and public class members I say "Meh."
I like the cleanliness of the Foo.prototype = { ... }; syntax. Making methods public also allows you to unit test all the methods in your "class". On top of that, I just simply don't trust JavaScript from a security standpoint. Always have security measures on the server protecting your system.
Go for "ease of programming and testing" and "cleanliness of code." Make it easy to write and maintain, so whichever you feel is easier to write and maintain is the answer.

Javascript 'normal' objects vs module pattern

Currently I'm developing a large scale Javascript app(single page) and I've searched around the web to find some best practices. Most projects use the module pattern so the objects doesn't pollute the global namespace. At this moment I use normal objects:
function LoginModel(){
this.model = new MyModel();
this.getModel = function(){
return this.model;
};
}
This is readable and easy to maintain(my opinion). Is it better to use the module pattern just because of the namespacing or does it has other advantages I'm not aware of(counter memory leaks, ... )? Furthermore, I've already splitted up the files to have a nice MVC pattern and destroy every object when needed(counter memory leaks). So the main question is: do I need, in my case, to use the module pattern or not?
Module pattern:
var LoginModel = (function(){
var model = MyModel;
function getModel(){
return model;
};
return {
getModel: getModel
};
});
The module pattern is better for overall code organization. It lets you have data, logic and functions that are private to that scope.
In your second example getModel() is the only way to get the model from the outside. The variable declared int he module are hidden unless explicitly exposed. This can be a very handy thing.
And there's not really any drawback, other than being a little more complex. You just get more options for organization and encapsulation.
I'd use a plain object until my model gets complex enough to need more structure and some private scoping. And when you hit that point, it's trivial to redefine it as a revealing module without breaking any of the code that uses it.
If you're only going to be using one instance per page, I don't see the need to involve the new keyword. So personally I would create a revealing module like you did in your last example, and expose an object with the "public" properties.
Though I don't see your point with the getModel() function, since MyModel is obviously accessable outside of the scope.
I would have rewritten it slightly:
var LoginModel = (function(model, window, undefined){
function init(){ } // or whatever
function doSomethingWithModel(){
console.log(model);
}
return { init: init };
})(MyModel, window);
If you're uncertain of which modules that will get a model, you can use loose augumentation and change
})(MyModel, window);
to
})(MyModel || {}, window);
If you need several instances of a module, it would look something like this:
var LoginModel = (function(model, window, undefined){
function loginModel(name){ // constructor
this.name = name; // something instance specific
}
loginModel.prototype.getName = function(){
return this.name;
};
return loginModel;
})(MyModel, window);
var lm1 = new LoginModel('foo');
var lm2 = new LoginModel('bar');
console.log(lm1.getName(), lm2.getName()); // 'foo', 'bar'
There's several concepts conflated in your question
With what you call the "normal object", the function becomes a constructor function and requires the new keyword.
The second example uses the Revealing Module Pattern inside of an IIFE. This is the most popular variant of the Module Pattern, but unfortunately deeply flawed. For an explanation of the differences see my answer here, and for its flaws, see here.
Now, your question poses a false dichotomy -- normal objects or module pattern? You don't have to make a choice -- a normal object can use the module pattern simply by putting whatever it wants to keep private inside its closure scope. For example,
function LoginModel(){
var _notifyListeners = function(){
// Do your stuff here
};
this.model = new MyModel();
this.getModel = function(){
_notifyListeners();
return this.model;
};
}
This is an example of a "normal object" using the module pattern. What you have to avoid doing is what the Revealing Module Pattern does -- putting everything into closure scope. You should only put the things you want to keep private inside the closure scope.

jQuery and object-oriented JavaScript - howto?

I've read this and this (thanks google)
But it doesn't help enough. I'd like to know, if, straight out of the box, without any plugin addons, it's possible to do something like it's possible with prototype, for example:
MyClass = Class.create(Table,
{
cookieName: 'w_myclass',
prefix: 'myclass',
...blabla...
// function
initStr: function()
{
...blabla...
},
// another function
getIndice: function(param)
{
...blabla...
return 0;
}
});
Any idea/suggestions are welcome.
JQuery never had the purpose of being a class framework. It's about page manipulation and tools (like AJAX). You can pound a nail with a fork, but why not use a hammer?
Using native JavaScript to create a class-based inheritance system is asking for trouble unless you're a highly skilled JavaScript programmer. Douglas Crockford will tell you it's possible, but he has a deep understanding if the intricacies of closure etc etc. Also, using native inheritance features becomes unsustainable very quickly if your system grows large.
I highly recommend James Coglan's JS.Class framework. The class definitions will look almost identical to your example. It's not native JS but it works fine with JQuery.
If you want a near object oriented solution using javascript with jquery you can define an object in javascript that will set up your event controllers.
The second half of this post http://www.codescream.com/?p=18 covers that. but i'll write here a resume on how to make an object in javascript that you can use in a near object oriented structure.
It would look something like this:
function myObject(constructorParam1, constructorParam2, anotherOne, blabla){
var text = "";
// this event will be set everyTime you run myObject
$(".foo").click(function(){
text = $(this).text(); // copies the text inside the elements ".foo" to a local variable
doSomething();
});
function aPrivateFunction1(){
}
function aPrivateFunction2(){
}
function internalAdd(a,b){
return a+b;
}
var size = 1; // privateVaribale
var name = blabla;
if(name===undefined){
name="No name";
}
aPrivateFunction1(); // run "aPrivateFunction1()
// you can consider all code above as being part of the constructor.
// The variables declared above are private, and the functions are private as well
// bellow are public functions that you can access in an OOP manner
return {
getSize: function(){
return size;
},
setSize: function(newSize){
size = newSize;
},
getName: function(){
return name;
},
setName: function(newName){
name = newname;
},
addAndTurnPositive: function(n1,n2){
var val = internalAdd(n1,n2);
if(val<0){
return val*-1;
}
return val;
}
}
}
// then you can run it like
var anInstance = myObject("aaa",1234,"asdak",123);
anInstance.setSize(1234);
var t = anInstance.addAndTurnPositive(-5,2);
In a word, no. jQuery doesn't offer any class and inheritance functionality. You'd need to include another library, such as klass (although there is a jQuery plugin which ties it in more closely with jQuery)

(Seemingly) redundant naming of functions in classes

I've seen various patterns in object creation, but upon diving into some Firefox framework Javascript, I'd noticed that they're using a convention that I haven't seen before and I'm hoping that someone here can either confirm my assumption or correct me:
When building a class, I've done this (and variations of) in the past:
function MyClass() {
this.myPublicFunction = function() {
};
var myPrivateFunction = function() {
};
}
Bound anonymous functions. Cool. This is what I've seen throughout most frameworks and such.
However, it seem that Mozilla does this:
function MyClass() {
this.myPublicFunction = function MYCLASS_myPublicFunction() {
};
var myPrivateFunction = function MYCLASS_myPrivateFunction() {
};
}
My assumption is that in using the latter convention, JS JIT compiles the functions, but wouldn't pick up the first two as they'd be defined at run-time rather than parse time.
Is this assumption correct and if so, does this also apply to other JS engines or just Spidermonkey?
Reasons to use NFE:
a function with a name gives more debugging information in your stack trace
NFE are self documenting. (if you put useful information in the name).
Note that function declarations are better then NFE. (From a personal style choice)
function MyClass() {
this.myPublicFunction = myPublicFunction;
function myPrivateFunction() {
}
function myPublicFunction() {
}
}
Also note that the word "private" is misleading, but that's a tangent.

Object oriented javascript with prototypes vs closures

I'm curious what the difference is between the following OOP javascript techniques. They seem to end up doing the same thing but is one considered better than the other?
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
vs
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title;
};
return book;
}
var myBook = Book('War and Peace');
alert(myBook.getTitle())
The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.
If you want to specify your object methods in the constructor, this is the proper way to do it:
function Book(title) {
this.title = title;
this.getTitle = function () {
return this.title;
};
}
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:
function Book(title) {
var title_;
this.getTitle = function() {
return title_;
};
this.setTitle = function(title) {
title_ = title;
};
// should use the setter in case it does something else than just assign
this.setTitle(title);
}
Code outside of the Book function can not access the member variable directly, they have to use the accessors.
Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx
Which is better can sometimes be defined by the context of their usage.
Three constraints of how I choose between Prototype and Closure methods of coding (I actively use both):
Performance/Resources
Compression requirements
Project Management
1. Performance/Resources
For a single instance of the object, either method is fine. Any speed advantages would most likely be negligible.
If I am instantiating 100,000 of these, like building a book library, then the Prototype Method would be preferred. All the .prototype. functions would only be created once, instead of these functions being created 100,000 times if using the Closure Method. Resources are not infinite.
2. Compression
Use the Closure Method if compression efficiency is important (ex: most browser libraries/modules). See below for explanation:
Compression - Prototype Method
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
Is YUI compressed to
function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};
A savings of about 18% (all spaces/tabs/returns). This method requires variables/functions to be exposed (this.variable=value) so every prototype function can access them. As such, these variables/functions can't be optimized in compression.
Compression - Closure Method
function Book(title) {
var title = title; // use var instead of this.title to make this a local variable
this.getTitle = function () {
return title;
};
}
Is YUI compressed to
function Book(a){var a=a;this.getTitle=function(){return a}};
A savings of about 33%. Local variables can be optimized. In a large module, with many support functions, this can have significant savings in compression.
3. Project Management
In a project with multiple developers, who could be working on the same module, I prefer the Prototype Method for that module, if not constrained by performance or compression.
For browser development, I can override the producton.prototype.aFunction from "production.js" in my own "test.js" (read in afterwords) for the purpose of testing or development, without having to modify the "production.js", which may be in active development by a different developer.
I'm not a big fan of complex GIT repository checkout/branch/merge/conflict flow. I prefer simple.
Also, the ability to redefine or "hijack" a module's function by a testbench can be beneficial, but too complicated to address here...
The former method is how JavaScript was intended to be used. The latter is the more modern technique, popularised in part by Douglas Crockford. This technique is much more flexible.
You could also do:
function Book(title) {
return {
getTitle: function () {
return title;
}
}
}
The returned object would just have an accessor called getTitle, which would return the argument, held in closure.
Crockford has a good page on Private Members in JavaScript - definitely worth a read to see the different options.
It's also a little bit about re-usability under the hood. In the first example with the Function.prototype property usage all the instances of the Book function-object will share the same copy of the getTitle method. While the second snippet will make the Book function execution create and keep in the heap 'bookshelf' different copies of the local closurable book object.
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title += '#';
};
return book;
}
var myBook = Book('War and Peace');
var myAnotherBook = Book('Anna Karenina');
alert(myBook.getTitle()); // War and Peace#
alert(myBook.getTitle()); // War and Peace##
alert(myAnotherBook.getTitle()); // Anna Karenina#
alert(myBook.getTitle());// War and Peace###
The prototype members exist in the only copy for all the new instances of the object on the other hand. So this is one more subtle difference between them that is not very obvious from the first sigh due to the closure trick.
here is an article about this
in general Book inharets from Book.prototype. In first example you add function to getTitle Book.prototype

Categories

Resources