Prototyping with Javascript Constructors - javascript

Consider the Following Example
var Foo = function(){
this.identity = 'Foo';
};
Foo.prototype.bar = function(){
this.identity = 'bar';
};
var fooInstance = new Foo(),
bar = new fooInstance.bar();
Question
Within bar, how may I obtain the fooInstance variable? Is there a way for a child of Foo to recognize its parent as fooInstance? For example, how could I create a function in bar that would return fooInstance. A slight caveat is that bar must by created using the prototype command and cannot simply be nested in Foo to access any Foo instances that way.
My Ideas and Why They Don't Work
It would be possible to rewrite the functions like so
var Foo = function(){
this.identity = 'Foo';
};
Foo.prototype.createBar = function(){
var parent = this;
function bar(){
this.parent = parent;
this.identity = 'bar';
};
return new bar();
};
var fooInstance = new Foo(),
bar = fooInstance.createBar();
Yet for the purposes of creating easily readable code i would rather not use this approach if not needed.
Further Clarification
Let me put the question in context. I am prototyping on CanvasRenderingContext2D so that all contexts for the canvas element will contain my new method. Lets call that method foo and assume context is a created canvas context. How create a variable like so "new context.foo()" such that the foo function can use the context variable?

If you need to reference the fooInstance object from the bar object, you could use dependency injection like this:
Foo.prototype.bar = function(fooInstance) {
this.identity = 'bar';
this.fooInstance = fooInstance;
};
var fooInstance = new Foo(),
bar = new foo.bar(fooInstance);
You could simplify the creation process by implementing a factory function on Foo.
Foo.prototype.createBar = (function() {
function Bar(parent){
this.parent = parent;
this.identity = 'bar';
};
return function () {
return new Bar(this);
};
})();
var fooInstance = new Foo(),
bar = fooInstance.createBar();

how could I create a function in bar that would return fooInstance
If that function is called as a constructor (with new), you can't really do it. The this keyword, the only reference to the "parent" (the object on which you called the method) is set to the new instance in a constructor invocation. You can get the reference only with a closure, for example by creating the constructor in the parent's constructor function (which doesn't work for you) or by returning the constructor from a closure on the prototype (which you nearly got in the second example):
Foo.prototype.getBarCoonstructor = function() {
var parentFoo = this;
return function Bar() {
// constructor things
// using "parentFoo" reference
};
};
// Usage:
var bar = new (foo.getBarConstructor()) (); // ugly.
Instead of creating new constructors for every call of getBarConstructor, you better should put it outside of the method and put parentFoo as an argument to it. Your idea was already quite good.
function Bar(parent) {
// constructor things, referring "parent"
}
Bar.prototype.… = …;
Foo.prototype.createBar = function() {
return new Bar(this); // passing the Foo instance
};
(#plalx has the same solution, but wrapped in a module closure)

Foo.prototype.bar is simply a function on the prototype Object of Foo. There is no way for that function to know of its 'parent' unless you explicitly define it in its scope chain.
I.e. if you would do
var Foo = function(){
this.identity = 'Foo';
};
var fooInstance = new Foo();
Foo.prototype.bar = function(){
console.log(fooInstance); // retrieve from scope
this.identity = 'bar';
};
bar = new foo.bar();
that would work.

Related

How to access a property on a function?

I am just starting to learn Javascript and was experimenting with functions. I wrote the following thinking that it would work. Is something like this possible or is it just wrong?
function foo() {
console.log(this.language);
}
foo.language = "English";
foo();
It is not possible, because to gain access to this as the current object, you'll need to instantiate the (constructor) function, which is what invoking new will do for you. Accessing this for a reference to the current instance is not only the case in Javascript though; in Java, this also isn't accessible from static context.
What you're looking for is something like:
function Foo(language) {
this.language = language;
}
Foo.prototype.log = function(){
console.log(this.language);
}
var bar = new Foo("English");
bar.log();
You can make a foo object (an instance of foo) using the new keyword. Then set the language property of that instance. If foo has a function to output its language property, then you can invoke that function on your instance to see its language.
function foo() {
this.outputLanguage = function() {
console.log(this.language);
}
}
var f1 = new foo();
f1.language = "English";
var f2 = new foo();
f2.language = "French";
f1.outputLanguage();
f2.outputLanguage();
In this example, we make 2 foo objects, and assign each a different language.
The foo() function is a constructor function. We usually pass the initial values of the instance variables to it, like this:
function foo(language) {
this.language = language;
this.outputLanguage = function() {
console.log(this.language);
}
}
var f1 = new foo("English");
var f2 = new foo("French");
f1.outputLanguage();
f2.outputLanguage();
Javascript only supports prototypal Inheritance. So to assign a property (in your case language is the property) to an Object (in your case foo) you need to use constructor. And by convention constructor are written Initcap.
function Foo(lang){
this.language = lang;
}
Foo.prototype.getLanguage = function(){
return this.language;
}
var lang1 = new Foo('english');
var lang2 = new Foo('bengali');
console.log(lang1.getLanguage()); // english
console.log(lang2.getLanguage()); // bengali
this is available on instance variables, in your case it's named function
function foo() {
console.log(foo.language); //instead of this, use function property
}
foo.language = "English";
foo();
If you want to dive more, checkout my other answer for the same topic

Why can't I assign a function to a variable using prototype?

I keep on trying to assign a function to a variable and I keep getting a message saying foo is not a function. I am not sure why it is saying that. When I invoke the method by itself it works, but when I assign it to a variable it won't work.
Can anyone please help me figure this out? Thank you!!!
Below is my code:
function Test(){
function foo(){
return "foo";
}
this.bar = function () {
var foo = foo();
console.log(foo);
};
}
var test = new Test();
test.bar();
The culprit is this line var foo = foo();. The statement var foo is redeclaring the local foo variable. By the time you try to access it with foo() it has become an undefined variable.
Rename the variable or the function and everything works correctly.
Following code will work. As Now we are not trying to assign same function variable to variable.
The problem is because JavaScript is function scoped. It is failing because this.bar function will try to evaluate foo first and foo is name of variable in this function so interpreter will try to execute the foo but foo is variable in this scope it will not consider foo mentioned above. Hence it fails.
Where as foo1 will work because when interpreter hits the term foo1 it will look for current scope and all parent scopes and it will get it.
function Test(){
function foo1(){
return "foo";
}
this.bar = function () {
var foo = foo1();
console.log(foo);
};
}
var test = new Test();
test.bar();
Error is at this line
var foo = foo();
Your variable foo has the same name as the function, that hides the function outside.
Renaming it will resolve the error.
var foo1 = foo();
There error you're seeing is from this line:
var foo = foo();
When you use var there you are saying that foo is being defined for the current level of scope (this.bar) - meaning it won't bubble up to Test. You can either rename the variable to something else:
var result = foo();
console.log(result);
or just forgo that variable altogether like this:
console.log(foo());
totally your choice.
If you are learning how to create and work with JavaScript objects, you may want to rewrite your code like so:
// This function constructs the object when called with new
function Test(prop) {
// Some arbitrary property
if (typeof prop === "undefined") {
prop = null;
}
this.prop = prop;
}
// The two functions
Test.prototype.foo = function() {
return "foo";
}
Test.prototype.bar = function() {
var foo = this.foo();
console.log(foo);
}
// Create the object and call foo
var test = new Test('p');
test.bar();
All JavaScript objects inherit the properties and methods from their
prototype. Objects created using an object literal, or with new
Object(), inherit from a prototype called Object.prototype. Objects
created with new Date() inherit the Date.prototype. The
Object.prototype is on the top of the prototype chain.
From: http://www.w3schools.com/js/js_object_prototypes.asp

Defining a constructor for a derived class in Javascript

Conventional wisdom is that to simulate OOP in Javascript, we do everything in terms of functions and prototypes:
var fooObject = function () {
//Variables should be defined in the constructor function itself,
//rather than the prototype so that each object will have its own variables
this.someProperty = 5; //Default value
};
//Functions should be defined on the prototype chain so that each object does not
//have its own, separate function methods attached to it for performing the same
//tasks.
fooObject.prototype.doFoo = function () {
//Foo
}
Now, to create a derived class, we do:
var derivedFromFoo = new foo();
But what happens if we want to do some other stuff in our constructor for the derived object? Like set other properties? Can we do something like
var derivedFromFoo = function () {
this = new foo();
};
new foo();
That's an instance, not a class.
To create a derived class, you need to make a new function, call the base ctor from inside of it, then set the new function's prototype to an object created from the base prototype:
function Derived() {
Base.call(this);
}
Derived.prototype = Object.create(Base.prototype);
For more details, and a longer, more-correct implementation, see my blog post.

Closures in auto executing functions vs objects

Let us say I have the following:
var foo = (function(){
var bar = 0;
return {
getBar: function(){
return bar;
},
addOne: function(){
bar++;
},
addRandom: function(rand){
bar += rand;
}
}
})();
And I have the following:
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
}
};
Is the only difference in executing the functions a new?
alert(foo.getBar()); //0
foo.addOne();
foo.addRandom(32);
alert(foo.getBar()); //33
var foo2_obj = new foo2;
alert(foo2_obj.getBar());//0
foo2_obj.addOne();
foo2_obj.addRandom(32);
alert(foo2_obj.getBar());//33
They both out put the exact same thing.
So what is the difference in the long run?
What can one do that the other cannot?
Fiddle Demo of the above: http://jsfiddle.net/maniator/YtBpe/
In the first one you can only create the object once, while with the second one you can create as many objects as you like. I.E. the first one is effectively a singleton.
Note that closures are not ok for the second one. Every time you instantiate it you are creating the functions all over again and waste a ton of memory. The prototype object is intended to counter this, where you can create the functions once outside a function scope and no accidental closures are created.
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
Then:
var a = new foo2, b = new foo2, c = new foo2;
Creates three instances which have their own _bar but share the same functionality.
jsperf
You can "compare" all of this to PHP, some of the code won't even run but it's "equivalent" in principle:
var foo = (function(){
var bar = 0;
return {
getBar: function(){
return bar;
},
addOne: function(){
bar++;
},
addRandom: function(rand){
bar += rand;
}
}
})();
is roughly "equivalent" to this in PHP:
$foo = new stdClass;
$foo->bar = 0;
$foo->getBar = function(){
return $this->bar;
};
$foo->addOne = function(){
$this->bar++;
}
$foo->addRandom = function($rand){
$this->bar += $rand;
}
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
}
};
Is roughly "equivalent" to this in PHP:
Class foo2 {
public function __construct(){
$bar = 0;
$this->getBar = function(){
return $bar;
};
$this->addOne = function(){
$bar++;
};
$this->addRandom = function($rand){
$bar += rand;
};
}
}
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
Is roughly "equivalent" to this in PHP:
Class foo2 {
public $_bar;
public function __construct(){
$this->_bar = 0;
}
public function getBar(){
return $this->_bar;
}
public function addOne(){
$this->_bar++
}
public function addRandom($rand){
$this->_bar += $rand;
}
}
...and is the only one that is close to OOP in the three above examples
The only difference is that foo will be a generic Object, whereas foo2_obj will identify as a foo2 when checking its type (i.e. foo2_obj.constructor == foo2 will be true, while the equivalent on foo is foo.constructor == Object).
Of course, there's an important distinction between foo and foo2 - foo is an object, while foo2 is a function (intended for use as a constructor). Thus, it is trivial to make as many instances of foo2 (of which foo2_obj is one), while the idea of creating "instances" of foo doesn't really make sense - the best you could do are copies (which is more difficult than calling a constructor).
Due to the copying/creating instances distinction, the second approach allows for real OO programming with prototype chains, while the first makes such things much more difficult (and ill-advised).
[1]first,but not important:efficiency
function Foo1() {
var bar = 0;
return {
getBar: function () {
return bar;
}
}
}
var o = Foo1();
o.getBar();
function Foo2() {
var bar = 0;
this.getBar = function () {
return bar;
}
}
var o = new Foo2();
o.getBar();
which is the faster?,look object-literal-vs-new-operate
[2]program pattern:the former has no program pattern,but the latter will benefit form prototypal inheritance.if now we want to add a method named "logBar",
former:
1:extend every Foo1 instance:
o.logBar = function () {
console.log(this.getBar());
}
o.logBar();
bad way!
2:find where Foo1 defined and add:
function Foo1() {
var bar = 0;
return {
getBar: function () {
return bar;
},
logBar:function () {
console.log(this.getBar());
}
}
}
var o = Foo1();
o.logBar = o.logBar();
would you want to go back to do this when you want to add more method ervey time?
latter:
Foo2.prototype.logBar = function () {
console.log(this.getBar());
}
var o = Foo2();
o.logBar = o.logBar();
this would be work fine.
[3] back to efficiency:
in Foo1's way,it product logBar function instance ervey time when a Foo1 instance created.object-literal-vs-new-operate
I think in my personal view of this two types
1- Singleton
2- Object
Let's we say we have one page having their javascript using Object (Second), and
having many utils using singletons (First), and works fine.
But one day we need a new page that call the first page via AJAX, this new page have their javascript using Object (Second) and have the same utils using singleton, but we add some new functions in the utils singletons.
Turns out, the utils singletons in the new page are overriden for the loaded utils singletons in the first page, So when the new page execute some of those new function doesn't exist, generating errors ...
I think this is my point, the singletons are overriden when you have this scenario, and find erros in cases like this are hard.. hard..., diferent from a object that have unique instances
Cheers.
The main difference is actually that foo is an object, whereas foo2 is a function.
That means that you'll not be able to create another object like foo that is not actually foo itself, except if you copy/paste its code.
On the other hand, you can create another foo2 object and manipulate it while using foo2_obj for another purpose.
To make short, foo is an instance while foo2 can bee seen as a class (even if it's just a function constructing an object).
It depends on what you want to do in your program, but I'd surely recommend to use the 2nd form which is allowing to reuse your code by creating other instances.
foo and foo2_obj They are the same. In both cases you have a function that creates a new object, references a variable in closure scope and returns that object.
You have 4 things
anonymous function that is a factory for "foos"
object foo created from anonymous factory
foo2 which is a name factory for "foo2_objs"
object foo2_obj created from foo2 factory
The exact difference between using new and returning function literals from a function is neglible if you don't touch <Function>.prototype
You probably want to compare
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
};
};
To
var Foo = {
addOne: function () { this.bar++; },
addRandom: function (x) { this.bar+=x; }
};
var foo3 = function () {
return Object.create(Foo, { bar: { value: 0 } });
}
foo3 uses prototypical OO. this means you don't have to recreate those functions all the time.
In simple terms if you are creating 10 instances of foo and foo2, the getBar function of foo will exists 10 times in memory and that of foo2 will be only once.
Also, modern browsers like chrome with V8 compiler, it compiles the js to machine code... in that case foo2 will get translated to a native class object and its like a 20 times faster (when you create say 1000 instances in a loop)
I normally uses the simple object method when there is only once instance of that class/module is needed. The structure that I follow is,
var myInstance = function(){
var self = {};
self.bar = null;
self.gerBar = function(){
return self.bar
}
return self;
}();
this is quite similar to the foo approach, but I find this structure more handy.
One other difference (in practical use) that i normally encounter is when I have callback functions or timeouts inside the class,
var foo2 = function(){
this.doSomething = function(){
var temp = this;
$.someAsyncCall(function(){
// 'this' in current scope is the inline function itself, not the class instance
// so have to store the instance ref in a local var in outer scope and then use that to get the class instance
temp.callAfterAsyncCall();
});
};
this.callAfterAsyncCall = function(){
};
};
as you can see the local temp variable is not pretty when you have a lot these cases.
where in the other approach, you always the the self reference everywhere inside the module scope,
var myInstance = function(){
var self = {};
self.doSomething = function(){
$.someAsyncCall(function(){
self.callAfterAsyncCall();
});
}
self.callAfterAsyncCall = function(){
};
return self;
}();
I not sure if its important for you, but just thought worth mentioning.

Is there a name for this particular construct?

In example:
function foo() {
var bar = this.bar = function () {
return "bar";
};
this.mybar = function () {
return bar();
}
}
var myFoo = new foo();
myFoo.bar = function() {
return "notbar";
};
myFoo.bar(); // returns 'notbar'
myFoo.mybar(); // returns "bar"
Basically it allows for an internal private method to a closure, with the possibility of being overwritten only for external access. So the reference to the original function never changes, for references of that function within the closure. But instantiators of the closure object can overwrite that function without breaking the functionality of the object.
Is there a name for this particular construct, and is it even useful?
If you refer to assigning a function to a local variable and using this function in another public method, then yes, this would some form of data encapsulation. Apart from that, I'd say there is not special name for that.
var bar is a variable local to the function and this.bar is a property of the new object. The variable and the property happen to have the same name, but they are not related.
It is only useful if you want to make the function in bar publicly accessible and ensure the correct working of the other function, in case the public bar is overwritten.
So it is some form of protecting the other functions, but it is not a special pattern to allow external overwriting.
If the sole purpose of this.bar is to be overwritten, then you'd achieve the same with:
function foo() {
var bar = function () {
return "bar";
};
this.mybar = function () {
return bar();
}
}
var myFoo = new foo();
myFoo.bar = function() {
return "notbar";
};
myFoo.bar(); // returns 'notbar'
myFoo.mybar(); // returns "bar"
Of course, if you call myFoo.bar() before you assign a function to it, then you will get an error.

Categories