84 lines
3.7 KiB
Markdown
84 lines
3.7 KiB
Markdown
# Chapter 8. Functions
|
|
|
|
**Function** = a block of JS code that's defined once but may be invoked multiple times.
|
|
* *argument*: values provided by during invocation as function's parameters.
|
|
* *return value*: computed by function using argument values
|
|
* *invocation context*: value of `this` keyword for each invocation
|
|
|
|
Utilization of functions:
|
|
* **method of object**: if function is assigned to a property of an obj.
|
|
* When a function is invoked on an object (e.g. `obj.method()`), this object become invocation context (aka `this`) for the function
|
|
* **Constructor**: function designed to initialize a new obj.
|
|
|
|
Function as **first class citizen** (object):
|
|
* In JS, functions are obj. Hence, can be manipulated by programs
|
|
* We can set properties on functions and invoke methods on them (i.e. pass function as parameter to method)
|
|
|
|
JS function definitions can be nested within other functions
|
|
|
|
## 8.1 Defining Functions
|
|
|
|
### 8.1.1 Function Declarations
|
|
|
|
**Function declaration (函数声明)** = `function` keyword + Identifier as function name + `(param1, param2, ...)` + `{JS statements as function body}`
|
|
* `return` causes function to stop executing and return computed value to caller
|
|
* if body has no `return`, value of function is `undefined`
|
|
|
|
```js
|
|
// Print the name and value of each property of o. Return undefined.
|
|
function printprops(o) {
|
|
for(let p in o) {
|
|
console.log(`${p}: ${o[p]}\n`);
|
|
}
|
|
}
|
|
|
|
// Compute the distance between Cartesian points (x1,y1) and (x2,y2).
|
|
function distance(x1, y1, x2, y2) {
|
|
let dx = x2 - x1;
|
|
let dy = y2 - y1;
|
|
return Math.sqrt(dx*dx + dy*dy);
|
|
}
|
|
|
|
// A recursive function (one that calls itself) that computes factorials
|
|
// Recall that x! is the product of x and all positive integers less than it.
|
|
function factorial(x) {
|
|
if (x <= 1) return 1;
|
|
return x * factorial(x-1);
|
|
}
|
|
```
|
|
|
|
* Name of function (in function declaration) becomes a variable, whose value is function itself.
|
|
* function declaration statements are "hoisted" (level up) to top of enclosing block.
|
|
* All function in a JS block will be defined before JS interpreter start execution
|
|
|
|
### 8.1.2 Function Expressions
|
|
|
|
Multiple Function Expression e.g.
|
|
```js
|
|
// This function expression defines a function that squares its argument.
|
|
// Note that we assign it to a variable
|
|
const square = function(x) { return x*x; };
|
|
|
|
// Function expressions can include names, which is useful for recursion.
|
|
const f = function fact(x) { if (x <= 1) return 1; else return x*fact(x-1); };
|
|
|
|
// Function expressions can also be used as arguments to other functions:
|
|
[3,2,1].sort(function(a,b) { return a-b; });
|
|
|
|
// Function expressions are sometimes defined and immediately invoked:
|
|
let tensquared = (function(x) {return x*x;}(10));
|
|
```
|
|
|
|
**Function Expression (FE 函数表达式)**:
|
|
* FE appear within context of a larger expression, or within statement
|
|
* name of function in FE is *optional*. (e.g. 1st FE e.g. has no function name)
|
|
* FE/FD declare variable:
|
|
* How FD use variable: (follow e.g. in 8.1.1 `function factorial(x)`) declares a variable and assigns a function obj to it.
|
|
* How FE use variable: developer can decide whether assign the newly defined function obj to a const or var, so we can refer to it mult-times later. (e.g. 3rd & 5th FE e.g. does not assign function obj to obj, and directly use it)
|
|
* Good practice: assign FE to `const` to protect function obj.
|
|
|
|
FD vs (assign FE to variable after creation):
|
|
* Function defined by FD: the func obj are created before the script get executed (i.e. hoisted), so we can call these functions from code that appears above FD.
|
|
* Functions defined by FE **DO NOT EXIST** until FE are evaluated.
|
|
* To invoke a function (either defined using FE/FD), JS must can refer to it, function defined by FE cannot be referred until it's assigned to a variable
|