Check out a free preview of the full Advanced JavaScript course:
The "Binding Confusion" Lesson is part of the full, Advanced JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Attempting to force the "this" keyword into a different lexical scope can lead to some binding confusion. Kyle pulls an example he found on Stack Overflow around this confusion to further demystify usage of the "this" keyword.

Get Unlimited Access Now

Transcript from the "Binding Confusion" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Kyle Simpson: So I want to take just a little detour here and talk about some binding confusions. And I'm not just making this up, this is actually, this is fake code, but this is distilled from an actual question on stack overflow that I ran across. And it's not the only one, where people try to create this connection between these two models that we've presented, between the lexical scoping mechanism, and the this scoping mechanism.

[00:00:28] And the way that it usually occurs is, somebody has some other function somewhere. Like the baz function here on lines five through seven, maybe that one's declared as part of a third party utility that they don't control. So they don't have any control over it, but they know that that function makes a reference to something like, this.bar.

[00:00:47] And then they have a function that they do control, like the function foo, and they've got a local variable inside of their function called bar. And they wanna be able to invoke that function in some way that when he makes a this.reference, it will reference their own local copy of the variable.

[00:01:05] And that may or not be something you've ever attempted to do, but people attempt to do this, where they take some function, and make it reference their own local lexical environment, make the this reference somehow cross over to their own lexical environment. What I will say, plainly, is it is impossible to create a crossover between the lexical environment and the, this, binding mechanism.

[00:01:27] They're just two fundamentally different mechanisms and they don't cross over. But there's an attempt that people make to do this, and it's a well meaning and well spirited attempt. Here I'm trying to say I want to call this function in such a way and make it so that that bar variable references my bar variable.

[00:01:46] And so what you can see here is they're trying to get this reference to somehow magically local lexical context. We don't have any reference to our own local lexical context. It's a thing that exists, but we get no reference to it in our code. So we don't have a way to tell them, make this point to my electable context, and yet people attempt to do this.

[00:02:07] So this question was post on stack overflow, I'm attempting to do this. Again, it was a different form of the code, but I've distilled it down to the problem. This is what I'm attempting to do and it doesn't work. And I was dismayed to scroll down a little bit, and to see the first answer was the one with the big green check mark on it, and it literally had several thousand up votes, and I looked at the code that was posted, and I'll show you again the distillation of the code that was posted, it is abjectly wrong.

[00:02:40] And yet thousands of people have upvoted it as the correct answer, and people are giving it the green check mark and saying well this is obviously the right code. It's a testament to the fact that people are not rationally thinking about the, this, mechanism the way it actually works, they're thinking about it the way they want it to work.

[00:02:58] So, I just want to caution you against that. I want to call it out. I want to show you how incorrectly they tried to solve this problem. This is the distillation of the way they tried to solve this problem. They said, okay, well, what I really need to do is I need to make that baz function, I need to make a local reference to it.

[00:03:16] So, I'll say, this.baz is equal to baz, and then I'll invoke that function as my own local context. And that will somehow magically, kind of import that function back into my local lexical environment. And then therefore, it'll be able to reference the bar. And again, this is the answer that got a lots and lots of upvotes.

[00:03:35] It's like nobody actually tried the code because the code is still objectly broken. It doesn't actually work. But everybody thought that this was the correct answer and I'll explain to you, based on the same rules that we've already learned why this is objectively wrong, why this doesn't work.

[00:03:50] In the previous code we were attempting to somehow make the this reference here on line seven reference our own lexical context. So the way they tried to solve that was say, well if I make a this reference here, and I sort of import the function, that should work.

[00:04:04] But as I already explained to you, the, this reference, gets set by the call site of the function call. So to ask on line three, what does my this reference look like? I need to ask where does foo get called and how does it get called? So we come down to line 11 and we say, which rule would apply when line 11 executes the function?

[00:04:24]
>> Speaker 1: This is global?
>> Kyle Simpson: It's gonna be the global. Because we're in non strict mode, and the default binding role will apply, does everybody follow that? So on line three, we are essentially saying global.baz is equal to baz, but there's already a global.baz. This is a complete no op, it's complete nonsense.

[00:04:42] It's a testament to somebody not actually understanding the mechanism that they're writing about. So this is a complete no op, this line here. On line four, we're saying global.baz. Now when the baz function is called, what is the call sign for baz look like? Which rule will apply?

[00:05:00]
>> Speaker 2: Default isn't global.
>> Kyle Simpson: Not the default rule, the implicit binding rule, because look at our call site. We have an object.reference here. So, there's a containing object, but it happens to be the global object still. So, it's still, just like the previous slide, it's still going to be global.bar here.

[00:05:16] It's not going to be the global bar that you want it to be. And no matter how hard you try I put this challenge, I tell people not to do this and people always take it as a challenge. I can figure out a way. I assure you, no matter how hard you try, there is no way to create a crossover between this mechanism, the way it gets bound and your local lexical environment.

[00:05:37] Put metaphorically, if we go back to, sorry let me go back a few slides, put metaphorically, what you are attempting to do, I assume that you probably have this here but not all use that. Do you have those little cross bridges between tall buildings, where.you're on the tenth floor, and you can walk across instead of going all the way down.

[00:05:58] So what you're attempting to do metaphorically, is to create a crossbridge between your two buildings. And what I'll just tell you is that it's impossible. You can't create a crossbridge between them. They're two separate mechanisms, like they're two separate buildings, and you can take one elevator, or you can take the other elevator.

[00:06:12] But you can't take both of them at the same time. It's just not possible. Okay? So, your brains may attempt to do that, and if you ask a question at some point, and I refer you back, and I say you're trying to create a cross bridge, it's not possible, that's why.

[00:06:26] I just have to remind you that, regardless of what we attempt to do, there's no way to make those two mix. They're two separate mechanisms.