panzerdp / dmitripavlutin.com-comments

7 stars 0 forks source link

/gentle-explanation-of-this-in-javascript/ #7

Open panzerdp opened 3 years ago

panzerdp commented 3 years ago

Written on 05/08/2016 14:22:00

URL: https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/

dongCode commented 3 years ago

cool

rdwaller commented 3 years ago

Thank you for your well-written and helpful articles.

panzerdp commented 3 years ago

Thank you for your well-written and helpful articles.

You’re welcome @rdwaller!

Gleb-Gaiduk commented 3 years ago

Thank you, perfect article!

phutngo commented 3 years ago

Thank you for writing this guide! I love how thorough and detailed your explanations are! It's perfect!

ottacke1991 commented 3 years ago

Great article! Than you a lot. This is the best explanation I ever read on this theme.

panzerdp commented 3 years ago

Great article! Than you a lot. This is the best explanation I ever read on this theme.

Thanks @ottacke1991!

KirtiMittal777 commented 3 years ago

Best explanation up to now, I have ever read about "this" keyword, Thanks a lot!!

panzerdp commented 3 years ago

Best explanation up to now, I have ever read about "this" keyword, Thanks a lot!!

You're welcome @KirtiMittal777!

arnisdruka commented 3 years ago

Great article, very enjoyable and educational! I think "return" is missing in: Country.prototype.travel = function() { this.traveled = true; }; Shouldn't it be: Country.prototype.travel = function() { return this.traveled = true; };

ecatugy commented 2 years ago

Fantastic explanation, best on the internet, you could use this didactic to explain about Inversion of Control in React, all explanations on the web are not didactic.

gagan-bansal commented 2 years ago

Very informative and well explained article. @Dmitri, how can I buy you a coffee?

Thank you.

vyspiansky commented 2 years ago

Hi! πŸ‘‹ First of all thanks for your great JavaScript articles. Just one question here. Are you sure that sumArguments.name from 7. Arrow function returns "", but not "sumArguments"? I tried this code in my Chrome browser and actually got "sumArguments" instead. [ Demo ]

panzerdp commented 2 years ago

Hi! πŸ‘‹ First of all thanks for your great JavaScript articles. Just one question here. Are you sure that sumArguments.name from 7. Arrow function returns "", but not "sumArguments"? I tried this code in my Chrome browser and actually got "sumArguments" instead. [ Demo ]

You're right. At the time I wrote this post, a few years ago, the browser didn't determine the function name. Now it does.

mugglim commented 2 years ago

I read it so well. Can I translate this into Korean and post it on my personal blog? I will definitely leave the source.

panzerdp commented 2 years ago

@mugglim Sure, feel free to translate.

loulou1994 commented 2 years ago

Great article! It really helped me clear up some misunderstandings I had about 'THIS' context. This makes it two articles I read from your blog and I find it personally beneficial for the beginner progammer that I am.

panzerdp commented 2 years ago

Great article! It really helped me clear up some misunderstandings I had about 'THIS' context. This makes it two articles I read from your blog and I find it personally beneficial for the beginner progammer that I am.

That's great @loulou1994! Good luck learning.

Darshan4114 commented 2 years ago

this is a great article

panzerdp commented 2 years ago

this is a great article

Haha, nice one!

stef-pellegrino commented 2 years ago

This is a brilliant explanation, thanks !!!

panzerdp commented 2 years ago

This is a brilliant explanation, thanks !!!

Thanks @stef-pellegrino!

zaibugemi commented 2 years ago

Learned a good deal about 'this'. Thank you!

Prabhav-Sharma commented 2 years ago

Hii, I have a doubt, In the arrow function, when 'this' is called, we get the value from where the arrow function is defined lexically, meaning if it's defined inside the function, Arrow function's 'this' will refer to the 'this' of enclosing function and it can't be modified later (if my understanding is correct). The doubt is whether the arrow functions creates a closure for 'this'?

RoyiNamir commented 2 years ago

I would've shown also a simplw example and talk about it :

Let o = {a:5 ,b:this.a}

nicole0707 commented 2 years ago

It's really awesome and useful, I am looking forward to coming articles, thanks.

tolerious commented 2 years ago

thiis is best article I have learned about 'this' in JavaScript. Thanks a lot !

panzerdp commented 1 year ago

@zaibugemi @nicole0707 @tolerious Glad you find the post useful!

panzerdp commented 1 year ago

The doubt is whether the arrow functions creates a closure for 'this'?

@Prabhav-Sharma Yes, in a way the arrow function closes over this from the outer function.

angelr1076 commented 1 year ago

This is, hands down, the best article breaking down the use of the 'this' keyword with excellent examples. Kudos!

panzerdp commented 1 year ago

@angelr1076 Glad you find it useful. :)

dad-shoes commented 1 year ago

Absolutely wonderful article! Thank you friend.

panzerdp commented 1 year ago

Absolutely wonderful article! Thank you friend.

@Bills78 You're welcome friend.

petar-i-todorov commented 1 year ago

Been trying to understand this topic for 2 days before I found your blog post. It's amazing and clarified everything except one moment - why when we use this inside an arrow function, it points to the instance of the class instead of undefined?

class MyClass { constructor() { this.message = "Hello"; }

sayHello = () => { console.log(this); //classInstance }; }

const classInstance = new MyClass(); classInstance.sayHello();

First, I thought that since we use an arrow function for the method, this will point to the context above it which is the class scope. But from my understanding of the topic, the class context is undefined so the console.log should have printed undefined. Secondly, I thought that the class itself is a syntactic sugar over the constructor function (I'm not sure about that) so under the hood the code above is being transformed to a code like this:

function FunctionConstructor() { this.message = "Hello"; }

FunctionConstructor.prototype.sayHello = () => { console.log(this); //globalThis };

const obj = new FunctionConstructor(); obj.sayHello();

Based on my understanding that would return (and actually returns) the global object so that's definitely not the case either. Then why the 1st code snippet returns the instance? Does someone have an answer to that to close the last misunderstanding on that topic? Thanks in advance!

petar-i-todorov commented 1 year ago

I found out something interesting. In a class, when we declare a method with the function keyword, it's being added to the prototype of the class:

class MyClass {
  constructor() {
    this.message = "Hello";
  }

  sayHello() {
    console.log(this); //classInstance
  }
}

const classInstance = new MyClass(); 
const classInstance2 = new MyClass(); 
console.log(classInstance.hasOwnProperty("sayHello")); //false since it's a part of their __proto__
console.log(classInstance.sayHello === classInstance2.sayHello); //true, because they both point to the same method which is MyClass.prototype.sayHello

So, in my head it's equivalent (but not exactly since classes behave a little bit differently than the constructor functions) to something like this:

function ConstructorFunction() {
  this.message = "Hello";
}

ConstructorFunction.prototype.sayHello = function () {
  console.log(this);
};

const object1 = new ConstructorFunction();
const object2 = new ConstructorFunction();
console.log(object1.hasOwnProperty("sayHello")); //false for the same reason
console.log(object2.sayHello === object2.sayHello); //true for the same reason

Meanwhile, when we declare a method in that class with an arrow function, a new completely new object (function) is being created in the memory of the PC so the instance' methods point to different functions:

class MyClass {
  constructor() {
    this.message = "Hello";
  }

  sayHello = () => {
    console.log(this); //classInstance
  };
}

const classInstance = new MyClass();
const classInstance2 = new MyClass();
console.log(classInstance.hasOwnProperty("sayHello")); //true since the method is a property of the instance itself, not a part of the __proto__
console.log(classInstance.sayHello === classInstance2.sayHello); //false since the methods of each object point to a different place in the memory 

So it's an equivalent to something like this:

function ConstructorFunction() {
  this.message = "Hello";
  this.sayHello = () => {
    console.log(this);
  };
}

const object1 = new ConstructorFunction(); 
const object2 = new ConstructorFunction();
console.log(object1.hasOwnProperty("sayHello")); //true for the same reason
console.log(object1.sayHello === object2.sayHello); //false for the same reason

And since the outer scope of the arrow function in this case is the constructor function, "this" inside it will act the same way like the constructor function which means that it's context will be the newly created objects.

Again, I'm a newbie (been using JS for ~6 months) and might be completely wrong but that's how I'm going to remember these things.

uyquoc commented 1 year ago

Very clear explanation, awesome! Thank you very much. I have a question, what if function invocation on the event of element. For example:

function onLoad(params) {
    const btn = document.getElementById("btn");
    function myThis() {
        console.log(this); // this == btn
    }
    btn.addEventListener('click', myThis);
}

It seems implementation of addEventListener changes the binding context of its handler, right?

taewookim02 commented 1 year ago

Thank you very much for clarifying what this is! :)

panzerdp commented 1 year ago

It seems implementation of addEventListener changes the binding context of its handler, right?

@uyquoc Yes, DOM invokes the event listener with the target element as being this.

panzerdp commented 1 year ago

@taewookim02 You're welcome!

panzerdp commented 1 year ago

And since the outer scope of the arrow function in this case is the constructor function, "this" inside it will act the same way like the constructor function which means that it's context will be the newly created objects.

@petardotjs Yes, the mental model you described is correct.

Mugabe000 commented 1 year ago

Thank you! very much for this article.

an4s911 commented 1 year ago

Hi! πŸ‘‹ First of all thanks for your great JavaScript articles. Just one question here. Are you sure that sumArguments.name from 7. Arrow function returns "", but not "sumArguments"? I tried this code in my Chrome browser and actually got "sumArguments" instead. [ Demo ]

When I run the demo linked this is the output I get:

"undefined"
16
""
""
yogeshdnumb commented 1 year ago

Thank you so much this was very useful

hitesh-pathak commented 11 months ago

Thanks a lot! I can see the time you put into creating such a helpful resource. Again thanks, and I appreciate the hard work :)

AngeloThys commented 11 months ago

Another nice recommendation of The Odin Project :rocket: Beautiful article, very complete and thorough.


Sidenote

If I could make a small adjustment it would be in chapter 3.1. this in a method invocation. I believe saying that "this is the object that owns the method" makes it seem as if this refers to the object containing the method rather than the object on which this is called, which is rather confusing, in my opinion stating "this is the object that the method has been called on" seems more correct.

Inquisitive-Rishi commented 11 months ago

This was a really long article and took me 3 days to finish but definately worth it. It would save me hours and hours of future headaches

Adexyme commented 9 months ago

Thanks a million. This is the best material on this subject that i have seen. Thanks

porobertdev commented 8 months ago

Everyone said pretty much all there is to say, but I just wanna say it here too. Thank you so much! :)

I think this can save a lot of time in the future. We might forget some info later on, but we know there's this haha :D

zerone0x commented 6 months ago

So long can't read it for once, I'll come back:/

odilson-dev commented 6 months ago

Thank you mate!