javascript object pointer to this [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I have an array of classes in javascript, each instance is created passing it the name of an mp3file. the idea is that each instance creates an "invisible" audio element and a div. When you click on the div you here it's audio.
This is a simplified version of the class... Every attempt I have tried to pass a pointer to the appropriate class to the "onclick" function has failed.. "this" obviously fails, the example below fails..
I have provisionally solved the problem by passing the class an "idx" and then to the div.onclick, so it "find's itself", but I am sure there is a more elegant solution of passing the div a reference to the appropriate audio element to play.
function myClass (mp3file) {
this.aud = document.createElement('audio');
this.aud.src = mp3file;
this.div = document.createElement('div');
this.div.className = 'dictDiv';
this.context = this;
this.div.onclick = function () {
context.aud.play();
}
}

var context = this;
this.div.onclick = function () {
context.aud.play();
}
Onclick overrides this, so working with this wouldnt work. You can store it in the scope (see top) or override the this binding:
this.div.onclick=function(){
this.div.appendChild(this.aud);
this.aud.play();
}.bind(this);
document.body.appendChild(this.div);

Related

onmouseenter - Dynamic function variable for each new element [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I'm attaching elements created by Javascript inside a for loop.
What I'm trying to achieve is different variables passed to a function for each element.
Here's my code:
var thumbnail_box = document.createElement("div");
thumbnail_box.onmouseenter = function(){show_new_attachement_toolbar(total_upload)};
thumbnail_box.onmouseleave = function(){hide_new_attachement_toolbar(total_upload)};
the variable total_upload is automatically incremented in the end of each loop, however when all the elements are added, the function only triggers for the final value of total_upload instead of separate value for each element
A simple fix would be to wrap that code in an IIFE:
(function(x) {
var thumbnail_box = document.createElement("div");
thumbnail_box.onmouseenter = function () { show_new_attachement_toolbar(x) };
thumbnail_box.onmouseleave = function () { hide_new_attachement_toolbar(x) };
})(total_upload);
You might need to read this

Prototype method attached to event getting undefined [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I am new in OOP in Javascript, I wanted to have my Slider object with its own attributes and methods. It works fine until I add the Eventlistener with my method slideNextImage. Once this method is triggered every attribute inside the method is undefined. If I launch the method without attaching any event it works good.
function Slider(photos, currentPhoto){ //Constructor
this.photos = photos;
this.currentPhoto = currentPhoto;
}
Slider.prototype.slideNextImage = function () {
document.getElementById("slider").style.backgroundImage = "url(" + this.photos[this.currentPhoto] + ")";
console.log("La foto actual es la " + this.currentPhoto + " y en el almacen hay " + this.photos.length);
}
var photos = ["../imagenes/images/wallpaper_5.jpg", "../imagenes/images/wallpaper_4.jpg", "../imagenes/images/wallpaper_3.jpg", "../imagenes/images/wallpaper_2.jpg", "../imagenes/images/wallpaper_1.jpg"];
var slider = new Slider(photos, 0);
document.getElementById("next").addEventListener("click", slider.slideNextImage);
Thank you in advance.
Thats because 'this' is not bound to the object you really want in this case. (in your case 'this' will be bound to the element on which the event had been triggered)
One way to solve it is by explicitly bind 'this' to the slider by changing the addEventListener line to:
document.getElementById("next").addEventListener("click", Slider.prototype.slideNextImage.bind(slider));
Your method loses its context when called as an event handler (this is no longer your slider object). You have a couple of options, the simplest is to use Function.prototype.bind:
slider.slideNextImage.bind(slider);

jQuery overwriting 'this' in prototype [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
jQuery - trigger not produce the expected result
(1 answer)
Closed 7 years ago.
I have declared a JavaScript object:
function A(name){
this.name=name
}
A.prototype.test=function(){
console.log(this.name);
};
as a simple example I have set up a button that if it's clicked should output a variable to the local console log:
<button id='test'>test</button>
the script:
var t=new A('hello');
$('#test').click(t.test);
when I click the button I want this.name to show (in this case 'hello'), but instead this refers to the clicked button, and not to the object I created.
this is a debugging script of course. In real life I'm binding a function to the window.resize event which will re-build a window on resizing.
There is a JSFiddle that shows the problem.
I have one solution for this, that is declaring the resize (or click function) in the constructor of the object and using an alternative name for this, like so (Here's the JSFiddle):
function A(name){
this.name=name
var self=this;
$("#test").click(function(){
console.log(self.name);
});
}
but I'd rather use a prototype and bind the function in the object's constructor. How can I do this using prototypes?
You can use bind, which will set the value of this ahead of time:
var t=new A('hello');
$('#test').click(t.test.bind(t));

How to instantiate class dynamically [duplicate]

This question already has answers here:
How to execute a JavaScript function when I have its name as a string
(36 answers)
Closed 8 years ago.
I have an array with names of constructors var arr = ['Class1', 'Class2', 'Class3'].
function Class1() {
this.name = 'class1';
}
Is it possible to dynamically create instances of these classes? I mean something like
var class1Object = new arr[0]();
I tried that but it isn't working (Uncaught TypeError: string is not a function).
functions defined in "global" scope are actually created on the window object, so you can do this (as long as the code is in the head of the page, and not scoped to something specific):
function Class1(){
this.name = 'class1';
}
var className = "Class1";
var c1 = new window[className]();
Live example: http://jsfiddle.net/vdf4W/
Previously answered in this post (Google: Dynamic Instantiation In JavaScript)
Dynamic Instantiation In JavaScript

What is the reasoning behind declaring var that = this; in javascript? [duplicate]

This question already has answers here:
What does 'var that = this;' mean in JavaScript?
(6 answers)
Closed 9 years ago.
I came across this many times in a new code base that I'm looking at and was wondering is there is any proper reasoning behind it?
You can use var that = this; is order to keep a reference to current this object, when later this will be pointing to something else.
Example (taken from here):
$('#element').click(function(){
// this is a reference to the element clicked on
var that = this;
$('.elements').each(function(){
// this is a reference to the current element in the loop
// that is still a reference to the element clicked on
});
});
Sometimes the meaning of this in JavaScript changes based on the scope. this inside of a constructor means something different than this inside of a function. Here's a good article about it.
If you want access to "this" outside/inside of the scope of a specific function call where what "this" is may have changed. Just one example I can think of.

Categories

Resources