This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 25 days ago.
So I am trying to understand the this keyword in javascript and inner functions. and I have an inner function with the this keyword but it is returning "my hobby is undefined".
How can I make it return "my hobby is programming"
Here is what I tried and it did not work:
function practice() {
function close() {
console.log(`my hobby is ${this.hobby}`)
}
return close()
}
let person = {
hobby: "programming"
}
let binding = practice.bind(person)
console.log(binding())
You inner function should be an arrow function because a normal one overwrites the this context :
function practice() {
const close = () => {
return `my hobby is ${ this.hobby }`
}
return close()
}
let person = {
hobby: "programming"
}
let binding = practice.bind(person)
console.log(binding())
Hope it helped you !
So you would need to bind the data to the inner function inside the function as well as binding them to the outer one. See below:
function practice() {
function close() {
console.log(`my hobby is ${this.hobby}`)
}
let binding2 = close.bind(this)
return binding2()
}
let person = {
hobby: "programming"
}
let binding = practice.bind(person)
binding()
Related
This question already has answers here:
Referencing "this" inside setInterval/setTimeout within object prototype methods [duplicate]
(2 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 5 years ago.
This question is from an written test for a company. It looks very confusing. I thought it will print whatever this.name is set to. Bu when I typed the code it shows nothing. I have little knowledge about closures and I think it is related to the problem. I want a little explanation here.
function dd(name) {
this.name = name;
this.go = function() {
setInterval(function() {
return this.name;
}, 2000)
}
}
var tt = new dd("corolla");
tt.go()
You can't get the return value from setInterval in this way. Try with a callback as in the following snippet
function dd(name)
{
this.name=name;
console.log( name );
var _this = this;
this.go=function(cb)
{
setInterval(function() {
cb(_this.name);
},1000)
}
}
var tt=new dd("corolla");
tt.go(function(ret) {
console.log( ret );
})
Also, please note that inside setInteval the value of this is not the same as in the otter function. That's why var _this=this;
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
My createCon function uses this to set the con for this object. I am getting this to be undefined. Error: Can not set property of 'con' of undefined.
What is the best of being able to reference this from the objects functions?
class parent {
constructor(stringA, stringB){
this.config = {};
this.con = {};
}
}
class child extends parent {
constructor(stringA, stringB) {
super(stringA,stringB)
this.config = {
full : stringA+stringB
}
}
createConn(){
var con = con(this.config.full);
con.connect(function(err){
if(!err) this.con = con;
})
}
}
You are using the this keyword inside of a function. this is not like other OOP languages and refers to a 'context', which can change based on the execution of the function.
You want to use an arrow function, which will lexically bind (i.e, preserve) the this of the context where the arrow function is defined.
createConn(){
var con = con(this.config.full);
con.connect((err) => {
if(!err) this.con = con;
})
}
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I have the following code (simplified)
var Page = new UI('page.html');
Page.onLoad = function(html){
this.name = 'Page 1';
Util.test(this.run);
};
Page.run = function(){
console.log(this.name); // undefined
console.log(Page.name); // correct
};
var Util = function(){};
Util.prototype.test = function(callback){
// when finished run the callback
callback();
};
My question is why I can't use the this keyword if the execution leaves the object then comes back? Please explain what should I change to be able to access this again.
You can bind "this" to function run, like this.
Page.onLoad = function(html){
this.name = 'Page 1';
Util.test(this.run.bind(this));
};
You can find more information for function "bind". https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
The top of the article references another post regarding 'this', so, I thought I'd just provide the code. If you read the other post and the articles linked within, you should be able to follow this code.
function UI(html) {
this.name = html;
}
UI.prototype = {
onLoad: function () {
util.test(this);
},
run: function () {
console.log(this.name);
}
}
var util = (function () {
return {
test: function (ui) {
if (ui && ui.run) {
ui.run();
}
}
}
})();
var page = new UI("index.html");
This question already has answers here:
Pass correct "this" context to setTimeout callback?
(6 answers)
Closed 6 years ago.
In this example
class Car {
describe() {
console.log("I have " + this.wheels);
}
testMe() {
setTimeout( this.describe, 1000);
}
constructor(wheels) {
this.wheels = wheels;
}
}
let myCar = new Car(4);
myCar.testMe(); // I have undefined
How come the expected value of this isn't passed inside the describe function ?
edit : Can you confirm that is setTimeout was an arrow function, I wouldn't get undefined ?
A bare function reference has no context, even if it was retrieved as a property of an object.
Within your testMe function you need either:
setTimeout(() => this.describe(), 1000);
or
setTimeout(this.describe.bind(this), 1000);
or
let self = this;
setTimeout(function() {
self.describe();
}, 1000);
That last one could be written as an arrow function, of course, but if you're doing that you might as well use the first version, with no local copy of this required.
Regarding your edit, it is possible to pass just this.describe by making describe an arrow function, assigned from inside the constructor, but note that this then means that every instance of the object would have its own copy of that function instead of there just being a single copy on the prototype of the class:
constructor(wheels) {
this.wheels = wheels;
this.describe = () => {
console.log("I have " + this.wheels);
}
}
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
When test.testHello(helloWorld.sayHello); runs, it doesn't recognize that I have inserted a new greeting is the greeting is undefined. I can use bind to make sure it runs it in the proper scope, I am not really sure why isn't it running in the proper scope to begin with. Could someone explain why this is happening and show me a better solution?
Solution: test.testHello(helloWorld.sayHello.bind(helloWorld));
http://jsfiddle.net/EzabX/
var HelloWorldClass = function() {
this.greetings = [];
}
HelloWorldClass.prototype.addGreeting = function(greeting) {
this.greetings.push(greeting);
}
HelloWorldClass.prototype.sayHello = function() {
document.getElementById('output').innerHTML += this.greetings;
this.greetings.forEach(function(greeting) {
greeting.execute();
})
}
var TestClass = function() {
this.testHello = function(callback) {
alert("TestHello is working, now callback");
callback();
}
}
var main = function() {
var helloWorld = new HelloWorldClass();
var test = new TestClass();
helloWorld.addGreeting({
execute: function() {
alert("Konichiwa!");
}
});
helloWorld.sayHello();
test.testHello(helloWorld.sayHello);
}
main();
Managing the this variable within the prototype function scope when called as a callback can be complicated for novice users. You don't always need a prototype for all functions on a class. If you really want to use a prototype function look at Javascript .bind(this) implementations. Google and Stackoverflow are your friend on that topic. Example: Preserving a reference to "this" in JavaScript prototype functions
Offending code with this referring to DOM Window object and not a HelloWorld instance:
this.greetings.forEach(function(greeting) {
greeting.execute();
})
A non-prototype version that works just great, easy to use. Fiddle: http://jsfiddle.net/EzabX/2/
var HelloWorldClass = function() {
var greetings = [];
this.greetings = greetings;
this.addGreeting = function(greeting) {
greetings.push(greeting);
};
this.sayHello = function() {
document.getElementById('output').innerHTML += greetings;
greetings.forEach(function(greeting) {
greeting.execute();
})
}; }