Simple javascript inheritance using $.extend and module pattern - javascript

I have wondered for a couple years now what people think of doing inheritance with a module-pattern-esque constructor pattern and WITHOUT normal prototypal inheritance. Why do programmers not use a module pattern for non-singleton js classes? For me the advantages are:
Very clear public and private scope (easy to understand the code and the api)
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
Disadvantages:
Small perf degradation
Risk possible "wag of the finger" from Doug Crockford?
Consider this (just run in any js console)
var Animal = function () {
var publicApi = {
Name: 'Generic',
IsAnimal: true,
AnimalHello: animalHello,
GetHelloCount:getHelloCount
};
var helloCount = 0;
function animalHello() {
helloCount++;
console.log(publicApi.Name + ' says hello (animalHello)');
}
function getHelloCount(callback) {
callback.call(helloCount);
}
return publicApi;
};
var Sheep = function (name) {
var publicApi = {
Name: name || 'Woolie',
IsSheep: true,
SheepHello: sheepHello
};
function sheepHello() {
publicApi.AnimalHello();
publicApi.GetHelloCount(function() {
console.log('i (' + publicApi.Name + ') have said hello ' + this + ' times (sheepHello anon callback)');
});
}
publicApi = $.extend(new Animal(), publicApi);
return publicApi;
};
var sheepie = new Sheep('Sheepie');
var lambie = new Sheep('Lambie');
sheepie.AnimalHello();
sheepie.SheepHello();
lambie.SheepHello();
My question is what are the drawbacks to this approach that I am not seeing? Is this a good approach?
Thanks!
[update]
Thanks for the great responses. Wish I could give everyone the bounty. It was what I was looking for. Basically what I thought. I would never use module pattern to construct more than a few instances of something. Usually only a couple. The reason I think it has its advantages is whatever small perf degradation you see is recaptured in the simplicity of the coding experience. We have a LOT of code to write these days. We also have to reuse other peoples' code and personally I appreciate when someone has taken the time to create a nice elegant pattern rather than dogmatically adhering to prototypal inheritance when it makes sense.

I think it boils down to the issue of performance. You mentioned that there is small performance degradation, but this really depends on scale of the application(2 sheep vs 1000 sheep). Prototypal inheritance should not be ignored and we can create an effective module pattern using a mix of functional and prototypal inheritance.
As mentioned in the post JS - Why use Prototype?,
one of the beauties of prototype is that you only need to initialize the prototypal members only once,
whereas members within the constructor are created for each instance.
In fact, you can access prototype directly without creating a new object.
Array.prototype.reverse.call([1,2,3,4]);
//=> [4,3,2,1]
function add() {
//convert arguments into array
var arr = Array.prototype.slice.call(arguments),
sum = 0;
for(var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
add(1,2,3,4,5);
//=> 15
In your functions, there is extra overhead to create a completely new
Animal and sheep each time a constructor is invoked. Some members such as Animal.name are created with each instance, but we know
that Animal.name is static so it would be better to instantiate it once. Since your code implies that Animal.name
should be the same across all animals, it is easy to update Animal.name for all instance simply by updating Animal.prototype.name if we moved
it to the prototype.
Consider this
var animals = [];
for(var i = 0; i < 1000; i++) {
animals.push(new Animal());
}
Functional inheritance/Module Pattern
function Animal() {
return {
name : 'Generic',
updateName : function(name) {
this.name = name;
}
}
}
//update all animal names which should be the same
for(var i = 0;i < animals.length; i++) {
animals[i].updateName('NewName'); //1000 invocations !
}
vs. Prototype
Animal.prototype = {
name: 'Generic',
updateName : function(name) {
this.name = name
};
//update all animal names which should be the same
Animal.prototype.updateName('NewName'); //executed only once :)
As shown above with your currently module pattern we lose effeciency in
updating properties that should be in common to all members.
If you are concered about visibility, I would use the same modular method you are currently using to encapsulate private members but also use
priviledged members for accessing these members should they need to be reached. Priviledged members are public members that provide an interface to access private variables. Finally add common members to the prototype.
Of course going this route, you will need to keep track of this.
It is true that in your implementation there is
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
, but you are are creating a very large object each time which will consume more memory in comparison to using some prototypal inheritance.
Event Delegation as Analogy
An analogy to gaining performance by using prototypes is improved performance by using event delegation when manipulating the DOM.Event Delegation in Javascript
Lets say you have a large grocery list.Yum.
<ul ="grocery-list">
<li>Broccoli</li>
<li>Milk</li>
<li>Cheese</li>
<li>Oreos</li>
<li>Carrots</li>
<li>Beef</li>
<li>Chicken</li>
<li>Ice Cream</li>
<li>Pizza</li>
<li>Apple Pie</li>
</ul>
Let's say that you want to log the item you click on.
One implementation would be to attach an event handler to every item(bad), but if our list is very long there will be a lot of events to manage.
var list = document.getElementById('grocery-list'),
groceries = list.getElementsByTagName('LI');
//bad esp. when there are too many list elements
for(var i = 0; i < groceries.length; i++) {
groceries[i].onclick = function() {
console.log(this.innerHTML);
}
}
Another implementation would be to attach one event handler to the parent(good) and have that one parent handle all the clicks.
As you can see this is similar to using a prototype for common functionality and significantly improves performance
//one event handler to manage child elements
list.onclick = function(e) {
var target = e.target || e.srcElement;
if(target.tagName = 'LI') {
console.log(target.innerHTML);
}
}
Rewrite using Combination of Functional/Prototypal Inheritance
I think the combination of functional/prototypal inheritance can be written in an easy understandable manner.
I have rewritten your code using the techniques described above.
var Animal = function () {
var helloCount = 0;
var self = this;
//priviledge methods
this.AnimalHello = function() {
helloCount++;
console.log(self.Name + ' says hello (animalHello)');
};
this.GetHelloCount = function (callback) {
callback.call(null, helloCount);
}
};
Animal.prototype = {
Name: 'Generic',
IsAnimal: true
};
var Sheep = function (name) {
var sheep = new Animal();
//use parasitic inheritance to extend sheep
//http://www.crockford.com/javascript/inheritance.html
sheep.Name = name || 'Woolie'
sheep.SheepHello = function() {
this.AnimalHello();
var self = this;
this.GetHelloCount(function(count) {
console.log('i (' + self.Name + ') have said hello ' + count + ' times (sheepHello anon callback)');
});
}
return sheep;
};
Sheep.prototype = new Animal();
Sheep.prototype.isSheep = true;
var sheepie = new Sheep('Sheepie');
var lambie = new Sheep('Lambie');
sheepie.AnimalHello();
sheepie.SheepHello();
lambie.SheepHello();
Conclusion
The takeaway is to use both prototypal and functional inheritance to their advantages both to tackle performance and visibility issues.
Lastly, if you are working on a small JavaScript applications and these performance issues are not a concern,
then your method would be viable approach.

a module-pattern-esque constructor pattern
This is known as parasitic inheritance or functional inheritance.
For me the advantages are:
Very clear public and private scope (easy to understand this code and the api)
The same holds true for the classical constructor pattern. Btw, in your current code it's not super clear whether animalHello and getHelloCount are supposed to be private or not. Defining them right in the exported object literal might be better if you care about that.
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
That's basically the same. You either use a that dereference or binding to solve this problem. And I don't see this as a huge disadvantage, since the situation where you'd use object "methods" directly as callbacks are pretty rare - and apart from the context you often want to feed additional arguments. Btw, you're using a that reference as well in your code, it's called publicApi there.
Why do programmers not use a module pattern for non-singleton js classes?
Now, you've named some disadvantages yourself already. Additionally, you are loosing prototypical inheritance - with all its advantages (simplicity, dynamism, instanceof, …). Of course, there are cases where they don't apply, and your factory function is perfectly fine. It is indeed used in these cases.
publicApi = $.extend(new Animal(), publicApi);
…
… new Sheep('Sheepie');
These parts of your code are a little confusing as well. You are overwriting the variable with a different object here, and it happens in the middle-to-end of your code. It would be better to see this as a "declaration" (you're inheriting the parent properties here!) and put it at the top of your function - right as var publicApi = $.extend(Animal(), {…});
Also, you should not use the new keyword here. You do not use the functions as constructors, and you don't want to create instances that inherit from Animal.prototype (which slows down your execution). Also, it confuses people that might expect prototypical inheritance from that constructor invocation with new. For clarity, you even might rename the functions to makeAnimal and makeSheep.
What would be a comparable approach to this in nodejs?
This design pattern is completely environment-independent. It will work in Node.js just as like as at the client and in every other EcmaScript implementation. Some aspects of it even are language-independent.

With your approach, you wont be able to override functions and call the super function so conveniently.
function foo ()
{
}
foo.prototype.GetValue = function ()
{
return 1;
}
function Bar ()
{
}
Bar.prototype = new foo();
Bar.prototype.GetValue = function ()
{
return 2 + foo.prototype.GetValue.apply(this, arguments);
}
Also, in the prototype approach, you can share data among all the instances of the object.
function foo ()
{
}
//shared data object is shared among all instance of foo.
foo.prototype.sharedData = {
}
var a = new foo();
var b = new foo();
console.log(a.sharedData === b.sharedData); //returns true
a.sharedData.value = 1;
console.log(b.sharedData.value); //returns 1
One more advantage of the prototype approach would be to save memory.
function foo ()
{
}
foo.prototype.GetValue = function ()
{
return 1;
}
var a = new foo();
var b = new foo();
console.log(a.GetValue === b.GetValue); //returns true
Whereas in of your approach,
var a = new Animal();
var b = new Animal();
console.log(a.AnimalHello === b.AnimalHello) //returns false
This means with each new object, a new instance of the functions are created where as it is shared among all objects incase of prototype approach.
This wont make much difference incase of few instances but when large number of instances are created, it would show a considerable difference.
Also, one more powerful feature of prototype would be once all objects are created, you can still change the properties among all objects at once (only if they are not altered after object creation).
function foo ()
{
}
foo.prototype.name = "world";
var a = new foo ();
var b = new foo ();
var c = new foo();
c.name = "bar";
foo.prototype.name = "hello";
console.log(a.name); //returns 'hello'
console.log(b.name); //returns 'hello'
console.log(c.name); //returns 'bar' since has been altered after object creation
Conclusion:
If the above mentioned advantages of the prototype approach are not so useful for your application, your approach would be better.

Related

Variable privacy in Javascript's behaviour delegation pattern

Since my last question, I've been studying Javascript's prototype model and trying to get rid of the OOP vision I inherited from other languages (pun slightly intended).
I went back to basics and read Crookford's Javascript: The Good Parts, along with You Don't Know JS material and decided to stick with the so called behaviour delegation.
Restructuring my previous example implementing behaviour delegation and namespacing, I wrote:
var GAME = {};
(function(namespace) {
var Warrior = {};
Warrior.init = function(weapon) {
this.setWeapon(weapon);
};
Warrior.getWeapon = function() {
return this.weapon;
};
Warrior.setWeapon = function(value) {
this.weapon = value || "Bare hands";
};
namespace.Warrior = namespace.Warrior || Warrior;
})(GAME);
(function(namespace) {
var Archer = Object.create(namespace.Warrior);
Archer.init = function(accuracy) {
this.setWeapon("Bow");
this.setAccuracy(accuracy);
};
Archer.getAccuracy = function() {
return this.accuracy;
};
Archer.setAccuracy = function(value) {
this.accuracy = value;
};
namespace.Archer = namespace.Archer || Archer;
})(GAME);
So, everytime I copy a new Archer object:
var archer1 = Object.create(GAME.Archer);
only this object will be created, conserving memory.
But what if I don't want to expose "accuracy" attribute? The attribute would only increase by calling a "training()" method or something similar. I tried to use var accuracy inside the anonymous function, but it turns into kind of static variable, all instances of Archer would share the same value.
The question: Is there any way to set a variable as private while still keeping behaviour-delegation/prototypal pattern?
I do know of functional pattern as well, Here I succesfully achieved variable privacy, at the cost of memory. By going functional, every new "archer" instance generates a new "Warrior" and then a new "Archer". Even considering that Chrome and Firefox have different optmizations, testings on both report that the Delegation/Prototypal pattern is more efficient:
http://jsperf.com/delegation-vs-functional-pattern
If I go with the pure-object delegation pattern, should I just forget the classic encapsulation concept and accept the free changing nature of properties?
I would try to answer your question with something that is slightly different then this one that tells you how to use a library.
Different in that it will(hopefully) give you some ideas of how can we tackle the problem of private vars in OLOO ourselves. At least to some extent, with our own code, no external lib needed, which could be useful in certain scenarios.
In order for code to be cleaner I've striped your anonymous wrapper functions, since they are not related to problem in any way.
var Warrior = {};
Warrior.warInit = function (weapon){
this.setWeapon(weapon);
}
Warrior.getWeapon = function(){
return this.weapon;
}
Warrior.setWeapon = function (value){
this.weapon = value || "Bare hands";
}
var Archer = Object.create(Warrior);
Archer.archInit = function (accuracy){
this.setWeapon("Bow");
this.setAccuracy(accuracy);
}
Archer.getAccuracy = function (pocket) {
return pocket.accuracy;
}
Archer.setAccuracy = function (value, pocket){
pocket.accuracy = value;
}
function attachPocket(){
var pocket = {};
var archer = Object.create(Archer);
archer.getAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]);
return Archer.getAccuracy.apply(this, args)
};
archer.setAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]);
return Archer.setAccuracy.apply(this, args);
};
return archer;
}
var archer1 = attachPocket();
archer1.archInit("accuracy high");
console.log(archer1.getAccuracy()); // accuracy high
archer1.setAccuracy("accuracy medium");
console.log(archer1.getAccuracy()); // accuracy medium
Test code above here. (and open your browser console)
Usage
1 ) General practice in OLOO about naming functions on different levels of prototype chain is apposite from OOP. We want different names that are more descriptive and self documenting, which brigs code that is cleaner and more readable. More importantly, by giving different names we avoid recursion loop:
Archer.init = function(accuracy, pocket){
this.init() // here we reference Archer.init() again, indefinite recurson. Not what we want
...
}
Archer.archInit = fucntion (accuracy, pocket){ // better,
this.warInit() // no name "collisions" .
}
2 ) We've created an attachPocket() function that creates internal variable pocket. Creates new object with Object.create() and sets it's prototype to point to Archer. Pause. If you notice, functions that required a private var we have defined so that each of them take one more parameter(pocket), some use just pocket. Here is the trick.
By making wrapper functions like archer.setAccuracy(), archer.getAccuracy()
... we can create closures and call directly functions that need
private var (here pocket) and pass it to them as an argument.
Like so:
function AtachPocket(){
...
var pocket = {};
archer.setAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]); // appending pocket to args
return Archer.setAccuracy(this, args);
};
...
}
Essencially by doing this we are bypassing what would have been a normal search for functions in prototype chain, just for functions that have need for a private var. This is what "call directly" refers to.
By setting the same name for a function in archer("instance") like it is in prototype chain (Archer) we are shadowing that function at the instance level. No danger of having indefinite loops, since we are "calling directly" like stated above. Also by having the same function name we preserve the normal, expected behaviour of having access to same function in an "instance" like it is in a prototype chain. Meaning that afther var archer = Object.create(Archer) we have access to function setAccuracy like we would if it had been normal search for function in prototype chain.
3 ) Every time attachPocket() is invoked it creates a new "instance" that has those wrapper functions that pass a pocket argument (all as an internal detail of implementation). And therefore every instance has own, unique, private variable.
You would use functions in an "instance" normally:
archer1.archInit("accuracy high"); // Passing needed arguments.
// Placed into pocked internally.
archer1.getAccuracy(); // Getting accuracy from pocket.
Scalability
Up to now all we have is function that "attaches a pocket" with hardcoded values like Archer.setAccuracy, Archer.getAccuracy. What if we would like to expand prototype chain by introducing a new object type like this var AdvancedArcher = Object.create(Archer), how the attachPocket is going to behave if we pass to it AdvancedArcher object that might not even have setAccuracy() function? Are we going to change attachPocket() each time we introduce some change in prototype chain ?
Let's try to answer those questions, by making attachPocket() more general.
First, expand prototype chain.
var AdvancedArcher = Object.create(Archer);
AdvancedArcher.advInit = function(range, accuracy){
this.archInit(accuracy);
this.setShotRange(range);
}
AdvancedArcher.setShotRange = function(val){
this.shotRange = val;
}
More generic attachPocket.
function attachPocketGen(warriorType){
var funcsForPocket = Array.prototype.slice.call(arguments,1); // Take functions that need pocket
var len = funcsForPocket.length;
var pocket = {};
var archer = Object.create(warriorType); // Linking prototype chain
for (var i = 0; i < len; i++){ // You could use ES6 "let" here instead of IIFE below, for same effect
(function(){
var func = funcsForPocket[i];
archer[func] = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]); // appending pocket to args
return warriorType[func].apply(this, args);
}
})()
}
return archer;
}
var archer1 = attachPocketGen(Archer,"getAccuracy","setAccuracy");
archer1.advInit("11","accuracy high");
console.log(archer1.getAccuracy()); // "accuracy high";
archer1.setAccuracy("accuracy medium");
console.log(archer1.getAccuracy());
Test the code here.
In this more generic attachPocketGen as first argument we have a warriorType variable that represents any object in our prototype chain. Arguments that may fallow are ones that represent names of functions that need a private var.
attachPocketGen takes those function names and makes wrapper functions with same names in archer "instance". Shadowing, just like before.
Another thing to recognise is that this model of making wrapper functions and using apply() function to pass variables from closures is going to work for functions that use just pocket, functions that use pocket and other variables, and when ,of course, those variables use the relative this reference in front of them.
So we have achieved somewhat more usable attachPocket, but that are still things that should be noticed.
1) By having to pass names of functions that need private var, that usage implies that we(attachPocketGen users) need to know whole prototype chain (so we could see what functions need private var). Therefore if you are to make a prototype chain like the one here and just pass the attachPocketGen as an API to the programmer that wants to use your behaviour-delegation-with-private-variables, he/she would had to analyse objects in prototype chain. Sometimes that is not what wee want.
1a) But we could instead, when defining our functions in prototype chain (like Archer.getAccuracy) to add one property to them like a flag that can tell if that function have need for a private var:
Archer.getAccuracy.flg = true;
And then we could add additional logic that checks all functions in prototype chain that have this flg and fills the funcsForPocket.
Result would be to have just this call:
var archer1 = attachPocketGen(AdvancedArcher)
No other arguments except warriorType. No need for user of this function to have to know how prototype chain looks like, that is what functions have need for a private var.
Improved style
If we are to look at this code:
Archer.archInit = function (accuracy){
this.setWeapon("Bow");
this.setAccuracy(accuracy);
}
We see that it uses "pocket" function setAccuracy. But we are not adding pocket here as last argument to it because setAccuracy that gets called is shadowed version, the one from instance. Becouse it will be called only from an instance like so archer1.archInit(...) That one is already adding a pocket as last argument so there is on need to. That's kinda nice, but the definition of it is:
Archer.setAccuracy = function (value, pocket){ ...
and that can be confusing when making objects in prototype chain like Archer.archInit above. If we look the definition of setAccuracy it looks like we should it. So in order not have to remember that we don't have to add pocket as last arg in functions (like archInit) that use other pocket functions, maybe we should to something like this:
Archer.setAccuracy = function (value){
var pocket = arguments[arguments.length -1];
pocket.accuracy = value;
}
Test the code here.
No pocket as last argument in function definition. Now it's clear that function doesn't have to be called with pocket as an argument wherever in code.
1 ) There are other arguably minor stuff to refer to when we think about more general prototype chain and attachPocketGen.Like making functions that use pocket callable when we dont wan't to pass them a pocket, that is to toggle pocket usage to a function, but in order not to make this post too long, let's pause it.
Hope this can give you view ideas for solution to your question.

Difference In declaring Javascript objects

I have been reading a few different Javascript authors and each has their preferred way to declare properties on objects. None of the authors really explains the difference between these different ways. What are the differences and which way is the preferred declaration to us?
var One = function() {
var self = this;
self.foo = function() {};
return self;
}
var two = function() {
foo: function() {}
};
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
tl;dr - See conclusion
Introduction
Declaring objects in javascript can be done many different ways, and from my point of view it all depends on how complex your project is.
The examples you proposed would be ways to declare variables within a complex project. You could even say for project maintainability and code quality the examples you proposed can be very interesting.
Part 1 - First example
Your first example you proposed was this function.
var One = function(){
var self = this;
self.foo = function(){};
return self;
}
Context: Global -> One()
Suppose we don't create an instance of One (not using new) This function has two objectives.
Attach the foo function to its parents context (usually window object = globally)
Return foo function
You could say you're killing two birds with one stone. While doing two things at once can be interesting, in the end it could really become a context problem.
Context is pretty much asking yourself, what does this refer to? Non instantiated functions inherit the parents context which is fine if none of those parents are instantiated themselves. If this is the case (meaning this != window object) and your primary goal was to attach foo globally well it just won't work.
Context: Self -> new One()
If you call this function with new, this will be different. this will refer to an instance of One. This is a lot more logical way.
In the end you could say that an instance of One will feel almost like an object.
Comparing with objects
I say almost mainly because what is the difference if One was:
var One_object = {
foo: function(){}
}
Well there isn't really, except you'll be more flexible with an object rather than an instance of a function.
//This will not work.
var a = new One();
a.titi = function(){
alert('titi');
}
//This will work
One_object.titi = function(){
alert('titi');
}
Improving the example
The only way that One as an instance can become interesting is if you declare multiple instances. Performance wise and memory wise it'll be more interesting.
var One = function(foo){
//auto instantiate it's self
if(!(this instanceof One)){
return new One(foo);
}
this.foo = foo || function(){};
}
Creating multiple instances of One with the same function probably defeats the purpose, so here is an example of how you could improve One.
var a = One(function(){
alert('instance one');
});
var b = One(function(){
alert('instance two');
});
Part 2 - Second example
var two = function() {
foo: function() {}l
};
Is actually wrong as I'm sure you've noticed from the comments. It should be instead:
var two = {
foo: function() {}
};
Where two is in fact an object and not a function.
This way of declaring variables/functions ensures that you are not overriding on a global scope any other function named "foo".
This can be very useful when you have a lot of js and you are declaring a lot of variables.
In this case, to access foo you need to simply call two.foo();
This is honestly my preferred way of declaring variables.
Variables are not scattered all across the js file.
They do not override any existing variables with the same name
It's clean and maintainable.
They can easily be moved around.
With this in mind, here is an example:
var options = {
foo: function(){
console.log('This is foo');
},
toto: function(){
console.log('This is titi');
}
};
var example = function(options){
options.foo();
options.toto();
}
example(options);
Part 3 - Barbaric
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
A good standard when writing code is to keep the code readable. While this may work, it's not good practice. The main issue with writing Javascript is that it can easily become unreadable.. And in this case it feels barbaric (personal opinion).
Conclusion
As you've probably noticed example two is my preferred way (and to many others I know) in declaring Objects for the following reasons:
Structured
Organized
Easy to handle
Easy to maintain
Flexibility
No conflicts
Feel free to point out on anything I've missed.
In JavaScript you can declare "Objects" via several ways. The most easy way is:
var myObject = {}
from here on, adding methods or attributes is very easy as well:
myObject.myFirstMethod = function(){};
myObject.myFirstAttr = true;
myObject.mySecondAttr = "hello world!";
in this case, you would add those functions and attributes to your "myObject" Object. But there is a better and much cleaner way to do such stuff:
var myObject = function();
myObject.prototype.method1 = function(){};
myObject.prototype.method2 = functiion(){};
myObject.prototype.attr1 = true;
myObject.prototype.attr2 = "hello world!";
myObject.prototype.setAttr1 = function(value){
this.attr1 = value;
}
myObject.prototype.setAttr2 = function(value){
this.attr2 = value;
}
if you declared your Object this way, you can use
var myObjectInstance = new myObject();
this Object now has got every methods and attributes which you had defined in your prototype. more about prototypes:
http://www.w3schools.com/js/js_object_prototypes.asp
edit:
note that "this" in JavaScript means the "element", what called the actual method and NOT the object itself in any case...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

prototype closure in the constructor

Update:
This kind of implementation is simply bad, and I've removed that answer.
I just answered this question. The OP asked for the solution of a private member which can only be accessible by prototype methods. For my answer, I would not suggest to do that but propose the code of its possibility. (And sorry, I do not have a good idea with the title .. )
Code
function A(prop1) {
var myFunc=A.prototype.myFunc;
var that=this;
A.prototype.myFunc=function () {
if (this===that) {
alert(prop1); // do something
}
else {
myFunc.call(this);
}
};
this.retire=function () {
that=undefined;
};
}
A.prototype.myFunc=function () {
};
var a1=new A(1);
var a2=new A(2);
var a3=new A(3);
a1.myFunc();
a2.myFunc();
a3.myFunc();
a2.retire();
a1.myFunc();
a2.myFunc();
a3.myFunc();
// ..
As we can see if any other prototype methods would access prop1, will need to repeat this pattern. I've ever thought about to use a private array to achieve it, but this code seems significantly shorter.
But there are things not good:
It needs an extra function to ensure that not reference to this.
A.prototype.myFunc is growing up(deeper) with the object creation afterwards.
As every var myFunc are still referenced by A.prototype.myFunc, there's a doubt even after invoked retire and clean up all outter reference to an object, it might still alive when the gc comes.
I have limited testing environment and be pleasure to know if there's potential risk with this implementation.
So I think an answer to the question could be:
A. A more feasible approach to alter the prototype methods in the constructor to achieve that the private members can only be accessible in prototype methods.
B. Another method to achieve the same thing, and the code is as simple as possible.
It would also be greatly appreciated to point out my misunderstanding of the closures and the garbage collection within your answers.
Let's see the requirements of the OP in the other question:
Is there a JavaScript pattern which mimics "Protected" object
properties
Answer: sort of, best way (in my opinion) name them _myPrivate
BTW - I do not want the pattern of privileged member functions
accessing private properties since the member function is still
public.
That just makes no sense at all, does the OP think that A.prototype.myFunc is not publicly accessible on A instances?
An introduction to prototype and constructor functions (plus some patterns for privates) can be found here
1 . It needs an extra function to ensure that not reference to this.
There isn't a workaround. that is captured by A.prototype.myFunc within each instantiation, and the instance itself is the object which can access that directly, more objects involve would just make things worse; the retire method is already the simplest way to untangle the reference.
2 . A.prototype.myFunc is growing up(deeper) with the object creation afterwards.
This is just the potential risk. A.prototype.myFunc is made similar to a recursive method, but in fact it isn't. It calls to the previous myFunc and check the instance for its identity. For a few instances it isn't a problem, but for a plenty of the instances, the growing depth will finally cause stack overflow.
As the implementation will whatever need a mechanism for cleanning up, to make the calls deeper gains nothing than just use an array to hold the references, and to clean up on-demand.
3 . As every var myFunc are still referenced by A.prototype.myFunc, there's a doubt even after invoked retire and clean up all outter reference to an object, it might still alive when the gc comes.
The fact is var myFunc which is captured by A.prototype.myFunc will still alive even when the gc comes to collect garbages. There is almost impossible to make the reference to myFunc be released, since it's a chained invocation, the contexts of a deeper call and the shallow call do not have the visibility to each other, thus none of them are able to modify the chain of invocation for skipping a level; unset myFunc would just break the chain. Any trick trying to solve this would involve more objects, that may either increase the cost or being an overkill.
4 . I have limited testing environment and be pleasure to know if there's potential risk with this implementation.
As the answer to the bullet point 2, it may cause stack overflowing when a lot of object are created with it.
I tend to agree with people that say "just don't bother with private," but I think the best way to do this, if you really want it, is with Function#bind. The Crockford article doesn't mention this approach, possibly because it predates bind, and emulating bind with apply gets kind of hairy (or possibly because it's an extra bit of overhead for not much gain).
function classify(fn) {
var privateScope = {}, publicScope = {};
function bindProp(to, target, src, key) {
if (!src.hasOwnProperty(key)) return;
if (!(src[key] && src[key].bind)) return;
target[key] = src[key].bind(to);
}
function ctor() {
var instancePublic = {}, instancePrivate = Object.create(instancePublic);
for (var key in publicScope) {
bindProp(instancePrivate, instancePublic, publicScope, key);
}
for (var key in privateScope) {
instancePrivate[key] = privateScope[key];
}
if (publicScope.hasOwnProperty('constructor'))
publicScope.constructor.apply(instancePrivate, arguments);
return instancePublic;
}
fn.call(publicScope, publicScope, privateScope);
return ctor;
}
This function lets you define a pseudoclass with a "public" and "private" scope. The idea is that:
The public scope object is placed in the prototype chain of the private scope object.
All functions are bound to the private scope object.
First attempt
function classify(fn) {
var privateScope = {}, publicScope = {};
function bindProp(privateScope, scopeObject, key) {
if (!scopeObject.hasOwnProperty(key)) return true;
if (!(scopeObject[key] && scopeObject[key].bind)) return;
privateScope[key] = scopeObject[key].bind(privateScope);
}
function ctor() {
var instancePrivate = Object.create(privateScope),
instancePublic = Object.create(instancePrivate);
for (var key in publicScope) {
console.log(key);
bindProp(instancePrivate, publicScope, key);
}
for (var key in privateScope) {
if (!bindProp(instancePrivate, privateScope, key)
&& !publicScope.hasOwnProperty(key))
instancePublic[key] = void 0;
}
if (publicScope.hasOwnProperty('constructor'))
publicScope.constructor.apply(instancePrivate, arguments);
return instancePublic;
}
fn(publicScope, privateScope);
return ctor;
}
This version had the prototype chain reversed:
The private scope object is placed in the prototype chain of the public scope object.
All functions are bound to the private scope object.
Any private member that's not shadowed by a public member is shadowed by undefined.
Usage
You'd use it something like this:
var Foo = classify(function(pub, priv) {
// constructors are supported but not required
pub.constructor = function(a, b) {
this.a = a;
this.b = b;
};
priv.somePrivateProp = "lol";
priv.doPrivateStuff = function(x, y) {
return x + y;
};
pub.somePublicProp = "rofl";
pub.doStuff = function(x, y) {
return this.doPrivateStuff(x + 1, y + 1) + ' ' + this.somePrivateProp;
};
});
You can play around with this in the console and see that it works like you'd probably expect.
var foo = new Foo('abc', 123);
foo.doStuff(3, 5); // "10 lol"
foo.doPrivateStuff(3, 5) // throws TypeError

Do we really have to change to Object.create?

I have a question for you
As I know, new operator works this way
function fakeNew(Ctor) {
var instance = Object.create(Ctor.prototype);
instance.constructor();
// I skip the conditional for simplicity
return instance;
}
It all begin when I did a Object.create polifill so I could create objects without using new.
Object.create = function(proto) {
function F() { }
F.prototype = proto;
return new F();
}
I started creating a lot of objcts and prototiping them, but as many times then need to initializa its properties I did a .init() method to them
var base = {
init: function() {
EmitterMixin.call(this);
return this;
}
};
var obj = Object.create(base).init();
But of course, I had to rembember to return this always from .init() and many times I forget it or worst, I forgot to call .init(). So trying to simplify object initialization I wanted to create a global helper to do it: invoke Object.create, invoke the initializer function and return this.
function create(proto) {
var child = Object.create(proto);
child.init();
return child;
}
Then was when I wanted to hit my head against the wall when I realized what I was doing was virtually what new operator does but a lot slower. And in case the polifill applies I would even use new under the hood.
So I ask myself, what benefits throwing new? It's notably quicker on main browsers and because of javascript nature we usually need to call a initualizer function, something than new does from it's begining.
And worst, I've noticed than I used two different types of objects, "abstract" and "instances", the bigger difference is than for instances I had to invoke .init() while with abstracts it was not necesasary because they will only be used to be prototypes of other objects. And I've already seen this pattern while using new:
function Foo() { }
Foo.prototype.method = function() { ... };
function Bar() { }
// "abstract" doesnt invoke initializer
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.other = function() { ... };
// "instance", the constructor is called as initializer
var obj = new Bar();
Is there really a benefit if we stop seeing new? are we sure it's not a higher-level tool than simplifies something we'll have to do anyway?
What pros/cons do you see about new and Object.create?
I have tried both approaches and I don't personally see any problem with the traditional approach using new. The main argument for Object.create is that it makes the prototypal inheritance more clear - you don't have to understand the intricacy of the prototype property on function constructors and how that relates to the actual prototype of the object. But it does require that initialization be a separate step.
My preferred approach is to combine the two approaches, e.g.:
function Animal(name) {
this.name = name || null;
}
Animal.prototype.eat = function() {
console.log('yum');
}
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.meow = function() {
console.log('meow');
}
var garfield = new Cat('garfield');
garfield.eat();
garfield.meow();
Object.create is better for inheritance here than Cat.prototype = new Animal() for two reasons:
If you wanted to require the name parameter (throwing an exception if it wasn't passed), you could do so and the inheritance (Cat.prototype = Object.create(Animal.prototype)) would still work.
If you forgot to call the Cat constructor from the Animal constructor, all of the properties that would have been created by the Animal constructor will be undefined instead, allowing you to quickly realize the mistake.
Although this approach (using constructor functions and new) is less "purely" prototypal, it's still prototypal inheritance and as long as you understand how to use it correctly it works just fine, and requires a little less typing than the Object.create approach.
I wrote some other notes about this in the documentation for my Javascript OO library, simpleoo. (Note: I may be changing the API soon for that library; I'm linking to it mainly because the documentation discusses some of these concepts in more detail.)

Is there a performance penalty associated with methods created in the constructor versus methods created on the prototype?

I can declare methods of an object in two ways:
The first way uses the self=this idiom.
function SelfIdiomExample(name){
var self = this;
self.sayHello = function (name){
alert("Hello, "+name);
}
}
Which is useful when you need a reference to the object in a method (for example if the method will be passed as a callback). The other way is to do it by modifying the prototype:
function PrototypeModExample(){
//pass
}
PrototypeModExample.prototype.sayHello = function(name){
alert("Hello, "+name);
}
Both have the same result:
var sieg = new SelfIdiomExample();
var pmeg = new PrototypeModExample();
sieg.sayHello("Barnaby");
pmeg.sayHello("Josephine");
While I understand the use case for the self=this idiom, I am wondering:
Is there a performance penalty to using the methods created in the constructor versus methods created on the prototype?
Well this here:
var self = this;
Is not something has performance implications at all. It's wicked fast as it's simply accessing a local variable. Even from nested funcitons, this is a very fast operation in JavaScript.
However, methods created in the constructor versus methods created on the prototype has a huge performance difference.
In this example:
var PrototypeModExample = function(){
this.name = "Joe";
};
PrototypeModExample.prototype.sayHello = function(){
alert("Hello, " + this.name);
};
var a = new PrototypeModExample();
var b = new PrototypeModExample();
console.log(a.sayHello === b.sayHello); // true
Every instance of the constructor gets access to the same function objects. Which can be proved by using the === operator to compare the function objects on two instances. It will only return true when they are the same object. So globally we now have 2 instances, but they share one function object for the implementation of the sayHello method. This means that function is already setup and created when you want to make a new instance.
In other words, for all instance obj.sayHello points to the same function object, which was created before any instances existed at all.
But this on the the other hand:
function SelfIdiomExample(name){
var self = this;
this.name = "Joe";
this.sayHello = function(){
alert("Hello, " + self.name);
}
}
var a = new SelfIdiomExample();
var b = new SelfIdiomExample();
console.log(a.sayHello === b.sayHello); // false
Works differently. Now we see that the === comparison is false. That's because a new function object was created for each instance. Creating this function takes time (it needs to be parsed) and memory (this unique version of that function needs to be stored). So when creating lots of these instances, this method will be both slower and consume more memory.
In other words, for all instance obj.sayHello points to a unique function object which was created when the instance itself was created.
So usually, the prototype method is preferred. Especially in cases where a large number of instance might exist, since each instance can share function objects for it's methods.
As always, you have to test in order to answer questions like this: http://jsperf.com/this-vs-self/2.
When you test, there appears to be not much difference (less than few percent with a slight advantage to self in some cases). One advantage to self is that it can be minimized better by changing it to a one character variable name and that is apparently why some frameworks use it.
In your example, I would say that the use of self is extranous and not neccessary. Normally folks only use self when a closure is used and the value of this in some callback is no longer what you want it to be like this:
counter.prototype.incrementWithDelay(delay) {
var self = this;
setTimeout(function() {
self.counter++;
}, delay);
}
But, if you just have a normal method, there is little reason to use self.
counter.prototype.set(val) {
this.counter = val;
}

Categories

Resources