Check out a free preview of the full The Good Parts of JavaScript and the Web course
The "Good Parts Reconsidered" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:
Doug looks back at the the original Good Parts and reflects on what’s changed. For example, originally he stopped using the new operator and switched to Object.create(). Now he’s stopped using Object.create(). Doug explains why and also talks about his experience with AdSafe.org
Transcript from the "Good Parts Reconsidered" Lesson
[00:00:00]
>> [MUSIC]
[00:00:03]
>> Douglas Crockford: So I'm also reconsidering things that I had put in in the book. Do I still think the things I said were good then?. Are they good now? So, in the book, I didn't recommend use of new. I stopped using it, I recommended using Object.create instead, and in fact, I managed to get Object.create added to the language just so that I could use it.
[00:00:23]
So, I was really surprised to kind of notice that I've stopped using Object.create, and the reason for that is because I stopped using this. If you're not using this, then create doesn't do all that much for you, and the reason I stopped using this was because of ADsafe.
[00:00:42]
So in 2007 there were a number of experiments at trying to figure out how to turn JavaScript into a secure language for doing mashups and in third party interaction. There was FBJS at Facebook, there was web sandbox of Microsoft. There was the Caja project at Google and there was my own ADsafe project.
[00:01:04]
And one of the difficult problems everybody was struggling to solve was, what do you do about this? Because if you have a method, this will get bound to the object of interest and that's good. But if you call that same method as a function, this gets bound to the global object, which gives away the farm.
[00:01:22]
And how do you deal with that? And so the approach that the other three projects took wa,s they have translators, they read JavaScript and they write JavaScript. And the JavaScript they write is much bigger, because they're adding a lot of runtime checking and indirection in order to find cases where this is turning into a global object and allowing bad things to happen.
[00:01:48]
The approach I took with ADsafe was much simpler. I said, this is illegal. So if we see a program with this in it, we reject it, done, easy. So we don't rewrite the programs. We don't make them harder to debug or slower to run. If a program passes ADsafe, it gets to run at full speed without any modification.
[00:02:08]
But the ADsafe rules would reject pretty close to 100% of all existing programs in the Web. So in order to use ADsafe you had to work in the ADsafe dialect. So I decided as an experiment, well I'll work in that dialect. I'll see what it's like and how painful it is.
[00:02:29]
Now after working with it for a while I was really surprised to learn that it got easier. That I expected it was gonna be a hardship that I was gonna have to get around, but that it actually got easier and my programs were getting better. I was forced to use the functional patterns because prototypal patterns weren't available because I stopped using this and I really liked it.
[00:02:51]
And so as I've gained confidence in this model and I've become an advocate now of getting rid of this entirely, and going all with functions because that's where the goodness is. Yeah?
>> Speaker 2: What does JSLint say about this?
>> Douglas Crockford: So JSLint, this is now an option. So there is now an option that you can specify which will suppress warnings about this.
[00:03:17]
I don't recommend using that option but it's there. I added options to JSLint for a transition, because over time I'm constantly looking at, how can I make this language smaller and better? And things that I thought were maybe a good idea last year, this year I'm thinking I'm not sure.
[00:03:39]
Like this year I'm starting to decide that labeled break is probably a bad idea, that I actually haven't used one in many years and I think I'm better for not having used one in many years. So that labeled break is on its way onto the bad part list.
[00:03:56]
But there are people using JSLint who, when JSLint rules change, go aah. We're used to doing that and we can't do that now. So I add the options so that they can transit out. We can just get by for now and eventually we'll fix our code. Except what happens is people don't fix their code and they design their programming style based on what options they can turn on.
[00:04:22]
So I'm trying to remove options now from JSLint as much as I can, but I recently added the this option so we can transit out.
>> Speaker 2: You don't use prototypes at all in the code you write, you personally?
>> Douglas Crockford: I am not using prototypes anymore.
>> Speaker 2: Okay, so Ben pointed out yesterday that one of the drawbacks to function versus objects is that all your functions, every function you have, there's an instance of that function.
[00:04:51]
That's functional programming that's-
>> Douglas Crockford: Yeah, we're gonna talk about that. That's coming up next.
>> Speaker 2: Okay, I was gonna say are there any other drawbacks to abandoning prototypical?
>> Douglas Crockford: That's the one.
>> Speaker 2: Okay.
>> Douglas Crockford: So I've stopped using null. JavaScript has two bottom values, which is at least one more than it should.
[00:05:11]
And so I'd stopped using null, I just use undefined now for everything. Even though it's longer to type it, that doesn't matter. So, and I stopped relying on falsiness. I used to think that falsiness was a good idea and I advocated having comparisons and ifs that were as small as possible.
[00:05:33]
I now think that was a mistake, that we should be trying to make comparisons that are as explicit as possible, trying to intelligently bifurcate the true cases from the false cases.
>> Douglas Crockford: I've stopped using for, because in years five we got foreach and every and map and all those others and those are great.
[00:05:53]
So for most purposes I don't need to use for loops anymore. I don't use for in, because I managed to get object.keys out of the ES5. So for in never worked correctly anyway, because it would always dredge through the prototype chain and you get all the inherited methods coming up, which you would then have to filter out.
[00:06:13]
For in never worked right. So ES6 will have proper tail calls, and when we get that, I will stop using while.
>> Douglas Crockford: So here are two versions of the repeat function. repeat takes a function as an argument, and we'll call it until it returns undefined. And that's a version written using a loop, and that's a version using tail recursion.
[00:06:37]
In ES6, these should both run at the same speed, both consuming the same amount of memory. So this will probably be the last feature implemented in ES6, so I'm still waiting for it. But when it comes, then I'm done with loops and I'm gonna be doing tail recursion from here on out.
[00:06:57]
>> Speaker 2: Under the hood, what does tail recursion look like in order to prevent from having this extremely long stack?
>> Douglas Crockford: It's really simple. Just this turns into jump to, it's like a goto with an argument list. So we jump to the repeat function. So we're jumping to the top.
[00:07:20]
And if this has a new value, which it doesn't, the new value would get assigned up here and we go again.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops