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.
Related
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
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());
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
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);
}
};
}
I have an object that looks like this:
var BigObject = {
'CurrentInt': 0,
'CurrentBool': false,
'CurrentObject': {}
}
And then, I declare SomeObject like this:
var SomeObject = {
'SomeString': "",
'SomeInt': 0
}
These two definitions are for the objects when they're in their initial state, sort of like a type definition I guess. Now I want to assign a new SomeObject to BigObject['CurrentObject']. I tried this:
BigObject['CurrentObject'] = new SomeObject();
But it's not working. At the moment, I just do a straight assignment by reference BigObject['CurrentObject'] = SomeObject; and then when I need to reset the values of SomeObject, I just run a function that redeclares each property of SomeObject in its initial stage.
But how can I use the new keyword to create a reusable object type that's a property of BigObject.
Thanks.
new can only be used with a function, to run it as constructor:
function SomeObject() {
this.SomeString = "";
this.SomeInt = 0;
}
What you have done is equivalent to:
var SomeObject = new Object();
SomeObject.SomeString = "";
SomeObject.SomeInt = 0;
If you're defining a type, you should use a constructor function:
var SomeObject = function() {
this.someString = "";
this.someInt = 0;
}
var BigObject = function() {
this.currentInt = 0;
this.currentBool = false;
this.currentObject = new SomeObject();
}
Once you've defined these constructors, you can new them (create instances):
var myBigObject = new BigObject();
console.log(myBigObject.currentObject);
Use JavaScript classes.
function SomeObject() { }
SomeObject.prototype.someString = "";
SomeObject.prototype.someInt = 0;
function BigObject(){ this.currentObj = new SomeObject; }
BigObject.prototype.currentInt = 0;
BigObject.prototype.currentBool = false;
BigObject.prototype.currentObj = null;
var a = new BigObject;
a.currentObj instanceof SomeObject; // true