Transcript from the "Function Best Practices" Lesson
[00:00:24] It will actually return the value undefined or if the function falls through the bottom, it will return the undefined value.
>> Douglas Crockford: I recommend that you not make function objects in a loop. It can be wasteful, because every new function object is created on every iteration, so that could be expensive.
[00:00:43] It can also be confusing, because the new function closes over the loops variables not over their current values and that confusion can lead to bugs. For example, here we've got a for loop, which is going to loop over an array of divs and it's gonna add a click handler to each one, which when clicked on will alert the id of the div and this code looks very straightforward, but it will fail.
[00:01:11] And the way it fails is no matter which div you click on, they will all display the same id. It'll be the last one and it's because what's being captured by the inner function is the current value of div.id not not the value of div.id the at the time that the function was created.
[00:01:30] So the way to get around that is to not use a four loop at all, use four each and will pass in a function, which will receive each div of as an argument and will alert correctly.
>> Douglas Crockford: We invoke functions with the pairing suffix operator, which will surround zero or more comma separated arguments and each of those arguments will be bound to one of the parameters of the function.
[00:01:59] If a function is called with too many arguments, the extra arguments are ignored. It is not an error. If an argument is called with too few arguments, the missing values will be the undefined value. If there is no explicit type checking on the arguments, on their types or on their numbers.
[00:02:43] I don't recommend using either of them, but they're both very popular in the language. So, I'd need to describe them both. I will start with the arguments. When a function is invoked in addition to its parameters, it also gets a special printer called arguments and it contains all of the arguments from the invocation.
[00:03:17] It's an object that has a length property, but it's not a magical length property and it doesn't inherit any of the useful array methods. So, it's a difficult thing to work with. You do get arguments dot length, which will be the number of arguments that were actually passed and there's a weird interaction with the parameters.
[00:04:03] So, let me show you an example of how you could use it. So we've got a simple sum function, which will receive some variable number of numbers and it will add them up and return the total. So, we're going to get from arguments that length and the number of things that we're going to add.
[00:04:22] We're gonna loop through in and we're gonna get each of those arguments, and add it to the total. Notice I didn't include any parameters in some, cuz I didn't need to I could have. But it wasn't necessary, because I'm getting all the material from arguments.
>> Douglas Crockford: So now this is a really difficult thing to have in any language, because it makes the language hard to talk about.
[00:04:51] It's like pair programming with Abbott and Costello. So, bear with me. So, the this parameter contains a reference to the object of invocation. This allows a method to know what object it is concerned with. This allows a single function object to service many objects and it's the key to prototypal inheritance.
[00:05:35] The method form, we say, some object dot method name or some object bracket, an expression that evaluates to a method name. When we call a function this way, then this will get bound to this object. It allows the method that gets called to know which object it's going to be manipulating.
[00:06:20] In this case, this gets bounced to the global object. It's the thing that is the container of all the global variables and that's a terrible thing, because it's leaking way too much capability. It's a security hazard, it's a reliability hazard. This was sort of fixed in ES5/Strict mode.
>> Douglas Crockford: But not completely. In ES5/Strict mode, this gets bound to undefined. So at least we're not binding it to something dangerous, but sometimes it's not what you want either. That if you have an inner function inside of a method, you want the inner function to help the method do its work.
[00:06:59] But the inner function doesn't get to see this, because the inner function gets called as a function. And so, it's this will be either the global object or undefined. So the workaround is in the outer function, in the method, you create a variable called that assign this to it and then the inner function gets to see that.
>> Douglas Crockford: Then there is a constructor form, it looks like the function form, except there is a new prefix. And when a function is called with a new prefix, a new object is created and will be bound to this. And if the constructor function does not have an explicit return value, then this will be the return value and this is used in the pseudo classical style, which will get to in a few minutes.
[00:07:45] And finally, there is the apply form. In the apply form, you call the apply method of the function object and you get to specify what the value of this is going to be. In addition, you can also provide either an array of arguments or you can provide individual arguments separated by commas.
>> Douglas Crockford: So to summarize, there are four invocation forms, function, method, constructor and apply. They each vary according to what they do with this. And again, I don't recommend using this at all, but that's how most people use the language and I'll show you an alternative in a few minutes.
[00:09:08] Highly, highly recommended. This is one of those books that can significantly change the way you think in a really good way.
>> Douglas Crockford: There's another book called The Principles of Programming Languages by RC Tennent and one of his principles is the principle of correspondence in which he talks about how variables are like parameters in some languages.
[00:09:35] So here, we have two versions of the factorial function and one of them result is a variable and the other the result is a parameter. Otherwise, these two functions do exactly the same thing. And so, this demonstrates the similarity of variables and parameters based on how the function is constructed.
[00:09:54] The interesting thing about the second function is, it's using an immediately revocable function expression. So here, we have a function, declaration or function of expression, which is creating a new function object, which we then call immediately passing in the one. So in general, we can take any expression and wrap it in a function that will return that expression and call the function immediately and it does the same thing as expression.
[00:10:48] You can take any bunch of statements and put them in a function and call immediately and it's says, though, you had executed those statements, except that var function break continue and return change their meaning when you put them in another function. Otherwise, you can do this transformation and there are some interesting things that can happen as a result of being being able to do this.
[00:11:12] So, this is a feature that you look for in a functional language.