Javascript sub prototyping - javascript

I have a question about sub-prototyping.
As example I want to do something like:
var Foo = function() { this.Bar.prototype.Foo = this.Baz.prototype.Foo = this };
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };
Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.is = "bar";
Foo.prototype.Bar.prototype.Iam = function() { return this.Foo.is + this.is };
Foo.prototype.Baz = function() {};
Foo.prototype.Baz.prototype.is = "baz";
Foo.prototype.Baz.prototype.Iam = function() { return this.Foo.is + this.is };
var foo = new Foo();
var bar = new foo.Bar();
var baz = new foo.Baz();
console.log(foo.Iam()); // output: foo
console.log(bar.Iam()); // output: foobar
console.log(baz.Iam()); // output: foobaz
To access the Foo-object within Bar and Baz I extend the prototype of Bar and Baz with this.Bar.prototype.Foo = this.Baz.prototype.Foo = this.
My question is if there exists an easier way to do that and to access the main object Foo within Bar and Baz, or is this the common way to do that? The reason I want to do that is to create one main object var x = new Foo() and all sub objects can access the main object.

I haven't seen sub-prototyping using much. I found only this way:
var Foo = function() {};
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };
Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.foo = new Foo();
Foo.prototype.Bar.prototype.is = "bar";
Foo.prototype.Bar.prototype.Iam = function() { return this.foo.is + this.is };
Foo.prototype.Baz = function() {};
Foo.prototype.Baz.prototype.foo = new Foo();
Foo.prototype.Baz.prototype.is = "baz";
Foo.prototype.Baz.prototype.Iam = function() { return this.foo.is + this.is };
var foo = new Foo();
var bar = new foo.Bar();
var baz = new foo.Baz();
console.log(foo.Iam()); // output: foo
console.log(bar.Iam()); // output: foobar
console.log(baz.Iam()); // output: foobaz

Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.foo = new Foo();
yes, this is exactly what I found most times, but if I go this way then changes to Foo() are lost.
In my example above I am able to set "global" parameters to Foo() that are accessable from Bar() and Baz(). Example:
var extend = function(a, b) {
var n;
for (n in b) {
a[n] = b[n];
}
};
var Foo = function(o) {
extend(this, o);
this.Bar.prototype.Foo = this.Baz.prototype.Foo = this;
};
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };
Foo.prototype.greeting = "hello, I am";
Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.is = "bar";
Foo.prototype.Bar.prototype.Iam = function() { return this.Foo.greeting +" "+ this.Foo.is + this.is };
Foo.prototype.Baz = function() {};
Foo.prototype.Baz.prototype.is = "baz";
Foo.prototype.Baz.prototype.Iam = function() { return this.Foo.is + this.is };
var foo = new Foo({ greeting: "hi my friend, I am" });
var bar = new foo.Bar();
console.log(bar.Iam());
//output is: hi my friend, I am foobar
I set the greeting to Foo() that is accessable from all sub functions. The reason to go this was is that there exists different "global" parameters of an object. If a "global" parameter is changed on Foo(), then it should affect Bar() and Baz().
I don't really know if this is the right way to go, because I just started to learn Javascript. I am open to new ideas.
Regards,
Jonny

Maybe here is what you are looking for:
var extend = function(a, b) {
var n;
for (n in b) {
a[n] = b[n];
}
};
var Foo = function(o) {
extend(this, o);
var foo = this;
this.Bar = function() {};
this.Bar.prototype.is = "bar";
this.Bar.prototype.Iam = function() { return foo.is + this.is };
this.Baz = function() {};
this.Baz.prototype.is = "baz";
this.Baz.prototype.Iam = function() { return foo.is + this.is };
};
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };
var foo = new Foo({ is: "foo2" });
var bar = new foo.Bar();
var baz = new foo.Baz();
console.log(foo.Iam()); // output: foo2
console.log(bar.Iam()); // output: foo2bar
console.log(baz.Iam()); // output: foo2baz

There is only one instance of Foo so you can declare foo as an object literal:
var foo = {
is:"foo",
Iam:function(){return this.is}
};
foo.Bar = function() {};
foo.Bar.prototype.is = "bar";
foo.Baz = function() {};
foo.Baz.prototype.is = "baz";
foo.Bar.prototype.Iam = foo.Baz.prototype.Iam
= function() { return foo.is + this.is };
var bar = new foo.Bar();
var baz = new foo.Baz();
console.log(foo.Iam()); // output: foo
console.log(bar.Iam()); // output: foobar
console.log(baz.Iam()); // output: foobaz

Related

How can I reference the parent object in a child function?

Given an object like this:
var MyObj = {
bar: 10,
foo: function() {
alert(MyObj.bar);
}
}
How can I generically reference MyObj from MyObj.foo such that if I were to change var MyObj to var MyObj2 I wouldn't need to modify the foo function?
If you want to treat MyObj like a class, you could do something like what lumio suggested, or you could do something like
function MyObj(){
this.bar = 10;
this.foo = function(){
return this.bar;
}
}
var a = new MyObj();
var b = new MyObj();
b.bar = 5;
console.log(a.foo(), b.foo()) // 10 5
If instead, you just want to reference the object's bar value, then you could just replace the alert(MyObj.bar); with alert(this.bar);
Classes would help you a lot here. In ES5 classes can be created like so:
function MyObj() {
this.bar = 10;
}
MyObj.prototype.foo = function() {
console.log( this.bar );
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
ES6 allows an even better notation:
class MyObj {
constructor() {
this.bar = 10;
}
foo() {
console.log( this.bar );
}
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
Use babel to convert it to ES5.

javascript access "this" in function constructor

I'm trying to create a function constructor:
var obj = function() {
this.num = 2;
this.func = function() {
// need to access the **instance** num variable here
};
};
var instance = new obj();
I need to access the instance properties from a propery (which is the function func) of the object. But it doesn't work, since this is always the current function..
Store this in a variable which func can access:
var obj = function() {
var _this = this;
_this.num = 2;
_this.func = function() {
console.log(_this.num);
};
};
Please, use well-known approach, store this into separate field:
var obj = function() {
self = this;
self.num = 2;
self.func = function() {
alert(self.num);
// need to access the **instance** num variable here
};
};
var instance = new obj();
This is the pattern I use for the problem:
var obj = function(){
var self = this;
this.num = 2;
this.func = function() {
console.info(self.num);
};
};
var instance = new obj();
The variable self now can be accessed in all function of obj and is always the obj itself.
This is the same then:
var obj = function(){
var self = this;
self.num = 2;
self.func = function() {
console.info(self.num);
};
};
var instance = new obj();
You can do it using the Custom Constructor Functions, used to create a custom constructor and it's accessed without any problem, try it:
var Obj = function () {
this.num = 2;
this.func = function () {
alert("I have " + this.num);
return "I have " + this.num;
};
};
var instance= new Obj();
instance.func();//will return and show I have 2

What is the best way to access to "this" inside a sub object in javascript class?

This doesn't work because f.bar.bar() in undefined.
var myFunction = function(foo){
this.foo = foo;
this.bar = {
bar: function(){
return this.foo;
}
}
}
var f = new myFunction('foo');
alert(f.bar.bar());
You can always declare a variable in the parent scope:
var myFunction = function(foo){
var func = this;
this.foo = foo;
this.bar = {
bar: function(){
return func.foo;
}
}
}
var f = new myFunction('foo');
alert(f.bar.bar());

How to reference proprerty from sub objects with "this" keyword

i have to call a property in "object1" from sub object "object3", but this example doesn't work because the "this" keyword is referenced in "object2" and not "object1", do you know how to do this ?
function object1() {
this.a = "hello world";
this.object2 = function() {
this.object3 = function() {
alert(this.a); //prints "undefined"
}
};
}
try this example with:
var obj1 = new object1();
var obj2 = new obj1.object2();
obj2.object3();
thank you in advance :-)
function object1() {
this.a = "hello world";
var self = this;
this.object2 = function () {
this.object3 = function () {
alert(self.a); //prints "undefined"
}
};
}
var obj1 = new object1();
var obj2 = new obj1.object2();
obj2.object3();
You have to store the this object, otherwise you will be accessing the this of the function this.object3's scope
this changes as scope changes. You need to save a reference of this for any new scope:
function object1 () {
var first_scope = this;
this.a = "hello world";
this.object2 = function() {
var second_scope = this;
this.object3 = function() {
var third_scope = this;
alert(first_scope.a);
}
};
}

externally setting variables that should be accessible within an object

Ok, so I know through closure I can do something like this:
var x,
obj = {
init: function() {
x = 123;
},
func: function() {
return x;
}
};
obj.init();
obj.func();
==> 123
However, I would like to externally be able to apply values for x (outside of the object, and later on)... I thought that perhaps I could just do:
var obj = {
init: function() {
// do something nice here...
},
func: function() {
return x;
}
};
var foo = {
doIt: function() {
var init = obj.init;
var x;
obj.init = function() {
x = 456;
init.apply(obj);
}
obj.init();
obj.func();
}
};
foo.doIt();
==> (error) x is not defined
However, it doesn't work.. Is this possible to do somehow?
Thanks.
You could create objects of your type using the new operator, and set the property on that object.
function Foo() {
this.init = function() {
this.x = -1;
};
this.func = function() {
return this.x;
};
}
var o = new Foo;
o.x = 941;
o.func(); // 941
o.x = 22;
o.func(); // 22

Categories

Resources