Private var inside Javascript literal object - javascript

How can I declare a private var inside a literal object? Becasuse I've this code:
var foo = {
self: null,
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
}
This works perfectly, but if I have some objects, the var "self" it will override.. apparently it's a global var.. and I cannot use the restricted word "var" inside this object..
How can I solve this, or make an NameSpace for each object?
Thanks!

You can create a function scope to hide the variable:
var foo = (function() {
var self = null
return {
init: ...,
doStuff: ...
};
})();
Though it is not clear what self is supposed to do here, and how foo is used.

You have to use this:
init: function() {
this.self = this;
this.self.doStuff();
},
edit However, it's still a property of the "foo" object, and it's not super-clear where you're getting instances of "foo" from. In other words, the way your code is written, there's only one object.
Alternatively, you could create your object with a closure:
var foo = function() {
var self = null;
return {
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
};
}();

You are not even using the property that you have created. Instead you create another global variable with the same name. Use the this keyword to access properties:
var foo = {
self: null,
init: function() {
this.self = this;
this.self.doStuff();
},
doStuff: function() {
//stuff here
}
}
(Although saving this in a property is truly pointless...)
If you want a local variable in the object, create a closure for it:
var foo = (function(){
var self = null;
return {
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
};
}());

Related

Assign an element to a variable

I have an Javascript object following the Module Pattern
var foo = (function() {
var obj = (function() {
var $button = $('#myButton');
var init = function() {
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();
If I call foo.obj.init(), the button should be hidden, and this does not occur.
I saw different questions here about the assignment of an element to a variable, but I think that the problem is with the object. Can't I access a private variable from a public method?
From my comment:
Do it as part of init... you can just declare the var in order to isolate the scope, and then modify it to actually set the button as part of init
Example:
var foo = (function() {
var obj = (function() {
var $button; //$('#myButton');
var init = function() {
if (typeof $button === 'undefined') {
// i would probably make the selector an argument to `init`
// if i were you.
$button = $('#myButton');
}
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();

var self=this multiple times in methods defined on the prototype?

If you have to use var self=this for methods on the prototype object. Will you write var self=this inside each method?
Is there any way to avoid writing var self =this inside all methods?
function Test () {
}
Test.prototype.method1 = function () {
var self = this;
};
Test.prototype.method2 = function () {
var self = this;
};
You only need to create an alias for the this context if you are going to be introducing new contexts with function literals that still need to access the class's this context.
function Test () {}
Test.prototype.method1 = function () {
// This is fine.
this.someProperty = 123;
this.doSomething();
};
Test.prototype.method2 = function () {
var self = this;
var callback = function() {
// The `this` here is no longer the same `this` as outside the function.
self.someProperty = 456;
};
var anotherCallback = function() {
// No reference to the class's `this` needed here.
alert('Boo');
};
this.doAsyncThing(callback);
};
Alternatively, you can use Function.prototype.bind to force a this context:
var callback = function() {
this.someProperty = 456;
}.bind(this);

Javascript "this" scope

I am writing some JavaScript code. I am a little confused about this keyword. How do I access logger variable in the dataReceivedHandler function?
MyClass: {
logger: null,
init: function() {
logger = LogFactory.getLogger();
},
loadData: function() {
var dataReceivedHandler = function() {
// how to access the logger variable here?
}
// more stuff
}
};
You can do something like this inside the loadData function to access your object...
MyClass: {
logger: null,
init: function() {
this.logger = LogFactory.getLogger();
},
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
// how to access the logger variable here?
self.logger.log('something');
}
// more stuff
}
};
Assuming loadData is called like so:
MyClass.loadData();
then:
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
self.logger ...
}
// more stuff
}
Because dataReceivedHandler is an anonymous function this will refer to the window object on the global scope. I think of two way you can bypass that.
a) Create a variable inside loadData to hold it's context then use it inside dataReceivedHandler as such:
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
console.log(self.logger);
}
// more stuff
}
b) Change the context of your anonymous function using apply or call.
loadData: function() {
var dataReceivedHandler = function() {
console.log(this.logger);
}
// more stuff
dataReceivedHandler.call(this); // by passing this as the first argument we make sure the context of the excuted function is our current scope's this
}
I prefer option B due to performance and memory usage optimizations, but both would work just fine.

Referencing "private methods" in a closure

var Foo = (function () {
var foo = function() { };
var privateMethod = function(){ };
foo.prototype = {
init: function() {
console.log(this.privateMethod); //undefined
}
};
return foo;
})();
I know that I can access privateMethod directly without using the this pointer. But since I come from the c# world, I would like to use it for readability purposes.
Is there any way to reference my "private methods" using a pointer?
You can't. You can only use this to refer to "public" methods. If you really want to use a something.method notation, you could use:
var Foo = (function () {
var foo = function() { };
var private = {
privateMethod : function(){ };
}
foo.prototype = {
init: function() {
console.log(private.privateMethod);
}
};
return foo;
})();
privateMethod is not specific to each instance of foo. Just reference it without the this. qualifier—although you probably want to log the results of a function call, not the function itself:
console.log(privateMethod());

Using variables in JQuery functions

I've got a simple question about accessing variables in jQuery. Is there are way to access the variable (wrap) when I call the read function on click of 'a'.
(function() {
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();
There are a few ways to accomplish this. Perhaps the easiest is to change the scope of the 'wrap' variable. Currently, since it's declared with a var inside the init function, it's scoped to the init function and not available outside of init directly. So, you can declare the 'wrap' outside the init (it could be a property of the 'Example' object):
var Example= {
wrap: 'hello world',
init: function() {
var self = this;
$('a').click(function(){
self.read();
});
},
read: function() {
console.log(this.wrap);
}
};
​Exa​mple.init();
This makes 'wrap' scoped to 'Example' and available as a property of 'Example' throughout any function defined within 'Example'.
(Edit: had to tweak this a bit to properly handle the closure.)
(function() {
var wrap;
var Example= {
init: function() {
wrap = 'hello world';
$('a').on('click', this.read);
...
Because functions have access to all variables visible from their definition scope.
(function() {
var Example= {
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(this.wrap)
}
};
Example.init();
})();
try this: (Fiddle: http://jsfiddle.net/jRJFQ/3/)
(function(){
var Example= {
wrap:null,
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(Example.wrap)
}
};
Example.init();
}​)();​
If you consider using the revealing module pattern you can define which variables are private and which are public like this:
var Example = (function(){
var wrap = 'hello world',
init = function(){
...
},
read = function(){
... // You can use `wrap` here
};
return { // Return public variables and methods
init: init,
read: read
};
})();
Example.init();
yup this should do it:
(function() {
var wrap;
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();

Categories