panzerdp / dmitripavlutin.com-comments

7 stars 0 forks source link

javascript-this-interview-questions/ #107

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

7 Interview Questions on "this" keyword in JavaScript. Can You Answer Them?

7 interview questions to challenge your knowledge on "this" keyword in JavaScript.

https://dmitripavlutin.com/javascript-this-interview-questions/

kj2whe commented 3 years ago

This was a great article. I loved the format of 'Here is some code. What do you think it will do, expand answer to find out' ..expands answer.. 'Here ya go! Also, here is a demo to prove it!'

Great Job!

panzerdp commented 3 years ago

This was a great article. I loved the format of 'Here is some code. What do you think it will do, expand answer to find out' ..expands answer.. 'Here ya go! Also, here is a demo to prove it!'

Great Job!

Glad you like it @kj2whe!

freaksauce commented 3 years ago

Javascript is so confusing sometimes :D

For Q3 I would do: setTimeout(() => object.logMessage(), 1000);

That will update the scope so that this.message refers to the object instead of window.

panzerdp commented 3 years ago

Javascript is so confusing sometimes :D

For Q3 I would do: setTimeout(() => object.logMessage(), 1000);

That will update the scope so that this.message refers to the object instead of window.

Yes, that would work @freaksauce.

Maybach91 commented 3 years ago

Great article! Thanks you so much! I have one question, since lack of understanding:

Q4 Solution 1:

const object = {
  message: 'Hello, World!'
};

function logMessage() {
  console.log(this.message); // logs 'Hello, World!'
}

Can you explain why/how this is referenced to the object? I thought object.message() would logs it correctly, but hoe does it logs this as well with the this? Shouldn’t this be window? And how did the message() invoked to the window object?

Thanks!

panzerdp commented 3 years ago

Great article! Thanks you so much!

You're welcome @Maybach91!

I have one question, since lack of understanding. [...]

const object = {
  message: 'Hello, World!'
};

function logMessage() {
  console.log(this.message); // logs 'Hello, World!'
}

Just by looking at the logMessage function definition, you cannot determine what is the value of this. The value of this is determined by when and how the function is invoked, specifically by the function invocation context.

In this case, logMessage() function isn't a part of an object. To make this pointing an object you need just use the indirect function invocation. For example, myFunc.call(thisArg) method:

const object = {
  message: 'Hello, World!'
};

function logMessage() {
  console.log(this.message); // logs 'Hello, World!'
}

logMessage.call(object); // logs 'Hello, World!'

logMessage.call(object) performs an indirect invocation of the logMessage on the object, particularly making object to be the invocation context (i.e. the value of this).

(Note: the arrow function is an exception since its this value is resolved lexically)

In this post you will find described the types of how a function can be invoked in JavaScript, and how each type of invocation influences the value of this.

RoxVell commented 3 years ago

Great article, thanks. Can you explain why in the second question the code prints "Fluffy"? "this" is evaluated at runtime, why then is "this" equal to "cat" object at runtime and not "window"?

const { getName } = cat;
console.log(getName());
JacekLab commented 3 years ago

Hi Dimitri! Thanks for the challenge :)

In Q3 getter seems to resolve the issue:

const object = {
  message: 'Hello, World!',

  get logMessage() {
    console.log(this.message); // What is logged?
  }
};
panzerdp commented 3 years ago

Great article, thanks. Can you explain why in the second question the code prints "Fluffy"? "this" is evaluated at runtime, why then is "this" equal to "cat" object at runtime and not "window"?

const { getName } = cat;
console.log(getName());

getName() is an arrow function that resolves this lexically. In other words, it captures the value of this from the outer function where it is defined.

An arrow function doesn't change its this value no matter how it is invoked, contrary to the regular function.

panzerdp commented 3 years ago

Hi Dimitri! Thanks for the challenge :)

In Q3 getter seems to resolve the issue:

const object = {
  message: 'Hello, World!',

  get logMessage() {
    console.log(this.message); // What is logged?
  }
};

@JacekLab Nope, it won't work.

When running your solution 'Hello, World!' is logged right away, but it should be logged with a delay of 1 second.

JacekLab commented 3 years ago

Hmm I didn't notice that... :) How about moving object.logMessage call inside body of a callback function?

setTimeout(function() { object.logMessage }, 1000);
panzerdp commented 3 years ago

Hmm I didn't notice that... :) How about moving object.logMessage call inside body of a callback function?

setTimeout(function() { object.logMessage }, 1000);

@JacekLab In such a case you don't need the getter function. You could simply invoke the method:

const object = {
  message: 'Hello, World!',

  logMessage() {
    console.log(this.message); // What is logged?
  }
};

setTimeout(function() { object.logMessage() }, 1000);
akmaekki commented 3 years ago

Really great article. In general I really like your articles. Somehow not too short or too long, but always well explained and on a personally appropriate level of difficulty.

Fodin commented 3 years ago

Q3. We can use .bind()

setTimeout(object.logMessage.bind(object), 1000);
panzerdp commented 3 years ago

Q3. We can use .bind()

setTimeout(object.logMessage.bind(object), 1000);

@Fodin A good solution! I personally prefer it for such situations.

panzerdp commented 3 years ago

Really great article. In general I really like your articles. Somehow not too short or too long, but always well explained and on a personally appropriate level of difficulty.

Thanks @akmaekki, glad you like my posts!

ottacke1991 commented 3 years ago

I can't get it clearly. Q5. Why farewell function has global scope? For me its looks like farewell is inside "object" and the context of farewell is "object". What is this inside the outer function where the arrow function is defined? I think I miss understood that object is not a function (not every object is a function ), but window is object too. So why we get window context instead of "object"

panzerdp commented 3 years ago

I can't get it clearly. Q5. Why farewell function has global scope? For me its looks like farewell is inside "object" and the context of farewell is "object".

The outer scope of farewell() is the global scope. Also, farewell() is an arrow function that uses this value from the outer scope - which is the global scope where this is the global object.

ottacke1991 commented 3 years ago

I can't get it clearly. Q5. Why farewell function has global scope? For me its looks like farewell is inside "object" and the context of farewell is "object".

The outer scope of farewell() is the global scope. Also, farewell() is an arrow function that uses this value from the outer scope - which is the global scope where this is the global object.

Thank you a lot for answering my question, but I still don't get it. Question. What is this inside the outer function where the arrow function is defined? farewell defined inside object --> const object. So its look like the outer scope is global scope, but this is the enclosing context where the arrow function is defined and arrow function is defined inside --> const object.

panzerdp commented 3 years ago

Thank you a lot for answering my question, but I still don't get it.

Let me rephrase a bit.

"this is the enclosing context where the arrow function is defined" means "this inside of an arrow function equals to this value from the outer scope where the arrow function is defined (global scope in our case)". It has nothing to do with objects, because objects do not create scope, but functions and code blocks create scopes.

In other words, "when determining this value, the arrow function doesn't care to which object it belongs to, it cares only what is this value in the outer scope"

ottacke1991 commented 3 years ago

Thank you a lot for answering my question, but I still don't get it.

Let me rephrase a bit.

"this is the enclosing context where the arrow function is defined" means "this inside of an arrow function equals to this value from the outer scope where the arrow function is defined (global scope in our case)". It has nothing to do with objects, because objects do not create scope, but functions and code blocks create scopes.

In other words, "when determining this value, the arrow function doesn't care to which object it belongs to, it cares only what is this value in the outer scope"

Thank you a lot! Now I clearly get it.

xr280xr commented 3 years ago

I got every one wrong and am more confused than ever

cptntz2119 commented 2 years ago

Thanks for THIS great expalnation on THIS :) For Q3 challenge: setTimeout(object.logMessage.bind(object), 1000); will output "Hello world"

nicole0707 commented 2 years ago

Question 3

setTimeout(() => {
  object.logMessage();
}, 1000)
ashutjha commented 1 year ago

const object = { message: 'Hello, World!', get logMessage() { console.log(this.message); // What is logged? } }; setTimeout(() => object.logMessage, 1000);

poojavirgo commented 1 year ago

const object = { message: 'Hello, World!', logMessage() { console.log(this.message); // What is logged? } }; setTimeout(object.logMessage(), 1000);

gabedavaa commented 1 year ago

3

thanks for challenging const object = { message: 'Hello, World!',

logMessage(message) { this.message = 'Hello, World!',

console.log(this.message); // What is logged?

} };

setTimeout(object.logMessage, 1000);

gabedavaa commented 1 year ago

4;

thanks again

const object = { message: 'Hello, World!',

logMessage() { console.log(this.message); // "Hello, World!" }, };

object.logMessage()

a-xtreme commented 1 year ago

Q6. output is undefined, not 4.

panzerdp commented 1 year ago

Q6. output is undefined, not 4.

No, it's 4. See the demo.

a-xtreme commented 1 year ago

@panzerdp, it is strange if I ran this program :

var length = 4; function callback() { console.log(this.length); // What is logged? }

const object = {
  length: 5,
  method(callback) {
    callback();
  }
};

object.method(callback, 1, 2);

here -> https://www.programiz.com/javascript/online-compiler/

It gives me undefined and on your demo like it is 4.