Access values of object from within a javascript closure - javascript

I can't get how to access that value, this is my code:
function Filters()
{
this.filters = ["filter_1", "filter_2", "filter_3"];
this.someData = "test";
this.draw = draw;
function draw(){
for(var i=0; i<this.filters.length;i++)
{
var filter = this.filters[i];
$("#" + filter).click(function(){
doSomething();
});
}
}
function doSomething(){
alert(this.someData);
}
}
I am aware of the fact that since doSomething() is called from within the closure, this. will refer a JQuery object being worked on. So how do I go about being able to use someData from my object in that function/closure ? Can't seem to figure it out.
Thanks for help :)

No, this inside doSomething will be the global object. You need to keep a reference to this in a separate variable:
function Filters()
{
var that = this; // reference to this
this.filters = ["filter_1", "filter_2", "filter_3"];
this.someData = "test";
this.draw = draw;
function draw(){
for(var i=0; i<this.filters.length;i++)
{
var filter = this.filters[i];
$("#" + filter).click(function(){
doSomething();
});
}
}
function doSomething(){
alert(that.someData);
}
}
Unrelated to your problem: you could also pass a reference to doSomething as the event listener, instead of wrapping it in another function:
$("#" + filter).click(doSomething);

Related

how to reference a method from within an object

I need to call the object showMe() method from a child object, when debugging the this does not recognize the showMe() method.
How can I reference an object method from within the method ???
code follows -
function myObj(n) {
this.name = n;
this.frame = $('<div />');
var subFrame = $('<div />');
subFrame.on("click", function () {
**//how do I reference this.showName() from here ?**
});
this.frame.append(subFrame);
this.showName = function (nn) {
alert(nn);
};
}
$(function () {
var a = new myObj("Test");
});
A common way to do this is to define var that = this, and refer to that in the function body.
You could also use bind, but then you give up the local scope.
You can actually just pass a reference to the object into on() as data,
function myObj(n) {
this.name = n;
this.frame = $('<div />');
var subFrame = $('<div />');
subFrame.on("click", {myObj : this}, function (e) {
e.data.myObj.showName();
});
this.frame.append(subFrame);
this.showName = function (nn) {
alert(nn);
};
}
$(function () {
var a = new myObj("Test");
});
FIDDLE

Access Object's "this" in another object's foreach function?

function Test(){
this.update = function(entity){
entity.forEach(function(enemy) {
this.checkHit(enemy);
});
}
this.checkHit = function(entity){
console.log("worked!");
}
}
How can I call Test's this.checkHit function, and pass it the current value in the entity's foreach loop?
Current code gives "this.checkHit" is not a function.
If you don't care about old browsers - which seems to be the case since you're using forEach - you could use bind (also I assume that you're doing new Test() somewhere) :
entity.forEach(function (enemy) {
this.checkHit(enemy);
}.bind(this));
Just put this in a normal variable. self is commonly used
function Test(){
var self = this;
this.update = function(entity){
entity.forEach(function(enemy) {
self.checkHit(enemy);
});
}
this.checkHit = function(entity){
console.log("worked!");
}
}

Using jQuery on Object Oriented Javascript files

I'm creating the script files for my Project using Object Orientation and I also use frameworks/widgets like jQuery and Datatables.
The public properties I create on my class, are not accessible from the inner scope of functions that are executed from jQuery code.
Here is a sample:
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
$(document).ready(function(){
alert(this.MyProperty); // MyProperty is undefined at this point
}
};
How can I fix this? Is this the correct way to have a property that can be accessed from every member of a class?
store this :
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
var that=this;
$(document).ready(function(){
// in event handler regardless of jquery this points
// on element which fire event. here this === document,
alert(that.MyProperty); // MyProperty is defined at this point
}
};
That is because this does not point to your class but to the document in that function. You need to store what it points to, when it points to your class:
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
var myClassInstance=this;
$(document).ready(function(){
alert(myClassInstance.MyProperty); // Will contain the property
});
}
$.proxy can help with this,
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
$(document).ready($.proxy(function(){
alert(this.MyProperty);
},this));
};
This is a little different from the others, but a little easier to work with. Keeps the logic of assigning the "this" context outside of the initialize() function itself. Your unique case could nullify this solution from being viable, but thought I'd share anyway.
function MyClass() {
this.MyProperty = '';
$(function(){
this.initialize();
}.call(this));
}
MyClass.prototype.initialize = function () {
alert(this.MyProperty);
}

How to prevent jquery to override "this"

I have the following class in javascript:
function User(aJid){
this.jid = aJid;
this.name = '';
this.uni = '';
this.edad = '';
this.foto = '';
this.avatar = '';
this.initialize2 = function(){
$('#edit_vcards').on('click', '#enviar_vcard', function(){
//alert("enviando...");
console.log(this);
});
};
As you can see I have a method "initialize2" that binds a function to some elements in the DOM. In there I do a console.log(this) which prints the DOM element we binded the method to and not the object that is executing the method initialize2. How can I have access to that object from that function?
Its like if the scope of the function binded is the whole DOM and not the object. Anyway to do what Im trying to do ?
function User(aJid){
this.jid = aJid;
this.name = '';
this.uni = '';
this.edad = '';
this.foto = '';
this.avatar = '';
this.initialize2 = function(){
var that = this; //store a reference to maintain scope
$('#edit_vcards').on('click', '#enviar_vcard', function(){
//alert("enviando...");
console.log(that); //use that variable here
});
};
Try passing the obj this to .on and the inside the handler you can use event.data to access the obj this. See below,
this.initialize2 = function(){
$('#edit_vcards').on('click', '#enviar_vcard', {obj_this: this }, function(){
//alert("enviando...");
console.log(event.data.obj_this); //should be the obj this
});
};
Pass the outer this through event.data:
$('#edit_vcards').on('click', { outerThis: this }, function (event) {
console.log(event.data.outerThis);
});
Nowadays with ES6 it can be even more elegant
$('#edit_vcards').click( () => {
//alert("enviando...");
console.log(this); // all your variables are availabled here
});
or even like that (if you need only one line):
$('#edit_vcards').click( () => console.log(this) );
NOTE: This code cannot be used directly and should be additionally compiled with balel, for example.

jQuery: how to access parent function "this" from inside anonymous function?

...
$.fn.annotateEdit = function(image, note) {
if (note) {
this.note = note;
} else {
var newNote = new Object();
newNote.id = "new";
this.note = newNote;
}
}
...
var mynote = this.note;
form.find(':radio').change(function() {
var vacancy = $(this).attr('value');
mynote.vacancy = vacancy;
});
...
Is it possible to access "this.note" from the change() handler without defining "mynote"?
I use a pattern like this so I can access anything in the enclosing scope:
var that = this;
...
form.find(':radio').change(function () {
that.note.vacancy = $(this).attr('value');
});
I am a fan of this pattern because it makes the code a little more readable. In my opinion, it is clear what it being accessed is part of the enclosing scope (as long as the usage of that is consistent).
Use $.proxy to bind it to a function...
// Returns a function-------v
form.find(':radio').change( $.proxy(function() {
var vacancy = $(this).attr('value');
mynote.vacancy = vacancy;
}, this) );
// ^---- ...that has its "this" value set as this argument.
There is no dedicated language mechanism for it. The common pattern is to store the this in local (closure) variable (often named self or that) of the outer function:
var self = this;
var innerFunction = function() {
self.x = 1;
};
Check this - http://api.jquery.com/bind/ and "Passing event data"
You can do something like this :
form.find(':radio').bind("change", {
context : this
}, function(event){
console.log(event.data.context);
console.log(event.data.context.note);
});
You can bind the context of the parent object like so.
form.find(':radio').change(function(that) {
var vacancy = $(this).attr('value');
that.note.vacancy = vacancy;
}.bind(null,this));

Categories