Deep JavaScript Foundations, v3

this & prototypes Q&A

Kyle Simpson

Kyle Simpson

You Don't Know JS
Deep JavaScript Foundations, v3

Check out a free preview of the full Deep JavaScript Foundations, v3 course

The "this & prototypes Q&A" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle discusses binding, arrow function scope, setting dunder proto, and super.


Transcript from the "this & prototypes Q&A" Lesson

>> Speaker 2: If function is already bound using bind can be rebound to a different object later.
>> Kyle Simpson: Okay, so in our this discussion a bit earlier in this unit, we talked about the idea that a function that is not yet bound, you can call that bind on it and produces a so called hardbound function, all right?

That hardbound function is fixed to the context that you said to bind it to, and there's only one possible way to override that binding. You cannot call .bind on it again, but you could invoke it with a new key word, which would have the effect of overriding its this behavior to be a newly constructed object.

So the answer to that question is only via the new keyword. You cannot recall.bind and rebind it somewhere else.
>> Speaker 2: If you define a variable inside an arrow function, is that variable scoped to the arrow function or to the parent scope?
>> Kyle Simpson: Good question. Arrow functions do have lexical scope.

They just don't have this keyword. I've seen actually a number of places where people say that arrow functions don't have scope. They absolutely have scope. They are lexical just like any other function. So if you define a variable inside of an arrow function it's exactly like defining any other variable in any other kind of function.

The only difference between those two, really, is the difference of regular functions define a this keyword, and arrow functions don't define a this keyword.
>> Speaker 2: In the case of the this were callback, does the value of this depend upon how the higher order function calls the callback?
>> Kyle Simpson: Yes, the call site is the only thing that matters.

So if you pass a function into say .map, how .map invokes your callback is the only thing that determines its this binding. Unless you have passed in a hardbound function, in which case, your hard binding has taking precedence. But .map internally, you can think of it as calling CB open closed parentheses or something like that.

That call site isn't binding of this. So yes, absolutely your high order functions, your or filter, all those, those all absolutely have this nuance or this quirk to it that how they invoke your function entirely determines what the this context will be.
>> Speaker 2: What happens when you set dunder proto?

>> Kyle Simpson: Good question. It is not very common for you to use the Dunder Proto as a setter. It is technically both a getter and a setter. It is almost always used just to reference it. And I would say generally speaking, it's sort of an anti-pattern to rewire the prototype chain of an object.

But as of ES6, dunder proto is officially also something that can set the proto linkage from one object to a different object. So if you have an object A that's linked over here and then later you decide, I want that object prototype linked over here, you can use dunder proto as a setter to change it.

And there's also a utility or an API version of that called object.setPrototypeOf. Which will allow you to take any any object and rewire it. I would say 0.001% of the time do you ever see anybody rewiring prototype chains, but yes, you absolutely can do them and it might in fact be very powerful and useful in certain circumstances.

>> Speaker 2: Do the prototype objects, the squares come pre-installed with every function?
>> Kyle Simpson: So the question is. In the diagram that I was drawing, where we drew a circle for a function. And then we drew a square over here, which was its dot prototype. Regular functions have dot prototypes, arrow functions do not.

So if we have a regular function, it's a declaration, it's an expression, it's anonymous, its name. All of those are always gonna have a square. But if you make an arrow function it's not gonna have a prototype, which is why by the way when you call new on it, it fails.

Because it is not a constructor. It doesn't have a prototype so it can't be constructed with the new keyword.
>> Speaker 3: It just a side question because you said use the keyword super also. Can it be used as a prototype too?
>> Kyle Simpson: Good question. So the super keyword, is able to used outside of classes, when you're dealing with objects and their methods.

So you could go and take one object and wire it up to another object with the prototype linkage. We're gonna look at that pattern in a bit. The idea of making objects that are linked without classes. And you could use technically a super inside one of those methods to refer to something of the prototype chain.

The caveat is that the super keyword is not dynamically bound, it is statically bound which means to use that you actually have to create an object literal with the method in it, and it has to at that moment be linked to the object. So in other words, you won't be able to take one object, change its prototype, and magically have super refer to the other one.

It is statically bound the first time it's created to wherever it's linked. But yes, you can use super inside of object literals as long as they are the concise method form.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now