This course has been updated! We now recommend you take the The Good Parts of JavaScript and the Web course.

Check out a free preview of the full JavaScript the Good Parts course:
The "Problems 13-15" Lesson is part of the full, JavaScript the Good Parts course featured in this preview video. Here's what you'd learn in this lesson:

o Problem 13: Write a function that allows another function to only be called once. o Problem 14: Write a factory function that returns two functions that implement an up/down counter. o Problem 15: Make a revocable function that takes a nice function, and returns a revoke function that denies access to the nice function, and an invoke function that can invoke the nice function until it’s revoked.

Get Unlimited Access Now

Transcript from the "Problems 13-15" Lesson

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

[00:00:04]
>> Douglas Crockford: Write a function that allows another function to be called only once.
>> Douglas Crockford: So here we've got once, we'll pass it the add function. That gives us an add_once function. We can call it with three and four. It returns seven. We call it again, boom.
>> Douglas Crockford: This can be really useful for managing functions that are not item potent.

[00:00:40] So you can guarantee that they're not gonna be called more than once. It could be useful in financial applications or in security applications.
>> Douglas Crockford: And because we're composing functions, you don't have to rewrite the add function in order to get this capability.
>> Douglas Crockford: Does anyone need more time?

[00:01:16]
>> Douglas Crockford: Okay, here we go. Function once returns a function that sets f, variable f, to the function that got passed in. Nulls out the function that was passed to it and then uses apply to call the function. And that's it. So, this will work once. If you try to do this again, it will fail because the function will be null and it will throw an exception.

[00:01:50] There are other ways of doing this. You could have the once function have a variable which maybe is initially true and then later you decide to false. That would be another way of doing this. Or could keep it counting. You could set it to one and each time you call it you decrement it.

[00:02:05] So if you wanted to do a three wishes protocol you would do it like that. You'd set the number of wishes to three and then when it goes to zero you stop doing the apply, yeah.
>> Speaker 2: Can I ask a question on arguments? Could you add another argument to that ,5, so that you're.

[00:02:24] So you're calling, I guess not. Arguments is a single parameter.
>> Douglas Crockford: Yeah, so the one thing here that you might not have seen before is, f.apply of this and arguments. What that does is it calls this function with exactly the same parameters and disk bindings as that function.

[00:02:44]
>> Speaker 2: So, could you add another primary argument.
>> Douglas Crockford: Argument as in array?
>> Speaker 2: Could you add to that array, something else, and continue with your passing line?
>> Douglas Crockford: You could, yeah, you could append stuff to the end of it. Any questions about this one? And so who got this one?

[00:03:10]
>> Douglas Crockford: Pretty good.
>> Speaker 2: I did it the other way that you were talking about, giving like a boolean variable.
>> Douglas Crockford: That's fine, there is nothing wrong with that.
>> Speaker 2: I'm not totally sure that it works that way.
>> Douglas Crockford: As we're getting more complicated, when all the examples were really simple, there was probably one best way to do it.

[00:03:28] We are now giving it to a territory where there's gonna be more variation in the possible answers. Okay, here's the next one. Write a factory function that, hey. Write a factory function that returns two functions that implement an up/down counter. So counter f is our factory function. It returns an object and that object has an inc method and a dec method.

[00:03:58] And inc will return one bigger than the previous value and dec will return to one smaller.
>> Speaker 2: Can I ask you a question?
>> Douglas Crockford: Sure.
>> Speaker 2: Let's say if a function of 100 variables in it. If you reference one of them, you hang on to all of them?

[00:04:21]
>> Douglas Crockford: Yeah, they all live. So there's sometimes memory leakage which results. So the way you avoid that is, if there's a big data structure in there that you know you're not gonna need any more, then at some place you wanna null it out.
>> Douglas Crockford: Otherwise everything survives.
>> Speaker 2: Like a whole new physics compared to like the Java in terms of its problems and settled with it's damages.

[00:04:51]
>> Douglas Crockford: You can kind of get this stuff with inner functions, or I'm sorry inner classes. But they are so expressively weak, compared to this, that you rarely see them used anymore.
>> Speaker 2: I mean, I see that you used the ++ operator in your definition.
>> Douglas Crockford: [LAUGH]
>> Douglas Crockford: Does anybody need more time?

[00:05:48] Okay, everybody ready? Okay, so here we go. Our counterf function takes a value and returns an object containing two methods, an increment method which adds 1 to value and returns it, and a decrement method that subtracts 1 from value and returns it. So who got something like this?

[00:06:09] Great, anybody got anything different that they think is right?
>> Douglas Crockford: .Any comment or question about this one? Okay, I think we'll do maybe one more and then we'll take a break, okay? So make a revocable function that takes a nice function, and returns a revoke function that denies access to the nice function, and an invoke function that can invoke the nice function until it is revoked.

[00:06:42] [LAUGH] Okay, so it might be a little easier to see from the code. So we're going to make something called temp which will be the revocable version of alert. Okay so we can call temp dot invoke and it works until we call temp dot revoke and after that Temp.invoke stops working.

[00:07:11]
>> Douglas Crockford: Any questions about that?
>> Douglas Crockford: So it's similar to once, except instead of happening once, it happens until we call the function that makes it stop.
>> Douglas Crockford: So one way you could use this, you could pass the revoke function to set time out. So if you wanted a function to work until some time and then have it stop, this is a way to do that.

[00:07:57]
>> Speaker 2: So how do you re-enable, is that not part of this?
>> Douglas Crockford: This doesn't allow for that. You could have a reenable method which would turn it back on but-
>> Speaker 2: [COUGH]
>> Douglas Crockford: We're not doing that this time.
>> Douglas Crockford: Maybe for extra credit.
>> Douglas Crockford: Okay, does anyone need more time?

[00:08:31]
>> Douglas Crockford: Everybody ready? Okay, here we go. So we have revocable takes a nice function and returns an object containing two functions. One of them is invoke. Which will call the nice function using apply. So it sends over all the disk bindings and arguments. And there´s the revoke function which just nulls nice out causing invoke to fail.

[00:08:56] Anybody getting anything like this?
>> Douglas Crockford: Yeah?
>> Speaker 2: I tried doing that with alert. It was giving me an issue with apply and I'm saying a legal operation.
>> Speaker 3: Yeah I got the same thing.
>> Speaker 2: So I had to use explicit perameters in a case of a blur. It works with other functions.

[00:09:23]
>> Speaker 3: Some of the browsers get mad about calling a native plan a function from what I´ve seen in the past.
>> Douglas Crockford: Was that a Safari thing?
>> Speaker 2: Chrome.
>> Douglas Crockford: Chrome. They´re buggy. That's not true. One problem with the way the DOM API is designed is not everything that looks like an object or a function is actually an object or a function So that's a problem in their API.

[00:09:53] I didn't know that but anybody else?
>> Speaker 2: I have a question
>> Douglas Crockford: Yeah
>> Speaker 2: If you want, go back to the other one for a second. If you made the function, or return the invoke, would actually return a function, that would then get called at the parameters. Would you put parentheses around the () temp.invoke () and then (7)?

[00:10:23]
>> Speaker 2: Does that, I don't know if that makes sense.
>> Douglas Crockford: Not yet.
>> Speaker 2: [INAUDIBLE].
>> Douglas Crockford: Okay, all right so let's take a break. What do you say? And then we'll do some more of this, okay.
>> Douglas Crockford: Okay it's now time for the democratic process. We have two options here.

[00:10:48] We continue doing this stuff. I've got many hours [LAUGH] Of problems left [LAUGH] Or we can go back to the thing where I just yap at you and you don't have to work so hard. So,-
>> Speaker 2: [INAUDIBLE].
>> Douglas Crockford: We have to decide which way we wanna go.
>> Speaker 2: What do we talk about?

[00:11:04]
>> Douglas Crockford: I'm gonna talk about monards. It's gonna be one of application of fuctional programming. So it gonna take the stuff you have been learning and push it in a whole other direction. So you like that? Who wants to keep doing the problems? Looks like the will of the people.

[00:11:22] All right so we'll move on.