8.1 函数定义
- 函数表达式
- 函数声明式
8.2 函数调用
- 作为函数
- 作为方法
- 作为构造函数
- 通过它们的call()和apply()方法间接调用
8.3 函数的实参和形参
8.3.1 可选形参
传入的实参比形参个数少,剩余的形参置为undefined。
8.3.2 实参对象
arguments指向实参对象的引用,是一个类数组对象
callee:当前正在执行的函数
caller(非标准的):调用当前正在执行的函数的函数
8.6 闭包1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31var scope = "global scope"; // A global variable
function checkscope() {
var scope = "local scope"; // A local variable
function f() {
return scope;
} // Return the value in scope here
return f;
}
checkscope()() // What does this return?
/**
*
*/
function counter() {
var n = 0;
return {
count: function() {
return n++;
},
reset: function() {
n = 0;
}
};
}
var c = counter(),
d = counter(); // Create two counters
c.count() // => 0
d.count() // => 0: they count independently
c.reset() // reset() and count() methods share state
c.count() // => 0: because we reset c
d.count() // => 1: d was not reset
8.7 函数的属性、方法和构造函数
8.7.1 length属性
arguments.length表示传入实参的个数
8.7.2 prototype属性
指向一个对象的引用,这个对象称作“原型对象”
8.7.3 call()和apply()1
2f.call(o, 1, 2);
f.apply(o, [1,2]);
8.7.4 bind()
bind()是在ECMAScript 5中新增的方法,但在ECMAScript 3中可以轻易模拟bind()。从名字就可以看出,这个方法的主要作用就是将函数绑定至某个对象。当在函数f()上调用b1nd()方法并传入一个对象o作为参数,这个方法将返回一个新的函数。(以函数调用的方式)调用新的函数将会把原始的函数f()当做o的方法来调用。传入新函数的任何实参都将传入原始函数,比如:
1 | var sum = function(x, y) { |
1 | /** |
8.7.5 toString()
返回函数源码或者”[native code]”
8.7.6 Function()构造函数var f = new Function("x", "y", "return x*y;");
关于Function()构造函数有几点需要特别注意:
- Function()构造函数允许JavaScript在运行时动态地创建并编译函数。
- 每次调用Function()构造函数都会解析函数体,并创建新的函数对象。如果是在一个循环或者多次调用的函数中执行这个构造函数,执行效率会受影响。相比之下,循环中的嵌套函数和函数定义表达式则不会每次执行时都重新编译。
- 最后一点,也是关于Function()构造函数非常重要的一点,就是它所创建的函数并不是使用词法作用域,相反,函数体代码的编译总是会在顶层函数执行,正如下面代码所示:
1
2
3
4
5
6
7
8
9var scope = "global";
function constructFunction() {
var scope = "local";
return new Function("return scope"); // Does not capture the local scope!
}
// This line returns "global" because the function returned by the
// Function() constructor does not use the local scope.
constructFunction()(); // => "global"
8.7.7 可调用的对象
1 | /** |
8.8 函数式编程
8.8.2 高阶函数
所谓高阶函数,就是操作函数的函数,它接受一个或多个函数作为参数,并返回一个新函数。1
2
3
4
5
6
7
8
9
10
11
12
13// This higher-order function returns a new function that passes its
// arguments to f and returns the logical negation of f's return value;
function not(f) {
return function() { // Return a new function
var result = f.apply(this, arguments); // that calls f
return !result; // and negates its result.
};
}
var even = function(x) { // A function to determine if a number is even
return x % 2 === 0;
};
var odd = not(even); // A new function that does the opposite
[1, 1, 3, 5, 5].every(odd); // => true: every element of the array is odd
8.8.3 不完全函数
8.8.4 记忆1
2
3
4
5
6
7
8
9
10
11// Return a memoized version of f.
// It only works if arguments to f all have distinct string representations.
function memoize(f) {
var cache = {}; // Value cache stored in the closure.
return function() {
// Create a string version of the arguments to use as a cache key.
var key = arguments.length + Array.prototype.join.call(arguments, ",");
if (key in cache) return cache[key];
else return cache[key] = f.apply(this, arguments);
};
}