函数进阶
Rest参数和Spread语法
Rest参数
在函数定义时可以使用...args来用args数组收集后边所有的参数。...args后边不能再定义形参
例如,我们需要把所有的参数都放到数组 args
中:
1 | function sumAll(...args) { // 数组名为 args |
我们也可以选择获取第一个参数作为变量,并将剩余的参数收集起来
下面的例子把前两个参数定义为变量,并把剩余的参数收集到
titles
数组中:
1 | function showName(firstName, lastName, ...titles) { |
arguments变量
有一个名为 arguments
的特殊的类数组对象,该对象按参数索引包含所有参数。
例如:
1 | function showName() { |
但是arguments没有array的方法,因此最好用rest函数
Spread语法
与rest参数相反,使用时在变量名前加...就可以拆出来,内部使用了迭代器的原理
1 | let str = "Hello"; |
用spread合并数组
1 | let a = [1,2,3],b = [4,5,6] |
进行浅拷贝
1 | let arr = [1, 2, 3]; |
总结
有一个简单的方法可以区分它们:
- 若
...
出现在函数参数列表的最后,那么它就是 rest 参数,它会把参数列表中剩余的参数收集到一个数组中。 - 若
...
出现在函数调用或类似的表达式中,那它就是 spread 语法,它会把一个数组展开为列表。
使用场景:
- Rest 参数用于创建可接受任意数量参数的函数。
- Spread 语法用于将数组传递给通常需要含有许多参数的列表的函数。
变量作用域,闭包
代码块
用{}包裹的代码是一个代码块
1 | { |
函数对象
name:返回函数的名称
length:返回函数参数数量
自定义属性
1
2
3
4
5
6
7
8
9
10
11
12function sayHi() {
alert("Hi");
// 计算调用次数
sayHi.counter++;
}
sayHi.counter = 0; // 初始值
sayHi(); // Hi
sayHi(); // Hi
alert( `Called ${sayHi.counter} times` ); // Called 2 times命名函数表达式
1
2
3
4let sayHi = function func(who) {
alert(`Hello, ${who}`);
};func不会被外界所知,可以在函数内进行很方便的使用。
setTimeout和setInterval
setTimeout
允许我们将函数推迟到一段时间间隔之后再执行。setInterval
允许我们重复运行一个函数,从一段时间间隔之后开始运行,之后以该时间间隔连续重复运行该函数。
setTimeout
语法:
1 | let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...) |
参数说明:
func|code
想要执行的函数或代码字符串。 一般传入的都是函数。由于某些历史原因,支持传入代码字符串,但是不建议这样做。
delay
执行前的延时,以毫秒为单位(1000 毫秒 = 1 秒),默认值是 0;
arg1
,arg2
…要传入被执行函数(或代码字符串)的参数列表(IE9 以下不支持)
传入函数不要加括号。
setInterval
setInterval
方法和 setTimeout
的语法相同:
1 | let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...) |
所有参数的意义也是相同的。不过与 setTimeout
只执行一次不同,setInterval
是每间隔给定的时间周期性执行。
想要阻止后续调用,我们需要调用
clearInterval(timerId)
。
例:编写一个函数
printNumbers(from, to)
,使其每秒输出一个数字,数字从
from
开始,到 to
结束。
使用 setInterval
:
1 | function printNumbers(from, to) { |
使用嵌套的 setTimeout
:
1 | function printNumbers(from, to) { |
请注意,在这两种解决方案中,在第一个输出之前都有一个初始延迟。函数在
1000ms
之后才被第一次调用。
如果我们还希望函数立即运行,那么我们可以在单独的一行上添加一个额外的调用,像这样:
1 | function printNumbers(from, to) { |
装饰器,call/apply
缓存
1 | function slow(x) { |
call/apply
1 | func.apply(context, args) |
它运行 func
设置
this=context
,并使用类数组对象 args
作为参数列表(arguments)。
call
和 apply
之间唯一的语法区别是,call
期望一个参数列表,而
apply
期望一个包含这些参数的类数组对象。
方法借用:
1 | function hash() { |
函数绑定
let fun1 = func.bind(context,...args)可以把函数绑定了this赋值给fun1
箭头函数
没有this,没有arguments