externally setting variables that should be accessible within an object - javascript

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

Related

Javascript function does not return the right value

So i have this code:
function Class1() {
this.i = 1;
var that=this;
function nn() {
return 21;
}
this.aa = function() {
nn();
};
this.bb = function() {
this.aa();
};
this.cc = function() {
this.bb();
};
}
var o = new Class1();
var b=o.cc();
alert(b); //undefined
But when the alert is fired, I get an undefined error and not 21, Does the private method can not use a return? Thanks!
When using the function() {} syntax to define a function, you always explicitly need to return the value, i.e. not only from nn, but from all intermediate functions as well.
function Class1() {
this.i = 1;
var that = this;
function nn() {
return 21;
}
this.aa = function() {
return nn();
}
this.bb = function() {
return this.aa();
}
this.cc = function() {
return this.bb();
}
}
var o = new Class1();
var b = o.cc();
alert(b); // "21"
Apart from the answer above, the 'this' context seems weird in your functions. Maybe you are better of with arrow functions if you dont want to bind the this context to each function. I also think that it is better to actually separate private and public functions when using a 'class' like this.
function Class1() {
var _nn = function () {
return 21;
}
var _aa = function () {
return _nn();
}
var _bb = function () {
return _aa();
}
var cc = function () {
return _bb();
};
return {
cc
};
}
var o = new Class1();
var a = o.cc();
console.log(a);
Much easier to understand that it is only cc that is a public function.
So with arrow function it would instead look like this, and you can use the Class1 this context inside of your private functions without doing
var that = this; or using bind.
function Class1() {
this.privateThing = 'private';
var _nn = () => { return this.privateThing; };
var _aa = () => { return _nn(); };
var _bb = () => { return _aa(); };
var cc = () => { return _bb(); };
return {
cc
};
}

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());

Getting a reference to the object that holds a property that is a constructor

The title is really confusing, I couldn't find a better one.
Suppose I have:
var A = function (){
this.pa = { x: 1 };
};
A.prototype.B = function (){
this.pb = /* a reference to { x: 1 } */;
};
var a = new A ();
var b = new a.B ();
console.log (b.pb.x); //should print 1
a.pa.x = 2;
console.log (b.pb.x); //should print 2
I want to save in pb a reference to the pa object. Is it possible?
A function used as a constructor has only a reference to the new instance, inheriting from its prototype.
To make it maintain a reference to the original A instance, you will need to put the B constructor in a closure:
function A() {
var that = this;
this.pa = { x: 1 };
this.B = function() {
this.pb = that.pa;
};
};
var a = new A ();
var b = new a.B ();
console.log (b.pb.x); // does print 1
a.pa.x = 2;
console.log (b.pb.x); // does print 2
However, this has the disadvantage of creating a new B constructor (with its own prototype object) for every single A instance. Better would be something like
function A() {
this.pa = { x: 1 };
}
A.B = function() {
this.pb = null;
};
A.prototype.makeB = function() {
var b = new A.B();
b.pb = this.pa;
return b;
};
// you can modify the common A.B.prototype as well
var a = new A ();
var b = a.makeB();
console.log (b.pb.x); // does print 1
a.pa.x = 2;
console.log (b.pb.x); // does print 2
Yet, we could mix the two approaches so that you have only one prototype but different constructors:
function A() {
var that = this;
this.pa = { x: 1 };
this.B = function() {
this.pb = that.pa;
};
this.B.prototype = A.Bproto;
}
A.Bproto = {
…
};
var A = function (){
this.pa = { x: 1 };
};
A.prototype.B = function (a){
this.pb = a.pa;
};
var a = new A ();
var b = new a.B(a);
console.log(b.pb.x); //should print 1
a.pa.x = 2;
console.log(b.pb.x);
Well, it's not exactly what I want but it's very close:
var A = function (pa){
this.pa = pa;
};
A.prototype.B = function (a){
if (this instanceof A.prototype.B){
if (!a) throw "error";
this.pb = a.pa;
return;
}
return new A.prototype.B (this);
};
var a = new A ({ x: 1 });
var b = a.B ();
console.log (b.pb.x); //1
a.pa.x = 2;
console.log (b.pb.x); //2
new a.B () //throws "error"

scope of returned object in javascript function

How do I access 'a' below?
var test = function () {
return {
'a' : 1,
'b' : this.a + 1 //doesn't work
};
};
You can't do it this way. When you are in the process of constructing an object (that's what you actually do using the curly braces), there is no way to access it's properties before it is constructed.
var test = function () {
var o = {};
o['a'] = 1;
o['b'] = o['a'] + 1;
return o;
};
var t = function ()
{
return new x();
};
var x = function ()
{
this.a = 1;
this.b = this.a + 1; //works
}
abstract a layer
edited for formatting, and noting that this is shifting from OLN
You can't Object Literal Notion does not support this access
var test = function () {
//private members
var a = 1;
var b = a + 1;
//public interface
return {
geta : function () {
return a;
},
getb : function () {
return b;
}
}
}();

Categories

Resources