SURMA: Right. I don't know that this works. Why is it [INAUDIBLE] all Jake? What did you do? [MUSIC PLAYING] JAKE: So we did an episode
where we were looking at future JavaScript stuff. SURMA: We did. People liked that. JAKE: Yes. So what I thought we'd do
is look at new stuff that's already landed-- SURMA: Oh, I thought
you were going to say, let's look at old stuff. I was like, well,
that doesn't make-- JAKE: Well, I think new
stuff that's already landed is probably how you would
define old stuff, really. I feel like I'm doing a
bad job of introducing what this actually is. So I'm just going to show you. SURMA: Let's look at ES3. JAKE: Well, yes. SURMA: Oh. I was trying to
make a joke, but-- JAKE: Don't ever do
that again, mate. Just tell me what
is going on here. SURMA: This is
like the throwback to object oriented programming
in JavaScript before we had classes, isn't it? JAKE: Exactly. Yeah. SURMA: Where you
define a function, and suddenly you
can add properties on the prototype
of that function. It sounds really weird,
but that's how you did it. JAKE: So what's happening? Talk to me. SURMA: So you define
a function Car. I'm not going to
talk about what's inside the function for now. But then you can add
things in the prototype of this function called Car. And I think that
prototype is used when you use the function
with the new keyword. So if I say new
Car, then the things in the prototype in that
thing I can use also, on the instance of Car. That was a really
bad explanation. JAKE: It was. Yes. SURMA: I always
found it confusing. It's-- what is it called--
in prototypical inheritance? JAKE: Yes. SURMA: Something like that? JAKE: Prototypical. Prototypical. But what about-- SURMA: You're just
already doing weird stuff. JAKE: This. So I guess we should
explain that you were relatively
recent to the web, but you have ramped up fast. SURMA: Yeah, I never did-- JAKE: You would have
never have done this. SURMA: I've done
it at university. Not that specific. I just used [? Car.prototype ?]
[? dot ?] first function equals and then the function. JAKE: But this Car
inherits from Vehicle. And this is how we
used to do inheritance. SURMA: But that's disgusting. JAKE: Yes. Isn't it? Isn't it horrible? SURMA: Wow. JAKE: Because I mean-- SURMA: That's why people
use frameworks, right? Or little libraries that
would give you that. JAKE: Exactly. And so because you
want Car.prototype to be an instance of Vehicle. But Vehicle has-- you need to
call the function with stuff. It has options and things. So what you needed to do is
create a new constructor, copy the prototype over, or
reference the prototype over, create a new one of those,
and that meant your Car now inherits from Vehicle. And then here, this is where
you were doing the [INAUDIBLE].. My point is we've got classes. This is what we have now. So this is what I
want to talk about, is just some of the things
that we've got now-- SURMA: And we're taking for
granted almost, isn't it? JAKE: And we almost
take for granted. SURMA: The old version, the
prototypical inheritance, always reminds me of Lua,
where you only have tables and you have tables
within tables if you want to inherit--
it just gets super weird. It feels very similar. And this is just-- ha, feels better. JAKE: Never done Lua. I'll take your word for it. What's happening here? SURMA: You are defining
a function called spin. JAKE: Correct. SURMA: Let's take a closer look. So the options-- oh, OK. So this is basically
sanitization of the options object. JAKE: Yeah. SURMA: Which, you
know, even there is also [INAUDIBLE],,
where you just define a syntax, what the
options object would look like. Because otherwise, you
would have to write this, and this is just like-- it
took me a while to actually understand what you were doing. And now I didn't
read every detail, because I recognized the
pattern, because I've written that before. JAKE: Yes. SURMA: If you don't
know the pattern, this would be a lot of reading
time spent until you know, oh, you were just checking that
certain properties are present, and if they're not,
using a default value. JAKE: Yes. And this got a lot easier
with object.assign, which was essentially
what the library-- we all had to be doing
something like object.assign, and that's what we'd
use here, but nowadays-- SURMA: Destructuring
with the full values. JAKE: Yes. So what we see here,
we're destructuring. We're giving it
the default values, and then a default value
for the option object there, so it's entirely optional. But I brought this
example for a reason. SURMA: Because I don't like it. JAKE: Because you
don't like it, do you? SURMA: So I do like the
structuring and default base. I've gotten around
to it a little bit. I don't like it in the actual
function parameter definition. I prefer this where
you destructure in a separate place,
because, otherwise, it gets a little bit nested,
and it looks a bit crammed. And especially if
you have TypeScript, it gets even weirder,
because then the types just go all over the place. So when I use
TypeScript, I often have a type that's called
function name with the word options appended
to the end where I define what structure
the options object have. And then I have the
first line in my function will then assign
the default values. JAKE: Yeah, and I agree. Yeah. This looks a lot neater. The reason I would still do this
is because a static analyzer knows that these are the
properties of the option object. In this case, it's not-- SURMA: True. This is probably preferable
if you don't have TypeScript. JAKE: Right. So that's that. SURMA: What's happening here? JAKE: If you don't know
what's happening here-- SURMA: I need to get out. JAKE: We have to fire you, yeah. SURMA: You're making the DOM
element with a class whatever be 100 pixel tall. JAKE: Well saved. So I spend a lot of my
time designing in DevTools. I'll throw some rough
styles just into the editor, and then I'll go into
DevTools and that's where I'll be shifting values
around to make it look then-- SURMA: Copy and paste. JAKE: It's exactly that, yeah. In this case, editing
this in DevTools is hard, because what I want-- in this case, I want
whatever to be the same width as it is high. I want it to be square is
how a human would say that. And it means that if I'm
shifting values around in DevTools, I shift
one, and then I have to Tab twice, or whatever,
and shift the other one. And that's a pain. So here's one of the solutions. SURMA: Yes, that's the
proper solution, I'd say. JAKE: Yeah, and it's been nice
now that this is supported in all modern browsers. I've just found this
a dream, and it's-- SURMA: For what it's worth,
size is coming to CSS. JAKE: Is that
right, and it's just an alias width plus height. Oh, that's exciting. SURMA: Yeah, because we
have a lot of other things. For example, I think
background image size. Certain other size
properties exist where you can have one
value or two values, and if it's only one value, it's
the same for width and height. But we don't have it for the
actual size of the document. JAKE: So it becomes a shortcut
for width and height-- SURMA: Yeah, and you can also
do size 100 pixel, 200 pixel, if you want it to be
100 pixels wide and-- JAKE: In the same way you
do for background size. SURMA: Exactly. JAKE: Oh, OK. That's good. But in the meantime, this works. SURMA: For now, this works. JAKE: What's happening here? SURMA: I'm assuming that UL and
LI are well-named variables, and you're not trying
to throw me off. So you have a list that
you add a click handler and then you get the
event targets from the LI, and if it's not an LI, then
you say, well, you bubble up. Oh, OK. So what you're doing
is you, basically, do the event delegation where
you have one click handler on the UL of each
individual list item, and then you try to figure
out, on the click event, what is the actual list
item that you click on. JAKE: Yeah, so one event
listener on the list, but you're using it to detect
a click on all the list items. That means you can move
those list items around, add and remove them. You don't have to
change the list item. SURMA: But then
the problem becomes that if your list item
has an anchor tag, that event or target might be
the anchor tag within the list item. JAKE: It might just
be the list itself. SURMA: Or it might
be the list itself. JAKE: Click to list item. SURMA: And then
what you have to do is you have to walk
up the tree manually to find what the containing
list element is, if it exists. JAKE: Yeah, and I
always found this-- it's only a little bit
of code, but it always felt like a barrier to
using event delegation. Whereas, now-- SURMA: We've got closest. JAKE: We've got closest,
and it's so good, because it doesn't have to be a tag name. It could be a class name. SURMA: I wonder if I did a
"Supercharged" episode on this? Oh, wait. I did. JAKE: Oh, right. Yeah. I did worry that
maybe there's going to be a lot of crossover
between what I show now and "Supercharged." SURMA: This is just
because, as far as I know, closest was inspired by jQuery,
and at the jQuery series. JAKE: There might be some
of those coming up as well. Let's carry on. What is happening here? Good luck. SURMA: All right. Wait, wait. So you're replacing just a plus? Anything before the plus
will that match pluses? JAKE: Yes, that would
be a literal plus. SURMA: Wow, that is confusing,
because usually the plus means the preceding matcher once
or many times repeated. JAKE: But if there's
no preceding matcher-- I'm pretty sure that works. Some of these I haven't
checked thoroughly. I'm pretty sure that works. SURMA: I would probably
backslash it for clarity anyway, unless it then
breaks, because right axis. JAKE: Get over the first line. SURMA: We are replacing
pluses with spaces. And then we have a result-- oh, you are totally parsing
your alts, aren't you? JAKE: Yes, I am. Well, specifically
the query string. SURMA: The query string. Yeah, because
spaces are in code. It's pluses and the
individual parameters are separated by
ampersands, and then you do the [INAUDIBLE] split. Then, actually, in
the end-- oh, you do the URI component decode. That is a lot of work. JAKE: It's a lot of
work, and it looks-- SURMA: And it's frustrating,
because the browser can actually understand it
in coding, and doing it yourself is super frustrating. JAKE: Exactly. And it's useful to look at
the URL to decide stuff. It could either be
the current URL, or it could be
the URL of a link, or it could be some form data
that you're trying to send, because it's the same in coding. And having to do this
to figure it out-- SURMA: URL search parents. JAKE: It's just so much
nicer that we have that now, and we have that
across all modern-- SURMA: I'm still very
annoyed that they didn't add a new property
onto the location object. JAKE: So do you know why? So if you do new URL
and parse a URL in, you now have
URL.search parameters, which is an instance
of this, which you represent in the query string. The problem is the
location object is available across windows. SURMA: Oh, so if
I open a window, I can get access to the-- JAKE: Yeah, and even if that
window is in another process, like an iframe, you still have
access to the location object, and this has been
the whole problem of implementing that, is having
this extra object that exists. SURMA: Why is that a problem? JAKE: Because we have window
proxy, and so we would need the equivalent of a
search parameter's proxy, because of things like
[INAUDIBLE] and all of that sort of stuff,
it's not referencing exactly the same object. SURMA: I would be fine
if we just defined a [INAUDIBLE] function that
just gives me a new instance. JAKE: In the same
realm or something. SURMA: Every time I
do new URL search, new URL and then
location.string or something-- it's a small
[INAUDIBLE] compared to what we had to do before. JAKE: Agreed. It's work-aroundable, but it
would be nice if it was there. But yeah, this
[INAUDIBLE] it does the encoding, the decoding. And it's just there,
and it's brilliant. Excellent. SURMA: Ah, FileReader. I'm not sure about FileReader. So it was supposed to help
you read Blobs and files that are given from file picker
and these kind of things. And it's this super
non promise based API, which are always great. It's like [INAUDIBLE]
but for files, in a way. Is the support
super flaky across browsers or is this actually-- JAKE: No, this is
well-supported. As you say, it
predates promises. It will take a Blob or
a file, because file inherits from Blob. And if you wanted to take that-- because Blob, you don't
get access to the bytes. If you want access
to the bytes, as like text or an
array buffer, this is the mess you would
have to deal with. Nowadays [INAUDIBLE]. SURMA: [INAUDIBLE] that you
recently tweaked it, I think, and that's where I learned it. Yeah, I never thought about
abusing response in that way. I don't think it's
actually abuse, because-- JAKE: It's creating a
response when you don't really need to just because it
has these methods on there. SURMA: But it's suddenly
promise based, [INAUDIBLE] because actually, you
know what's going on, and I think that's
a big difference. JAKE: And that's one of the
things, when we designed the response API, we wanted
it to be very easy to get these other formats out
like text or array buffer, those sort of things. Nice promise based API. Obviously, async
functions are a thing we didn't used to have that
I take for granted now. It all made browsers
so much easier. So the last one. SURMA: Wait, what? JAKE: If you could
at least get a flavor for what's going on here. SURMA: We are creating
a styles object. We are creating a
random animation. Generating the animation
[INAUDIBLE] wide translation and we add the new styles,
then we add that new animation to an object, wait for-- JAKE: Do you know what? I'll save you time. This is if you're
wanting to create a programmatic animation. SURMA: I see. Because back in the
day you only had CSS. JAKE: Yes, so if I wanted
to animate from something to something else, this is the
kind of thing I have to do. I have to create the key frames. SURMA: AD hoc the
key frame animation, add it as a styles tag. JAKE: And this is because
an animation could end or it could cancel, so I need
to listen for both to know when the animation is done. And turn that into a promise. Ta-da. SURMA: Web animation's API. It's finally coming
to a point where it becomes usable across browsers. JAKE: Yeah, and this
is themed differently from the other examples because
we still don't have this. SURMA: We have it in
Chrome, at least a subset. JAKE: We don't have
the finished promise. SURMA: No, we don't. We sold out. That's true. JAKE: And do you know
whose fault that is? SURMA: My mom's? JAKE: By extension, yes. It's my fault, because at the
time that he designed this, we hadn't decided what to
do with cancellable promises at the time. And because finished is a
promise that may cancel, I put the brakes on, and said we
can't ship this yet, because it might turn out to be-- SURMA: Ladies and gentlemen,
please tweet at Jake. JAKE: I'm sorry. And do you know what's worse? The thing they were doing
is what we ended up doing. So if we shipped it, it
would have been fine. I used to do a JavaScript
library for the BBC, and we were having to target
things like Safari 1.3, and this is the sort of stuff. All this stuff
I'm showing you, I would have killed for
this stuff back then. And it is nice to see that-- we look at the future cool
stuff that might land, and it's like, oh,
that looks interesting. And it's nice to stop and look
at that things have got better. SURMA: We've got
nice things now. JAKE: Things have got better. I tend to, on stage,
I lock my arms in. I walk around like
a camp zombie. SURMA: Is that a sweat fear? JAKE: I think it might be that. So I'm a talking-- and here's how this is working. SURMA: T rex mode engaged. JAKE: Typing on my keyboard. Driving my car.
JavaScript classes are a concession to the incessant whining of Java and C# developers who couldn't wrap their crusty brains around the concept of prototypes.
They should have never been added to the language.
I find the gentleman in the glasses to be a pretentious insufferable person in this video for some reason.